• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
19SELECT RUN_METRIC('android/startup/thread_state_breakdown.sql');
20SELECT RUN_METRIC('android/startup/system_state.sql');
21SELECT RUN_METRIC('android/startup/mcycles_per_launch.sql');
22
23CREATE OR REPLACE PERFETTO FUNCTION _is_spans_overlapping(
24  ts1 LONG,
25  ts_end1 LONG,
26  ts2 LONG,
27  ts_end2 LONG)
28RETURNS BOOL AS
29SELECT (IIF($ts1 < $ts2, $ts2, $ts1)
30      < IIF($ts_end1 < $ts_end2, $ts_end1, $ts_end2));
31
32CREATE OR REPLACE PERFETTO FUNCTION get_percent(num LONG, total LONG)
33RETURNS STRING AS
34  SELECT SUBSTRING(CAST(($num * 100 + 0.0) / $total AS STRING), 1, 5);
35
36CREATE OR REPLACE PERFETTO FUNCTION get_ns_to_s(ns LONG)
37RETURNS STRING AS
38  SELECT CAST(($ns + 0.0) / 1e9 AS STRING);
39
40CREATE OR REPLACE PERFETTO FUNCTION get_ns_to_ms(ns LONG)
41RETURNS STRING AS
42  SELECT SUBSTRING(CAST(($ns + 0.0) / 1e6 AS STRING), 1, 6);
43
44CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_time_for_launch_in_runnable_state(
45  startup_id LONG, num_threads INT)
46RETURNS PROTO AS
47  SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection(
48    'start_timestamp', ts, 'end_timestamp', ts + dur,
49    'thread_utid', utid, 'thread_name', thread_name))
50  FROM (
51    SELECT ts, dur, utid, thread_name
52    FROM launch_threads_by_thread_state l
53    JOIN thread USING (utid)
54    WHERE l.startup_id = $startup_id AND (state GLOB "R" OR state GLOB "R+") AND l.is_main_thread
55    ORDER BY dur DESC
56    LIMIT $num_threads);
57
58CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_time_for_launch_and_state(
59  startup_id LONG, state STRING, num_threads INT)
60RETURNS PROTO AS
61  SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection(
62    'start_timestamp', ts, 'end_timestamp', ts + dur,
63    'thread_utid', utid, 'thread_name', thread_name))
64  FROM (
65    SELECT ts, dur, utid, thread_name
66    FROM launch_threads_by_thread_state l
67    JOIN thread USING (utid)
68    WHERE l.startup_id = $startup_id AND state GLOB $state AND l.is_main_thread
69    ORDER BY dur DESC
70    LIMIT $num_threads);
71
72CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_time_for_launch_state_and_io_wait(
73  startup_id INT, state STRING, io_wait BOOL, num_threads INT)
74RETURNS PROTO AS
75  SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection(
76    'start_timestamp', ts, 'end_timestamp', ts + dur,
77    'thread_utid', utid, 'thread_name', thread_name))
78  FROM (
79    SELECT ts, dur, utid, thread_name
80    FROM launch_threads_by_thread_state l
81    JOIN thread USING (utid)
82    WHERE l.startup_id = $startup_id AND state GLOB $state
83      AND l.is_main_thread AND l.io_wait = $io_wait
84    ORDER BY dur DESC
85    LIMIT $num_threads);
86
87CREATE OR REPLACE PERFETTO FUNCTION get_thread_time_for_launch_state_and_thread(
88  startup_id INT, state STRING, thread_name STRING, num_threads INT)
89RETURNS PROTO AS
90  SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection(
91    'start_timestamp', ts, 'end_timestamp', ts + dur,
92    'thread_utid', utid, 'thread_name', thread_name))
93  FROM (
94    SELECT ts, dur, utid, thread_name
95    FROM launch_threads_by_thread_state l
96    JOIN thread USING (utid)
97    WHERE l.startup_id = $startup_id AND state GLOB $state AND thread_name = $thread_name
98    ORDER BY dur DESC
99    LIMIT $num_threads);
100
101CREATE OR REPLACE PERFETTO FUNCTION get_missing_baseline_profile_for_launch(
102  startup_id LONG, pkg_name STRING)
103RETURNS PROTO AS
104  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
105    'start_timestamp', slice_ts,
106    'end_timestamp', slice_ts + slice_dur,
107    'slice_id', slice_id,
108    'slice_name', slice_name))
109  FROM (
110    SELECT slice_ts, slice_dur, slice_id, slice_name
111    FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME($startup_id,
112      "location=* status=* filter=* reason=*")
113    WHERE
114      -- when location is the package odex file and the reason is "install" or "install-dm",
115      -- if the compilation filter is not "speed-profile", baseline/cloud profile is missing.
116      SUBSTR(STR_SPLIT(slice_name, " status=", 0), LENGTH("location=") + 1)
117        GLOB ("*" || $pkg_name || "*odex")
118      AND (STR_SPLIT(slice_name, " reason=", 1) = "install"
119      OR STR_SPLIT(slice_name, " reason=", 1) = "install-dm")
120    ORDER BY slice_dur DESC
121    LIMIT 1);
122
123CREATE OR REPLACE PERFETTO FUNCTION get_run_from_apk(startup_id LONG)
124RETURNS PROTO AS
125  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
126    'start_timestamp', slice_ts,
127    'end_timestamp', slice_ts + slice_dur,
128    'slice_id', slice_id,
129    'slice_name', slice_name))
130  FROM (
131    SELECT slice_ts, slice_dur, slice_id, slice_name
132    FROM android_thread_slices_for_all_startups
133    WHERE
134      startup_id = $startup_id AND is_main_thread AND
135      slice_name GLOB "location=* status=* filter=* reason=*" AND
136      STR_SPLIT(STR_SPLIT(slice_name, " filter=", 1), " reason=", 0)
137        GLOB ("*" || "run-from-apk" || "*")
138    ORDER BY slice_dur DESC
139    LIMIT 1);
140
141CREATE OR REPLACE PERFETTO FUNCTION get_unlock_running_during_launch_slice(startup_id LONG)
142RETURNS PROTO AS
143  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
144    'start_timestamp', slice_ts,
145    'end_timestamp', slice_ts + slice_dur,
146    'slice_id', slice_id,
147    'slice_name', slice_name))
148  FROM (
149    SELECT slice.ts as slice_ts, slice.dur as slice_dur,
150      slice.id as slice_id, slice.name as slice_name
151    FROM slice, android_startups launches
152    JOIN thread_track ON slice.track_id = thread_track.id
153    JOIN thread USING(utid)
154    JOIN process USING(upid)
155    WHERE launches.startup_id = $startup_id
156    AND slice.name = "KeyguardUpdateMonitor#onAuthenticationSucceeded"
157    AND process.name = "com.android.systemui"
158    AND slice.ts >= launches.ts
159    AND (slice.ts + slice.dur) <= launches.ts_end
160    LIMIT 1);
161
162CREATE OR REPLACE PERFETTO FUNCTION get_gc_activity(startup_id LONG, num_slices INT)
163RETURNS PROTO  AS
164  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
165    'start_timestamp', slice_ts,
166    'end_timestamp', slice_ts + slice_dur,
167    'slice_id', slice_id,
168    'slice_name', slice_name))
169  FROM (
170    SELECT slice_ts, slice_dur, slice_id, slice_name
171    FROM android_thread_slices_for_all_startups slice
172    WHERE
173      slice.startup_id = $startup_id AND
174      (
175        slice_name GLOB "*semispace GC" OR
176        slice_name GLOB "*mark sweep GC" OR
177        slice_name GLOB "*concurrent copying GC"
178      )
179    ORDER BY slice_dur DESC
180    LIMIT $num_slices);
181
182CREATE OR REPLACE PERFETTO FUNCTION get_dur_on_main_thread_for_startup_and_slice(
183  startup_id LONG, slice_name STRING, num_slices INT)
184RETURNS PROTO AS
185  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
186    'start_timestamp', slice_ts,
187    'end_timestamp', slice_ts + slice_dur,
188    'slice_id', slice_id,
189    'slice_name', slice_name))
190  FROM (
191    SELECT slice_ts, slice_dur, slice_id, slice_name
192    FROM android_thread_slices_for_all_startups l
193    WHERE startup_id = $startup_id
194      AND slice_name GLOB $slice_name
195    ORDER BY slice_dur DESC
196    LIMIT $num_slices);
197
198CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_binder_transactions_blocked(
199  startup_id LONG, threshold DOUBLE, num_slices INT)
200RETURNS PROTO AS
201  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
202    'start_timestamp', slice_ts, 'end_timestamp', slice_ts + slice_dur,
203    'slice_id', slice_id, 'slice_name', slice_name))
204  FROM (
205    SELECT request.slice_ts as slice_ts, request.slice_dur as slice_dur,
206      request.id as slice_id, request.slice_name as slice_name
207    FROM (
208      SELECT slice_id as id, slice_dur, thread_name, process.name as process,
209        s.arg_set_id, is_main_thread,
210        slice_ts, s.utid, slice_name
211      FROM android_thread_slices_for_all_startups s
212      JOIN process ON (
213        EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid
214      )
215      WHERE startup_id = $startup_id AND slice_name GLOB "binder transaction"
216        AND slice_dur > $threshold
217    ) request
218    JOIN following_flow(request.id) arrow
219    JOIN slice reply ON reply.id = arrow.slice_in
220    JOIN thread USING (utid)
221    WHERE reply.dur > $threshold AND request.is_main_thread
222    ORDER BY request.slice_dur DESC
223    LIMIT $num_slices);
224
225CREATE OR REPLACE PERFETTO FUNCTION get_slices_concurrent_to_launch(
226  startup_id INT, slice_glob STRING, num_slices INT)
227RETURNS PROTO AS
228  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
229    'start_timestamp', ts, 'end_timestamp', ts + dur,
230    'slice_id', id, 'slice_name', name))
231  FROM (
232    SELECT s.ts as ts, dur, id, name FROM slice s
233    JOIN (
234      SELECT ts, ts_end
235      FROM android_startups
236      WHERE startup_id = $startup_id
237    ) launch
238    WHERE
239      s.name GLOB $slice_glob AND
240      s.ts BETWEEN launch.ts AND launch.ts_end
241    ORDER BY dur DESC LIMIT $num_slices);
242
243CREATE OR REPLACE PERFETTO FUNCTION get_slices_for_startup_and_slice_name(
244  startup_id INT, slice_name STRING, num_slices INT)
245RETURNS PROTO AS
246  SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection(
247    'start_timestamp', slice_ts, 'end_timestamp', slice_ts + slice_dur,
248    'slice_id', slice_id, 'slice_name', slice_name))
249  FROM (
250    SELECT slice_ts, slice_dur, slice_id, slice_name
251    FROM android_thread_slices_for_all_startups
252    WHERE startup_id = $startup_id AND slice_name GLOB $slice_name
253    ORDER BY slice_dur DESC
254    LIMIT $num_slices);
255
256CREATE OR REPLACE PERFETTO FUNCTION get_process_running_concurrent_to_launch(
257  startup_id INT, process_glob STRING)
258RETURNS STRING AS
259  SELECT process.name
260     FROM sched
261     JOIN thread USING (utid)
262     JOIN process USING (upid)
263     JOIN (
264       SELECT ts, ts_end
265       FROM android_startups
266       WHERE startup_id = $startup_id
267       ) launch
268     WHERE
269       process.name GLOB $process_glob AND
270       sched.ts BETWEEN launch.ts AND launch.ts_end
271       ORDER BY (launch.ts_end - sched.ts) DESC
272       LIMIT 1;
273
274CREATE OR REPLACE PERFETTO FUNCTION get_slow_start_reason_with_details(startup_id LONG)
275RETURNS PROTO AS
276      SELECT RepeatedField(AndroidStartupMetric_SlowStartReason(
277        'reason_id', reason_id,
278        'reason', slow_cause,
279        'launch_dur', launch_dur,
280        'expected_value', expected_val,
281        'actual_value', actual_val,
282        'trace_slice_sections', trace_slices,
283        'trace_thread_sections', trace_threads,
284        'additional_info', extra))
285      FROM (
286        SELECT 'No baseline or cloud profiles' as slow_cause,
287          launch.dur as launch_dur,
288          'NO_BASELINE_OR_CLOUD_PROFILES' as reason_id,
289          AndroidStartupMetric_ThresholdValue(
290            'value', FALSE,
291            'unit', 'TRUE_OR_FALSE') as expected_val,
292          AndroidStartupMetric_ActualValue(
293            'value', TRUE) as actual_val,
294          get_missing_baseline_profile_for_launch(launch.startup_id, launch.package)
295            as trace_slices,
296          NULL as trace_threads,
297          NULL as extra
298        FROM android_startups launch
299        WHERE launch.startup_id = $startup_id
300          AND missing_baseline_profile_for_launch(launch.startup_id, launch.package)
301
302        UNION ALL
303        SELECT 'Optimized artifacts missing, run from apk' as slow_cause,
304          launch.dur as launch_dur,
305          'RUN_FROM_APK' as reason_id,
306          AndroidStartupMetric_ThresholdValue(
307            'value', FALSE,
308            'unit', 'TRUE_OR_FALSE') as expected_val,
309          AndroidStartupMetric_ActualValue(
310            'value', TRUE) as actual_val,
311          get_run_from_apk(launch.startup_id) as trace_slices,
312          NULL as trace_threads,
313          NULL as extra
314        FROM android_startups launch
315        WHERE launch.startup_id = $startup_id
316          AND run_from_apk_for_launch(launch.startup_id)
317
318        UNION ALL
319        SELECT 'Unlock running during launch' as slow_cause,
320          launch.dur as launch_dur,
321          'UNLOCK_RUNNING' as reason_id,
322          AndroidStartupMetric_ThresholdValue(
323            'value', FALSE,
324            'unit', 'TRUE_OR_FALSE') as expected_val,
325          AndroidStartupMetric_ActualValue(
326            'value', TRUE) as actual_val,
327          get_unlock_running_during_launch_slice(launch.startup_id) as trace_slices,
328          NULL as trace_threads,
329          NULL as extra
330        FROM android_startups launch
331        WHERE launch.startup_id = $startup_id
332         AND is_unlock_running_during_launch(launch.startup_id)
333
334        UNION ALL
335        SELECT 'App in debuggable mode' as slow_cause,
336          launch.dur as launch_dur,
337          'APP_IN_DEBUGGABLE_MODE' as reason_id,
338          AndroidStartupMetric_ThresholdValue(
339            'value', FALSE,
340            'unit', 'TRUE_OR_FALSE') as expected_val,
341          AndroidStartupMetric_ActualValue(
342            'value', TRUE) as actual_val,
343          NULL as trace_slices,
344          NULL as trace_threads,
345          NULL as extra
346        FROM android_startups launch
347        WHERE launch.startup_id = $startup_id
348          AND is_process_debuggable(launch.package)
349
350        UNION ALL
351        SELECT 'GC Activity' as slow_cause,
352          launch.dur as launch_dur,
353          'GC_ACTIVITY' as reason_id,
354          AndroidStartupMetric_ThresholdValue(
355            'value', FALSE,
356            'unit', 'TRUE_OR_FALSE') as expected_val,
357          AndroidStartupMetric_ActualValue(
358            'value', TRUE) as actual_val,
359          get_gc_activity(launch.startup_id, 1) as trace_slices,
360          NULL as trace_threads,
361          NULL as extra
362        FROM android_startups launch
363        WHERE launch.startup_id = $startup_id
364          AND total_gc_time_by_launch(launch.startup_id) > 0
365
366        UNION ALL
367        SELECT 'dex2oat running during launch' AS slow_cause,
368          launch.dur as launch_dur,
369          'DEX2OAT_RUNNING' as reason_id,
370          AndroidStartupMetric_ThresholdValue(
371            'value', FALSE,
372            'unit', 'TRUE_OR_FALSE') as expected_val,
373          AndroidStartupMetric_ActualValue(
374            'value', TRUE) as actual_val,
375          NULL as trace_slices,
376          NULL as trace_threads,
377          'Process: ' || get_process_running_concurrent_to_launch(launch.startup_id, '*dex2oat64')
378            as extra
379        FROM android_startups launch
380        WHERE launch.startup_id = $startup_id AND
381          dur_of_process_running_concurrent_to_launch(launch.startup_id, '*dex2oat64') > 0
382
383        UNION ALL
384        SELECT 'installd running during launch' AS slow_cause,
385          launch.dur as launch_dur,
386          'INSTALLD_RUNNING' as reason_id,
387          AndroidStartupMetric_ThresholdValue(
388            'value', FALSE,
389            'unit', 'TRUE_OR_FALSE') as expected_val,
390          AndroidStartupMetric_ActualValue(
391            'value', TRUE) as actual_val,
392          NULL as trace_slices,
393          NULL as trace_threads,
394          'Process: ' || get_process_running_concurrent_to_launch(launch.startup_id, '*installd')
395            as extra
396        FROM android_startups launch
397        WHERE launch.startup_id = $startup_id AND
398          dur_of_process_running_concurrent_to_launch(launch.startup_id, '*installd') > 0
399
400        UNION ALL
401        SELECT 'Main Thread - Time spent in Runnable state' as slow_cause,
402          launch.dur as launch_dur,
403          'MAIN_THREAD_TIME_SPENT_IN_RUNNABLE' as reason_id,
404          AndroidStartupMetric_ThresholdValue(
405            'value', 15,
406            'unit', 'PERCENTAGE',
407            'higher_expected', FALSE) as expected_val,
408          AndroidStartupMetric_ActualValue(
409            'value',
410              main_thread_time_for_launch_in_runnable_state(launch.startup_id) * 100 / launch.dur,
411            'dur', main_thread_time_for_launch_in_runnable_state(launch.startup_id)) as actual_val,
412          NULL as trace_slices,
413          get_main_thread_time_for_launch_in_runnable_state(launch.startup_id, 3) as trace_threads,
414          NULL as extra
415        FROM android_startups launch
416        WHERE launch.startup_id = $startup_id
417          AND main_thread_time_for_launch_in_runnable_state(launch.startup_id) > launch.dur * 0.15
418
419        UNION ALL
420        SELECT 'Main Thread - Time spent in interruptible sleep state' as slow_cause,
421          launch.dur as launch_dur,
422          'MAIN_THREAD_TIME_SPENT_IN_INTERRUPTIBLE_SLEEP' as reason_id,
423          AndroidStartupMetric_ThresholdValue(
424            'value', 2900000000,
425            'unit', 'NS',
426            'higher_expected', FALSE) as expected_val,
427          AndroidStartupMetric_ActualValue(
428            'value', main_thread_time_for_launch_and_state(launch.startup_id, 'S')) as actual_val,
429          NULL as trace_slices,
430          get_main_thread_time_for_launch_and_state(launch.startup_id, 'S', 3) as trace_threads,
431          NULL as extra
432        FROM android_startups launch
433        WHERE launch.startup_id = $startup_id
434          AND main_thread_time_for_launch_and_state(launch.startup_id, 'S') > 2900e6
435
436        UNION ALL
437        SELECT 'Main Thread - Time spent in Blocking I/O' as slow_cause,
438          launch.dur as launch_dur,
439          'MAIN_THREAD_TIME_SPENT_IN_BLOCKING_IO' as reason_id,
440          AndroidStartupMetric_ThresholdValue(
441            'value', 450000000,
442            'unit', 'NS',
443            'higher_expected', FALSE) as expected_val,
444          AndroidStartupMetric_ActualValue(
445            'value', main_thread_time_for_launch_state_and_io_wait(
446              launch.startup_id, 'D*', TRUE)) as actual_val,
447          NULL as trace_slices,
448          get_main_thread_time_for_launch_state_and_io_wait(
449            launch.startup_id, 'D*', TRUE, 3) as trace_threads,
450          NULL as extra
451        FROM android_startups launch
452        WHERE launch.startup_id = $startup_id
453          AND main_thread_time_for_launch_state_and_io_wait(launch.startup_id, 'D*', TRUE) > 450e6
454
455        UNION ALL
456        SELECT 'Main Thread - Time spent in OpenDexFilesFromOat*' as slow_cause,
457          launch.dur as launch_dur,
458          'MAIN_THREAD_TIME_SPENT_IN_OPEN_DEX_FILES_FROM_OAT' as reason_id,
459          AndroidStartupMetric_ThresholdValue(
460            'value', 20,
461            'unit', 'PERCENTAGE',
462            'higher_expected', FALSE) as expected_val,
463          AndroidStartupMetric_ActualValue(
464            'value', android_sum_dur_on_main_thread_for_startup_and_slice(
465              launch.startup_id, 'OpenDexFilesFromOat*') * 100 / launch.dur,
466            'dur', android_sum_dur_on_main_thread_for_startup_and_slice(
467              launch.startup_id, 'OpenDexFilesFromOat*')) as actual_val,
468          get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'OpenDexFilesFromOat*', 3)
469            as trace_slices,
470          NULL as trace_threads,
471          NULL as extra
472        FROM android_startups launch
473        WHERE launch.startup_id = $startup_id AND
474          android_sum_dur_on_main_thread_for_startup_and_slice(
475          launch.startup_id, 'OpenDexFilesFromOat*') > launch.dur * 0.2
476
477        UNION ALL
478        SELECT 'Time spent in bindApplication' as slow_cause,
479          launch.dur as launch_dur,
480          'TIME_SPENT_IN_BIND_APPLICATION' as reason_id,
481          AndroidStartupMetric_ThresholdValue(
482            'value', 1250000000,
483            'unit', 'NS',
484            'higher_expected', FALSE) as expected_val,
485          AndroidStartupMetric_ActualValue(
486            'value', android_sum_dur_for_startup_and_slice(
487              launch.startup_id, 'bindApplication')) as actual_val,
488          get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'bindApplication', 3)
489            as trace_slices,
490          NULL as trace_threads,
491          NULL as extra
492        FROM android_startups launch
493        WHERE launch.startup_id = $startup_id
494          AND android_sum_dur_for_startup_and_slice(launch.startup_id, 'bindApplication') > 1250e6
495
496        UNION ALL
497        SELECT 'Time spent in view inflation' as slow_cause,
498          launch.dur as launch_dur,
499          'TIME_SPENT_IN_VIEW_INFLATION' as reason_id,
500          AndroidStartupMetric_ThresholdValue(
501            'value', 450000000,
502            'unit', 'NS',
503            'higher_expected', FALSE) as expected_val,
504          AndroidStartupMetric_ActualValue(
505            'value', android_sum_dur_for_startup_and_slice(
506              launch.startup_id, 'inflate')) as actual_val,
507          get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'inflate', 3)
508            as trace_slices,
509          NULL as trace_threads,
510          NULL as extra
511        FROM android_startups launch
512        WHERE launch.startup_id = $startup_id
513          AND android_sum_dur_for_startup_and_slice(launch.startup_id, 'inflate') > 450e6
514
515        UNION ALL
516        SELECT 'Time spent in ResourcesManager#getResources' as slow_cause,
517          launch.dur as launch_dur,
518          'TIME_SPENT_IN_RESOURCES_MANAGER_GET_RESOURCES' as reason_id,
519          AndroidStartupMetric_ThresholdValue(
520            'value', 130000000,
521            'unit', 'NS',
522            'higher_expected', FALSE) as expected_val,
523          AndroidStartupMetric_ActualValue(
524            'value', android_sum_dur_for_startup_and_slice(
525              launch.startup_id, 'ResourcesManager#getResources')) as actual_val,
526          get_dur_on_main_thread_for_startup_and_slice(
527            launch.startup_id, 'ResourcesManager#getResources', 3) as trace_slices,
528          NULL as trace_threads,
529          NULL as extra
530        FROM android_startups launch
531        WHERE launch.startup_id = $startup_id
532          AND android_sum_dur_for_startup_and_slice(
533          launch.startup_id, 'ResourcesManager#getResources') > 130e6
534
535        UNION ALL
536        SELECT 'Time spent verifying classes' as slow_cause,
537          launch.dur as launch_dur,
538          'TIME_SPENT_VERIFYING_CLASSES' as reason_id,
539          AndroidStartupMetric_ThresholdValue(
540            'value', 15,
541            'unit', 'PERCENTAGE',
542            'higher_expected', FALSE) as expected_val,
543          AndroidStartupMetric_ActualValue(
544            'value', android_sum_dur_for_startup_and_slice(
545              launch.startup_id, 'VerifyClass*') * 100 / launch.dur,
546            'dur', android_sum_dur_for_startup_and_slice(
547              launch.startup_id, 'VerifyClass*')) as actual_val,
548          get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'VerifyClass*', 3)
549            as trace_slices,
550          NULL as trace_threads,
551          NULL as extra
552        FROM android_startups launch
553        WHERE launch.startup_id = $startup_id AND
554          android_sum_dur_for_startup_and_slice(launch.startup_id, 'VerifyClass*')
555            > launch.dur * 0.15
556
557        UNION ALL
558        SELECT 'Potential CPU contention with another process' AS slow_cause,
559          launch.dur as launch_dur,
560          'POTENTIAL_CPU_CONTENTION_WITH_ANOTHER_PROCESS' as reason_id,
561          AndroidStartupMetric_ThresholdValue(
562            'value', 100000000,
563            'unit', 'NS',
564            'higher_expected', FALSE) as expected_val,
565          AndroidStartupMetric_ActualValue(
566            'value',
567              main_thread_time_for_launch_in_runnable_state(launch.startup_id)) as actual_val,
568          NULL as trace_slices,
569          get_main_thread_time_for_launch_in_runnable_state(launch.startup_id, 3) as trace_threads,
570          NULL as extra
571        FROM android_startups launch
572        WHERE launch.startup_id = $startup_id AND
573          main_thread_time_for_launch_in_runnable_state(launch.startup_id) > 100e6 AND
574          most_active_process_for_launch(launch.startup_id) IS NOT NULL
575
576        UNION ALL
577        SELECT 'JIT Activity' as slow_cause,
578          launch.dur as launch_dur,
579          'JIT_ACTIVITY' as reason_id,
580          AndroidStartupMetric_ThresholdValue(
581            'value', 100000000,
582            'unit', 'NS',
583            'higher_expected', FALSE) as expected_val,
584          AndroidStartupMetric_ActualValue(
585            'value', thread_time_for_launch_state_and_thread(
586              launch.startup_id, 'Running', 'Jit thread pool')) as actual_val,
587          NULL as trace_slices,
588          get_thread_time_for_launch_state_and_thread(
589            launch.startup_id, 'Running', 'Jit thread pool', 3) as trace_threads,
590          NULL as extra
591        FROM android_startups launch
592        WHERE launch.startup_id = $startup_id
593        AND thread_time_for_launch_state_and_thread(
594          launch.startup_id,
595          'Running',
596          'Jit thread pool'
597        ) > 100e6
598
599        UNION ALL
600        SELECT 'Main Thread - Lock contention' as slow_cause,
601          launch.dur as launch_dur,
602          'MAIN_THREAD_LOCK_CONTENTION' as reason_id,
603          AndroidStartupMetric_ThresholdValue(
604            'value', 20,
605            'unit', 'PERCENTAGE',
606            'higher_expected', FALSE) as expected_val,
607          AndroidStartupMetric_ActualValue(
608            'value', android_sum_dur_on_main_thread_for_startup_and_slice(
609              launch.startup_id, 'Lock contention on*') * 100 / launch.dur,
610            'dur', android_sum_dur_on_main_thread_for_startup_and_slice(
611              launch.startup_id, 'Lock contention on*')) as actual_val,
612          get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'lock contention on*', 3)
613            as trace_slices,
614          NULL as trace_threads,
615          NULL as extra
616        FROM android_startups launch
617        WHERE launch.startup_id = $startup_id
618          AND android_sum_dur_on_main_thread_for_startup_and_slice(
619          launch.startup_id,
620          'Lock contention on*'
621        ) > launch.dur * 0.2
622
623        UNION ALL
624        SELECT 'Main Thread - Monitor contention' as slow_cause,
625          launch.dur as launch_dur,
626          'MAIN_THREAD_MONITOR_CONTENTION' as reason_id,
627          AndroidStartupMetric_ThresholdValue(
628            'value', 15,
629            'unit', 'PERCENTAGE',
630            'higher_expected', FALSE) as expected_val,
631          AndroidStartupMetric_ActualValue(
632            'value', android_sum_dur_on_main_thread_for_startup_and_slice(
633              launch.startup_id, 'Lock contention on a monitor*') * 100 / launch.dur,
634            'dur', android_sum_dur_on_main_thread_for_startup_and_slice(
635              launch.startup_id, 'Lock contention on a monitor*')) as actual_val,
636          get_dur_on_main_thread_for_startup_and_slice(
637            launch.startup_id, 'lock contention on a monitor*', 3) as trace_slices,
638          NULL as trace_threads,
639          NULL as extra
640        FROM android_startups launch
641        WHERE launch.startup_id = $startup_id
642          AND android_sum_dur_on_main_thread_for_startup_and_slice(
643            launch.startup_id,
644            'Lock contention on a monitor*'
645          ) > launch.dur * 0.15
646
647        UNION ALL
648        SELECT 'JIT compiled methods' as slow_cause,
649          launch.dur as launch_dur,
650          'JIT_COMPILED_METHODS' as reason_id,
651          AndroidStartupMetric_ThresholdValue(
652            'value', 65,
653            'unit', 'COUNT',
654            'higher_expected', FALSE) as expected_val,
655          AndroidStartupMetric_ActualValue(
656            'value', (SELECT COUNT(1)
657              FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(launch.startup_id, 'JIT compiling*')
658              WHERE thread_name = 'Jit thread pool')) as actual_val,
659          get_slices_for_startup_and_slice_name(launch.startup_id, 'JIT compiling*', 3)
660            as trace_slices,
661          NULL as traced_threads,
662          NULL as extra
663        FROM android_startups launch
664        WHERE launch.startup_id = $startup_id
665          AND (
666          SELECT COUNT(1)
667          FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(launch.startup_id, 'JIT compiling*')
668          WHERE thread_name = 'Jit thread pool') > 65
669
670        UNION ALL
671        SELECT 'Broadcast dispatched count' as slow_cause,
672          launch.dur as launch_dur,
673          'BROADCAST_DISPATCHED_COUNT' as reason_id,
674          AndroidStartupMetric_ThresholdValue(
675            'value', 15,
676            'unit', 'COUNT',
677            'higher_expected', FALSE) as expected_val,
678          AndroidStartupMetric_ActualValue(
679            'value', count_slices_concurrent_to_launch(launch.startup_id,
680              'Broadcast dispatched*')) as actual_val,
681          get_slices_concurrent_to_launch(launch.startup_id, 'Broadcast dispatched*', 3)
682            as trace_slices,
683          NULL as trace_threads,
684          NULL as extra
685        FROM android_startups launch
686        WHERE launch.startup_id = $startup_id
687          AND count_slices_concurrent_to_launch(
688          launch.startup_id,
689          'Broadcast dispatched*') > 15
690
691        UNION ALL
692        SELECT 'Broadcast received count' as slow_cause,
693          launch.dur as launch_dur,
694          'BROADCAST_RECEIVED_COUNT' as reason_id,
695          AndroidStartupMetric_ThresholdValue(
696            'value', 50,
697            'unit', 'COUNT',
698            'higher_expected', FALSE) as expected_val,
699          AndroidStartupMetric_ActualValue(
700            'value', count_slices_concurrent_to_launch(launch.startup_id,
701              'broadcastReceiveReg*')) as actual_val,
702          get_slices_concurrent_to_launch(launch.startup_id, 'broadcastReceiveReg*', 3)
703            as trace_slices,
704          NULL as trace_threads,
705          NULL as extra
706        FROM android_startups launch
707        WHERE launch.startup_id = $startup_id
708          AND count_slices_concurrent_to_launch(
709            launch.startup_id,
710            'broadcastReceiveReg*') > 50
711
712        UNION ALL
713        SELECT 'Startup running concurrent to launch' as slow_cause,
714          launch.dur as launch_dur,
715          'STARTUP_RUNNING_CONCURRENT' as reason_id,
716          AndroidStartupMetric_ThresholdValue(
717            'value', FALSE,
718            'unit', 'TRUE_OR_FALSE') as expected_val,
719          AndroidStartupMetric_ActualValue(
720            'value', TRUE) as actual_val,
721          NULL as trace_slices,
722          NULL as trace_threads,
723          'Package: ' || (
724            SELECT package
725            FROM android_startups l
726            WHERE l.startup_id != launch.startup_id
727              AND _is_spans_overlapping(l.ts, l.ts_end, launch.ts, launch.ts_end)
728              LIMIT 1) as extra
729        FROM android_startups launch
730        WHERE launch.startup_id = $startup_id
731          AND EXISTS(
732          SELECT package
733          FROM android_startups l
734          WHERE l.startup_id != launch.startup_id
735            AND _is_spans_overlapping(l.ts, l.ts_end, launch.ts, launch.ts_end))
736
737        UNION ALL
738        SELECT 'Main Thread - Binder transactions blocked' as slow_cause,
739          launch.dur as launch_dur,
740          'MAIN_THREAD_BINDER_TRANSCATIONS_BLOCKED' as reason_id,
741          AndroidStartupMetric_ThresholdValue(
742            'value', FALSE,
743            'unit', 'TRUE_OR_FALSE') as expected_val,
744          AndroidStartupMetric_ActualValue(
745            'value', TRUE) as actual_val,
746          get_main_thread_binder_transactions_blocked(launch.startup_id, 2e7, 3) as trace_slices,
747          NULL as trace_threads,
748          NULL as extra
749        FROM android_startups launch
750        WHERE launch.startup_id = $startup_id
751          AND (
752          SELECT COUNT(1)
753          FROM BINDER_TRANSACTION_REPLY_SLICES_FOR_LAUNCH(launch.startup_id, 2e7)) > 0
754    );
755