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