• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2020 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-- WebView is embedded in the hosting app's main process, which means it shares some threads
17-- with the host app's work. We approximate WebView-related power usage
18-- by selecting user slices that belong to WebView and estimating their power use
19-- through the CPU time they consume at different core frequencies.
20-- This file populates a summary table that can be used to produce metrics in different formats.
21
22SELECT RUN_METRIC('android/android_proxy_power.sql');
23SELECT RUN_METRIC('android/cpu_info.sql');
24
25DROP TABLE IF EXISTS top_level_slice;
26
27-- Select topmost slices from the 'toplevel' and 'Java' categories.
28-- Filter out Looper events since they are likely to belong to the host app.
29-- Slices are only used to calculate the contribution of the browser process,
30-- renderer contribution will be calculated as the sum of all renderer processes' usage.
31CREATE TABLE top_level_slice AS
32  SELECT *
33  FROM slice WHERE
34  depth = 0 AND
35  ((category GLOB '*toplevel*' OR category = 'Java') AND
36  name NOT GLOB '*looper*');
37
38DROP TABLE IF EXISTS webview_browser_slices;
39
40-- Match top-level slices to threads and hosting apps.
41-- This excludes any renderer slices because renderer processes are counted
42-- as a whole separately.
43-- Slices from Chrome browser processes are also excluded.
44CREATE TABLE webview_browser_slices AS
45  SELECT
46    top_level_slice.ts,
47    top_level_slice.dur,
48    thread_track.utid,
49    process.upid AS upid,
50    extract_arg(process.arg_set_id, 'chrome.host_app_package_name') AS app_name
51  FROM top_level_slice
52  INNER JOIN thread_track
53  ON top_level_slice.track_id = thread_track.id
54  INNER JOIN process
55  ON thread.upid = process.upid
56  INNER JOIN thread
57  ON thread_track.utid = thread.utid
58  WHERE process.name NOT GLOB '*SandboxedProcessService*'
59  AND process.name NOT GLOB '*chrome*'
60  AND app_name IS NOT NULL;
61
62DROP TABLE IF EXISTS webview_browser_slices_power;
63
64-- Assign power usage to WebView browser slices.
65CREATE VIRTUAL TABLE webview_browser_slices_power
66USING SPAN_JOIN(power_per_thread PARTITIONED utid,
67                webview_browser_slices PARTITIONED utid);
68
69DROP TABLE IF EXISTS webview_browser_slices_power_summary;
70
71-- Calculate the power usage of all WebView browser slices for each app
72-- in milliampere-seconds.
73CREATE TABLE webview_browser_slices_power_summary AS
74SELECT
75  app_name,
76  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
77  FROM webview_browser_slices_power
78  GROUP BY app_name;
79
80DROP TABLE IF EXISTS webview_renderer_threads;
81
82-- All threads of all WebView renderer processes.
83CREATE TABLE webview_renderer_threads AS
84SELECT
85  thread.utid AS utid,
86  extract_arg(process.arg_set_id, 'chrome.host_app_package_name') as app_name
87  FROM process
88  INNER JOIN thread
89  ON thread.upid = process.upid
90  WHERE process.name GLOB '*webview*SandboxedProcessService*'
91  AND app_name IS NOT NULL;
92
93DROP TABLE IF EXISTS webview_renderer_power_summary;
94
95-- Calculate the power usage of all WebView renderer processes for each app
96-- in milliampere-seconds.
97CREATE TABLE webview_renderer_power_summary AS
98  SELECT
99    app_name,
100    SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
101  FROM power_per_thread
102  INNER JOIN webview_renderer_threads
103  ON power_per_thread.utid = webview_renderer_threads.utid
104  GROUP BY app_name;
105
106DROP TABLE IF EXISTS webview_renderer_power_per_core_type;
107
108-- Calculate the power usage of all WebView renderer processes for each app
109-- in milliampere-seconds grouped by core type.
110CREATE TABLE webview_renderer_power_per_core_type AS
111SELECT
112  app_name,
113  core_type_per_cpu.core_type AS core_type,
114  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
115FROM power_per_thread
116INNER JOIN webview_renderer_threads
117  ON power_per_thread.utid = webview_renderer_threads.utid
118INNER JOIN core_type_per_cpu
119  ON power_per_thread.cpu = core_type_per_cpu.cpu
120GROUP BY app_name, core_type_per_cpu.core_type;
121
122DROP TABLE IF EXISTS host_app_threads;
123
124-- All threads of hosting apps (this is a superset of webview_browser_slices).
125-- 1) select all threads that had any WebView browser slices associated with them;
126-- 2) get all threads for processes matching threads from 1).
127-- For example, only some of app's threads wrote any slices, but we are selecting
128-- all threads for this app's process.
129-- Excludes all renderer processes and Chrome browser processes.
130CREATE TABLE host_app_threads AS
131SELECT
132    thread.utid AS utid,
133    thread.name AS name,
134    extract_arg(process.arg_set_id, 'chrome.host_app_package_name') as app_name
135  FROM thread
136  JOIN process ON thread.upid = process.upid
137  WHERE thread.upid IN
138    (SELECT DISTINCT(webview_browser_slices.upid) FROM webview_browser_slices)
139  AND process.name NOT GLOB '*SandboxedProcessService*'
140  AND process.name NOT GLOB '*chrome*'
141  AND app_name IS NOT NULL;
142
143DROP TABLE IF EXISTS host_app_power_summary;
144
145-- Calculate the power usage of all WebView (host app+browser) processes for each app
146-- in milliampere-seconds.
147CREATE TABLE host_app_power_summary AS
148  SELECT
149    app_name,
150    SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
151  FROM power_per_thread
152  INNER JOIN host_app_threads
153  ON power_per_thread.utid = host_app_threads.utid
154  GROUP BY app_name;
155
156DROP TABLE IF EXISTS host_app_power_per_core_type;
157
158-- Calculate the power usage of all WebView (host app+browser) processes for each app
159-- in milliampere-seconds grouped by core type.
160CREATE TABLE host_app_power_per_core_type AS
161SELECT
162  app_name,
163  core_type_per_cpu.core_type AS core_type,
164  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
165FROM power_per_thread
166INNER JOIN host_app_threads
167  ON power_per_thread.utid = host_app_threads.utid
168INNER JOIN core_type_per_cpu
169  ON power_per_thread.cpu = core_type_per_cpu.cpu
170GROUP BY app_name, core_type_per_cpu.core_type;
171
172DROP TABLE IF EXISTS webview_only_threads;
173
174-- A subset of the host app threads that are WebView-specific.
175CREATE TABLE webview_only_threads AS
176SELECT *
177FROM host_app_threads
178  WHERE name GLOB 'Chrome*' OR name GLOB 'CookieMonster*'
179  OR name GLOB 'CompositorTileWorker*' OR name GLOB 'ThreadPool*ground*'
180  OR NAME GLOB 'ThreadPoolService*' OR  name GLOB 'VizCompositorThread*'
181  OR name IN ('AudioThread', 'DedicatedWorker thread', 'GpuMemoryThread',
182  'JavaBridge', 'LevelDBEnv.IDB', 'MemoryInfra', 'NetworkService', 'VizWebView');
183
184DROP TABLE IF EXISTS webview_only_power_summary;
185
186-- Calculate the power usage of all WebView-specific host app threads
187-- (browser + in-process renderers) for each app in milliampere-seconds.
188CREATE TABLE webview_only_power_summary AS
189  SELECT
190    app_name,
191    SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
192  FROM power_per_thread
193  INNER JOIN webview_only_threads
194  ON power_per_thread.utid = webview_only_threads.utid
195  GROUP BY app_name;
196
197DROP TABLE IF EXISTS webview_only_power_per_core_type;
198
199-- Calculate the power usage of all WebView-specific host app threads
200-- for each app in milliampere-seconds grouped by core type.
201CREATE TABLE webview_only_power_per_core_type AS
202  SELECT app_name,
203  core_type_per_cpu.core_type AS core_type,
204  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
205FROM power_per_thread
206INNER JOIN webview_only_threads
207  ON power_per_thread.utid = webview_only_threads.utid
208INNER JOIN core_type_per_cpu
209  ON power_per_thread.cpu = core_type_per_cpu.cpu
210GROUP BY app_name, core_type_per_cpu.core_type;
211
212-- Create views for output.
213
214DROP TABLE IF EXISTS total_app_power_output;
215
216CREATE TABLE total_app_power_output AS
217  SELECT
218    host_app_power_summary.app_name as app_name,
219    host_app_power_summary.power_mas AS total_mas,
220    host_app_power_little_cores_mas.power_mas AS little_cores_mas,
221    host_app_power_big_cores_mas.power_mas AS big_cores_mas,
222    host_app_power_bigger_cores_mas.power_mas AS bigger_cores_mas
223  FROM host_app_power_summary LEFT JOIN host_app_power_per_core_type AS host_app_power_little_cores_mas
224  ON host_app_power_summary.app_name = host_app_power_little_cores_mas.app_name
225  AND host_app_power_little_cores_mas.core_type = 'little'
226  LEFT JOIN host_app_power_per_core_type AS host_app_power_big_cores_mas
227  ON host_app_power_summary.app_name = host_app_power_big_cores_mas.app_name
228  AND host_app_power_big_cores_mas.core_type = 'big'
229  LEFT JOIN host_app_power_per_core_type AS host_app_power_bigger_cores_mas
230  ON host_app_power_summary.app_name = host_app_power_bigger_cores_mas.app_name
231  AND host_app_power_bigger_cores_mas.core_type = 'bigger';
232
233DROP TABLE IF EXISTS webview_renderer_power_output;
234
235CREATE TABLE webview_renderer_power_output AS
236  SELECT
237    webview_renderer_power_summary.app_name AS app_name,
238    webview_renderer_power_summary.power_mas AS total_mas,
239    webview_renderer_little_power.power_mas AS little_cores_mas,
240    webview_renderer_big_power.power_mas AS big_cores_mas,
241    webview_renderer_bigger_power.power_mas AS bigger_cores_mas
242  FROM webview_renderer_power_summary LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_little_power
243  ON webview_renderer_power_summary.app_name = webview_renderer_little_power.app_name
244  AND webview_renderer_little_power.core_type = 'little'
245  LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_big_power
246  ON webview_renderer_power_summary.app_name = webview_renderer_big_power.app_name
247  AND webview_renderer_big_power.core_type = 'big'
248  LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_bigger_power
249  ON webview_renderer_power_summary.app_name = webview_renderer_bigger_power.app_name
250  AND webview_renderer_bigger_power.core_type = 'bigger';
251
252DROP TABLE IF EXISTS webview_only_power_output;
253
254CREATE TABLE webview_only_power_output AS
255  SELECT
256    webview_only_power_summary.app_name AS app_name,
257    webview_only_power_summary.power_mas AS total_mas,
258    webview_only_power_little_cores_mas.power_mas AS little_cores_mas,
259    webview_only_power_big_cores_mas.power_mas AS big_cores_mas,
260    webview_only_power_bigger_cores_mas.power_mas AS bigger_cores_mas
261  FROM webview_only_power_summary LEFT JOIN webview_only_power_per_core_type AS webview_only_power_little_cores_mas
262  ON webview_only_power_summary.app_name = webview_only_power_little_cores_mas.app_name
263  AND webview_only_power_little_cores_mas.core_type = 'little'
264  LEFT JOIN webview_only_power_per_core_type AS webview_only_power_big_cores_mas
265  ON webview_only_power_summary.app_name = webview_only_power_big_cores_mas.app_name
266  AND webview_only_power_big_cores_mas.core_type = 'big'
267  LEFT JOIN webview_only_power_per_core_type AS webview_only_power_bigger_cores_mas
268  ON webview_only_power_summary.app_name = webview_only_power_bigger_cores_mas.app_name
269  AND webview_only_power_bigger_cores_mas.core_type = 'bigger';
270
271DROP TABLE IF EXISTS total_device_power;
272
273-- Calculate the power usage of the device in milliampere-seconds.
274CREATE TABLE total_device_power AS
275  SELECT SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
276  FROM power_per_thread;
277