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