• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-- The start of the launching event corresponds to the end of the AM handling
18-- the startActivity intent, whereas the end corresponds to the first frame drawn.
19-- Only successful app launches have a launching event.
20DROP TABLE IF EXISTS launching_events;
21CREATE TABLE launching_events AS
22SELECT
23  ts,
24  dur,
25  ts + dur AS ts_end,
26  STR_SPLIT(s.name, ": ", 1) AS package_name
27FROM slice s
28JOIN process_track t ON s.track_id = t.id
29JOIN process USING(upid)
30WHERE s.name LIKE 'launching: %'
31AND (process.name IS NULL OR process.name = 'system_server');
32
33-- Marks the beginning of the trace and is equivalent to when the statsd launch
34-- logging begins.
35DROP VIEW IF EXISTS activity_intent_received;
36CREATE VIEW activity_intent_received AS
37SELECT ts FROM slice
38WHERE name = 'MetricsLogger:launchObserverNotifyIntentStarted';
39
40-- Successful activity launch. The end of the 'launching' event is not related
41-- to whether it actually succeeded or not.
42DROP VIEW IF EXISTS activity_intent_launch_successful;
43CREATE VIEW activity_intent_launch_successful AS
44SELECT ts FROM slice
45WHERE name = 'MetricsLogger:launchObserverNotifyActivityLaunchFinished';
46
47-- We partition the trace into spans based on posted activity intents.
48-- We will refine these progressively in the next steps to only encompass
49-- activity starts.
50DROP TABLE IF EXISTS activity_intent_recv_spans;
51CREATE TABLE activity_intent_recv_spans(id INT, ts BIG INT, dur BIG INT);
52
53INSERT INTO activity_intent_recv_spans
54SELECT
55  ROW_NUMBER()
56    OVER(ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS id,
57  ts,
58  LEAD(ts, 1, (SELECT end_ts FROM trace_bounds)) OVER(ORDER BY ts) - ts AS dur
59FROM activity_intent_received
60ORDER BY ts;
61
62-- Filter activity_intent_recv_spans, keeping only the ones that triggered
63-- a launch.
64DROP VIEW IF EXISTS launch_partitions;
65CREATE VIEW launch_partitions AS
66SELECT * FROM activity_intent_recv_spans AS spans
67WHERE 1 = (
68  SELECT COUNT(1)
69  FROM launching_events
70  WHERE launching_events.ts BETWEEN spans.ts AND spans.ts + spans.dur);
71
72-- All activity launches in the trace, keyed by ID.
73DROP TABLE IF EXISTS launches;
74CREATE TABLE launches(
75  ts BIG INT,
76  ts_end BIG INT,
77  dur BIG INT,
78  id INT,
79  package STRING);
80
81-- Use the starting event package name. The finish event package name
82-- is not reliable in the case of failed launches.
83INSERT INTO launches
84SELECT
85  lpart.ts AS ts,
86  launching_events.ts_end AS ts_end,
87  launching_events.ts_end - lpart.ts AS dur,
88  lpart.id AS id,
89  package_name AS package
90FROM launch_partitions AS lpart
91JOIN launching_events ON
92  (launching_events.ts BETWEEN lpart.ts AND lpart.ts + lpart.dur) AND
93  (launching_events.ts_end BETWEEN lpart.ts AND lpart.ts + lpart.dur)
94WHERE (
95  SELECT COUNT(1)
96  FROM activity_intent_launch_successful AS successful
97  WHERE successful.ts BETWEEN lpart.ts AND lpart.ts + lpart.dur
98) > 0;
99
100-- Maps a launch to the corresponding set of processes that handled the
101-- activity start. The vast majority of cases should be a single process.
102-- However it is possible that the process dies during the activity launch
103-- and is respawned.
104DROP TABLE IF EXISTS launch_processes;
105CREATE TABLE launch_processes(launch_id INT, upid BIG INT);
106
107-- We make the (not always correct) simplification that process == package
108INSERT INTO launch_processes
109SELECT launches.id, process.upid
110FROM launches
111  JOIN process ON launches.package = process.name
112  JOIN thread ON (process.upid = thread.upid AND process.pid = thread.tid)
113WHERE (process.start_ts IS NULL OR process.start_ts < launches.ts_end)
114AND (thread.end_ts IS NULL OR thread.end_ts > launches.ts_end)
115ORDER BY process.start_ts DESC;
116