blob: 344c772554aef1f408abcaa311e366f968643eb8 [file] [log] [blame]
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001/*
2 * Copyright (C) 2009 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 * http://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
17package com.android.internal.os;
18
19
20import android.content.Context;
Adam Lesinskie08af192015-03-25 16:42:59 -070021import android.content.res.Resources;
Amith Yamasani244fa5c2009-05-22 14:36:07 -070022import android.content.res.XmlResourceParser;
23
Mike Ma3d422c32017-10-25 11:08:57 -070024import com.android.internal.annotations.VisibleForTesting;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080025import com.android.internal.util.XmlUtils;
Amith Yamasani244fa5c2009-05-22 14:36:07 -070026
27import org.xmlpull.v1.XmlPullParser;
28import org.xmlpull.v1.XmlPullParserException;
29
30import java.io.IOException;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070031import java.util.ArrayList;
Amith Yamasani244fa5c2009-05-22 14:36:07 -070032import java.util.HashMap;
33
34/**
35 * Reports power consumption values for various device activities. Reads values from an XML file.
36 * Customize the XML file for different devices.
37 * [hidden]
38 */
39public class PowerProfile {
40
41 /**
42 * No power consumption, or accounted for elsewhere.
43 */
44 public static final String POWER_NONE = "none";
45
Mike Ma07305c02018-03-02 16:57:31 -080046 /*
Mike Ma3d422c32017-10-25 11:08:57 -070047 * POWER_CPU_SUSPEND: Power consumption when CPU is in power collapse mode.
48 * POWER_CPU_IDLE: Power consumption when CPU is awake (when a wake lock is held). This should
49 * be zero on devices that can go into full CPU power collapse even when a wake
50 * lock is held. Otherwise, this is the power consumption in addition to
Mike Ma07305c02018-03-02 16:57:31 -080051 * POWER_CPU_SUSPEND due to a wake lock being held but with no CPU activity.
Mike Ma3d422c32017-10-25 11:08:57 -070052 * POWER_CPU_ACTIVE: Power consumption when CPU is running, excluding power consumed by clusters
53 * and cores.
54 *
55 * CPU Power Equation (assume two clusters):
56 * Total power = POWER_CPU_SUSPEND (always added)
57 * + POWER_CPU_IDLE (skip this and below if in power collapse mode)
58 * + POWER_CPU_ACTIVE (skip this and below if CPU is not running, but a wakelock
59 * is held)
60 * + cluster_power.cluster0 + cluster_power.cluster1 (skip cluster not running)
61 * + core_power.cluster0 * num running cores in cluster 0
62 * + core_power.cluster1 * num running cores in cluster 1
Amith Yamasani244fa5c2009-05-22 14:36:07 -070063 */
Mike Ma3d422c32017-10-25 11:08:57 -070064 public static final String POWER_CPU_SUSPEND = "cpu.suspend";
Amith Yamasani244fa5c2009-05-22 14:36:07 -070065 public static final String POWER_CPU_IDLE = "cpu.idle";
Amith Yamasanie43530a2009-08-21 13:11:37 -070066 public static final String POWER_CPU_ACTIVE = "cpu.active";
Amith Yamasani244fa5c2009-05-22 14:36:07 -070067
68 /**
69 * Power consumption when WiFi driver is scanning for networks.
70 */
71 public static final String POWER_WIFI_SCAN = "wifi.scan";
72
73 /**
74 * Power consumption when WiFi driver is on.
75 */
76 public static final String POWER_WIFI_ON = "wifi.on";
77
78 /**
79 * Power consumption when WiFi driver is transmitting/receiving.
80 */
81 public static final String POWER_WIFI_ACTIVE = "wifi.active";
82
Adam Lesinskie08af192015-03-25 16:42:59 -070083 //
84 // Updated power constants. These are not estimated, they are real world
85 // currents and voltages for the underlying bluetooth and wifi controllers.
86 //
Adam Lesinskie08af192015-03-25 16:42:59 -070087 public static final String POWER_WIFI_CONTROLLER_IDLE = "wifi.controller.idle";
88 public static final String POWER_WIFI_CONTROLLER_RX = "wifi.controller.rx";
89 public static final String POWER_WIFI_CONTROLLER_TX = "wifi.controller.tx";
Roshan Pius2a91e4a2016-03-31 16:33:54 -070090 public static final String POWER_WIFI_CONTROLLER_TX_LEVELS = "wifi.controller.tx_levels";
Adam Lesinskie08af192015-03-25 16:42:59 -070091 public static final String POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE = "wifi.controller.voltage";
92
93 public static final String POWER_BLUETOOTH_CONTROLLER_IDLE = "bluetooth.controller.idle";
94 public static final String POWER_BLUETOOTH_CONTROLLER_RX = "bluetooth.controller.rx";
95 public static final String POWER_BLUETOOTH_CONTROLLER_TX = "bluetooth.controller.tx";
96 public static final String POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE =
97 "bluetooth.controller.voltage";
Adam Lesinski33dac552015-03-09 15:24:48 -070098
Siddharth Ray2038af82018-01-17 17:40:26 -080099 public static final String POWER_MODEM_CONTROLLER_SLEEP = "modem.controller.sleep";
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800100 public static final String POWER_MODEM_CONTROLLER_IDLE = "modem.controller.idle";
101 public static final String POWER_MODEM_CONTROLLER_RX = "modem.controller.rx";
102 public static final String POWER_MODEM_CONTROLLER_TX = "modem.controller.tx";
103 public static final String POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE =
104 "modem.controller.voltage";
105
Mike Maeb0d8a72018-02-27 16:41:54 -0800106 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700107 * Power consumption when GPS is on.
108 */
109 public static final String POWER_GPS_ON = "gps.on";
110
111 /**
Siddharth Ray0ed2e952018-01-22 11:32:14 -0800112 * GPS power parameters based on signal quality
113 */
114 public static final String POWER_GPS_SIGNAL_QUALITY_BASED = "gps.signalqualitybased";
115 public static final String POWER_GPS_OPERATING_VOLTAGE = "gps.voltage";
116
117 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700118 * Power consumption when Bluetooth driver is on.
Mike Ma07305c02018-03-02 16:57:31 -0800119 *
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800120 * @deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700121 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800122 @Deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700123 public static final String POWER_BLUETOOTH_ON = "bluetooth.on";
124
125 /**
126 * Power consumption when Bluetooth driver is transmitting/receiving.
Mike Ma07305c02018-03-02 16:57:31 -0800127 *
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800128 * @deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700129 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800130 @Deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700131 public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";
132
133 /**
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700134 * Power consumption when Bluetooth driver gets an AT command.
Mike Ma07305c02018-03-02 16:57:31 -0800135 *
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800136 * @deprecated
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700137 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800138 @Deprecated
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700139 public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at";
140
Mike Maeb0d8a72018-02-27 16:41:54 -0800141 /**
142 * Power consumption when screen is in doze/ambient/always-on mode, including backlight power.
143 */
144 public static final String POWER_AMBIENT_DISPLAY = "ambient.on";
Adam Lesinski33dac552015-03-09 15:24:48 -0700145
146 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700147 * Power consumption when screen is on, not including the backlight power.
148 */
149 public static final String POWER_SCREEN_ON = "screen.on";
150
151 /**
152 * Power consumption when cell radio is on but not on a call.
153 */
154 public static final String POWER_RADIO_ON = "radio.on";
155
156 /**
Amith Yamasanif37447b2009-10-08 18:28:01 -0700157 * Power consumption when cell radio is hunting for a signal.
158 */
159 public static final String POWER_RADIO_SCANNING = "radio.scanning";
160
161 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700162 * Power consumption when talking on the phone.
163 */
164 public static final String POWER_RADIO_ACTIVE = "radio.active";
165
166 /**
167 * Power consumption at full backlight brightness. If the backlight is at
168 * 50% brightness, then this should be multiplied by 0.5
169 */
170 public static final String POWER_SCREEN_FULL = "screen.full";
171
172 /**
173 * Power consumed by the audio hardware when playing back audio content. This is in addition
174 * to the CPU power, probably due to a DSP and / or amplifier.
175 */
Mike Ma07305c02018-03-02 16:57:31 -0800176 public static final String POWER_AUDIO = "audio";
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700177
178 /**
179 * Power consumed by any media hardware when playing back video content. This is in addition
180 * to the CPU power, probably due to a DSP.
181 */
Mike Ma07305c02018-03-02 16:57:31 -0800182 public static final String POWER_VIDEO = "video";
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700183
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700184 /**
Ruben Brunk5b1308f2015-06-03 18:49:27 -0700185 * Average power consumption when camera flashlight is on.
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700186 */
187 public static final String POWER_FLASHLIGHT = "camera.flashlight";
188
Ruben Brunk5b1308f2015-06-03 18:49:27 -0700189 /**
James Carr2dd7e5e2016-07-20 18:48:39 -0700190 * Power consumption when DDR is being used.
191 */
192 public static final String POWER_MEMORY = "memory.bandwidths";
193
194 /**
Ruben Brunk5b1308f2015-06-03 18:49:27 -0700195 * Average power consumption when the camera is on over all standard use cases.
196 *
197 * TODO: Add more fine-grained camera power metrics.
198 */
199 public static final String POWER_CAMERA = "camera.avg";
200
Amith Yamasani169741b2010-05-27 10:37:54 -0700201 /**
Robert Greenwalta029ea12013-09-25 16:38:12 -0700202 * Power consumed by wif batched scaning. Broken down into bins by
203 * Channels Scanned per Hour. May do 1-720 scans per hour of 1-100 channels
204 * for a range of 1-72,000. Going logrithmic (1-8, 9-64, 65-512, 513-4096, 4097-)!
205 */
206 public static final String POWER_WIFI_BATCHED_SCAN = "wifi.batchedscan";
207
208 /**
Amith Yamasani169741b2010-05-27 10:37:54 -0700209 * Battery capacity in milliAmpHour (mAh).
210 */
211 public static final String POWER_BATTERY_CAPACITY = "battery.capacity";
212
Mike Ma3d422c32017-10-25 11:08:57 -0700213 /**
214 * A map from Power Use Item to its power consumption.
215 */
216 static final HashMap<String, Double> sPowerItemMap = new HashMap<>();
217 /**
218 * A map from Power Use Item to an array of its power consumption
219 * (for items with variable power e.g. CPU).
220 */
221 static final HashMap<String, Double[]> sPowerArrayMap = new HashMap<>();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700222
223 private static final String TAG_DEVICE = "device";
224 private static final String TAG_ITEM = "item";
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700225 private static final String TAG_ARRAY = "array";
226 private static final String TAG_ARRAYITEM = "value";
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700227 private static final String ATTR_NAME = "name";
228
jackqdyulei0e3504c2017-08-03 15:46:52 -0700229 private static final Object sLock = new Object();
230
Mike Ma3d422c32017-10-25 11:08:57 -0700231 @VisibleForTesting
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700232 public PowerProfile(Context context) {
Mike Ma3d422c32017-10-25 11:08:57 -0700233 this(context, false);
234 }
235
236 /**
237 * For PowerProfileTest
238 */
239 @VisibleForTesting
240 public PowerProfile(Context context, boolean forTest) {
241 // Read the XML file for the given profile (normally only one per device)
jackqdyulei0e3504c2017-08-03 15:46:52 -0700242 synchronized (sLock) {
Mike Ma3d422c32017-10-25 11:08:57 -0700243 if (sPowerItemMap.size() == 0 && sPowerArrayMap.size() == 0) {
244 readPowerValuesFromXml(context, forTest);
jackqdyulei0e3504c2017-08-03 15:46:52 -0700245 }
246 initCpuClusters();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700247 }
248 }
249
Mike Ma3d422c32017-10-25 11:08:57 -0700250 private void readPowerValuesFromXml(Context context, boolean forTest) {
251 final int id = forTest ? com.android.internal.R.xml.power_profile_test :
252 com.android.internal.R.xml.power_profile;
Adam Lesinskie08af192015-03-25 16:42:59 -0700253 final Resources resources = context.getResources();
254 XmlResourceParser parser = resources.getXml(id);
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700255 boolean parsingArray = false;
Mike Ma3d422c32017-10-25 11:08:57 -0700256 ArrayList<Double> array = new ArrayList<>();
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700257 String arrayName = null;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700258
259 try {
260 XmlUtils.beginDocument(parser, TAG_DEVICE);
261
262 while (true) {
263 XmlUtils.nextElement(parser);
264
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700265 String element = parser.getName();
266 if (element == null) break;
Robert Greenwalta029ea12013-09-25 16:38:12 -0700267
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700268 if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
269 // Finish array
Mike Ma3d422c32017-10-25 11:08:57 -0700270 sPowerArrayMap.put(arrayName, array.toArray(new Double[array.size()]));
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700271 parsingArray = false;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700272 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700273 if (element.equals(TAG_ARRAY)) {
274 parsingArray = true;
275 array.clear();
276 arrayName = parser.getAttributeValue(null, ATTR_NAME);
277 } else if (element.equals(TAG_ITEM) || element.equals(TAG_ARRAYITEM)) {
278 String name = null;
279 if (!parsingArray) name = parser.getAttributeValue(null, ATTR_NAME);
280 if (parser.next() == XmlPullParser.TEXT) {
281 String power = parser.getText();
282 double value = 0;
283 try {
284 value = Double.valueOf(power);
285 } catch (NumberFormatException nfe) {
286 }
287 if (element.equals(TAG_ITEM)) {
Mike Ma3d422c32017-10-25 11:08:57 -0700288 sPowerItemMap.put(name, value);
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700289 } else if (parsingArray) {
290 array.add(value);
291 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700292 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700293 }
294 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700295 if (parsingArray) {
Mike Ma3d422c32017-10-25 11:08:57 -0700296 sPowerArrayMap.put(arrayName, array.toArray(new Double[array.size()]));
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700297 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700298 } catch (XmlPullParserException e) {
299 throw new RuntimeException(e);
300 } catch (IOException e) {
301 throw new RuntimeException(e);
302 } finally {
303 parser.close();
304 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700305
306 // Now collect other config variables.
Adam Lesinski6832f392015-09-05 18:05:40 -0700307 int[] configResIds = new int[]{
Adam Lesinskie08af192015-03-25 16:42:59 -0700308 com.android.internal.R.integer.config_bluetooth_idle_cur_ma,
309 com.android.internal.R.integer.config_bluetooth_rx_cur_ma,
310 com.android.internal.R.integer.config_bluetooth_tx_cur_ma,
311 com.android.internal.R.integer.config_bluetooth_operating_voltage_mv,
Adam Lesinskie08af192015-03-25 16:42:59 -0700312 };
313
Adam Lesinski6832f392015-09-05 18:05:40 -0700314 String[] configResIdKeys = new String[]{
Adam Lesinskie08af192015-03-25 16:42:59 -0700315 POWER_BLUETOOTH_CONTROLLER_IDLE,
316 POWER_BLUETOOTH_CONTROLLER_RX,
317 POWER_BLUETOOTH_CONTROLLER_TX,
318 POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE,
Adam Lesinskie08af192015-03-25 16:42:59 -0700319 };
320
321 for (int i = 0; i < configResIds.length; i++) {
Roshan Pius2a91e4a2016-03-31 16:33:54 -0700322 String key = configResIdKeys[i];
323 // if we already have some of these parameters in power_profile.xml, ignore the
324 // value in config.xml
Mike Ma3d422c32017-10-25 11:08:57 -0700325 if ((sPowerItemMap.containsKey(key) && sPowerItemMap.get(key) > 0)) {
Roshan Pius2a91e4a2016-03-31 16:33:54 -0700326 continue;
327 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700328 int value = resources.getInteger(configResIds[i]);
329 if (value > 0) {
Mike Ma3d422c32017-10-25 11:08:57 -0700330 sPowerItemMap.put(key, (double) value);
Adam Lesinskie08af192015-03-25 16:42:59 -0700331 }
332 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700333 }
334
Adam Lesinski6832f392015-09-05 18:05:40 -0700335 private CpuClusterKey[] mCpuClusters;
336
Mike Ma3d422c32017-10-25 11:08:57 -0700337 private static final String CPU_PER_CLUSTER_CORE_COUNT = "cpu.clusters.cores";
338 private static final String CPU_CLUSTER_POWER_COUNT = "cpu.cluster_power.cluster";
339 private static final String CPU_CORE_SPEED_PREFIX = "cpu.core_speeds.cluster";
340 private static final String CPU_CORE_POWER_PREFIX = "cpu.core_power.cluster";
Adam Lesinski6832f392015-09-05 18:05:40 -0700341
Adam Lesinski6832f392015-09-05 18:05:40 -0700342 private void initCpuClusters() {
Mike Ma3d422c32017-10-25 11:08:57 -0700343 if (sPowerArrayMap.containsKey(CPU_PER_CLUSTER_CORE_COUNT)) {
344 final Double[] data = sPowerArrayMap.get(CPU_PER_CLUSTER_CORE_COUNT);
345 mCpuClusters = new CpuClusterKey[data.length];
346 for (int cluster = 0; cluster < data.length; cluster++) {
347 int numCpusInCluster = (int) Math.round(data[cluster]);
348 mCpuClusters[cluster] = new CpuClusterKey(
349 CPU_CORE_SPEED_PREFIX + cluster, CPU_CLUSTER_POWER_COUNT + cluster,
350 CPU_CORE_POWER_PREFIX + cluster, numCpusInCluster);
351 }
352 } else {
Adam Lesinski6832f392015-09-05 18:05:40 -0700353 // Default to single.
354 mCpuClusters = new CpuClusterKey[1];
Mike Ma3d422c32017-10-25 11:08:57 -0700355 int numCpus = 1;
356 if (sPowerItemMap.containsKey(CPU_PER_CLUSTER_CORE_COUNT)) {
357 numCpus = (int) Math.round(sPowerItemMap.get(CPU_PER_CLUSTER_CORE_COUNT));
Adam Lesinski6832f392015-09-05 18:05:40 -0700358 }
Mike Ma3d422c32017-10-25 11:08:57 -0700359 mCpuClusters[0] = new CpuClusterKey(CPU_CORE_SPEED_PREFIX + 0,
360 CPU_CLUSTER_POWER_COUNT + 0, CPU_CORE_POWER_PREFIX + 0, numCpus);
Adam Lesinski6832f392015-09-05 18:05:40 -0700361 }
362 }
363
364 public static class CpuClusterKey {
Mike Ma3d422c32017-10-25 11:08:57 -0700365 private final String freqKey;
366 private final String clusterPowerKey;
367 private final String corePowerKey;
Adam Lesinski6832f392015-09-05 18:05:40 -0700368 private final int numCpus;
369
Mike Ma3d422c32017-10-25 11:08:57 -0700370 private CpuClusterKey(String freqKey, String clusterPowerKey,
371 String corePowerKey, int numCpus) {
372 this.freqKey = freqKey;
373 this.clusterPowerKey = clusterPowerKey;
374 this.corePowerKey = corePowerKey;
Adam Lesinski6832f392015-09-05 18:05:40 -0700375 this.numCpus = numCpus;
376 }
377 }
378
379 public int getNumCpuClusters() {
380 return mCpuClusters.length;
381 }
382
Mike Ma3d422c32017-10-25 11:08:57 -0700383 public int getNumCoresInCpuCluster(int cluster) {
384 return mCpuClusters[cluster].numCpus;
Adam Lesinski6832f392015-09-05 18:05:40 -0700385 }
386
Mike Ma3d422c32017-10-25 11:08:57 -0700387 public int getNumSpeedStepsInCpuCluster(int cluster) {
388 if (cluster < 0 || cluster >= mCpuClusters.length) {
389 return 0; // index out of bound
390 }
391 if (sPowerArrayMap.containsKey(mCpuClusters[cluster].freqKey)) {
392 return sPowerArrayMap.get(mCpuClusters[cluster].freqKey).length;
Adam Lesinski6832f392015-09-05 18:05:40 -0700393 }
394 return 1; // Only one speed
395 }
396
Mike Ma3d422c32017-10-25 11:08:57 -0700397 public double getAveragePowerForCpuCluster(int cluster) {
Adam Lesinski6832f392015-09-05 18:05:40 -0700398 if (cluster >= 0 && cluster < mCpuClusters.length) {
Mike Ma3d422c32017-10-25 11:08:57 -0700399 return getAveragePower(mCpuClusters[cluster].clusterPowerKey);
400 }
401 return 0;
402 }
403
404 public double getAveragePowerForCpuCore(int cluster, int step) {
405 if (cluster >= 0 && cluster < mCpuClusters.length) {
406 return getAveragePower(mCpuClusters[cluster].corePowerKey, step);
Adam Lesinski6832f392015-09-05 18:05:40 -0700407 }
408 return 0;
409 }
410
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700411 /**
James Carr2dd7e5e2016-07-20 18:48:39 -0700412 * Returns the number of memory bandwidth buckets defined in power_profile.xml, or a
413 * default value if the subsystem has no recorded value.
Mike Ma07305c02018-03-02 16:57:31 -0800414 *
James Carr2dd7e5e2016-07-20 18:48:39 -0700415 * @return the number of memory bandwidth buckets.
416 */
417 public int getNumElements(String key) {
Mike Ma3d422c32017-10-25 11:08:57 -0700418 if (sPowerItemMap.containsKey(key)) {
419 return 1;
420 } else if (sPowerArrayMap.containsKey(key)) {
421 return sPowerArrayMap.get(key).length;
James Carr2dd7e5e2016-07-20 18:48:39 -0700422 }
423 return 0;
424 }
425
426 /**
Adam Lesinski33dac552015-03-09 15:24:48 -0700427 * Returns the average current in mA consumed by the subsystem, or the given
428 * default value if the subsystem has no recorded value.
Mike Ma07305c02018-03-02 16:57:31 -0800429 *
430 * @param type the subsystem type
Adam Lesinski33dac552015-03-09 15:24:48 -0700431 * @param defaultValue the value to return if the subsystem has no recorded value.
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700432 * @return the average current in milliAmps.
433 */
Adam Lesinski33dac552015-03-09 15:24:48 -0700434 public double getAveragePowerOrDefault(String type, double defaultValue) {
Mike Ma3d422c32017-10-25 11:08:57 -0700435 if (sPowerItemMap.containsKey(type)) {
436 return sPowerItemMap.get(type);
437 } else if (sPowerArrayMap.containsKey(type)) {
438 return sPowerArrayMap.get(type)[0];
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700439 } else {
Adam Lesinski33dac552015-03-09 15:24:48 -0700440 return defaultValue;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700441 }
442 }
Adam Lesinski33dac552015-03-09 15:24:48 -0700443
444 /**
445 * Returns the average current in mA consumed by the subsystem
Mike Ma07305c02018-03-02 16:57:31 -0800446 *
Adam Lesinski33dac552015-03-09 15:24:48 -0700447 * @param type the subsystem type
448 * @return the average current in milliAmps.
449 */
450 public double getAveragePower(String type) {
451 return getAveragePowerOrDefault(type, 0);
452 }
Mike Ma07305c02018-03-02 16:57:31 -0800453
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700454 /**
Amith Yamasanie43530a2009-08-21 13:11:37 -0700455 * Returns the average current in mA consumed by the subsystem for the given level.
Mike Ma07305c02018-03-02 16:57:31 -0800456 *
457 * @param type the subsystem type
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700458 * @param level the level of power at which the subsystem is running. For instance, the
Mike Ma07305c02018-03-02 16:57:31 -0800459 * signal strength of the cell network between 0 and 4 (if there are 4 bars max.)
460 * If there is no data for multiple levels, the level is ignored.
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700461 * @return the average current in milliAmps.
462 */
463 public double getAveragePower(String type, int level) {
Mike Ma3d422c32017-10-25 11:08:57 -0700464 if (sPowerItemMap.containsKey(type)) {
465 return sPowerItemMap.get(type);
466 } else if (sPowerArrayMap.containsKey(type)) {
467 final Double[] values = sPowerArrayMap.get(type);
468 if (values.length > level && level >= 0) {
469 return values[level];
470 } else if (level < 0 || values.length == 0) {
471 return 0;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700472 } else {
Mike Ma3d422c32017-10-25 11:08:57 -0700473 return values[values.length - 1];
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700474 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700475 } else {
476 return 0;
477 }
478 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700479
Amith Yamasani169741b2010-05-27 10:37:54 -0700480 /**
481 * Returns the battery capacity, if available, in milli Amp Hours. If not available,
482 * it returns zero.
Mike Ma07305c02018-03-02 16:57:31 -0800483 *
Amith Yamasani169741b2010-05-27 10:37:54 -0700484 * @return the battery capacity in mAh
485 */
486 public double getBatteryCapacity() {
487 return getAveragePower(POWER_BATTERY_CAPACITY);
488 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700489}