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 17INCLUDE PERFETTO MODULE android.startup.startups; 18 19-- Helper function to build a Slice proto from a duration. 20CREATE OR REPLACE PERFETTO FUNCTION startup_slice_proto(dur INT) 21RETURNS PROTO AS 22SELECT AndroidStartupMetric_Slice( 23 "dur_ns", $dur, 24 "dur_ms", $dur / 1e6 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 PERFETTO VIEW thread_slices_for_all_launches AS 32SELECT * FROM android_thread_slices_for_all_startups; 33 34-- Given a launch id and GLOB for a slice name, returns the startup slice proto, 35-- summing the slice durations across the whole startup. 36CREATE OR REPLACE PERFETTO FUNCTION dur_sum_slice_proto_for_launch(startup_id LONG, slice_name STRING) 37RETURNS PROTO AS 38SELECT NULL_IF_EMPTY( 39 startup_slice_proto( 40 android_sum_dur_for_startup_and_slice($startup_id, $slice_name) 41 ) 42); 43 44-- Same as |dur_sum_slice_proto_for_launch| except only counting slices happening 45-- on the main thread. 46CREATE OR REPLACE PERFETTO FUNCTION dur_sum_main_thread_slice_proto_for_launch(startup_id LONG, slice_name STRING) 47RETURNS PROTO AS 48SELECT NULL_IF_EMPTY( 49 startup_slice_proto( 50 android_sum_dur_on_main_thread_for_startup_and_slice($startup_id, $slice_name) 51 ) 52); 53 54-- Given a launch id and GLOB for a slice name, returns the startup slice proto by 55-- taking the duration between the start of the launch and start of the slice. 56-- If multiple slices match, picks the latest one which started during the launch. 57CREATE OR REPLACE PERFETTO FUNCTION launch_to_main_thread_slice_proto(startup_id INT, slice_name STRING) 58RETURNS PROTO AS 59SELECT NULL_IF_EMPTY(startup_slice_proto(MAX(slice_ts) - startup_ts)) 60FROM android_thread_slices_for_all_startups s 61JOIN thread t USING (utid) 62WHERE 63 s.slice_name GLOB $slice_name AND 64 s.startup_id = $startup_id AND 65 s.is_main_thread AND 66 (t.end_ts IS NULL OR t.end_ts >= s.startup_ts_end); 67 68-- Given a lauch id, returns the total time spent in GC 69CREATE OR REPLACE PERFETTO FUNCTION total_gc_time_by_launch(startup_id LONG) 70RETURNS INT AS 71SELECT SUM(slice_dur) 72FROM android_thread_slices_for_all_startups slice 73WHERE 74 slice.startup_id = $startup_id AND 75 ( 76 slice_name GLOB "*semispace GC" OR 77 slice_name GLOB "*mark sweep GC" OR 78 slice_name GLOB "*concurrent copying GC" 79 ); 80 81-- Given a launch id and package name, returns if baseline or cloud profile is missing. 82CREATE OR REPLACE PERFETTO FUNCTION missing_baseline_profile_for_launch(startup_id LONG, pkg_name STRING) 83RETURNS BOOL AS 84SELECT (COUNT(slice_name) > 0) 85FROM ( 86 SELECT * 87 FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME( 88 $startup_id, 89 "location=* status=* filter=* reason=*" 90 ) 91 ORDER BY slice_name 92) 93WHERE 94 -- when location is the package odex file and the reason is "install" or "install-dm", 95 -- if the compilation filter is not "speed-profile", baseline/cloud profile is missing. 96 SUBSTR(STR_SPLIT(slice_name, " status=", 0), LENGTH("location=") + 1) 97 GLOB ("*" || $pkg_name || "*odex") 98 AND (STR_SPLIT(slice_name, " reason=", 1) = "install" 99 OR STR_SPLIT(slice_name, " reason=", 1) = "install-dm") 100 AND STR_SPLIT(STR_SPLIT(slice_name, " filter=", 1), " reason=", 0) != "speed-profile"; 101 102-- Given a launch id, returns if there is a main thread run-from-apk slice. 103CREATE OR REPLACE PERFETTO FUNCTION run_from_apk_for_launch(launch_id LONG) 104RETURNS BOOL AS 105SELECT EXISTS( 106 SELECT slice_name, startup_id, is_main_thread 107 FROM android_thread_slices_for_all_startups 108 WHERE 109 startup_id = $launch_id AND is_main_thread AND 110 slice_name GLOB "location=* status=* filter=* reason=*" AND 111 STR_SPLIT(STR_SPLIT(slice_name, " filter=", 1), " reason=", 0) 112 GLOB ("*" || "run-from-apk" || "*") 113); 114 115CREATE OR REPLACE PERFETTO FUNCTION summary_for_optimization_status( 116 loc STRING, 117 status STRING, 118 filter_str STRING, 119 reason STRING 120) 121RETURNS STRING AS 122SELECT 123CASE 124 WHEN 125 $loc GLOB "*/base.odex" AND $loc GLOB "*==/*-*" 126 THEN STR_SPLIT(STR_SPLIT($loc, "==/", 1), "-", 0) || "/.../" 127 ELSE "" 128END || 129CASE 130 WHEN $loc GLOB "*/*" 131 THEN REVERSE(STR_SPLIT(REVERSE($loc), "/", 0)) 132 ELSE $loc 133END || ": " || $status || "/" || $filter_str || "/" || $reason; 134 135CREATE OR REPLACE PERFETTO FUNCTION binder_transaction_reply_slices_for_launch( 136 startup_id INT, threshold DOUBLE) 137RETURNS TABLE(name STRING) AS 138SELECT reply.name AS name 139FROM android_binder_transaction_slices_for_startup($startup_id, $threshold) request 140JOIN following_flow(request.id) arrow 141JOIN slice reply ON reply.id = arrow.slice_in 142WHERE reply.dur > $threshold AND request.is_main_thread; 143 144-- Given a launch id, return if unlock is running by systemui during the launch. 145CREATE OR REPLACE PERFETTO FUNCTION is_unlock_running_during_launch(startup_id LONG) 146RETURNS BOOL AS 147SELECT EXISTS( 148 SELECT slice.name 149 FROM slice, android_startups launches 150 JOIN thread_track ON slice.track_id = thread_track.id 151 JOIN thread USING(utid) 152 JOIN process USING(upid) 153 WHERE launches.startup_id = $startup_id 154 AND slice.name = "KeyguardUpdateMonitor#onAuthenticationSucceeded" 155 AND process.name = "com.android.systemui" 156 AND slice.ts >= launches.ts 157 AND (slice.ts + slice.dur) <= launches.ts_end 158); 159