1244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani/*
2244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * Copyright (C) 2009 The Android Open Source Project
3244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani *
4244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
5244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * you may not use this file except in compliance with the License.
6244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * You may obtain a copy of the License at
7244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani *
8244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
9244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani *
10244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * Unless required by applicable law or agreed to in writing, software
11244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
12244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * See the License for the specific language governing permissions and
14244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * limitations under the License.
15244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani */
16244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
17244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasanipackage com.android.internal.os;
18244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
19244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
20244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasaniimport android.content.Context;
21244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasaniimport android.content.res.XmlResourceParser;
22244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
232269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.XmlUtils;
24244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
25244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasaniimport org.xmlpull.v1.XmlPullParser;
26244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasaniimport org.xmlpull.v1.XmlPullParserException;
27244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
28244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasaniimport java.io.IOException;
293718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasaniimport java.util.ArrayList;
30244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasaniimport java.util.HashMap;
31244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
32244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani/**
33244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * Reports power consumption values for various device activities. Reads values from an XML file.
34244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * Customize the XML file for different devices.
35244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani * [hidden]
36244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani */
37244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasanipublic class PowerProfile {
38244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
39244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
40244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * No power consumption, or accounted for elsewhere.
41244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
42244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_NONE = "none";
43244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
44244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
45244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when CPU is in power collapse mode.
46244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
47244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_CPU_IDLE = "cpu.idle";
48244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
49244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
500c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn     * Power consumption when CPU is awake (when a wake lock is held).  This
510c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn     * should be 0 on devices that can go into full CPU power collapse even
520c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn     * when a wake lock is held.  Otherwise, this is the power consumption in
530c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn     * addition to POWERR_CPU_IDLE due to a wake lock being held but with no
540c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn     * CPU activity.
550c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn     */
560c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn    public static final String POWER_CPU_AWAKE = "cpu.awake";
570c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn
580c8b4d3f7e280da5d981651be13b8966b36bc45cDianne Hackborn    /**
59e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani     * Power consumption when CPU is in power collapse mode.
60244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
61e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    public static final String POWER_CPU_ACTIVE = "cpu.active";
62244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
63244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
64244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when WiFi driver is scanning for networks.
65244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
66244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_WIFI_SCAN = "wifi.scan";
67244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
68244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
69244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when WiFi driver is on.
70244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
71244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_WIFI_ON = "wifi.on";
72244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
73244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
74244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when WiFi driver is transmitting/receiving.
75244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
76244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_WIFI_ACTIVE = "wifi.active";
77244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
78244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
79244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when GPS is on.
80244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
81244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_GPS_ON = "gps.on";
82244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
83244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
84244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when Bluetooth driver is on.
85244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
86244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_BLUETOOTH_ON = "bluetooth.on";
87244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
88244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
89244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when Bluetooth driver is transmitting/receiving.
90244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
91244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";
92244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
93244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
943f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani     * Power consumption when Bluetooth driver gets an AT command.
953f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani     */
963f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani    public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at";
973f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani
983f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani    /**
99244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when screen is on, not including the backlight power.
100244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
101244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_SCREEN_ON = "screen.on";
102244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
103244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
104244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when cell radio is on but not on a call.
105244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
106244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_RADIO_ON = "radio.on";
107244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
108244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
109f37447bad3773b62176baa837908daf6edb44273Amith Yamasani     * Power consumption when cell radio is hunting for a signal.
110f37447bad3773b62176baa837908daf6edb44273Amith Yamasani     */
111f37447bad3773b62176baa837908daf6edb44273Amith Yamasani    public static final String POWER_RADIO_SCANNING = "radio.scanning";
112f37447bad3773b62176baa837908daf6edb44273Amith Yamasani
113f37447bad3773b62176baa837908daf6edb44273Amith Yamasani    /**
114244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption when talking on the phone.
115244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
116244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_RADIO_ACTIVE = "radio.active";
117244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
118244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
119244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumption at full backlight brightness. If the backlight is at
120244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * 50% brightness, then this should be multiplied by 0.5
121244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
122244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_SCREEN_FULL = "screen.full";
123244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
124244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
125244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumed by the audio hardware when playing back audio content. This is in addition
126244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * to the CPU power, probably due to a DSP and / or amplifier.
127244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
128244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_AUDIO = "dsp.audio";
129244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
130244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
131244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Power consumed by any media hardware when playing back video content. This is in addition
132244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * to the CPU power, probably due to a DSP.
133244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
134244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public static final String POWER_VIDEO = "dsp.video";
135244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
136e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    public static final String POWER_CPU_SPEEDS = "cpu.speeds";
137e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
138169741b70880607701d704262dd9b386fcfd083dAmith Yamasani    /**
139a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt     * Power consumed by wif batched scaning.  Broken down into bins by
140a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt     * Channels Scanned per Hour.  May do 1-720 scans per hour of 1-100 channels
141a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt     * for a range of 1-72,000.  Going logrithmic (1-8, 9-64, 65-512, 513-4096, 4097-)!
142a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt     */
143a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt    public static final String POWER_WIFI_BATCHED_SCAN = "wifi.batchedscan";
144a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt
145a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt    /**
146169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     * Battery capacity in milliAmpHour (mAh).
147169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     */
148169741b70880607701d704262dd9b386fcfd083dAmith Yamasani    public static final String POWER_BATTERY_CAPACITY = "battery.capacity";
149169741b70880607701d704262dd9b386fcfd083dAmith Yamasani
1503718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    static final HashMap<String, Object> sPowerMap = new HashMap<String, Object>();
151244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
152244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    private static final String TAG_DEVICE = "device";
153244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    private static final String TAG_ITEM = "item";
1543718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private static final String TAG_ARRAY = "array";
1553718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private static final String TAG_ARRAYITEM = "value";
156244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    private static final String ATTR_NAME = "name";
157244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
1583718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    public PowerProfile(Context context) {
159244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        // Read the XML file for the given profile (normally only one per
160244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        // device)
161244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        if (sPowerMap.size() == 0) {
1623718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            readPowerValuesFromXml(context);
163244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        }
164244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    }
165244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
1663718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private void readPowerValuesFromXml(Context context) {
1673718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani        int id = com.android.internal.R.xml.power_profile;
168244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        XmlResourceParser parser = context.getResources().getXml(id);
1693718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani        boolean parsingArray = false;
1703718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani        ArrayList<Double> array = new ArrayList<Double>();
1713718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani        String arrayName = null;
172244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
173244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        try {
174244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani            XmlUtils.beginDocument(parser, TAG_DEVICE);
175244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
176244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani            while (true) {
177244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani                XmlUtils.nextElement(parser);
178244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
1793718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                String element = parser.getName();
1803718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                if (element == null) break;
181a029ea131836725b050e1a7550aa171b68171522Robert Greenwalt
1823718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
1833718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    // Finish array
1843718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
1853718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    parsingArray = false;
186244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani                }
1873718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                if (element.equals(TAG_ARRAY)) {
1883718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    parsingArray = true;
1893718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    array.clear();
1903718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    arrayName = parser.getAttributeValue(null, ATTR_NAME);
1913718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                } else if (element.equals(TAG_ITEM) || element.equals(TAG_ARRAYITEM)) {
1923718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    String name = null;
1933718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    if (!parsingArray) name = parser.getAttributeValue(null, ATTR_NAME);
1943718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    if (parser.next() == XmlPullParser.TEXT) {
1953718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        String power = parser.getText();
1963718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        double value = 0;
1973718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        try {
1983718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                            value = Double.valueOf(power);
1993718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        } catch (NumberFormatException nfe) {
2003718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        }
2013718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        if (element.equals(TAG_ITEM)) {
2023718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                            sPowerMap.put(name, value);
2033718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        } else if (parsingArray) {
2043718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                            array.add(value);
2053718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                        }
206244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani                    }
207244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani                }
208244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani            }
2093718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            if (parsingArray) {
2103718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
2113718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            }
212244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        } catch (XmlPullParserException e) {
213244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani            throw new RuntimeException(e);
214244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        } catch (IOException e) {
215244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani            throw new RuntimeException(e);
216244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        } finally {
217244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani            parser.close();
218244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        }
219244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    }
220244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
221244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    /**
222244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * Returns the average current in mA consumed by the subsystem
223244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * @param type the subsystem type
224244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     * @return the average current in milliAmps.
225244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani     */
226244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    public double getAveragePower(String type) {
227244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        if (sPowerMap.containsKey(type)) {
2283718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            Object data = sPowerMap.get(type);
2293718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            if (data instanceof Double[]) {
2303718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                return ((Double[])data)[0];
2313718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            } else {
2323718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                return (Double) sPowerMap.get(type);
2333718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            }
2343718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani        } else {
2353718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            return 0;
2363718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani        }
2373718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    }
2383718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani
2393718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    /**
240e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani     * Returns the average current in mA consumed by the subsystem for the given level.
2413718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani     * @param type the subsystem type
2423718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani     * @param level the level of power at which the subsystem is running. For instance, the
243e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani     *  signal strength of the cell network between 0 and 4 (if there are 4 bars max.)
2443718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani     *  If there is no data for multiple levels, the level is ignored.
2453718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani     * @return the average current in milliAmps.
2463718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani     */
2473718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    public double getAveragePower(String type, int level) {
2483718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani        if (sPowerMap.containsKey(type)) {
2493718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            Object data = sPowerMap.get(type);
25032dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani            if (data instanceof Double[]) {
25132dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani                final Double[] values = (Double[]) data;
25232dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani                if (values.length > level && level >= 0) {
2533718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    return values[level];
25432dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani                } else if (level < 0) {
25532dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani                    return 0;
2563718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                } else {
2573718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                    return values[values.length - 1];
2583718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                }
2593718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            } else {
2603718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani                return (Double) data;
2613718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani            }
262244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        } else {
263244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani            return 0;
264244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        }
265244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    }
266e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
267169741b70880607701d704262dd9b386fcfd083dAmith Yamasani    /**
268169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     * Returns the battery capacity, if available, in milli Amp Hours. If not available,
269169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     * it returns zero.
270169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     * @return the battery capacity in mAh
271169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     */
272169741b70880607701d704262dd9b386fcfd083dAmith Yamasani    public double getBatteryCapacity() {
273169741b70880607701d704262dd9b386fcfd083dAmith Yamasani        return getAveragePower(POWER_BATTERY_CAPACITY);
274169741b70880607701d704262dd9b386fcfd083dAmith Yamasani    }
275169741b70880607701d704262dd9b386fcfd083dAmith Yamasani
276169741b70880607701d704262dd9b386fcfd083dAmith Yamasani    /**
277169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     * Returns the number of speeds that the CPU can be run at.
278169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     * @return
279169741b70880607701d704262dd9b386fcfd083dAmith Yamasani     */
280e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    public int getNumSpeedSteps() {
281e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        Object value = sPowerMap.get(POWER_CPU_SPEEDS);
282e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        if (value != null && value instanceof Double[]) {
283e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani            return ((Double[])value).length;
284e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        }
285e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        return 1; // Only one speed
286e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    }
287244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani}
288