• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2023 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-- Converts a battery_stats counter value to human readable string.
17CREATE PERFETTO FUNCTION android_battery_stats_counter_to_string(
18  -- The counter track name (e.g. 'battery_stats.audio').
19  track STRING,
20  -- The counter value.
21  value FLOAT)
22-- The human-readable name for the counter value.
23RETURNS STRING AS
24SELECT
25  CASE
26    WHEN ($track = "battery_stats.wifi_scan" OR
27          $track = "battery_stats.wifi_radio" OR
28          $track = "battery_stats.mobile_radio" OR
29          $track = "battery_stats.audio" OR
30          $track = "battery_stats.video" OR
31          $track = "battery_stats.camera" OR
32          $track = "battery_stats.power_save" OR
33          $track = "battery_stats.phone_in_call")
34      THEN
35        CASE $value
36          WHEN 0 THEN "inactive"
37          WHEN 1 THEN "active"
38          ELSE "unknown"
39        END
40    WHEN $track = "battery_stats.wifi"
41      THEN
42        CASE $value
43          WHEN 0 THEN "off"
44          WHEN 1 THEN "on"
45          ELSE "unknown"
46        END
47    WHEN $track = "battery_stats.phone_state"
48      THEN
49        CASE $value
50          WHEN 0 THEN "in"
51          WHEN 1 THEN "out"
52          WHEN 2 THEN "emergency"
53          WHEN 3 THEN "off"
54          ELSE "unknown"
55        END
56    WHEN ($track = "battery_stats.phone_signal_strength" OR
57          $track = "battery_stats.wifi_signal_strength")
58      THEN
59        CASE $value
60          WHEN 0 THEN "0/4"
61          WHEN 1 THEN "1/4"
62          WHEN 2 THEN "2/4"
63          WHEN 3 THEN "3/4"
64          WHEN 4 THEN "4/4"
65          ELSE "unknown"
66        END
67    WHEN $track = "battery_stats.wifi_suppl"
68      THEN
69        CASE $value
70          WHEN 0 THEN "invalid"
71          WHEN 1 THEN "disconnected"
72          WHEN 2 THEN "disabled"
73          WHEN 3 THEN "inactive"
74          WHEN 4 THEN "scanning"
75          WHEN 5 THEN "authenticating"
76          WHEN 6 THEN "associating"
77          WHEN 7 THEN "associated"
78          WHEN 8 THEN "4-way-handshake"
79          WHEN 9 THEN "group-handshake"
80          WHEN 10 THEN "completed"
81          WHEN 11 THEN "dormant"
82          WHEN 12 THEN "uninitialized"
83          ELSE "unknown"
84        END
85    WHEN $track = "battery_stats.data_conn"
86      THEN
87        CASE $value
88          WHEN 0 THEN "Out of service"
89          WHEN 1 THEN "2.5G (GPRS)"
90          WHEN 2 THEN "2.7G (EDGE)"
91          WHEN 3 THEN "3G (UMTS)"
92          WHEN 4 THEN "3G (CDMA)"
93          WHEN 5 THEN "3G (EVDO Rel 0)"
94          WHEN 6 THEN "3G (EVDO Rev A)"
95          WHEN 7 THEN "3G (LXRTT)"
96          WHEN 8 THEN "3.5G (HSDPA)"
97          WHEN 9 THEN "3.5G (HSUPA)"
98          WHEN 10 THEN "3.5G (HSPA)"
99          WHEN 11 THEN "2G (IDEN)"
100          WHEN 12 THEN "3G (EVDO Rev B)"
101          WHEN 13 THEN "4G (LTE)"
102          WHEN 14 THEN "3.5G (eHRPD)"
103          WHEN 15 THEN "3.7G (HSPA+)"
104          WHEN 16 THEN "2G (GSM)"
105          WHEN 17 THEN "3G (TD SCDMA)"
106          WHEN 18 THEN "Wifi calling (IWLAN)"
107          WHEN 19 THEN "4.5G (LTE CA)"
108          WHEN 20 THEN "5G (NR)"
109          WHEN 21 THEN "Emergency calls only"
110          WHEN 22 THEN "Other"
111          ELSE "unknown"
112        END
113    ELSE CAST($value AS text)
114  END;
115
116-- View of human readable battery stats counter-based states. These are recorded
117-- by BatteryStats as a bitmap where each 'category' has a unique value at any
118-- given time.
119CREATE PERFETTO VIEW android_battery_stats_state(
120  -- Timestamp in nanoseconds.
121  ts INT,
122  -- The duration the state was active, may be negative for incomplete slices.
123  dur INT,
124  -- The same as `dur`, but extends to trace end for incomplete slices.
125  safe_dur INT,
126  -- The name of the counter track.
127  track_name STRING,
128  -- The counter value as a number.
129  value INT,
130  -- The counter value as a human-readable string.
131  value_name STRING
132) AS
133SELECT
134  ts,
135  IFNULL(LEAD(ts) OVER (PARTITION BY name ORDER BY ts) - ts, -1) AS dur,
136  LEAD(ts, 1, TRACE_END()) OVER (PARTITION BY name ORDER BY ts) - ts AS safe_dur,
137  name AS track_name,
138  CAST(value AS INT64) AS value,
139  android_battery_stats_counter_to_string(name, value) AS value_name
140FROM counter
141JOIN counter_track
142  ON counter.track_id = counter_track.id
143WHERE counter_track.name GLOB 'battery_stats.*';
144
145
146-- View of slices derived from battery_stats events. Battery stats records all
147-- events as instants, however some may indicate whether something started or
148-- stopped with a '+' or '-' prefix. Events such as jobs, top apps, foreground
149-- apps or long wakes include these details and allow drawing slices between
150-- instant events found in a trace.
151--
152-- For example, we may see an event like the following on 'battery_stats.top':
153--
154--     -top=10215:"com.google.android.apps.nexuslauncher"
155--
156-- This view will find the associated start ('+top') with the matching suffix
157-- (everything after the '=') to construct a slice. It computes the timestamp
158-- and duration from the events and extract the details as follows:
159--
160--     track_name='battery_stats.top'
161--     str_value='com.google.android.apps.nexuslauncher'
162--     int_value=10215
163CREATE PERFETTO VIEW android_battery_stats_event_slices(
164  -- Timestamp in nanoseconds.
165  ts INT,
166  -- The duration the state was active, may be negative for incomplete slices.
167  dur INT,
168  -- The same as `dur`, but extends to trace end for incomplete slices.
169  safe_dur INT,
170  -- The name of the counter track.
171  track_name STRING,
172  -- String value.
173  str_value STRING,
174  -- Int value.
175  int_value INT
176) AS
177WITH
178  event_markers AS (
179    SELECT
180      ts,
181      track.name AS track_name,
182      str_split(slice.name, '=', 1) AS key,
183      substr(slice.name, 1, 1) = '+' AS start
184    FROM slice
185    JOIN track
186      ON slice.track_id = track.id
187    WHERE
188      track_name GLOB 'battery_stats.*'
189      AND substr(slice.name, 1, 1) IN ('+', '-')
190  ),
191  with_neighbors AS (
192    SELECT
193      *,
194      LAG(ts) OVER (PARTITION BY track_name, key ORDER BY ts) AS last_ts,
195      LEAD(ts) OVER (PARTITION BY track_name, key ORDER BY ts) AS next_ts
196    FROM event_markers
197  ),
198  -- Note: query performance depends on the ability to push down filters on
199  -- the track_name. It would be more clear below to have two queries and union
200  -- them, but doing so prevents push down through the above window functions.
201  event_spans AS (
202    SELECT
203      track_name, key,
204      IIF(start, ts, trace_start()) AS ts,
205      IIF(start, next_ts, ts) AS end_ts
206    FROM with_neighbors
207    -- For the majority of events, we take the `start` event and compute the dur
208    -- based on next_ts. In the off chance we get an end event with no prior
209    -- start (matched by the second half of this where), we can create an event
210    -- starting from the beginning of the trace ending at the current event.
211    WHERE (start OR last_ts IS NULL)
212  )
213SELECT
214  ts,
215  IFNULL(end_ts-ts, -1) AS dur,
216  IFNULL(end_ts, TRACE_END()) - ts AS safe_dur,
217  track_name,
218  str_split(key, '"', 1) AS str_value,
219  CAST(str_split(key, ':', 0) AS INT64) AS int_value
220FROM event_spans;
221