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