@gracker/smartperfetto 1.0.20 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/agent/config/domainManifest.d.ts +5 -3
  2. package/dist/agent/config/domainManifest.d.ts.map +1 -1
  3. package/dist/agent/config/domainManifest.js +120 -5
  4. package/dist/agent/config/domainManifest.js.map +1 -1
  5. package/dist/agent/core/orchestratorTypes.d.ts +5 -0
  6. package/dist/agent/core/orchestratorTypes.d.ts.map +1 -1
  7. package/dist/agent/core/orchestratorTypes.js.map +1 -1
  8. package/dist/agent/scene/buildSmartChatReport.d.ts +13 -0
  9. package/dist/agent/scene/buildSmartChatReport.d.ts.map +1 -0
  10. package/dist/agent/scene/buildSmartChatReport.js +333 -0
  11. package/dist/agent/scene/buildSmartChatReport.js.map +1 -0
  12. package/dist/agent/scene/sceneAnalysisJobRunner.d.ts +8 -4
  13. package/dist/agent/scene/sceneAnalysisJobRunner.d.ts.map +1 -1
  14. package/dist/agent/scene/sceneAnalysisJobRunner.js +78 -3
  15. package/dist/agent/scene/sceneAnalysisJobRunner.js.map +1 -1
  16. package/dist/agent/scene/sceneIntervalBuilder.d.ts +14 -5
  17. package/dist/agent/scene/sceneIntervalBuilder.d.ts.map +1 -1
  18. package/dist/agent/scene/sceneIntervalBuilder.js +578 -1
  19. package/dist/agent/scene/sceneIntervalBuilder.js.map +1 -1
  20. package/dist/agent/scene/sceneStage1Verifier.d.ts +8 -0
  21. package/dist/agent/scene/sceneStage1Verifier.d.ts.map +1 -0
  22. package/dist/agent/scene/sceneStage1Verifier.js +245 -0
  23. package/dist/agent/scene/sceneStage1Verifier.js.map +1 -0
  24. package/dist/agent/scene/sceneStoryService.d.ts +20 -2
  25. package/dist/agent/scene/sceneStoryService.d.ts.map +1 -1
  26. package/dist/agent/scene/sceneStoryService.js +238 -25
  27. package/dist/agent/scene/sceneStoryService.js.map +1 -1
  28. package/dist/agent/scene/smartCancelBridge.d.ts +13 -0
  29. package/dist/agent/scene/smartCancelBridge.d.ts.map +1 -0
  30. package/dist/agent/scene/smartCancelBridge.js +44 -0
  31. package/dist/agent/scene/smartCancelBridge.js.map +1 -0
  32. package/dist/agent/scene/smartDeepDiveDispatch.d.ts +15 -0
  33. package/dist/agent/scene/smartDeepDiveDispatch.d.ts.map +1 -0
  34. package/dist/agent/scene/smartDeepDiveDispatch.js +170 -0
  35. package/dist/agent/scene/smartDeepDiveDispatch.js.map +1 -0
  36. package/dist/agent/scene/types.d.ts +97 -6
  37. package/dist/agent/scene/types.d.ts.map +1 -1
  38. package/dist/agent/types.d.ts +1 -1
  39. package/dist/agent/types.d.ts.map +1 -1
  40. package/dist/agent/types.js.map +1 -1
  41. package/dist/agentv3/strategyLoader.d.ts +3 -0
  42. package/dist/agentv3/strategyLoader.d.ts.map +1 -1
  43. package/dist/agentv3/strategyLoader.js +17 -4
  44. package/dist/agentv3/strategyLoader.js.map +1 -1
  45. package/dist/config/index.d.ts +12 -0
  46. package/dist/config/index.d.ts.map +1 -1
  47. package/dist/config/index.js +6 -0
  48. package/dist/config/index.js.map +1 -1
  49. package/dist/routes/agent/finalizeAgentDrivenSession.d.ts +67 -0
  50. package/dist/routes/agent/finalizeAgentDrivenSession.d.ts.map +1 -0
  51. package/dist/routes/agent/finalizeAgentDrivenSession.js +103 -0
  52. package/dist/routes/agent/finalizeAgentDrivenSession.js.map +1 -0
  53. package/dist/routes/agent/normalizeAnalyzeOptions.d.ts +42 -0
  54. package/dist/routes/agent/normalizeAnalyzeOptions.d.ts.map +1 -0
  55. package/dist/routes/agent/normalizeAnalyzeOptions.js +185 -0
  56. package/dist/routes/agent/normalizeAnalyzeOptions.js.map +1 -0
  57. package/dist/routes/agentRoutes.d.ts.map +1 -1
  58. package/dist/routes/agentRoutes.js +285 -125
  59. package/dist/routes/agentRoutes.js.map +1 -1
  60. package/dist/scripts/verifyAgentSseScrolling.js +131 -8
  61. package/dist/scripts/verifyAgentSseScrolling.js.map +1 -1
  62. package/dist/services/sceneReport/sceneJobArtifactStore.d.ts +22 -0
  63. package/dist/services/sceneReport/sceneJobArtifactStore.d.ts.map +1 -0
  64. package/dist/services/sceneReport/sceneJobArtifactStore.js +65 -0
  65. package/dist/services/sceneReport/sceneJobArtifactStore.js.map +1 -0
  66. package/dist/services/sceneReport/sceneReportMemoryCache.d.ts +5 -3
  67. package/dist/services/sceneReport/sceneReportMemoryCache.d.ts.map +1 -1
  68. package/dist/services/sceneReport/sceneReportMemoryCache.js +15 -10
  69. package/dist/services/sceneReport/sceneReportMemoryCache.js.map +1 -1
  70. package/dist/services/sceneReport/sceneReportStore.d.ts +9 -4
  71. package/dist/services/sceneReport/sceneReportStore.d.ts.map +1 -1
  72. package/dist/services/sceneReport/sceneReportStore.js +27 -7
  73. package/dist/services/sceneReport/sceneReportStore.js.map +1 -1
  74. package/dist/services/traceProcessor/sqlSemaphore.d.ts +16 -0
  75. package/dist/services/traceProcessor/sqlSemaphore.d.ts.map +1 -0
  76. package/dist/services/traceProcessor/sqlSemaphore.js +63 -0
  77. package/dist/services/traceProcessor/sqlSemaphore.js.map +1 -0
  78. package/dist/types/dataContract.d.ts +1 -1
  79. package/dist/types/dataContract.d.ts.map +1 -1
  80. package/dist/types/dataContract.js +2 -0
  81. package/dist/types/dataContract.js.map +1 -1
  82. package/package.json +1 -1
  83. package/skills/README.md +13 -5
  84. package/skills/composite/device_state_snapshot.skill.yaml +204 -0
  85. package/skills/composite/scene_reconstruction.skill.yaml +5 -1
  86. package/strategies/scene-reconstruction-verifier.template.md +18 -0
  87. package/strategies/scrolling.strategy.md +5 -1
  88. package/strategies/smart.strategy.md +53 -0
  89. package/skills/atomic/device_state_snapshot.skill.yaml +0 -171
