1-- 2-- Copyright 2022 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 17SELECT IMPORT('android.startup.startups'); 18 19-- Helper function to build a Slice proto from a duration. 20SELECT CREATE_FUNCTION('STARTUP_SLICE_PROTO(dur INT)', 'PROTO', ' 21 SELECT AndroidStartupMetric_Slice( 22 "dur_ns", $dur, 23 "dur_ms", $dur / 1e6 24 ) 25'); 26 27-- View containing all the slices for all launches. Generally, this view 28-- should not be used. Instead, one of the helper functions below which wrap 29-- this view should be used. 30DROP VIEW IF EXISTS thread_slices_for_all_launches; 31CREATE VIEW thread_slices_for_all_launches AS 32SELECT * FROM android_thread_slices_for_all_startups; 33 34 35-- Given a launch id and GLOB for a slice name, 36-- summing the slice durations across the whole startup. 37SELECT CREATE_FUNCTION( 38 'ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(startup_id LONG, slice_name STRING)', 39 'INT', 40 ' 41 SELECT SUM(slice_dur) 42 FROM android_thread_slices_for_all_startups 43 WHERE startup_id = $startup_id AND slice_name GLOB $slice_name 44 ' 45); 46 47-- Given a launch id and GLOB for a slice name, returns the startup slice proto, 48-- summing the slice durations across the whole startup. 49SELECT CREATE_FUNCTION( 50 'DUR_SUM_SLICE_PROTO_FOR_LAUNCH(startup_id LONG, slice_name STRING)', 51 'PROTO', 52 ' 53 SELECT NULL_IF_EMPTY( 54 STARTUP_SLICE_PROTO( 55 ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE($startup_id, $slice_name) 56 ) 57 ) 58 ' 59); 60 61-- Same as |DUR_SUM_SLICE_PROTO_FOR_LAUNCH| except only counting slices happening 62-- on the main thread. 63SELECT CREATE_FUNCTION( 64 'DUR_SUM_MAIN_THREAD_SLICE_PROTO_FOR_LAUNCH(startup_id LONG, slice_name STRING)', 65 'PROTO', 66 ' 67 SELECT NULL_IF_EMPTY( 68 STARTUP_SLICE_PROTO( 69 ANDROID_SUM_DUR_ON_MAIN_THREAD_FOR_STARTUP_AND_SLICE($startup_id, $slice_name) 70 ) 71 ) 72 ' 73); 74 75-- Given a launch id and GLOB for a slice name, returns the startup slice proto by 76-- taking the duration between the start of the launch and start of the slice. 77-- If multiple slices match, picks the latest one which started during the launch. 78SELECT CREATE_FUNCTION( 79 'LAUNCH_TO_MAIN_THREAD_SLICE_PROTO(startup_id INT, slice_name STRING)', 80 'PROTO', 81 ' 82 SELECT NULL_IF_EMPTY(STARTUP_SLICE_PROTO(MAX(slice_ts) - startup_ts)) 83 FROM android_thread_slices_for_all_startups s 84 JOIN thread t USING (utid) 85 WHERE 86 s.slice_name GLOB $slice_name AND 87 s.startup_id = $startup_id AND 88 s.is_main_thread AND 89 (t.end_ts IS NULL OR t.end_ts >= s.startup_ts_end) 90 ' 91); 92 93-- Given a lauch id, returns the total time spent in GC 94SELECT CREATE_FUNCTION( 95 'TOTAL_GC_TIME_BY_LAUNCH(startup_id LONG)', 96 'INT', 97 ' 98 SELECT SUM(slice_dur) 99 FROM android_thread_slices_for_all_startups slice 100 WHERE 101 slice.startup_id = $startup_id AND 102 ( 103 slice_name GLOB "*semispace GC" OR 104 slice_name GLOB "*mark sweep GC" OR 105 slice_name GLOB "*concurrent copying GC" 106 ) 107 ' 108); 109 110-- Given a launch id and package name, returns if baseline or cloud profile is missing. 111SELECT CREATE_FUNCTION( 112 'MISSING_BASELINE_PROFILE_FOR_LAUNCH(startup_id LONG, pkg_name STRING)', 113 'BOOL', 114 ' 115 SELECT (COUNT(slice_name) > 0) 116 FROM ( 117 SELECT * 118 FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME( 119 $startup_id, 120 "location=* status=* filter=* reason=*" 121 ) 122 ORDER BY slice_name 123 ) 124 WHERE 125 -- when location is the package odex file and the reason is "install" or "install-dm", 126 -- if the compilation filter is not "speed-profile", baseline/cloud profile is missing. 127 SUBSTR(STR_SPLIT(slice_name, " status=", 0), LENGTH("location=") + 1) 128 GLOB ("*" || $pkg_name || "*odex") 129 AND (STR_SPLIT(slice_name, " reason=", 1) = "install" 130 OR STR_SPLIT(slice_name, " reason=", 1) = "install-dm") 131 AND STR_SPLIT(STR_SPLIT(slice_name, " filter=", 1), " reason=", 0) != "speed-profile" 132 ' 133); 134 135-- Given a launch id, returns if there is a main thread run-from-apk slice. 136-- Add an exception if "split_config" is in parent slice's name(b/277809828). 137-- TODO: remove the exception after Sep 2023 (b/78772867) 138SELECT CREATE_FUNCTION( 139 'RUN_FROM_APK_FOR_LAUNCH(launch_id LONG)', 140 'BOOL', 141 ' 142 SELECT EXISTS( 143 SELECT slice_name, startup_id, is_main_thread 144 FROM android_thread_slices_for_all_startups s 145 JOIN slice ON slice.id = s.slice_id 146 LEFT JOIN slice parent ON slice.parent_id = parent.id 147 WHERE 148 startup_id = $launch_id AND is_main_thread AND 149 slice_name GLOB "location=* status=* filter=* reason=*" AND 150 STR_SPLIT(STR_SPLIT(slice_name, " filter=", 1), " reason=", 0) 151 GLOB ("*" || "run-from-apk" || "*") AND 152 (parent.name IS NULL OR 153 parent.name NOT GLOB ("OpenDexFilesFromOat(*split_config*apk)")) 154 ) 155 ' 156); 157 158SELECT CREATE_VIEW_FUNCTION( 159 'BINDER_TRANSACTION_REPLY_SLICES_FOR_LAUNCH(startup_id INT, threshold DOUBLE)', 160 'name STRING', 161 ' 162 SELECT reply.name AS name 163 FROM ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP($startup_id, $threshold) request 164 JOIN following_flow(request.id) arrow 165 JOIN slice reply ON reply.id = arrow.slice_in 166 WHERE reply.dur > $threshold AND request.is_main_thread 167 ' 168); 169 170-- Given a launch id, return if unlock is running by systemui during the launch. 171SELECT CREATE_FUNCTION( 172 'IS_UNLOCK_RUNNING_DURING_LAUNCH(startup_id LONG)', 173 'BOOL', 174 ' 175 SELECT EXISTS( 176 SELECT slice.name 177 FROM slice, android_startups launches 178 JOIN thread_track ON slice.track_id = thread_track.id 179 JOIN thread USING(utid) 180 JOIN process USING(upid) 181 WHERE launches.startup_id = $startup_id 182 AND slice.name = "KeyguardUpdateMonitor#onAuthenticationSucceeded" 183 AND process.name = "com.android.systemui" 184 AND slice.ts >= launches.ts 185 AND (slice.ts + slice.dur) <= launches.ts_end 186 ) 187 ' 188); 189