• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 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
16INCLUDE PERFETTO MODULE android.frames.timeline;
17
18INCLUDE PERFETTO MODULE slices.with_context;
19
20CREATE PERFETTO TABLE _input_message_sent AS
21SELECT
22  str_split(str_split(slice.name, '=', 3), ')', 0) AS event_type,
23  str_split(str_split(slice.name, '=', 2), ',', 0) AS event_seq,
24  str_split(str_split(slice.name, '=', 1), ',', 0) AS event_channel,
25  thread.tid,
26  thread.name AS thread_name,
27  process.pid,
28  process.name AS process_name,
29  slice.ts,
30  slice.dur,
31  slice.track_id
32FROM slice
33JOIN thread_track
34  ON thread_track.id = slice.track_id
35JOIN thread
36  USING (utid)
37JOIN process
38  USING (upid)
39WHERE
40  slice.name GLOB 'sendMessage(*'
41ORDER BY
42  event_seq;
43
44CREATE PERFETTO TABLE _input_message_received AS
45SELECT
46  str_split(str_split(slice.name, '=', 3), ')', 0) AS event_type,
47  str_split(str_split(slice.name, '=', 2), ',', 0) AS event_seq,
48  str_split(str_split(slice.name, '=', 1), ',', 0) AS event_channel,
49  thread.tid,
50  thread.name AS thread_name,
51  process.pid,
52  process.name AS process_name,
53  slice.ts,
54  slice.dur,
55  slice.track_id
56FROM slice
57JOIN thread_track
58  ON thread_track.id = slice.track_id
59JOIN thread
60  USING (utid)
61JOIN process
62  USING (upid)
63WHERE
64  slice.name GLOB 'receiveMessage(*'
65ORDER BY
66  event_seq;
67
68CREATE PERFETTO TABLE _input_read_time AS
69SELECT
70  name,
71  str_split(str_split(name, '=', 1), ')', 0) AS input_event_id,
72  ts AS read_time
73FROM slice
74WHERE
75  name GLOB 'UnwantedInteractionBlocker::notifyMotion*';
76
77CREATE PERFETTO TABLE _event_seq_to_input_event_id AS
78SELECT
79  str_split(str_split(send_message_slice.name, '=', 2), ',', 0) AS event_seq,
80  str_split(str_split(send_message_slice.name, '=', 1), ',', 0) AS event_channel,
81  str_split(str_split(enqeue_slice.name, '=', 2), ')', 0) AS input_event_id,
82  thread_slice.thread_name
83FROM slice AS send_message_slice
84JOIN slice AS publish_slice
85  ON send_message_slice.parent_id = publish_slice.id
86JOIN slice AS start_dispatch_slice
87  ON publish_slice.parent_id = start_dispatch_slice.id
88JOIN slice AS enqeue_slice
89  ON start_dispatch_slice.parent_id = enqeue_slice.id
90JOIN thread_slice
91  ON send_message_slice.id = thread_slice.id
92WHERE
93  send_message_slice.name GLOB 'sendMessage(*'
94  AND thread_slice.thread_name = 'InputDispatcher';
95
96CREATE PERFETTO TABLE _input_event_id_to_android_frame AS
97SELECT
98  str_split(deliver_input_slice.name, '=', 3) AS input_event_id,
99  str_split(str_split(dispatch_input_slice.name, '_', 1), ' ', 0) AS event_action,
100  dispatch_input_slice.ts AS consume_time,
101  dispatch_input_slice.ts + dispatch_input_slice.dur AS finish_time,
102  thread_slice.utid,
103  thread_slice.process_name AS process_name,
104  (
105    SELECT
106      android_frames.frame_id
107    FROM android_frames
108    WHERE
109      android_frames.ts > dispatch_input_slice.ts
110    LIMIT 1
111  ) AS frame_id,
112  (
113    SELECT
114      android_frames.ts
115    FROM android_frames
116    WHERE
117      android_frames.ts > dispatch_input_slice.ts
118    LIMIT 1
119  ) AS ts,
120  (
121    SELECT
122      _input_message_received.event_channel
123    FROM _input_message_received
124    WHERE
125      _input_message_received.ts < deliver_input_slice.ts
126      AND _input_message_received.track_id = deliver_input_slice.track_id
127    ORDER BY
128      _input_message_received.ts DESC
129    LIMIT 1
130  ) AS event_channel
131FROM slice AS deliver_input_slice
132JOIN slice AS dispatch_input_slice
133  ON deliver_input_slice.parent_id = dispatch_input_slice.id
134JOIN thread_slice
135  ON deliver_input_slice.id = thread_slice.id
136WHERE
137  deliver_input_slice.name GLOB 'deliverInputEvent src=*';
138
139CREATE PERFETTO TABLE _app_frame_to_surface_flinger_frame AS
140SELECT
141  app.surface_frame_token AS app_surface_frame_token,
142  surface_flinger.ts AS surface_flinger_ts,
143  surface_flinger.dur AS surface_flinger_dur,
144  app.ts AS app_ts,
145  app.present_type,
146  app.upid
147FROM actual_frame_timeline_slice AS surface_flinger
148JOIN actual_frame_timeline_slice AS app
149  ON surface_flinger.display_frame_token = app.display_frame_token
150  AND surface_flinger.id != app.id
151WHERE
152  surface_flinger.surface_frame_token = 0 AND app.present_type != 'Dropped Frame';
153
154CREATE PERFETTO TABLE _first_non_dropped_frame_after_input AS
155SELECT
156  _input_read_time.input_event_id,
157  _input_read_time.read_time,
158  (
159    SELECT
160      surface_flinger_ts + surface_flinger_dur
161    FROM _app_frame_to_surface_flinger_frame AS sf_frames
162    WHERE
163      sf_frames.app_ts >= _input_event_id_to_android_frame.ts
164    LIMIT 1
165  ) AS present_time,
166  (
167    SELECT
168      app_surface_frame_token
169    FROM _app_frame_to_surface_flinger_frame AS sf_frames
170    WHERE
171      sf_frames.app_ts >= _input_event_id_to_android_frame.ts
172    LIMIT 1
173  ) AS frame_id,
174  event_seq,
175  event_action
176FROM _input_event_id_to_android_frame
177RIGHT JOIN _event_seq_to_input_event_id
178  ON _input_event_id_to_android_frame.input_event_id = _event_seq_to_input_event_id.input_event_id
179  AND _input_event_id_to_android_frame.event_channel = _event_seq_to_input_event_id.event_channel
180JOIN _input_read_time
181  ON _input_read_time.input_event_id = _event_seq_to_input_event_id.input_event_id;
182
183-- All input events with round trip latency breakdown. Input delivery is socket based and every
184-- input event sent from the OS needs to be ACK'ed by the app. This gives us 4 subevents to measure
185-- latencies between:
186-- 1. Input dispatch event sent from OS.
187-- 2. Input dispatch event received in app.
188-- 3. Input ACK event sent from app.
189-- 4. Input ACk event received in OS.
190CREATE PERFETTO TABLE android_input_events (
191  -- Duration from input dispatch to input received.
192  dispatch_latency_dur DURATION,
193  -- Duration from input received to input ACK sent.
194  handling_latency_dur DURATION,
195  -- Duration from input ACK sent to input ACK recieved.
196  ack_latency_dur DURATION,
197  -- Duration from input dispatch to input event ACK received.
198  total_latency_dur DURATION,
199  -- Duration from input read to frame present time. Null if an input event has no associated frame event.
200  end_to_end_latency_dur DURATION,
201  -- Tid of thread receiving the input event.
202  tid LONG,
203  -- Name of thread receiving the input event.
204  thread_name STRING,
205  -- Pid of process receiving the input event.
206  pid LONG,
207  -- Name of process receiving the input event.
208  process_name STRING,
209  -- Input event type. See InputTransport.h: InputMessage#Type
210  event_type STRING,
211  -- Input event action.
212  event_action STRING,
213  -- Input event sequence number, monotonically increasing for an event channel and pid.
214  event_seq STRING,
215  -- Input event channel name.
216  event_channel STRING,
217  -- Unique identifier for the input event.
218  input_event_id STRING,
219  -- Timestamp input event was read by InputReader.
220  read_time LONG,
221  -- Thread track id of input event dispatching thread.
222  dispatch_track_id JOINID(track.id),
223  -- Timestamp input event was dispatched.
224  dispatch_ts TIMESTAMP,
225  -- Duration of input event dispatch.
226  dispatch_dur DURATION,
227  -- Thread track id of input event receiving thread.
228  receive_track_id JOINID(track.id),
229  -- Timestamp input event was received.
230  receive_ts TIMESTAMP,
231  -- Duration of input event receipt.
232  receive_dur DURATION,
233  -- Vsync Id associated with the input. Null if an input event has no associated frame event.
234  frame_id LONG
235) AS
236WITH
237  dispatch AS MATERIALIZED (
238    SELECT
239      *
240    FROM _input_message_sent
241    WHERE
242      thread_name = 'InputDispatcher'
243    ORDER BY
244      event_seq,
245      event_channel
246  ),
247  receive AS MATERIALIZED (
248    SELECT
249      *,
250      replace(event_channel, '(client)', '(server)') AS dispatch_event_channel
251    FROM _input_message_received
252    WHERE
253      NOT event_type IN ('0x2', 'FINISHED')
254    ORDER BY
255      event_seq,
256      dispatch_event_channel
257  ),
258  finish AS MATERIALIZED (
259    SELECT
260      *,
261      replace(event_channel, '(client)', '(server)') AS dispatch_event_channel
262    FROM _input_message_sent
263    WHERE
264      thread_name != 'InputDispatcher'
265    ORDER BY
266      event_seq,
267      dispatch_event_channel
268  ),
269  finish_ack AS MATERIALIZED (
270    SELECT
271      *
272    FROM _input_message_received
273    WHERE
274      event_type IN ('0x2', 'FINISHED')
275    ORDER BY
276      event_seq,
277      event_channel
278  )
279SELECT
280  receive.ts - dispatch.ts AS dispatch_latency_dur,
281  finish.ts - receive.ts AS handling_latency_dur,
282  finish_ack.ts - finish.ts AS ack_latency_dur,
283  finish_ack.ts - dispatch.ts AS total_latency_dur,
284  frame.present_time - frame.read_time AS end_to_end_latency_dur,
285  finish.tid AS tid,
286  finish.thread_name AS thread_name,
287  finish.pid AS pid,
288  finish.process_name AS process_name,
289  dispatch.event_type,
290  frame.event_action,
291  dispatch.event_seq,
292  dispatch.event_channel,
293  frame.input_event_id,
294  frame.read_time,
295  dispatch.track_id AS dispatch_track_id,
296  dispatch.ts AS dispatch_ts,
297  dispatch.dur AS dispatch_dur,
298  receive.ts AS receive_ts,
299  receive.dur AS receive_dur,
300  receive.track_id AS receive_track_id,
301  frame.frame_id
302FROM dispatch
303JOIN receive
304  ON receive.dispatch_event_channel = dispatch.event_channel
305  AND dispatch.event_seq = receive.event_seq
306JOIN finish
307  ON finish.dispatch_event_channel = dispatch.event_channel
308  AND dispatch.event_seq = finish.event_seq
309JOIN finish_ack
310  ON finish_ack.event_channel = dispatch.event_channel
311  AND dispatch.event_seq = finish_ack.event_seq
312LEFT JOIN _first_non_dropped_frame_after_input AS frame
313  ON frame.event_seq = dispatch.event_seq;
314
315-- Key events processed by the Android framework (from android.input.inputevent data source).
316CREATE PERFETTO VIEW android_key_events (
317  -- ID of the trace entry
318  id LONG,
319  -- The randomly-generated ID associated with each input event processed
320  -- by Android Framework, used to track the event through the input pipeline
321  event_id LONG,
322  -- The timestamp of when the input event was processed by the system
323  ts TIMESTAMP,
324  -- Details of the input event parsed from the proto message
325  arg_set_id ARGSETID
326) AS
327SELECT
328  id,
329  event_id,
330  ts,
331  arg_set_id
332FROM __intrinsic_android_key_events;
333
334-- Motion events processed by the Android framework (from android.input.inputevent data source).
335CREATE PERFETTO VIEW android_motion_events (
336  -- ID of the trace entry
337  id LONG,
338  -- The randomly-generated ID associated with each input event processed
339  -- by Android Framework, used to track the event through the input pipeline
340  event_id LONG,
341  -- The timestamp of when the input event was processed by the system
342  ts TIMESTAMP,
343  -- Details of the input event parsed from the proto message
344  arg_set_id ARGSETID
345) AS
346SELECT
347  id,
348  event_id,
349  ts,
350  arg_set_id
351FROM __intrinsic_android_motion_events;
352
353-- Input event dispatching information in Android (from android.input.inputevent data source).
354CREATE PERFETTO VIEW android_input_event_dispatch (
355  -- ID of the trace entry
356  id LONG,
357  -- Event ID of the input event that was dispatched
358  event_id LONG,
359  -- Details of the input event parsed from the proto message
360  arg_set_id ARGSETID,
361  -- Vsync ID that identifies the state of the windows during which the dispatch decision was made
362  vsync_id LONG,
363  -- Window ID of the window receiving the event
364  window_id LONG
365) AS
366SELECT
367  id,
368  event_id,
369  arg_set_id,
370  vsync_id,
371  window_id
372FROM __intrinsic_android_input_event_dispatch;
373