• 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
32SELECT *
33FROM slice WHERE
34  depth = 0
35  AND ((category GLOB '*toplevel*' OR category = 'Java')
36    AND 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
45SELECT
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
51FROM top_level_slice
52JOIN thread_track
53  ON top_level_slice.track_id = thread_track.id
54JOIN process
55  ON thread.upid = process.upid
56JOIN thread
57  ON thread_track.utid = thread.utid
58WHERE 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
77FROM webview_browser_slices_power
78GROUP 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
87FROM process
88JOIN thread
89  ON thread.upid = process.upid
90WHERE 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
98SELECT
99  app_name,
100  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
101FROM power_per_thread
102JOIN webview_renderer_threads
103  ON power_per_thread.utid = webview_renderer_threads.utid
104GROUP 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
116JOIN webview_renderer_threads
117  ON power_per_thread.utid = webview_renderer_threads.utid
118JOIN 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
135FROM thread
136JOIN process ON thread.upid = process.upid
137WHERE 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
148SELECT
149  app_name,
150  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
151FROM power_per_thread
152JOIN host_app_threads
153  ON power_per_thread.utid = host_app_threads.utid
154GROUP 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
166JOIN host_app_threads
167  ON power_per_thread.utid = host_app_threads.utid
168JOIN 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
178WHERE 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
189SELECT
190  app_name,
191  SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
192FROM power_per_thread
193JOIN webview_only_threads
194  ON power_per_thread.utid = webview_only_threads.utid
195GROUP 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
202SELECT 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
206JOIN webview_only_threads
207  ON power_per_thread.utid = webview_only_threads.utid
208JOIN 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
217SELECT
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
223FROM 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'
226LEFT 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'
229LEFT 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
236SELECT
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
242FROM 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'
245LEFT 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'
248LEFT 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
255SELECT
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
261FROM 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'
264LEFT 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'
267LEFT 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
275SELECT SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
276FROM power_per_thread;
277