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