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-- 16 17CREATE PERFETTO FUNCTION _extract_freezer_pid(name STRING) 18RETURNS INT 19AS 20SELECT CAST(reverse(str_split(reverse(str_split($name, ' ', 1)), ':', 0)) AS INT); 21 22-- Converts a pid to a upid using the timestamp of occurence of an event from 23-- |pid| to disambiguate duplicate pids. 24-- 25-- This is still best effort because it relies on having information about 26-- process start and end in the trace. In the edge case that we are missing this, 27-- it best effort returns the last upid. 28CREATE PERFETTO FUNCTION _pid_to_upid( 29 -- Pid to convert from. 30 pid INT, 31 -- Timestamp of an event from the |pid|. 32 event_ts INT) 33-- Returns the converted upid. 34RETURNS INT 35AS 36WITH 37 process_lifetime AS ( 38 SELECT 39 pid, 40 upid, 41 COALESCE(start_ts, trace_start()) AS start_ts, 42 COALESCE(end_ts, trace_end()) AS end_ts 43 FROM process 44 ) 45SELECT upid 46FROM process_lifetime 47WHERE pid = $pid AND $event_ts BETWEEN start_ts AND end_ts 48ORDER BY upid DESC 49LIMIT 1; 50 51-- Translate unfreeze reason from INT to STRING. 52-- See: frameworks/proto_logging/stats/atoms.proto 53CREATE PERFETTO FUNCTION _translate_unfreeze_reason(reason INT) 54RETURNS STRING 55AS 56SELECT 57 CASE 58 WHEN $reason = 0 THEN 'none' 59 WHEN $reason = 1 THEN 'activity' 60 WHEN $reason = 2 THEN 'finish_receiver' 61 WHEN $reason = 3 THEN 'start_receiver' 62 WHEN $reason = 4 THEN 'bind_service' 63 WHEN $reason = 5 THEN 'unbind_service' 64 WHEN $reason = 6 THEN 'start_service' 65 WHEN $reason = 7 THEN 'get_provider' 66 WHEN $reason = 8 THEN 'remove_provider' 67 WHEN $reason = 9 THEN 'ui_visibility' 68 WHEN $reason = 10 THEN 'allowlist' 69 WHEN $reason = 11 THEN 'process_begin' 70 WHEN $reason = 12 THEN 'process_end' 71 WHEN $reason = 13 THEN 'trim_memory' 72 WHEN $reason = 15 THEN 'ping' 73 WHEN $reason = 16 THEN 'file_locks' 74 WHEN $reason = 17 THEN 'file_lock_check_failure' 75 WHEN $reason = 18 THEN 'binder_txns' 76 WHEN $reason = 19 THEN 'feature_flags' 77 WHEN $reason = 20 THEN 'short_fgs_timeout' 78 WHEN $reason = 21 THEN 'system_init' 79 WHEN $reason = 22 THEN 'backup' 80 WHEN $reason = 23 THEN 'shell' 81 WHEN $reason = 24 THEN 'remove_task' 82 WHEN $reason = 25 THEN 'uid_idle' 83 WHEN $reason = 26 THEN 'stop_service' 84 WHEN $reason = 27 THEN 'executing_service' 85 WHEN $reason = 28 THEN 'restriction_change' 86 WHEN $reason = 29 THEN 'component_disabled' 87 ELSE NULL 88 END; 89 90-- All frozen processes and their frozen duration. 91CREATE PERFETTO TABLE android_freezer_events ( 92 -- Upid of frozen process 93 upid INT, 94 -- Pid of frozen process 95 pid INT, 96 -- Timestamp process was frozen. 97 ts INT, 98 -- Duration process was frozen for. 99 dur INT, 100 -- Unfreeze reason Integer. 101 unfreeze_reason_int INT, 102 -- Unfreeze reason String. 103 unfreeze_reason_str INT 104 ) 105AS 106WITH 107 freeze AS ( 108 SELECT ts, _extract_freezer_pid(name) AS pid, 109 _pid_to_upid(_extract_freezer_pid(name), ts) AS upid, 'freeze' AS type, 110 NULL AS unfreeze_reason 111 FROM slice 112 WHERE name GLOB 'Freeze *:*' 113 ), 114 unfreeze AS ( 115 SELECT ts, _extract_freezer_pid(name) AS pid, 116 _pid_to_upid(_extract_freezer_pid(name), ts) AS upid, 'unfreeze' AS type, 117 str_split(name, ' ', 2) AS unfreeze_reason 118 FROM slice 119 WHERE name GLOB 'Unfreeze *:*' 120 ), 121 merged AS ( 122 SELECT * FROM freeze 123 UNION ALL 124 SELECT * FROM unfreeze 125 ), 126 starts AS ( 127 SELECT 128 type, 129 upid, 130 pid, 131 ts, 132 ifnull(lead(ts) OVER (PARTITION BY upid ORDER BY ts), trace_end()) - ts AS dur, 133 CAST(lead(unfreeze_reason) OVER (PARTITION BY upid ORDER BY ts) AS INT) AS unfreeze_reason 134 FROM merged 135 ) 136SELECT 137 upid, 138 pid, 139 ts, 140 dur, 141 unfreeze_reason AS unfreeze_reason_int, 142 _translate_unfreeze_reason(unfreeze_reason) AS unfreeze_reason_str 143FROM starts 144WHERE starts.type = 'freeze' AND upid IS NOT NULL; 145