@@ -0,0 +1,204 @@
1
+ # SPDX-License-Identifier: AGPL-3.0-or-later
2
+ # Copyright (C) 2024-2026 Gracker (Chris)
3
+ # This file is part of SmartPerfetto. See LICENSE for details.
4
+
5
+ # =============================================================================
6
+ # 设备环境状态快照(组合 Skill)
7
+ # =============================================================================
8
+ # 采集指定窗口内的屏幕、电量、温度、频率、内存压力与 idle 状态。
9
+
10
+ name: device_state_snapshot
11
+ version: "2.0"
12
+ type: composite
13
+ category: system_context
14
+ tier: B
15
+
16
+ meta:
17
+ display_name: "设备环境状态快照"
18
+ description: "采集 trace 期间的设备环境信息(屏幕、电量、温度、CPU、内存、idle 窗口等)"
19
+ icon: "devices"
20
+ tags: [device, state, environment, context, composite]
21
+
22
+ prerequisites:
23
+ required_tables:
24
+ - slice
25
+ - counter
26
+ - counter_track
27
+
28
+ inputs:
29
+ - name: start_ts
30
+ type: timestamp
31
+ required: false
32
+ description: "分析起始时间戳(ns)"
33
+ - name: end_ts
34
+ type: timestamp
35
+ required: false
36
+ description: "分析结束时间戳(ns)"
37
+
38
+ steps:
39
+ - id: environment_snapshot
40
+ type: atomic
41
+ name: "设备环境快照"
42
+ display:
43
+ level: summary
44
+ layer: overview
45
+ title: "设备环境状态"
46
+ columns:
47
+ - name: metric
48
+ label: "指标"
49
+ type: string
50
+ - name: value
51
+ label: "值"
52
+ type: string
53
+ - name: ts
54
+ label: "时间戳"
55
+ type: timestamp
56
+ unit: ns
57
+ clickAction: navigate_timeline
58
+ sql: |
59
+ WITH trace_bounds AS (
60
+ SELECT
61
+ COALESCE(${start_ts}, (SELECT MIN(ts) FROM slice)) as t_start,
62
+ COALESCE(${end_ts}, (SELECT MAX(ts + dur) FROM slice)) as t_end
63
+ ),
64
+ screen_state AS (
65
+ SELECT
66
+ 'screen_state' as metric,
67
+ CASE WHEN c.value > 0 THEN 'ON' ELSE 'OFF' END as value,
68
+ c.ts as ts
69
+ FROM counter c
70
+ JOIN counter_track ct ON c.track_id = ct.id
71
+ CROSS JOIN trace_bounds tb
72
+ WHERE (ct.name GLOB '*ScreenState*' OR ct.name GLOB '*screen_state*')
73
+ AND c.ts >= tb.t_start AND c.ts <= tb.t_end
74
+ ORDER BY c.ts DESC
75
+ LIMIT 1
76
+ ),
77
+ battery_info AS (
78
+ SELECT
79
+ 'battery_level' as metric,
80
+ CAST(c.value AS TEXT) as value,
81
+ c.ts as ts
82
+ FROM counter c
83
+ JOIN counter_track ct ON c.track_id = ct.id
84
+ CROSS JOIN trace_bounds tb
85
+ WHERE (ct.name GLOB '*battery_level*' OR ct.name GLOB '*BatteryLevel*')
86
+ AND c.ts >= tb.t_start AND c.ts <= tb.t_end
87
+ ORDER BY c.ts DESC
88
+ LIMIT 1
89
+ ),
90
+ charging_info AS (
91
+ SELECT
92
+ 'charging_state' as metric,
93
+ CASE WHEN c.value > 0 THEN 'CHARGING' ELSE 'NOT_CHARGING' END as value,
94
+ c.ts as ts
95
+ FROM counter c
96
+ JOIN counter_track ct ON c.track_id = ct.id
97
+ CROSS JOIN trace_bounds tb
98
+ WHERE (ct.name GLOB '*battery_status*' OR ct.name GLOB '*charging*' OR ct.name GLOB '*BatteryStatus*')
99
+ AND c.ts >= tb.t_start AND c.ts <= tb.t_end
100
+ ORDER BY c.ts DESC
101
+ LIMIT 1
102
+ ),
103
+ thermal_info AS (
104
+ SELECT
105
+ 'thermal_zone' as metric,
106
+ ct.name || ': ' || CAST(ROUND(MAX(CASE WHEN c.value > 1000 THEN c.value / 1000.0 ELSE c.value END), 1) AS TEXT) || ' C' as value,
107
+ MAX(c.ts) as ts
108
+ FROM counter c
109
+ JOIN counter_track ct ON c.track_id = ct.id
110
+ CROSS JOIN trace_bounds tb
111
+ WHERE (ct.name GLOB '*thermal_zone*' OR ct.name GLOB '*Temperature*' OR ct.name GLOB '*temp*')
112
+ AND c.ts >= tb.t_start AND c.ts <= tb.t_end
113
+ GROUP BY ct.name
114
+ ORDER BY MAX(c.value) DESC
115
+ LIMIT 5
116
+ ),
117
+ memory_info AS (
118
+ SELECT
119
+ 'memory_pressure' as metric,
120
+ ct.name || ': ' || CAST(ROUND(MAX(c.value), 0) AS TEXT) as value,
121
+ MAX(c.ts) as ts
122
+ FROM counter c
123
+ JOIN counter_track ct ON c.track_id = ct.id
124
+ CROSS JOIN trace_bounds tb
125
+ WHERE (ct.name GLOB '*mem.*pressure*' OR ct.name GLOB '*MemFree*' OR ct.name GLOB '*MemAvailable*' OR ct.name GLOB '*psi*mem*')
126
+ AND c.ts >= tb.t_start AND c.ts <= tb.t_end
127
+ GROUP BY ct.name
128
+ ORDER BY MAX(c.value) DESC
129
+ LIMIT 5
130
+ )
131
+ SELECT metric, value, printf('%d', ts) as ts FROM screen_state
132
+ UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM battery_info
133
+ UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM charging_info
134
+ UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM thermal_info
135
+ UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM memory_info
136
+ save_as: environment_snapshot
137
+ synthesize:
138
+ role: overview
139
+ fields:
140
+ - key: metric
141
+ label: 指标
142
+ - key: value
143
+ label: 值
144
+
145
+ - id: idle_window_summary
146
+ type: atomic
147
+ name: "Idle 窗口摘要"
148
+ optional: true
149
+ display:
150
+ level: detail
151
+ layer: list
152
+ title: "Idle / 空闲窗口"
153
+ columns:
154
+ - name: start_ts
155
+ label: "开始"
156
+ type: timestamp
157
+ unit: ns
158
+ clickAction: navigate_timeline
159
+ - name: end_ts
160
+ label: "结束"
161
+ type: timestamp
162
+ unit: ns
163
+ clickAction: navigate_timeline
164
+ - name: dur_ms
165
+ label: "时长"
166
+ type: duration
167
+ unit: ms
168
+ - name: source
169
+ label: "来源"
170
+ type: string
171
+ sql: |
172
+ WITH trace_bounds AS (
173
+ SELECT
174
+ COALESCE(${start_ts}, (SELECT MIN(ts) FROM slice)) as t_start,
175
+ COALESCE(${end_ts}, (SELECT MAX(ts + dur) FROM slice)) as t_end
176
+ )
177
+ SELECT
178
+ printf('%d', s.ts) as start_ts,
179
+ printf('%d', s.ts + s.dur) as end_ts,
180
+ ROUND(s.dur / 1000000.0, 2) as dur_ms,
181
+ s.name as source
182
+ FROM slice s
183
+ CROSS JOIN trace_bounds tb
184
+ WHERE s.dur > 0
185
+ AND s.ts + s.dur > tb.t_start
186
+ AND s.ts < tb.t_end
187
+ AND (
188
+ s.name GLOB '*idle*'
189
+ OR s.name GLOB '*Idle*'
190
+ OR s.name GLOB '*suspend*'
191
+ OR s.name GLOB '*doze*'
192
+ )
193
+ ORDER BY s.dur DESC
194
+ LIMIT 20
195
+ save_as: idle_window_summary
196
+ synthesize:
197
+ role: list
198
+ fields:
199
+ - key: dur_ms
200
+ label: Idle 时长
201
+ format: "{{value}} ms"
202
+
203
+ output:
204
+ format: structured
@@ -573,6 +573,9 @@ steps:
573
573
  - name: gesture_id
