1/*
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 */
16package com.android.internal.os;
17
18import android.os.BatteryStats.Uid;
19
20import java.util.List;
21
22/**
23 * Contains power usage of an application, system service, or hardware type.
24 */
25public class BatterySipper implements Comparable<BatterySipper> {
26    public int userId;
27    public Uid uidObj;
28    public DrainType drainType;
29
30    /**
31     * Smeared power from screen usage.
32     * We split the screen usage power and smear them among apps, based on activity time.
33     */
34    public double screenPowerMah;
35
36    /**
37     * Smeared power using proportional method.
38     *
39     * we smear power usage from hidden sippers to all apps proportionally.(except for screen usage)
40     *
41     * @see BatteryStatsHelper#shouldHideSipper(BatterySipper)
42     * @see BatteryStatsHelper#removeHiddenBatterySippers(List)
43     */
44    public double proportionalSmearMah;
45
46    /**
47     * Total power that adding the smeared power.
48     *
49     * @see #sumPower()
50     */
51    public double totalSmearedPowerMah;
52
53    /**
54     * Total power before smearing
55     */
56    public double totalPowerMah;
57
58    /**
59     * Whether we should hide this sipper
60     *
61     * @see BatteryStatsHelper#shouldHideSipper(BatterySipper)
62     */
63    public boolean shouldHide;
64
65    /**
66     * Generic usage time in milliseconds.
67     */
68    public long usageTimeMs;
69
70    /**
71     * Generic power usage in mAh.
72     */
73    public double usagePowerMah;
74
75    // Subsystem usage times.
76    public long cpuTimeMs;
77    public long gpsTimeMs;
78    public long wifiRunningTimeMs;
79    public long cpuFgTimeMs;
80    public long wakeLockTimeMs;
81    public long cameraTimeMs;
82    public long flashlightTimeMs;
83    public long bluetoothRunningTimeMs;
84
85    public long mobileRxPackets;
86    public long mobileTxPackets;
87    public long mobileActive;
88    public int mobileActiveCount;
89    public double mobilemspp;         // milliseconds per packet
90    public long wifiRxPackets;
91    public long wifiTxPackets;
92    public long mobileRxBytes;
93    public long mobileTxBytes;
94    public long wifiRxBytes;
95    public long wifiTxBytes;
96    public long btRxBytes;
97    public long btTxBytes;
98    public double percent;
99    public double noCoveragePercent;
100    public String[] mPackages;
101    public String packageWithHighestDrain;
102
103    // Measured in mAh (milli-ampere per hour).
104    // These are included when summed.
105    public double wifiPowerMah;
106    public double cpuPowerMah;
107    public double wakeLockPowerMah;
108    public double mobileRadioPowerMah;
109    public double gpsPowerMah;
110    public double sensorPowerMah;
111    public double cameraPowerMah;
112    public double flashlightPowerMah;
113    public double bluetoothPowerMah;
114
115    public enum DrainType {
116        IDLE,
117        CELL,
118        PHONE,
119        WIFI,
120        BLUETOOTH,
121        FLASHLIGHT,
122        SCREEN,
123        APP,
124        USER,
125        UNACCOUNTED,
126        OVERCOUNTED,
127        CAMERA,
128        MEMORY
129    }
130
131    public BatterySipper(DrainType drainType, Uid uid, double value) {
132        this.totalPowerMah = value;
133        this.drainType = drainType;
134        uidObj = uid;
135    }
136
137    public void computeMobilemspp() {
138        long packets = mobileRxPackets + mobileTxPackets;
139        mobilemspp = packets > 0 ? (mobileActive / (double) packets) : 0;
140    }
141
142    @Override
143    public int compareTo(BatterySipper other) {
144        // Over-counted always goes to the bottom.
145        if (drainType != other.drainType) {
146            if (drainType == DrainType.OVERCOUNTED) {
147                // This is "larger"
148                return 1;
149            } else if (other.drainType == DrainType.OVERCOUNTED) {
150                return -1;
151            }
152        }
153        // Return the flipped value because we want the items in descending order
154        return Double.compare(other.totalPowerMah, totalPowerMah);
155    }
156
157    /**
158     * Gets a list of packages associated with the current user
159     */
160    public String[] getPackages() {
161        return mPackages;
162    }
163
164    public int getUid() {
165        // Bail out if the current sipper is not an App sipper.
166        if (uidObj == null) {
167            return 0;
168        }
169        return uidObj.getUid();
170    }
171
172    /**
173     * Add stats from other to this BatterySipper.
174     */
175    public void add(BatterySipper other) {
176        totalPowerMah += other.totalPowerMah;
177        usageTimeMs += other.usageTimeMs;
178        usagePowerMah += other.usagePowerMah;
179        cpuTimeMs += other.cpuTimeMs;
180        gpsTimeMs += other.gpsTimeMs;
181        wifiRunningTimeMs += other.wifiRunningTimeMs;
182        cpuFgTimeMs += other.cpuFgTimeMs;
183        wakeLockTimeMs += other.wakeLockTimeMs;
184        cameraTimeMs += other.cameraTimeMs;
185        flashlightTimeMs += other.flashlightTimeMs;
186        bluetoothRunningTimeMs += other.bluetoothRunningTimeMs;
187        mobileRxPackets += other.mobileRxPackets;
188        mobileTxPackets += other.mobileTxPackets;
189        mobileActive += other.mobileActive;
190        mobileActiveCount += other.mobileActiveCount;
191        wifiRxPackets += other.wifiRxPackets;
192        wifiTxPackets += other.wifiTxPackets;
193        mobileRxBytes += other.mobileRxBytes;
194        mobileTxBytes += other.mobileTxBytes;
195        wifiRxBytes += other.wifiRxBytes;
196        wifiTxBytes += other.wifiTxBytes;
197        btRxBytes += other.btRxBytes;
198        btTxBytes += other.btTxBytes;
199        wifiPowerMah += other.wifiPowerMah;
200        gpsPowerMah += other.gpsPowerMah;
201        cpuPowerMah += other.cpuPowerMah;
202        sensorPowerMah += other.sensorPowerMah;
203        mobileRadioPowerMah += other.mobileRadioPowerMah;
204        wakeLockPowerMah += other.wakeLockPowerMah;
205        cameraPowerMah += other.cameraPowerMah;
206        flashlightPowerMah += other.flashlightPowerMah;
207        bluetoothPowerMah += other.bluetoothPowerMah;
208        screenPowerMah += other.screenPowerMah;
209        proportionalSmearMah += other.proportionalSmearMah;
210        totalSmearedPowerMah += other.totalSmearedPowerMah;
211    }
212
213    /**
214     * Sum all the powers and store the value into `value`.
215     * Also sum the {@code smearedTotalPowerMah} by adding smeared powerMah.
216     *
217     * @return the sum of all the power in this BatterySipper.
218     */
219    public double sumPower() {
220        totalPowerMah = usagePowerMah + wifiPowerMah + gpsPowerMah + cpuPowerMah +
221                sensorPowerMah + mobileRadioPowerMah + wakeLockPowerMah + cameraPowerMah +
222                flashlightPowerMah + bluetoothPowerMah;
223        totalSmearedPowerMah = totalPowerMah + screenPowerMah + proportionalSmearMah;
224
225        return totalPowerMah;
226    }
227}
228