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