574
574
  label: "手势ID"
575
575
  type: number
576
+ - name: app_package
577
+ label: "前台应用"
578
+ type: string
576
579
  - name: category
577
580
  label: "类别"
578
581
  type: string
@@ -633,6 +636,7 @@ steps:
633
636
  ELSE ''
634
637
  END AS event,
635
638
  gesture_id,
639
+ app AS app_package,
636
640
  'scroll_start' AS category,
637
641
  '💡 此时刻手指已移动足够距离,系统开始响应滑动' AS explanation
638
642
  FROM scroll_starts
@@ -2785,4 +2789,4 @@ steps:
2785
2789
 
2786
2790
  output:
2787
2791
  format: layered
2788
- default_expanded: [L1, L2]
2792
+ default_expanded: [L1, L2]
@@ -0,0 +1,18 @@
1
+ <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
2
+ <!-- Copyright (C) 2024-2026 Gracker (Chris) -->
3
+ <!-- This file is part of SmartPerfetto. See LICENSE for details. -->
4
+
5
+ 你是 Android Perfetto trace 的场景还原复核器。请检查下面的 Smart 场景时间线是否存在明显的拆分、合并、类型或归因问题。
6
+
7
+ 只能基于输入证据判断,不要创造没有证据的场景。不要输出长报告。
8
+
9
+ 请只输出 JSON,格式:{"status":"passed|needs_review","summary":"一句中文复核意见"}。
10
+
11
+ deterministic_summary:
12
+ {{deterministicSummary}}
13
+
14
+ deterministic_issues:
15
+ {{deterministicIssues}}
16
+
17
+ scenes:
18
+ {{scenes}}
@@ -107,7 +107,7 @@ phase_hints:
107
107
  critical: false
