blob: 240fc513055cdd8661c232bf0562ee66490e1d72 [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
46 /**
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
51 * POWER_CPU_SUSPEND due to a wake lock being held but with no CPU activity.
52 * 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 //
87
88 public static final String POWER_WIFI_CONTROLLER_IDLE = "wifi.controller.idle";
89 public static final String POWER_WIFI_CONTROLLER_RX = "wifi.controller.rx";
90 public static final String POWER_WIFI_CONTROLLER_TX = "wifi.controller.tx";
Roshan Pius2a91e4a2016-03-31 16:33:54 -070091 public static final String POWER_WIFI_CONTROLLER_TX_LEVELS = "wifi.controller.tx_levels";
Adam Lesinskie08af192015-03-25 16:42:59 -070092 public static final String POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE = "wifi.controller.voltage";
93
94 public static final String POWER_BLUETOOTH_CONTROLLER_IDLE = "bluetooth.controller.idle";
95 public static final String POWER_BLUETOOTH_CONTROLLER_RX = "bluetooth.controller.rx";
96 public static final String POWER_BLUETOOTH_CONTROLLER_TX = "bluetooth.controller.tx";
97 public static final String POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE =
98 "bluetooth.controller.voltage";
Adam Lesinski33dac552015-03-09 15:24:48 -070099
Siddharth Ray2038af82018-01-17 17:40:26 -0800100 public static final String POWER_MODEM_CONTROLLER_SLEEP = "modem.controller.sleep";
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800101 public static final String POWER_MODEM_CONTROLLER_IDLE = "modem.controller.idle";
102 public static final String POWER_MODEM_CONTROLLER_RX = "modem.controller.rx";
103 public static final String POWER_MODEM_CONTROLLER_TX = "modem.controller.tx";
104 public static final String POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE =
105 "modem.controller.voltage";
106
Adam Lesinski33dac552015-03-09 15:24:48 -0700107 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700108 * Power consumption when GPS is on.
109 */
110 public static final String POWER_GPS_ON = "gps.on";
111
112 /**
113 * Power consumption when Bluetooth driver is on.
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800114 * @deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700115 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800116 @Deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700117 public static final String POWER_BLUETOOTH_ON = "bluetooth.on";
118
119 /**
120 * Power consumption when Bluetooth driver is transmitting/receiving.
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800121 * @deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700122 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800123 @Deprecated
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700124 public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";
125
126 /**
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700127 * Power consumption when Bluetooth driver gets an AT command.
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800128 * @deprecated
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700129 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800130 @Deprecated
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700131 public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at";
132
Adam Lesinski33dac552015-03-09 15:24:48 -0700133
134 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700135 * Power consumption when screen is on, not including the backlight power.
136 */
137 public static final String POWER_SCREEN_ON = "screen.on";
138
139 /**
140 * Power consumption when cell radio is on but not on a call.
141 */
142 public static final String POWER_RADIO_ON = "radio.on";
143
144 /**
Amith Yamasanif37447b2009-10-08 18:28:01 -0700145 * Power consumption when cell radio is hunting for a signal.
146 */
147 public static final String POWER_RADIO_SCANNING = "radio.scanning";
148
149 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700150 * Power consumption when talking on the phone.
151 */
152 public static final String POWER_RADIO_ACTIVE = "radio.active";
153
154 /**
155 * Power consumption at full backlight brightness. If the backlight is at
156 * 50% brightness, then this should be multiplied by 0.5
157 */
158 public static final String POWER_SCREEN_FULL = "screen.full";
159
160 /**
161 * Power consumed by the audio hardware when playing back audio content. This is in addition
162 * to the CPU power, probably due to a DSP and / or amplifier.
163 */
164 public static final String POWER_AUDIO = "dsp.audio";
165
166 /**
167 * Power consumed by any media hardware when playing back video content. This is in addition
168 * to the CPU power, probably due to a DSP.
169 */
170 public static final String POWER_VIDEO = "dsp.video";
171
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700172 /**
Ruben Brunk5b1308f2015-06-03 18:49:27 -0700173 * Average power consumption when camera flashlight is on.
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700174 */
175 public static final String POWER_FLASHLIGHT = "camera.flashlight";
176
Ruben Brunk5b1308f2015-06-03 18:49:27 -0700177 /**
James Carr2dd7e5e2016-07-20 18:48:39 -0700178 * Power consumption when DDR is being used.
179 */
180 public static final String POWER_MEMORY = "memory.bandwidths";
181
182 /**
Ruben Brunk5b1308f2015-06-03 18:49:27 -0700183 * Average power consumption when the camera is on over all standard use cases.
184 *
185 * TODO: Add more fine-grained camera power metrics.
186 */
187 public static final String POWER_CAMERA = "camera.avg";
188
Amith Yamasani169741b2010-05-27 10:37:54 -0700189 /**
Robert Greenwalta029ea12013-09-25 16:38:12 -0700190 * Power consumed by wif batched scaning. Broken down into bins by
191 * Channels Scanned per Hour. May do 1-720 scans per hour of 1-100 channels
192 * for a range of 1-72,000. Going logrithmic (1-8, 9-64, 65-512, 513-4096, 4097-)!
193 */
194 public static final String POWER_WIFI_BATCHED_SCAN = "wifi.batchedscan";
195
196 /**
Amith Yamasani169741b2010-05-27 10:37:54 -0700197 * Battery capacity in milliAmpHour (mAh).
198 */
199 public static final String POWER_BATTERY_CAPACITY = "battery.capacity";
200
Mike Ma3d422c32017-10-25 11:08:57 -0700201 /**
202 * A map from Power Use Item to its power consumption.
203 */
204 static final HashMap<String, Double> sPowerItemMap = new HashMap<>();
205 /**
206 * A map from Power Use Item to an array of its power consumption
207 * (for items with variable power e.g. CPU).
208 */
209 static final HashMap<String, Double[]> sPowerArrayMap = new HashMap<>();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700210
211 private static final String TAG_DEVICE = "device";
212 private static final String TAG_ITEM = "item";
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700213 private static final String TAG_ARRAY = "array";
214 private static final String TAG_ARRAYITEM = "value";
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700215 private static final String ATTR_NAME = "name";
216
jackqdyulei0e3504c2017-08-03 15:46:52 -0700217 private static final Object sLock = new Object();
218
Mike Ma3d422c32017-10-25 11:08:57 -0700219 @VisibleForTesting
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700220 public PowerProfile(Context context) {
Mike Ma3d422c32017-10-25 11:08:57 -0700221 this(context, false);
222 }
223
224 /**
225 * For PowerProfileTest
226 */
227 @VisibleForTesting
228 public PowerProfile(Context context, boolean forTest) {
229 // Read the XML file for the given profile (normally only one per device)
jackqdyulei0e3504c2017-08-03 15:46:52 -0700230 synchronized (sLock) {
Mike Ma3d422c32017-10-25 11:08:57 -0700231 if (sPowerItemMap.size() == 0 && sPowerArrayMap.size() == 0) {
232 readPowerValuesFromXml(context, forTest);
jackqdyulei0e3504c2017-08-03 15:46:52 -0700233 }
234 initCpuClusters();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700235 }
236 }
237
Mike Ma3d422c32017-10-25 11:08:57 -0700238 private void readPowerValuesFromXml(Context context, boolean forTest) {
239 final int id = forTest ? com.android.internal.R.xml.power_profile_test :
240 com.android.internal.R.xml.power_profile;
Adam Lesinskie08af192015-03-25 16:42:59 -0700241 final Resources resources = context.getResources();
242 XmlResourceParser parser = resources.getXml(id);
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700243 boolean parsingArray = false;
Mike Ma3d422c32017-10-25 11:08:57 -0700244 ArrayList<Double> array = new ArrayList<>();
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700245 String arrayName = null;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700246
247 try {
248 XmlUtils.beginDocument(parser, TAG_DEVICE);
249
250 while (true) {
251 XmlUtils.nextElement(parser);
252
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700253 String element = parser.getName();
254 if (element == null) break;
Robert Greenwalta029ea12013-09-25 16:38:12 -0700255
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700256 if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
257 // Finish array
Mike Ma3d422c32017-10-25 11:08:57 -0700258 sPowerArrayMap.put(arrayName, array.toArray(new Double[array.size()]));
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700259 parsingArray = false;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700260 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700261 if (element.equals(TAG_ARRAY)) {
262 parsingArray = true;
263 array.clear();
264 arrayName = parser.getAttributeValue(null, ATTR_NAME);
265 } else if (element.equals(TAG_ITEM) || element.equals(TAG_ARRAYITEM)) {
266 String name = null;
267 if (!parsingArray) name = parser.getAttributeValue(null, ATTR_NAME);
268 if (parser.next() == XmlPullParser.TEXT) {
269 String power = parser.getText();
270 double value = 0;
271 try {
272 value = Double.valueOf(power);
273 } catch (NumberFormatException nfe) {
274 }
275 if (element.equals(TAG_ITEM)) {
Mike Ma3d422c32017-10-25 11:08:57 -0700276 sPowerItemMap.put(name, value);
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700277 } else if (parsingArray) {
278 array.add(value);
279 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700280 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700281 }
282 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700283 if (parsingArray) {
Mike Ma3d422c32017-10-25 11:08:57 -0700284 sPowerArrayMap.put(arrayName, array.toArray(new Double[array.size()]));
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700285 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700286 } catch (XmlPullParserException e) {
287 throw new RuntimeException(e);
288 } catch (IOException e) {
289 throw new RuntimeException(e);
290 } finally {
291 parser.close();
292 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700293
294 // Now collect other config variables.
Adam Lesinski6832f392015-09-05 18:05:40 -0700295 int[] configResIds = new int[]{
Adam Lesinskie08af192015-03-25 16:42:59 -0700296 com.android.internal.R.integer.config_bluetooth_idle_cur_ma,
297 com.android.internal.R.integer.config_bluetooth_rx_cur_ma,
298 com.android.internal.R.integer.config_bluetooth_tx_cur_ma,
299 com.android.internal.R.integer.config_bluetooth_operating_voltage_mv,
Adam Lesinskie08af192015-03-25 16:42:59 -0700300 };
301
Adam Lesinski6832f392015-09-05 18:05:40 -0700302 String[] configResIdKeys = new String[]{
Adam Lesinskie08af192015-03-25 16:42:59 -0700303 POWER_BLUETOOTH_CONTROLLER_IDLE,
304 POWER_BLUETOOTH_CONTROLLER_RX,
305 POWER_BLUETOOTH_CONTROLLER_TX,
306 POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE,
Adam Lesinskie08af192015-03-25 16:42:59 -0700307 };
308
309 for (int i = 0; i < configResIds.length; i++) {
Roshan Pius2a91e4a2016-03-31 16:33:54 -0700310 String key = configResIdKeys[i];
311 // if we already have some of these parameters in power_profile.xml, ignore the
312 // value in config.xml
Mike Ma3d422c32017-10-25 11:08:57 -0700313 if ((sPowerItemMap.containsKey(key) && sPowerItemMap.get(key) > 0)) {
Roshan Pius2a91e4a2016-03-31 16:33:54 -0700314 continue;
315 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700316 int value = resources.getInteger(configResIds[i]);
317 if (value > 0) {
Mike Ma3d422c32017-10-25 11:08:57 -0700318 sPowerItemMap.put(key, (double) value);
Adam Lesinskie08af192015-03-25 16:42:59 -0700319 }
320 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700321 }
322
Adam Lesinski6832f392015-09-05 18:05:40 -0700323 private CpuClusterKey[] mCpuClusters;
324
Mike Ma3d422c32017-10-25 11:08:57 -0700325 private static final String CPU_PER_CLUSTER_CORE_COUNT = "cpu.clusters.cores";
326 private static final String CPU_CLUSTER_POWER_COUNT = "cpu.cluster_power.cluster";
327 private static final String CPU_CORE_SPEED_PREFIX = "cpu.core_speeds.cluster";
328 private static final String CPU_CORE_POWER_PREFIX = "cpu.core_power.cluster";
Adam Lesinski6832f392015-09-05 18:05:40 -0700329
Adam Lesinski6832f392015-09-05 18:05:40 -0700330 private void initCpuClusters() {
Mike Ma3d422c32017-10-25 11:08:57 -0700331 if (sPowerArrayMap.containsKey(CPU_PER_CLUSTER_CORE_COUNT)) {
332 final Double[] data = sPowerArrayMap.get(CPU_PER_CLUSTER_CORE_COUNT);
333 mCpuClusters = new CpuClusterKey[data.length];
334 for (int cluster = 0; cluster < data.length; cluster++) {
335 int numCpusInCluster = (int) Math.round(data[cluster]);
336 mCpuClusters[cluster] = new CpuClusterKey(
337 CPU_CORE_SPEED_PREFIX + cluster, CPU_CLUSTER_POWER_COUNT + cluster,
338 CPU_CORE_POWER_PREFIX + cluster, numCpusInCluster);
339 }
340 } else {
Adam Lesinski6832f392015-09-05 18:05:40 -0700341 // Default to single.
342 mCpuClusters = new CpuClusterKey[1];
Mike Ma3d422c32017-10-25 11:08:57 -0700343 int numCpus = 1;
344 if (sPowerItemMap.containsKey(CPU_PER_CLUSTER_CORE_COUNT)) {
345 numCpus = (int) Math.round(sPowerItemMap.get(CPU_PER_CLUSTER_CORE_COUNT));
Adam Lesinski6832f392015-09-05 18:05:40 -0700346 }
Mike Ma3d422c32017-10-25 11:08:57 -0700347 mCpuClusters[0] = new CpuClusterKey(CPU_CORE_SPEED_PREFIX + 0,
348 CPU_CLUSTER_POWER_COUNT + 0, CPU_CORE_POWER_PREFIX + 0, numCpus);
Adam Lesinski6832f392015-09-05 18:05:40 -0700349 }
350 }
351
352 public static class CpuClusterKey {
Mike Ma3d422c32017-10-25 11:08:57 -0700353 private final String freqKey;
354 private final String clusterPowerKey;
355 private final String corePowerKey;
Adam Lesinski6832f392015-09-05 18:05:40 -0700356 private final int numCpus;
357
Mike Ma3d422c32017-10-25 11:08:57 -0700358 private CpuClusterKey(String freqKey, String clusterPowerKey,
359 String corePowerKey, int numCpus) {
360 this.freqKey = freqKey;
361 this.clusterPowerKey = clusterPowerKey;
362 this.corePowerKey = corePowerKey;
Adam Lesinski6832f392015-09-05 18:05:40 -0700363 this.numCpus = numCpus;
364 }
365 }
366
367 public int getNumCpuClusters() {
368 return mCpuClusters.length;
369 }
370
Mike Ma3d422c32017-10-25 11:08:57 -0700371 public int getNumCoresInCpuCluster(int cluster) {
372 return mCpuClusters[cluster].numCpus;
Adam Lesinski6832f392015-09-05 18:05:40 -0700373 }
374
Mike Ma3d422c32017-10-25 11:08:57 -0700375 public int getNumSpeedStepsInCpuCluster(int cluster) {
376 if (cluster < 0 || cluster >= mCpuClusters.length) {
377 return 0; // index out of bound
378 }
379 if (sPowerArrayMap.containsKey(mCpuClusters[cluster].freqKey)) {
380 return sPowerArrayMap.get(mCpuClusters[cluster].freqKey).length;
Adam Lesinski6832f392015-09-05 18:05:40 -0700381 }
382 return 1; // Only one speed
383 }
384
Mike Ma3d422c32017-10-25 11:08:57 -0700385 public double getAveragePowerForCpuCluster(int cluster) {
Adam Lesinski6832f392015-09-05 18:05:40 -0700386 if (cluster >= 0 && cluster < mCpuClusters.length) {
Mike Ma3d422c32017-10-25 11:08:57 -0700387 return getAveragePower(mCpuClusters[cluster].clusterPowerKey);
388 }
389 return 0;
390 }
391
392 public double getAveragePowerForCpuCore(int cluster, int step) {
393 if (cluster >= 0 && cluster < mCpuClusters.length) {
394 return getAveragePower(mCpuClusters[cluster].corePowerKey, step);
Adam Lesinski6832f392015-09-05 18:05:40 -0700395 }
396 return 0;
397 }
398
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700399 /**
James Carr2dd7e5e2016-07-20 18:48:39 -0700400 * Returns the number of memory bandwidth buckets defined in power_profile.xml, or a
401 * default value if the subsystem has no recorded value.
402 * @return the number of memory bandwidth buckets.
403 */
404 public int getNumElements(String key) {
Mike Ma3d422c32017-10-25 11:08:57 -0700405 if (sPowerItemMap.containsKey(key)) {
406 return 1;
407 } else if (sPowerArrayMap.containsKey(key)) {
408 return sPowerArrayMap.get(key).length;
James Carr2dd7e5e2016-07-20 18:48:39 -0700409 }
410 return 0;
411 }
412
413 /**
Adam Lesinski33dac552015-03-09 15:24:48 -0700414 * Returns the average current in mA consumed by the subsystem, or the given
415 * default value if the subsystem has no recorded value.
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700416 * @param type the subsystem type
Adam Lesinski33dac552015-03-09 15:24:48 -0700417 * @param defaultValue the value to return if the subsystem has no recorded value.
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700418 * @return the average current in milliAmps.
419 */
Adam Lesinski33dac552015-03-09 15:24:48 -0700420 public double getAveragePowerOrDefault(String type, double defaultValue) {
Mike Ma3d422c32017-10-25 11:08:57 -0700421 if (sPowerItemMap.containsKey(type)) {
422 return sPowerItemMap.get(type);
423 } else if (sPowerArrayMap.containsKey(type)) {
424 return sPowerArrayMap.get(type)[0];
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700425 } else {
Adam Lesinski33dac552015-03-09 15:24:48 -0700426 return defaultValue;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700427 }
428 }
Adam Lesinski33dac552015-03-09 15:24:48 -0700429
430 /**
431 * Returns the average current in mA consumed by the subsystem
432 * @param type the subsystem type
433 * @return the average current in milliAmps.
434 */
435 public double getAveragePower(String type) {
436 return getAveragePowerOrDefault(type, 0);
437 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700438
439 /**
Amith Yamasanie43530a2009-08-21 13:11:37 -0700440 * Returns the average current in mA consumed by the subsystem for the given level.
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700441 * @param type the subsystem type
442 * @param level the level of power at which the subsystem is running. For instance, the
Amith Yamasanie43530a2009-08-21 13:11:37 -0700443 * signal strength of the cell network between 0 and 4 (if there are 4 bars max.)
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700444 * If there is no data for multiple levels, the level is ignored.
445 * @return the average current in milliAmps.
446 */
447 public double getAveragePower(String type, int level) {
Mike Ma3d422c32017-10-25 11:08:57 -0700448 if (sPowerItemMap.containsKey(type)) {
449 return sPowerItemMap.get(type);
450 } else if (sPowerArrayMap.containsKey(type)) {
451 final Double[] values = sPowerArrayMap.get(type);
452 if (values.length > level && level >= 0) {
453 return values[level];
454 } else if (level < 0 || values.length == 0) {
455 return 0;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700456 } else {
Mike Ma3d422c32017-10-25 11:08:57 -0700457 return values[values.length - 1];
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700458 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700459 } else {
460 return 0;
461 }
462 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700463
Amith Yamasani169741b2010-05-27 10:37:54 -0700464 /**
465 * Returns the battery capacity, if available, in milli Amp Hours. If not available,
466 * it returns zero.
467 * @return the battery capacity in mAh
468 */
469 public double getBatteryCapacity() {
470 return getAveragePower(POWER_BATTERY_CAPACITY);
471 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700472}