1-- 2-- Copyright 2019 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 17-- Create the base tables and views containing the launch spans. 18SELECT RUN_METRIC('android/android_startup_launches.sql'); 19SELECT RUN_METRIC('android/android_task_state.sql'); 20SELECT RUN_METRIC('android/process_metadata.sql'); 21 22-- Slices for forked processes. Never present in hot starts. 23-- Prefer this over process start_ts, since the process might have 24-- been preforked. 25CREATE VIEW zygote_fork_slice AS 26SELECT slice.ts, slice.dur, STR_SPLIT(slice.name, ": ", 1) AS process_name 27FROM slice WHERE name LIKE 'Start proc: %'; 28 29CREATE TABLE zygote_forks_by_id AS 30SELECT 31 launches.id, 32 zygote_fork_slice.ts, 33 zygote_fork_slice.dur 34FROM zygote_fork_slice 35JOIN launches 36ON (launches.ts < zygote_fork_slice.ts 37 AND zygote_fork_slice.ts + zygote_fork_slice.dur < launches.ts_end 38 AND zygote_fork_slice.process_name = launches.package 39); 40 41CREATE VIEW launch_main_threads AS 42SELECT 43 launches.ts AS ts, 44 launches.dur AS dur, 45 launches.id AS launch_id, 46 thread.utid AS utid 47FROM launches 48JOIN launch_processes ON launches.id = launch_processes.launch_id 49JOIN process USING(upid) 50JOIN thread ON (process.upid = thread.upid AND process.pid = thread.tid) 51ORDER BY ts; 52 53CREATE VIRTUAL TABLE main_thread_state 54USING SPAN_JOIN( 55 launch_main_threads PARTITIONED utid, 56 task_state PARTITIONED utid); 57 58CREATE VIEW launch_by_thread_state AS 59SELECT launch_id, state, SUM(dur) AS dur 60FROM main_thread_state 61GROUP BY 1, 2; 62 63-- Tracks all slices for the main process threads 64CREATE TABLE main_process_slice AS 65SELECT 66 launches.id AS launch_id, 67 slice.name AS name, 68 AndroidStartupMetric_Slice( 69 'dur_ns', SUM(slice.dur), 70 'dur_ms', SUM(slice.dur) / 1e6 71 ) AS slice_proto 72FROM launches 73JOIN launch_processes ON (launches.id = launch_processes.launch_id) 74JOIN thread ON (launch_processes.upid = thread.upid) 75JOIN thread_track USING (utid) 76JOIN slice ON ( 77 slice.track_id = thread_track.id 78 AND slice.ts BETWEEN launches.ts AND launches.ts + launches.dur) 79WHERE slice.name IN ( 80 'PostFork', 81 'ActivityThreadMain', 82 'bindApplication', 83 'activityStart', 84 'activityResume', 85 'Choreographer#doFrame', 86 'inflate') 87GROUP BY 1, 2; 88 89CREATE VIEW to_event_protos AS 90SELECT 91 slice.name as slice_name, 92 launch_id, 93 AndroidStartupMetric_Slice( 94 'dur_ns', slice.ts - l.ts, 95 'dur_ms', (slice.ts - l.ts) / 1e6 96 ) as slice_proto 97FROM launch_main_threads l 98JOIN thread_track USING (utid) 99JOIN slice ON ( 100 slice.track_id = thread_track.id 101 AND slice.ts BETWEEN l.ts AND l.ts + l.dur); 102 103CREATE VIEW startup_view AS 104SELECT 105 AndroidStartupMetric_Startup( 106 'startup_id', launches.id, 107 'package_name', launches.package, 108 'process_name', ( 109 SELECT name FROM process 110 WHERE upid IN ( 111 SELECT upid FROM launch_processes 112 WHERE launch_id = launches.id 113 LIMIT 1 114 ) 115 ), 116 'process', ( 117 SELECT metadata FROM process_metadata 118 WHERE upid IN ( 119 SELECT upid FROM launch_processes 120 WHERE launch_id = launches.id 121 LIMIT 1 122 ) 123 ), 124 'zygote_new_process', EXISTS(SELECT TRUE FROM zygote_forks_by_id WHERE id = launches.id), 125 'activity_hosting_process_count', ( 126 SELECT COUNT(1) FROM launch_processes WHERE launch_id = launches.id 127 ), 128 'to_first_frame', AndroidStartupMetric_ToFirstFrame( 129 'dur_ns', launches.dur, 130 'dur_ms', launches.dur / 1e6, 131 'main_thread_by_task_state', AndroidStartupMetric_TaskStateBreakdown( 132 'running_dur_ns', IFNULL( 133 ( 134 SELECT dur FROM launch_by_thread_state 135 WHERE launch_id = launches.id AND state = 'running' 136 ), 0), 137 'runnable_dur_ns', IFNULL( 138 ( 139 SELECT dur FROM launch_by_thread_state 140 WHERE launch_id = launches.id AND state = 'runnable' 141 ), 0), 142 'uninterruptible_sleep_dur_ns', IFNULL( 143 ( 144 SELECT dur FROM launch_by_thread_state 145 WHERE launch_id = launches.id AND state = 'uninterruptible' 146 ), 0), 147 'interruptible_sleep_dur_ns', IFNULL( 148 ( 149 SELECT dur FROM launch_by_thread_state 150 WHERE launch_id = launches.id AND state = 'interruptible' 151 ), 0) 152 ), 153 'to_post_fork', ( 154 SELECT slice_proto 155 FROM to_event_protos 156 WHERE launch_id = launches.id AND slice_name = 'PostFork' 157 ), 158 'to_activity_thread_main', ( 159 SELECT slice_proto 160 FROM to_event_protos 161 WHERE launch_id = launches.id AND slice_name = 'ActivityThreadMain' 162 ), 163 'to_bind_application', ( 164 SELECT slice_proto 165 FROM to_event_protos 166 WHERE launch_id = launches.id AND slice_name = 'bindApplication' 167 ), 168 'other_processes_spawned_count', ( 169 SELECT COUNT(1) FROM process 170 WHERE (process.name IS NULL OR process.name != launches.package) 171 AND process.start_ts BETWEEN launches.ts AND launches.ts + launches.dur 172 ), 173 'time_activity_manager', ( 174 SELECT AndroidStartupMetric_Slice( 175 'dur_ns', launching_events.ts - launches.ts, 176 'dur_ms', (launching_events.ts - launches.ts) / 1e6 177 ) 178 FROM launching_events 179 WHERE launching_events.ts BETWEEN launches.ts AND launches.ts + launches.dur 180 ), 181 'time_post_fork', ( 182 SELECT slice_proto FROM main_process_slice 183 WHERE launch_id = launches.id AND name = 'PostFork' 184 ), 185 'time_activity_thread_main', ( 186 SELECT slice_proto FROM main_process_slice 187 WHERE launch_id = launches.id AND name = 'ActivityThreadMain' 188 ), 189 'time_bind_application', ( 190 SELECT slice_proto FROM main_process_slice 191 WHERE launch_id = launches.id AND name = 'bindApplication' 192 ), 193 'time_activity_start', ( 194 SELECT slice_proto FROM main_process_slice 195 WHERE launch_id = launches.id AND name = 'activityStart' 196 ), 197 'time_activity_resume', ( 198 SELECT slice_proto FROM main_process_slice 199 WHERE launch_id = launches.id AND name = 'activityResume' 200 ), 201 'time_choreographer', ( 202 SELECT slice_proto FROM main_process_slice 203 WHERE launch_id = launches.id AND name = 'Choreographer#doFrame' 204 ), 205 'time_before_start_process', ( 206 SELECT AndroidStartupMetric_Slice( 207 'dur_ns', ts - launches.ts, 208 'dur_ms', (ts - launches.ts) / 1e6 209 ) 210 FROM zygote_forks_by_id WHERE id = launches.id 211 ), 212 'time_during_start_process', ( 213 SELECT AndroidStartupMetric_Slice( 214 'dur_ns', dur, 215 'dur_ms', dur / 1e6 216 ) 217 FROM zygote_forks_by_id WHERE id = launches.id 218 ) 219 ) 220 ) as startup 221FROM launches; 222 223CREATE VIEW android_startup_output AS 224SELECT 225 AndroidStartupMetric( 226 'startup', ( 227 SELECT RepeatedField(startup) FROM startup_view 228 ) 229 ); 230