108
108
  - id: conclusion
109
109
  keywords: ['结论', 'conclusion', '输出', 'output', '报告', 'report', '总结']
110
- constraints: '输出必须包含:全帧根因分布表(按 reason_code 聚合)+ 代表帧分析(含四象限+频率+根因推理链)+ 按优先级排序的优化建议。每个 CRITICAL/HIGH 必须有量化证据+因果链。'
110
+ constraints: '输出必须包含:全帧根因分布表(按 reason_code 聚合)+ 代表帧分析(含四象限+频率+根因推理链)+ 按优先级排序的优化建议。每个 CRITICAL/HIGH 必须有量化证据+因果链。若深钻证据纠正了 batch reason_code(例如 lock_binder_wait 但 binder_overlap_ms=0,render_slices_json 指向 cache_miss/makePipeline/shader 编译),最终结论必须使用纠正后的根因命名,并明确标注原 reason_code 为误分类。'
111
111
  critical_tools: []
112
112
  critical: false
113
113
 
@@ -347,6 +347,10 @@ Phase 1 的 `batch_frame_root_cause` 已包含每帧的**完整统计数据**(
347
347
  - **reason_code 为 unknown 且帧数 >5%**:必须对至少 1 帧调用 jank_frame_detail 获取更多线索,不能在分布表中仅标记"未分类"就跳过
348
348
  - reason_code 与实际数据矛盾时(如 `lock_binder_wait` 但 Binder 耗时 0ms):应在结论中标注可能的误分类原因
349
349
 
350
+ 如果深钻结果已给出更具体的根因,不要在最终报告继续把原始 `reason_code` 当作根因名称。典型例子:
351
+ - `lock_binder_wait` 但 `binder_overlap_ms=0`,且 `render_slices_json` 出现 `cache_miss: makePipeline` / shader 编译 / Vulkan finish frame / `postAndWait`,最终根因应写成 **shader_compile + sync_wait** 或等价机制,并说明 `lock_binder_wait` 是批量分类误判。
352
+ - `workload_heavy` 但 `main_slices_json` 明确指向应用自定义方法,最终根因应写具体方法名和所处阶段,例如 `CustomScroll_longFrameLoad` 在 ANIMATION 回调同步执行,而不是只写 "workload_heavy"。
353
+
350
354
  `frame_blocking_calls` 是 Phase 1.9 的帧内阻塞证据补充,不占 `jank_frame_detail` 的 2 帧上限。遇到 Binder/IO/futex/锁相关根因时,优先用它确认阻塞调用是否真的与掉帧帧重叠。
351
355
 
352
356
  ```
@@ -0,0 +1,53 @@
1
+ <!--
2
+ SPDX-License-Identifier: AGPL-3.0-or-later
3
+ Copyright (C) 2024-2026 Gracker (Chris)
4
+ This file is part of SmartPerfetto. See LICENSE for details.
5
+ -->
6
+ ---
7
+ scene: smart
8
+ strategy_kind: contract_only
9
+ priority: 5
10
+ effort: high
11
+ keywords:
12
+ - smart
13
+ - 智能
14
+ - mixed trace
15
+ - 场景混合
16
+ required_capabilities: []
17
+ optional_capabilities: []
18
+ final_report_contract:
19
+ required_sections:
20
+ - id: scene_timeline
21
+ label: 场景时间线
22
+ description: 按时间顺序列出 trace 中检测到的关键用户操作和设备状态场景。
23
+ pattern_groups:
24
+ - ["场景时间线", "timeline", "时间线"]
25
+ - ["冷启动", "热启动", "滑动", "点击", "返回", "Home", "亮屏", "熄屏", "ANR"]
26
+ - id: per_scene_summary
27
+ label: 分场景摘要
28
+ description: 对每个被深度分析的场景给出关键指标、结论和证据引用。
29
+ pattern_groups:
30
+ - ["分场景", "逐场景", "per-scene"]
31
+ - ["证据", "指标", "耗时", "延迟", "帧"]
32
+ - id: cross_scene_narrative
33
+ label: 跨场景叙事
34
+ description: 总结多个场景之间的关联、共同瓶颈或前后影响。
35
+ pattern_groups:
36
+ - ["跨场景", "整体", "关联", "链路"]
37
+ - ["原因", "影响", "共同", "瓶颈"]
38
+ - id: bottleneck_ranking
39
+ label: 瓶颈排序
40
+ description: 按影响范围、严重度和可行动性给出优化优先级。
41
+ pattern_groups:
42
+ - ["瓶颈排序", "优先级", "ranking"]
43
+ - ["P0", "P1", "优先", "建议"]
44
+ ---
45
+
46
+ # Smart Analysis Contract
47
+
48
+ This strategy is intentionally contract-only. It must not be injected as a
49
+ normal scene strategy and must not participate in scene classification.
50
+
51
+ Smart Analysis Mode combines Scene Story detection with profile-specific
52
+ deep-dive routes, then projects the resulting scene report into a readable chat
53
+ summary and the standard HTML report chain.
@@ -1,171 +0,0 @@
1
- # SPDX-License-Identifier: AGPL-3.0-or-later
2
- # Copyright (C) 2024-2026 Gracker (Chris)
3
- # This file is part of SmartPerfetto. See LICENSE for details.
4
-
5
- # =============================================================================
6
- # 设备环境状态快照(原子 Skill)
7
- # =============================================================================
8
- # 采集 trace 期间的设备环境信息:屏幕状态、电量、温度、CPU 频率、内存压力等。
9
-
10
- name: device_state_snapshot
11
- version: "1.0"
12
- type: atomic
13
- category: system_context
14
- tier: B
15
-
16
- meta:
17
- display_name: "设备环境状态快照"
18
- description: "采集 trace 期间的设备环境信息(屏幕、电量、温度、CPU、内存等)"
19
- icon: "devices"
20
- tags: [device, state, environment, context, atomic]
21
-
22
- prerequisites:
23
- required_tables:
24
- - counter
25
- - counter_track
26
-
27
- inputs:
28
- - name: start_ts
29
- type: timestamp
30
- required: false
31
- description: "分析起始时间戳(ns)"
32
- - name: end_ts
33
- type: timestamp
34
- required: false
35
- description: "分析结束时间戳(ns)"
36
-
37
- display:
38
- level: summary
39
- layer: overview
40
- title: "设备环境状态"
41
- columns:
42
- - name: metric
43
- label: "指标"
44
- type: string
45
- - name: value
46
- label: "值"
47
- type: string
48
- - name: ts
49
- label: "时间戳"
50
- type: timestamp
51
- unit: ns
52
- clickAction: navigate_timeline
53
-
54
- sql: |
55
- WITH trace_bounds AS (
56
- SELECT
57
- COALESCE(${start_ts}, (SELECT MIN(ts) FROM slice)) as t_start,
58
- COALESCE(${end_ts}, (SELECT MAX(ts + dur) FROM slice)) as t_end
59
- ),
60
- screen_state AS (
61
- SELECT
62
- 'screen_state' as metric,
63
- CASE WHEN c.value > 0 THEN 'ON' ELSE 'OFF' END as value,
64
- c.ts as ts
65
- FROM counter c
66
- JOIN counter_track ct ON c.track_id = ct.id
67
- WHERE ct.name GLOB '*ScreenState*' OR ct.name GLOB '*screen_state*'
68
- ORDER BY c.ts DESC
69
- LIMIT 1
70
- ),
71
- battery_info AS (
72
- SELECT
73
- 'battery_level' as metric,
74
- CAST(c.value AS TEXT) as value,
75
- c.ts as ts
76
- FROM counter c
77
- JOIN counter_track ct ON c.track_id = ct.id
78
- WHERE ct.name GLOB '*battery_level*' OR ct.name GLOB '*BatteryLevel*'
79
- ORDER BY c.ts DESC
80
- LIMIT 1
81
- ),
82
- charging_info AS (
83
- SELECT
84
- 'charging_state' as metric,
85
- CASE WHEN c.value > 0 THEN 'CHARGING' ELSE 'NOT_CHARGING' END as value,
86
- c.ts as ts
87
- FROM counter c
88
- JOIN counter_track ct ON c.track_id = ct.id
89
- WHERE ct.name GLOB '*battery_status*' OR ct.name GLOB '*charging*' OR ct.name GLOB '*BatteryStatus*'
90
- ORDER BY c.ts DESC
91
- LIMIT 1
92
- ),
93
- thermal_info AS (
94
- SELECT
95
- 'thermal_zone' as metric,
96
- ct.name || ': ' || CAST(ROUND(MAX(c.value) / 1000.0, 1) AS TEXT) || '°C' as value,
97
- MAX(c.ts) as ts
98
- FROM counter c
99
- JOIN counter_track ct ON c.track_id = ct.id
100
- CROSS JOIN trace_bounds tb
101
- WHERE (ct.name GLOB '*thermal_zone*' OR ct.name GLOB '*Temperature*')
102
- AND c.ts >= tb.t_start AND c.ts <= tb.t_end
103
- GROUP BY ct.name
104
- ORDER BY MAX(c.value) DESC
105
- LIMIT 5
106
- ),
107
- cpu_freq_summary AS (
108
- SELECT
109
- 'cpu_max_freq' as metric,
110
- 'CPU' || ct.name || ': ' || CAST(ROUND(MAX(c.value) / 1e6, 2) AS TEXT) || 'GHz' as value,
111
- MAX(c.ts) as ts
112
- FROM counter c
113
- JOIN cpu_counter_track ct ON c.track_id = ct.id
114
- CROSS JOIN trace_bounds tb
115
- WHERE ct.name = 'cpufreq'
116
- AND c.ts >= tb.t_start AND c.ts <= tb.t_end
117
- GROUP BY ct.cpu
118
- ORDER BY ct.cpu
119
- ),
120
- memory_info AS (
121
- SELECT
122
- 'memory_pressure' as metric,
123
- CAST(ROUND(MAX(c.value), 0) AS TEXT) as value,
124
- MAX(c.ts) as ts
125
- FROM counter c
126
- JOIN counter_track ct ON c.track_id = ct.id
127
- CROSS JOIN trace_bounds tb
128
- WHERE (ct.name GLOB '*mem.*pressure*' OR ct.name GLOB '*MemFree*' OR ct.name GLOB '*MemAvailable*')
129
- AND c.ts >= tb.t_start AND c.ts <= tb.t_end
130
- ),
131
- process_count AS (
132
- SELECT
133
- 'active_processes' as metric,
134
- CAST(COUNT(DISTINCT p.upid) AS TEXT) as value,
135
- NULL as ts
136
- FROM process p
137
- JOIN thread t ON t.upid = p.upid
138
- JOIN thread_state ts_tbl ON ts_tbl.utid = t.utid
139
- CROSS JOIN trace_bounds tb
140
- WHERE ts_tbl.ts >= tb.t_start AND ts_tbl.ts <= tb.t_end
141
- AND ts_tbl.state = 'Running'
142
- ),
143
- oom_adj AS (
144
- SELECT
145
- 'foreground_apps' as metric,
146
- GROUP_CONCAT(p.name, ', ') as value,
147
- NULL as ts
148
- FROM (
149
- SELECT DISTINCT p.name, p.upid
150
- FROM counter c
151
- JOIN process_counter_track pct ON c.track_id = pct.id
152
- JOIN process p ON p.upid = pct.upid
153
- CROSS JOIN trace_bounds tb
154
- WHERE pct.name = 'oom_score_adj'
155
- AND c.value <= 0
156
- AND c.ts >= tb.t_start AND c.ts <= tb.t_end
157
- AND p.name IS NOT NULL AND p.name != ''
158
- LIMIT 10
159
- ) p
160
- )
161
- SELECT metric, value, printf('%d', ts) as ts FROM screen_state
162
- UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM battery_info
163
- UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM charging_info
164
- UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM thermal_info
165
- UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM cpu_freq_summary
166
- UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM memory_info
167
- UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM process_count
168
- UNION ALL SELECT metric, value, printf('%d', ts) as ts FROM oom_adj
169
-
170
- output:
171
- format: structured