• 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-- WARNING: This metric should not be used as a source of truth. It is under
17--          active development and the values & meaning might change without
18--          notice.
19
20SELECT RUN_METRIC('chrome/jank_utilities.sql');
21SELECT RUN_METRIC(
22  'chrome/chrome_tasks_template.sql',
23  'slice_table_name', 'slice',
24  'function_prefix', ''
25);
26
27SELECT CREATE_FUNCTION(
28  'IS_LONG_CHOREOGRAPHER_TASK(dur LONG)',
29  'BOOL',
30  'SELECT $dur >= 4 * 1e6'
31);
32
33-- Note that not all slices will be mojo slices; filter on interface_name IS
34-- NOT NULL for mojo slices specifically.
35DROP TABLE IF EXISTS long_tasks_extracted_slices;
36CREATE TABLE long_tasks_extracted_slices AS
37SELECT * FROM SELECT_LONG_TASK_SLICES(/*name*/'LongTaskTracker');
38
39-- Create |long_tasks_internal_tbl| table, which gathers all of the
40-- information needed to produce the full name + metadata required
41-- for LongTaskTracker slices. Unlike toplevel slices, which will
42-- have nested descendants, LongTaskTracker slices will store all of
43-- the relevant information within the single slice.
44DROP TABLE IF EXISTS long_tasks_internal_tbl;
45CREATE TABLE long_tasks_internal_tbl AS
46WITH
47  raw_extracted_values AS (
48    SELECT
49      mojo.id,
50      mojo.interface_name,
51      mojo.ipc_hash,
52      mojo.message_type,
53      EXTRACT_ARG(s.arg_set_id, 'task.posted_from.file_name') AS posted_from_file_name,
54      EXTRACT_ARG(s.arg_set_id, 'task.posted_from.function_name') AS posted_from_function_name
55    FROM long_tasks_extracted_slices mojo
56    JOIN slice s ON mojo.id = s.id
57  )
58SELECT
59  id,
60  CASE
61    WHEN interface_name IS NOT NULL
62      THEN printf('%s %s (hash=%d)', interface_name, message_type, ipc_hash)
63    ELSE
64      FORMAT_SCHEDULER_TASK_NAME(posted_from_file_name || ':' || posted_from_function_name)
65    END AS full_name,
66  interface_name IS NOT NULL AS is_mojo
67FROM raw_extracted_values;
68
69-- Attach java views to its associated LongTaskTracker slice, as they
70-- will be on different tracks. This follows the same logic as creating
71-- chrome_slices_with_java_views_internal, differing only in how a
72-- descendent is calculated.
73DROP VIEW IF EXISTS long_task_slices_with_java_views;
74CREATE VIEW long_task_slices_with_java_views AS
75WITH
76  -- Select UI thread BeginMainFrames frames.
77  root_slices AS (
78    SELECT *
79    FROM SELECT_BEGIN_MAIN_FRAME_JAVA_SLICES('LongTaskTracker')
80    UNION ALL
81    SELECT * FROM chrome_choreographer_tasks WHERE IS_LONG_CHOREOGRAPHER_TASK(dur)
82  ),
83  -- Intermediate step to allow us to sort java view names.
84  root_slice_and_java_view_not_grouped AS (
85    SELECT
86      s1.id, s1.kind, s2.name AS java_view_name
87    FROM root_slices s1
88    JOIN chrome_java_views_internal s2
89      ON (
90        s1.ts < s2.ts AND s1.ts + s1.dur > s2.ts + s2.dur)
91  )
92SELECT
93  s1.id,
94  s1.kind,
95  GROUP_CONCAT(DISTINCT s2.java_view_name) AS java_views
96FROM root_slices s1
97LEFT JOIN root_slice_and_java_view_not_grouped s2
98  USING (id)
99GROUP BY s1.id;
100
101DROP VIEW IF EXISTS chrome_long_tasks_internal;
102CREATE VIEW chrome_long_tasks_internal AS
103WITH -- Generate full names for tasks with java views.
104  java_views_tasks AS (
105    SELECT
106      printf('%s(java_views=%s)', kind, java_views) as full_name,
107      GET_JAVA_VIEWS_TASK_TYPE(kind) AS task_type,
108      id
109    FROM long_task_slices_with_java_views
110    WHERE kind = "SingleThreadProxy::BeginMainFrame"
111  ),
112  scheduler_tasks_with_mojo AS (
113    SELECT
114      full_name,
115      'mojo' as task_type,
116      id
117    FROM long_tasks_internal_tbl
118    WHERE is_mojo
119  ),
120  navigation_tasks AS (
121    SELECT
122      -- NOTE: unless Navigation category is enabled and recorded on the same
123      -- track as the LongTaskTracker slice, frame type will always be unknown.
124      printf('%s (%s)',
125        HUMAN_READABLE_NAVIGATION_TASK_NAME(full_name),
126        IFNULL(EXTRACT_FRAME_TYPE(id), 'unknown frame type')) AS full_name,
127      'navigation_task' AS task_type,
128      id
129    FROM scheduler_tasks_with_mojo
130    WHERE HUMAN_READABLE_NAVIGATION_TASK_NAME(full_name) IS NOT NULL
131  )
132SELECT
133  COALESCE(s4.full_name, s3.full_name, s2.full_name, s1.full_name) AS full_name,
134  COALESCE(s4.task_type, s3.task_type, s2.task_type, 'scheduler') as task_type,
135  s1.id as id
136FROM long_tasks_internal_tbl s1
137LEFT JOIN scheduler_tasks_with_mojo s2 ON s2.id = s1.id
138LEFT JOIN java_views_tasks s3 ON s3.id = s1.id
139LEFT JOIN navigation_tasks s4 ON s4.id = s1.id
140UNION ALL
141-- Choreographer slices won't necessarily be associated with an overlying
142-- LongTaskTracker slice, so join them separately.
143SELECT
144  printf('%s(java_views=%s)', kind, java_views) as full_name,
145  GET_JAVA_VIEWS_TASK_TYPE(kind) AS task_type,
146  id
147FROM long_task_slices_with_java_views
148WHERE kind = "Choreographer";
149
150DROP VIEW IF EXISTS chrome_long_tasks;
151CREATE VIEW chrome_long_tasks AS
152SELECT
153  full_name,
154  task_type,
155  thread.name AS thread_name,
156  thread.utid,
157  process.name AS process_name,
158  thread.upid,
159  ts.*
160FROM chrome_long_tasks_internal cti
161JOIN slice ts USING (id)
162JOIN thread_track tt ON ts.track_id = tt.id
163JOIN thread USING (utid)
164JOIN process USING (upid);