• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2020 The Android Open Source Project
3--
4-- Licensed under the Apache License, Version 2.0 (the "License");
5-- you may not use this file except in compliance with the License.
6-- You may obtain a copy of the License at
7--
8--     https://www.apache.org/licenses/LICENSE-2.0
9--
10-- Unless required by applicable law or agreed to in writing, software
11-- distributed under the License is distributed on an "AS IS" BASIS,
12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-- See the License for the specific language governing permissions and
14-- limitations under the License.
15
16
17DROP TABLE IF EXISTS android_jank_process_allowlist;
18CREATE TABLE android_jank_process_allowlist AS
19SELECT process.name, process.upid
20FROM process
21WHERE process.name IN (
22  'com.android.systemui',
23  'com.google.android.apps.nexuslauncher',
24  'com.google.android.inputmethod.latin'
25);
26
27SELECT RUN_METRIC(
28  'android/android_hwui_threads.sql',
29  'table_name_prefix', 'android_jank',
30  'process_allowlist_table', 'android_jank_process_allowlist');
31
32DROP TABLE IF EXISTS android_jank_thread_state_running;
33CREATE TABLE android_jank_thread_state_running AS
34SELECT utid, ts, dur, state
35FROM thread_state
36WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
37AND state = 'Running'
38AND dur > 0;
39
40DROP TABLE IF EXISTS android_jank_thread_state_scheduled;
41CREATE TABLE android_jank_thread_state_scheduled AS
42SELECT utid, ts, dur, state
43FROM thread_state
44WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
45AND (state = 'R' OR state = 'R+')
46AND dur > 0;
47
48DROP TABLE IF EXISTS android_jank_thread_state_io_wait;
49CREATE TABLE android_jank_thread_state_io_wait AS
50SELECT utid, ts, dur, state
51FROM thread_state
52WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
53AND (((state = 'D' OR state = 'DK') AND io_wait) OR (state = 'DK' AND io_wait IS NULL))
54AND dur > 0;
55
56--
57-- Main Thread alerts
58--
59
60-- Expensive measure/layout
61
62DROP TABLE IF EXISTS android_jank_measure_layout_slices;
63CREATE TABLE android_jank_measure_layout_slices AS
64SELECT
65  process_name,
66  utid,
67  id,
68  ts,
69  dur
70FROM android_jank_main_thread_slices
71WHERE name in ('measure', 'layout')
72AND dur >= 3000000;
73
74CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_measure_layout_slices_state
75USING span_join(android_jank_measure_layout_slices PARTITIONED utid, android_jank_thread_state_running PARTITIONED utid);
76
77DROP TABLE IF EXISTS android_jank_measure_layout_slices_high_cpu;
78CREATE TABLE android_jank_measure_layout_slices_high_cpu AS
79SELECT id FROM android_jank_measure_layout_slices_state
80GROUP BY id
81HAVING SUM(dur) > 3000000;
82
83DROP TABLE IF EXISTS android_jank_measure_layout_alerts;
84CREATE TABLE android_jank_measure_layout_alerts AS
85SELECT
86  process_name,
87  ts,
88  dur,
89  'Expensive measure/layout pass' as alert_name,
90  id
91FROM android_jank_measure_layout_slices
92JOIN android_jank_measure_layout_slices_high_cpu USING (id);
93
94-- Inflation during ListView recycling
95-- as additional alerts for expensive layout slices
96
97DROP TABLE IF EXISTS android_jank_listview_inflation_alerts;
98CREATE TABLE android_jank_listview_inflation_alerts AS
99SELECT
100  process_name,
101  ts,
102  dur,
103  'Inflation during ListView recycling' as alert_name
104FROM android_jank_main_thread_slices
105WHERE name IN ('obtainView', 'setupListItem')
106AND EXISTS (
107  SELECT 1
108  FROM descendant_slice(android_jank_main_thread_slices.id)
109  WHERE name = 'inflate')
110AND EXISTS(
111  SELECT 1
112  FROM android_jank_measure_layout_alerts
113  JOIN ancestor_slice(android_jank_main_thread_slices.id) USING (id)
114);
115
116-- Long View#draw()
117
118DROP TABLE IF EXISTS android_jank_view_draw_slices;
119CREATE TABLE android_jank_view_draw_slices AS
120SELECT
121  process_name,
122  utid,
123  id,
124  ts,
125  dur
126FROM android_jank_main_thread_slices
127WHERE name in ('getDisplayList', 'Record View#draw()')
128AND dur >= 3000000;
129
130CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_view_draw_slices_state
131USING span_join(android_jank_view_draw_slices PARTITIONED utid, android_jank_thread_state_running PARTITIONED utid);
132
133DROP TABLE IF EXISTS android_jank_view_draw_slices_high_cpu;
134CREATE TABLE android_jank_view_draw_slices_high_cpu AS
135SELECT id FROM android_jank_view_draw_slices_state
136GROUP BY id
137HAVING SUM(dur) > 3000000;
138
139DROP TABLE IF EXISTS android_jank_view_draw_alerts;
140CREATE TABLE android_jank_view_draw_alerts AS
141SELECT
142  process_name,
143  ts,
144  dur,
145  'Long View#draw()' as alert_name
146FROM android_jank_main_thread_slices
147JOIN android_jank_view_draw_slices_high_cpu USING (id);
148
149-- Scheduling delay and Blocking I/O delay
150
151DROP TABLE IF EXISTS android_jank_long_do_frame_slices;
152CREATE TABLE android_jank_long_do_frame_slices AS
153SELECT
154  process_name,
155  utid,
156  id,
157  ts,
158  dur
159FROM android_jank_main_thread_slices
160WHERE name GLOB 'Choreographer#doFrame*'
161AND dur >= 5000000;
162
163CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_do_frame_slices_state_scheduled
164USING span_join(android_jank_long_do_frame_slices PARTITIONED utid, android_jank_thread_state_scheduled PARTITIONED utid);
165
166
167DROP TABLE IF EXISTS android_jank_do_frame_slices_long_scheduled;
168CREATE TABLE android_jank_do_frame_slices_long_scheduled AS
169SELECT id FROM android_jank_do_frame_slices_state_scheduled
170GROUP BY id
171HAVING SUM(dur) > 5000000;
172
173DROP TABLE IF EXISTS android_jank_scheduling_delay_alerts;
174CREATE TABLE android_jank_scheduling_delay_alerts AS
175SELECT
176  process_name,
177  ts,
178  dur,
179  'Scheduling delay' as alert_name
180FROM android_jank_long_do_frame_slices
181JOIN android_jank_do_frame_slices_long_scheduled USING (id);
182
183CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_do_frame_slices_state_io_wait
184USING span_join(android_jank_long_do_frame_slices PARTITIONED utid, android_jank_thread_state_io_wait PARTITIONED utid);
185
186DROP TABLE IF EXISTS android_jank_do_frame_slices_long_io_wait;
187CREATE TABLE android_jank_do_frame_slices_long_io_wait AS
188SELECT id FROM android_jank_do_frame_slices_state_io_wait
189GROUP BY id
190HAVING SUM(dur) > 5000000;
191
192DROP TABLE IF EXISTS android_jank_blocking_delay_alerts;
193CREATE TABLE android_jank_blocking_delay_alerts AS
194SELECT
195  process_name,
196  ts,
197  dur,
198  'Blocking I/O delay' as alert_name
199FROM android_jank_do_frame_slices
200JOIN android_jank_do_frame_slices_long_io_wait USING (id);
201
202--
203-- Render Thread alerts
204--
205
206-- Expensive Canvas#saveLayer()
207
208DROP TABLE IF EXISTS android_jank_save_layer_alerts;
209CREATE TABLE android_jank_save_layer_alerts AS
210SELECT
211  process_name,
212  ts,
213  dur,
214  'Expensive rendering with Canvas#saveLayer()' as alert_name
215FROM android_jank_render_thread_slices
216WHERE name GLOB '*alpha caused *saveLayer *'
217AND dur >= 1000000;
218
219-- Path texture churn
220
221DROP TABLE IF EXISTS android_jank_generate_path_alerts;
222CREATE TABLE android_jank_generate_path_alerts AS
223SELECT
224  process_name,
225  ts,
226  dur,
227  'Path texture churn' as alert_name
228FROM android_jank_render_thread_slices
229WHERE name = 'Generate Path Texture'
230AND dur >= 3000000;
231
232-- Expensive Bitmap uploads
233
234DROP TABLE IF EXISTS android_jank_upload_texture_alerts;
235CREATE TABLE android_jank_upload_texture_alerts AS
236SELECT
237  process_name,
238  ts,
239  dur,
240  'Expensive Bitmap uploads' as alert_name
241FROM android_jank_render_thread_slices
242WHERE name GLOB 'Upload *x* Texture'
243AND dur >= 3000000;
244
245-- Merge all alerts tables into one table
246DROP TABLE IF EXISTS android_jank_alerts;
247CREATE TABLE android_jank_alerts AS
248SELECT process_name, ts, dur, alert_name FROM android_jank_measure_layout_alerts
249UNION ALL
250SELECT process_name, ts, dur, alert_name FROM android_jank_listview_inflation_alerts
251UNION ALL
252SELECT process_name, ts, dur, alert_name FROM android_jank_scheduling_delay_alerts
253UNION ALL
254SELECT process_name, ts, dur, alert_name FROM android_jank_blocking_delay_alerts
255UNION ALL
256SELECT process_name, ts, dur, alert_name FROM android_jank_save_layer_alerts
257UNION ALL
258SELECT process_name, ts, dur, alert_name FROM android_jank_generate_path_alerts
259UNION ALL
260SELECT process_name, ts, dur, alert_name FROM android_jank_upload_texture_alerts;
261
262DROP VIEW IF EXISTS android_jank_event;
263CREATE VIEW android_jank_event AS
264SELECT
265  'slice' as track_type,
266  process_name || ' warnings' as track_name,
267  ts,
268  0 as dur,
269  group_concat(alert_name) as slice_name
270FROM android_jank_alerts
271GROUP BY track_type, track_name, ts;
272
273DROP VIEW IF EXISTS android_jank_output;
274CREATE VIEW android_jank_output AS
275SELECT AndroidJankMetrics(
276  'warnings', (
277    SELECT RepeatedField(
278      AndroidJankMetrics_Warning(
279       'ts', ts,
280       'dur', dur,
281       'process_name', process_name,
282       'warning_text', alert_name))
283    FROM android_jank_alerts
284    ORDER BY process_name, ts, dur));
285