1 /* 2 * Copyright (C) 2020 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 17 package android.os; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.database.Cursor; 23 import android.database.CursorWindow; 24 import android.util.IntArray; 25 import android.util.Slog; 26 import android.util.SparseArray; 27 import android.util.proto.ProtoOutputStream; 28 29 import java.io.PrintWriter; 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.List; 35 36 /** 37 * Interface for objects containing battery attribution data. 38 * 39 * @hide 40 */ 41 @android.ravenwood.annotation.RavenwoodKeepWholeClass 42 public abstract class BatteryConsumer { 43 44 private static final String TAG = "BatteryConsumer"; 45 46 /** 47 * Power usage component, describing the particular part of the system 48 * responsible for power drain. 49 * 50 * @hide 51 */ 52 @IntDef(prefix = {"POWER_COMPONENT_"}, value = { 53 POWER_COMPONENT_ANY, 54 POWER_COMPONENT_SCREEN, 55 POWER_COMPONENT_CPU, 56 POWER_COMPONENT_BLUETOOTH, 57 POWER_COMPONENT_CAMERA, 58 POWER_COMPONENT_AUDIO, 59 POWER_COMPONENT_VIDEO, 60 POWER_COMPONENT_FLASHLIGHT, 61 POWER_COMPONENT_MOBILE_RADIO, 62 POWER_COMPONENT_SYSTEM_SERVICES, 63 POWER_COMPONENT_SENSORS, 64 POWER_COMPONENT_GNSS, 65 POWER_COMPONENT_WIFI, 66 POWER_COMPONENT_WAKELOCK, 67 POWER_COMPONENT_MEMORY, 68 POWER_COMPONENT_PHONE, 69 POWER_COMPONENT_AMBIENT_DISPLAY, 70 POWER_COMPONENT_IDLE, 71 POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS, 72 POWER_COMPONENT_BASE, 73 }) 74 @Retention(RetentionPolicy.SOURCE) 75 public @interface PowerComponent { 76 } 77 78 public static final int POWER_COMPONENT_ANY = -1; 79 public static final int POWER_COMPONENT_SCREEN = OsProtoEnums.POWER_COMPONENT_SCREEN; // 0 80 public static final int POWER_COMPONENT_CPU = OsProtoEnums.POWER_COMPONENT_CPU; // 1 81 public static final int POWER_COMPONENT_BLUETOOTH = OsProtoEnums.POWER_COMPONENT_BLUETOOTH; // 2 82 public static final int POWER_COMPONENT_CAMERA = OsProtoEnums.POWER_COMPONENT_CAMERA; // 3 83 public static final int POWER_COMPONENT_AUDIO = OsProtoEnums.POWER_COMPONENT_AUDIO; // 4 84 public static final int POWER_COMPONENT_VIDEO = OsProtoEnums.POWER_COMPONENT_VIDEO; // 5 85 public static final int POWER_COMPONENT_FLASHLIGHT = 86 OsProtoEnums.POWER_COMPONENT_FLASHLIGHT; // 6 87 public static final int POWER_COMPONENT_SYSTEM_SERVICES = 88 OsProtoEnums.POWER_COMPONENT_SYSTEM_SERVICES; // 7 89 public static final int POWER_COMPONENT_MOBILE_RADIO = 90 OsProtoEnums.POWER_COMPONENT_MOBILE_RADIO; // 8 91 public static final int POWER_COMPONENT_SENSORS = OsProtoEnums.POWER_COMPONENT_SENSORS; // 9 92 public static final int POWER_COMPONENT_GNSS = OsProtoEnums.POWER_COMPONENT_GNSS; // 10 93 public static final int POWER_COMPONENT_WIFI = OsProtoEnums.POWER_COMPONENT_WIFI; // 11 94 public static final int POWER_COMPONENT_WAKELOCK = OsProtoEnums.POWER_COMPONENT_WAKELOCK; // 12 95 public static final int POWER_COMPONENT_MEMORY = OsProtoEnums.POWER_COMPONENT_MEMORY; // 13 96 public static final int POWER_COMPONENT_PHONE = OsProtoEnums.POWER_COMPONENT_PHONE; // 14 97 public static final int POWER_COMPONENT_AMBIENT_DISPLAY = 98 OsProtoEnums.POWER_COMPONENT_AMBIENT_DISPLAY; // 15 99 public static final int POWER_COMPONENT_IDLE = OsProtoEnums.POWER_COMPONENT_IDLE; // 16 100 // Power that is re-attributed to other battery consumers. For example, for System Server 101 // this represents the power attributed to apps requesting system services. 102 // The value should be negative or zero. 103 public static final int POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS = 104 OsProtoEnums.POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS; // 17 105 // Power component ID that is used for technical purposes of attribution of time-in-state 106 // for UIDs and other general computations not associated with specific hardware. 107 public static final int POWER_COMPONENT_BASE = 18; 108 public static final int POWER_COMPONENT_COUNT = 19; 109 110 public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; 111 public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; 112 113 private static final String[] sPowerComponentNames = new String[POWER_COMPONENT_COUNT]; 114 115 static { 116 // Assign individually to avoid future mismatch 117 sPowerComponentNames[POWER_COMPONENT_SCREEN] = "screen"; 118 sPowerComponentNames[POWER_COMPONENT_CPU] = "cpu"; 119 sPowerComponentNames[POWER_COMPONENT_BLUETOOTH] = "bluetooth"; 120 sPowerComponentNames[POWER_COMPONENT_CAMERA] = "camera"; 121 sPowerComponentNames[POWER_COMPONENT_AUDIO] = "audio"; 122 sPowerComponentNames[POWER_COMPONENT_VIDEO] = "video"; 123 sPowerComponentNames[POWER_COMPONENT_FLASHLIGHT] = "flashlight"; 124 sPowerComponentNames[POWER_COMPONENT_SYSTEM_SERVICES] = "system_services"; 125 sPowerComponentNames[POWER_COMPONENT_MOBILE_RADIO] = "mobile_radio"; 126 sPowerComponentNames[POWER_COMPONENT_SENSORS] = "sensors"; 127 sPowerComponentNames[POWER_COMPONENT_GNSS] = "gnss"; 128 sPowerComponentNames[POWER_COMPONENT_WIFI] = "wifi"; 129 sPowerComponentNames[POWER_COMPONENT_WAKELOCK] = "wakelock"; 130 sPowerComponentNames[POWER_COMPONENT_MEMORY] = "memory"; 131 sPowerComponentNames[POWER_COMPONENT_PHONE] = "phone"; 132 sPowerComponentNames[POWER_COMPONENT_AMBIENT_DISPLAY] = "ambient_display"; 133 sPowerComponentNames[POWER_COMPONENT_IDLE] = "idle"; 134 sPowerComponentNames[POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS] = "reattributed"; 135 sPowerComponentNames[POWER_COMPONENT_BASE] = ""; // Top-level, no need for a name 136 } 137 138 /** 139 * An integer that is either one of @PowerComponent constants or a custom component ID 140 * between FIRST_CUSTOM_POWER_COMPONENT_ID and LAST_CUSTOM_POWER_COMPONENT_ID. 141 * 142 * @hide 143 */ 144 @Retention(RetentionPolicy.SOURCE) 145 public @interface PowerComponentId { 146 } 147 148 /** 149 * Identifiers of models used for power estimation. 150 * 151 * @hide 152 */ 153 @IntDef(prefix = {"POWER_MODEL_"}, value = { 154 POWER_MODEL_UNDEFINED, 155 POWER_MODEL_POWER_PROFILE, 156 POWER_MODEL_ENERGY_CONSUMPTION, 157 }) 158 @Retention(RetentionPolicy.SOURCE) 159 public @interface PowerModel { 160 } 161 162 /** 163 * Unspecified power model. 164 * 165 * @deprecated PowerModel is no longer supported 166 */ 167 @Deprecated 168 public static final int POWER_MODEL_UNDEFINED = 0; 169 170 /** 171 * Power model that is based on average consumption rates that hardware components 172 * consume in various states. 173 * 174 * @deprecated PowerModel is no longer supported 175 */ 176 @Deprecated 177 public static final int POWER_MODEL_POWER_PROFILE = 1; 178 179 /** 180 * Power model that is based on energy consumption stats provided by PowerStats HAL. 181 * 182 * @deprecated PowerModel is no longer supported 183 */ 184 @Deprecated 185 public static final int POWER_MODEL_ENERGY_CONSUMPTION = 2; 186 187 /** 188 * Identifiers of consumed power aggregations. 189 * 190 * @hide 191 */ 192 @IntDef(prefix = {"PROCESS_STATE_"}, value = { 193 PROCESS_STATE_ANY, 194 PROCESS_STATE_UNSPECIFIED, 195 PROCESS_STATE_FOREGROUND, 196 PROCESS_STATE_BACKGROUND, 197 PROCESS_STATE_FOREGROUND_SERVICE, 198 PROCESS_STATE_CACHED, 199 }) 200 @Retention(RetentionPolicy.SOURCE) 201 public @interface ProcessState { 202 } 203 204 public static final int PROCESS_STATE_ANY = -1; 205 public static final int PROCESS_STATE_UNSPECIFIED = 0; 206 public static final int PROCESS_STATE_FOREGROUND = 1; 207 public static final int PROCESS_STATE_BACKGROUND = 2; 208 public static final int PROCESS_STATE_FOREGROUND_SERVICE = 3; 209 public static final int PROCESS_STATE_CACHED = 4; 210 211 public static final int PROCESS_STATE_COUNT = 5; 212 213 private static final String[] sProcessStateNames = new String[PROCESS_STATE_COUNT]; 214 215 static { 216 // Assign individually to avoid future mismatch 217 sProcessStateNames[PROCESS_STATE_UNSPECIFIED] = "unspecified"; 218 sProcessStateNames[PROCESS_STATE_FOREGROUND] = "fg"; 219 sProcessStateNames[PROCESS_STATE_BACKGROUND] = "bg"; 220 sProcessStateNames[PROCESS_STATE_FOREGROUND_SERVICE] = "fgs"; 221 sProcessStateNames[PROCESS_STATE_CACHED] = "cached"; 222 } 223 224 private static final IntArray SUPPORTED_POWER_COMPONENTS_PER_PROCESS_STATE; 225 static { 226 int[] supportedPowerComponents = { 227 POWER_COMPONENT_BASE, 228 POWER_COMPONENT_CPU, 229 POWER_COMPONENT_MOBILE_RADIO, 230 POWER_COMPONENT_WIFI, 231 POWER_COMPONENT_BLUETOOTH, 232 POWER_COMPONENT_AUDIO, 233 POWER_COMPONENT_VIDEO, 234 POWER_COMPONENT_FLASHLIGHT, 235 POWER_COMPONENT_CAMERA, 236 POWER_COMPONENT_GNSS, 237 POWER_COMPONENT_SENSORS, 238 POWER_COMPONENT_WAKELOCK, 239 }; 240 Arrays.sort(supportedPowerComponents); 241 SUPPORTED_POWER_COMPONENTS_PER_PROCESS_STATE = IntArray.wrap(supportedPowerComponents); 242 }; 243 244 static final int COLUMN_INDEX_BATTERY_CONSUMER_TYPE = 0; 245 /** 246 * Identifiers of consumed power aggregations per SCREEN state. 247 * 248 * @hide 249 */ 250 @IntDef(prefix = {"SCREEN_STATE_"}, value = { 251 SCREEN_STATE_ANY, 252 SCREEN_STATE_UNSPECIFIED, 253 SCREEN_STATE_ON, 254 SCREEN_STATE_OTHER, 255 }) 256 @Retention(RetentionPolicy.SOURCE) 257 public @interface ScreenState { 258 } 259 260 static final int COLUMN_COUNT = 1; 261 262 public static final int SCREEN_STATE_ANY = 0; 263 public static final int SCREEN_STATE_UNSPECIFIED = 0; 264 public static final int SCREEN_STATE_ON = 1; 265 public static final int SCREEN_STATE_OTHER = 2; // Off, doze etc 266 267 public static final int SCREEN_STATE_COUNT = 3; 268 269 private static final String[] sScreenStateNames = new String[SCREEN_STATE_COUNT]; 270 271 static { 272 // Assign individually to avoid future mismatch 273 sScreenStateNames[SCREEN_STATE_UNSPECIFIED] = "unspecified"; 274 sScreenStateNames[SCREEN_STATE_ON] = "on"; 275 sScreenStateNames[SCREEN_STATE_OTHER] = "off/doze"; 276 } 277 278 /** 279 * Identifiers of consumed power aggregations per POWER state. 280 * 281 * @hide 282 */ 283 @IntDef(prefix = {"POWER_STATE_"}, value = { 284 POWER_STATE_ANY, 285 POWER_STATE_UNSPECIFIED, 286 POWER_STATE_BATTERY, 287 POWER_STATE_OTHER, 288 }) 289 @Retention(RetentionPolicy.SOURCE) 290 public @interface PowerState { 291 } 292 293 public static final int POWER_STATE_ANY = 0; 294 public static final int POWER_STATE_UNSPECIFIED = 0; 295 public static final int POWER_STATE_BATTERY = 1; 296 public static final int POWER_STATE_OTHER = 2; // Plugged in, or on wireless charger, etc. 297 298 public static final int POWER_STATE_COUNT = 3; 299 300 private static final String[] sPowerStateNames = new String[POWER_STATE_COUNT]; 301 302 static { 303 // Assign individually to avoid future mismatch 304 sPowerStateNames[POWER_STATE_UNSPECIFIED] = "unspecified"; 305 sPowerStateNames[POWER_STATE_BATTERY] = "on battery"; 306 sPowerStateNames[POWER_STATE_OTHER] = "not on battery"; 307 } 308 309 /** 310 * Identifies power attribution dimensions that a caller is interested in. 311 */ 312 public static final class Dimensions { 313 public final @PowerComponentId int powerComponentId; 314 public final @ProcessState int processState; 315 public final @ScreenState int screenState; 316 public final @PowerState int powerState; 317 Dimensions(@owerComponentId int powerComponentId, @ProcessState int processState)318 public Dimensions(@PowerComponentId int powerComponentId, @ProcessState int processState) { 319 this(powerComponentId, processState, SCREEN_STATE_ANY, POWER_STATE_ANY); 320 } 321 Dimensions(@owerComponentId int powerComponentId, int processState, @ScreenState int screenState, @PowerState int powerState)322 public Dimensions(@PowerComponentId int powerComponentId, int processState, 323 @ScreenState int screenState, @PowerState int powerState) { 324 this.powerComponentId = powerComponentId; 325 this.processState = processState; 326 this.screenState = screenState; 327 this.powerState = powerState; 328 } 329 330 @Override toString()331 public String toString() { 332 boolean dimensionSpecified = false; 333 StringBuilder sb = new StringBuilder(); 334 if (powerComponentId != POWER_COMPONENT_ANY) { 335 sb.append("powerComponent="); 336 if (powerComponentId < POWER_COMPONENT_COUNT) { 337 sb.append(sPowerComponentNames[powerComponentId]); 338 } else { 339 sb.append("CUSTOM/").append(powerComponentId); 340 } 341 dimensionSpecified = true; 342 } 343 if (processState != PROCESS_STATE_ANY) { 344 if (dimensionSpecified) { 345 sb.append(", "); 346 } 347 sb.append("processState=").append(sProcessStateNames[processState]); 348 dimensionSpecified = true; 349 } 350 if (screenState != SCREEN_STATE_ANY) { 351 if (dimensionSpecified) { 352 sb.append(", "); 353 } 354 sb.append("screenState=").append(screenStateToString(screenState)); 355 dimensionSpecified = true; 356 } 357 if (powerState != POWER_STATE_ANY) { 358 if (dimensionSpecified) { 359 sb.append(", "); 360 } 361 sb.append("powerState=").append(powerStateToString(powerState)); 362 dimensionSpecified = true; 363 } 364 if (!dimensionSpecified) { 365 sb.append("any components and process states"); 366 } 367 return sb.toString(); 368 } 369 } 370 371 public static final Dimensions UNSPECIFIED_DIMENSIONS = 372 new Dimensions(POWER_COMPONENT_ANY, PROCESS_STATE_ANY, SCREEN_STATE_ANY, 373 POWER_STATE_ANY); 374 375 /** 376 * Identifies power attribution dimensions that are captured by a data element of 377 * a BatteryConsumer. These Keys are used to access those values and to set them using 378 * Builders. See for example {@link #getConsumedPower(Key)}. 379 * 380 * Keys cannot be allocated by the client - they can only be obtained by calling 381 * {@link #getKeys} or {@link #getKey}. All BatteryConsumers that are part of the 382 * same BatteryUsageStats share the same set of keys, therefore it is safe to obtain 383 * the keys from one BatteryConsumer and apply them to other BatteryConsumers 384 * in the same BatteryUsageStats. 385 */ 386 public static final class Key { 387 public final @PowerComponentId int powerComponentId; 388 public final @ProcessState int processState; 389 public final @ScreenState int screenState; 390 public final @PowerState int powerState; 391 392 final int mPowerColumnIndex; 393 final int mDurationColumnIndex; 394 Key(@owerComponentId int powerComponentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState, int powerColumnIndex, int durationColumnIndex)395 private Key(@PowerComponentId int powerComponentId, @ProcessState int processState, 396 @ScreenState int screenState, @PowerState int powerState, 397 int powerColumnIndex, int durationColumnIndex) { 398 this.powerComponentId = powerComponentId; 399 this.processState = processState; 400 this.screenState = screenState; 401 this.powerState = powerState; 402 403 mPowerColumnIndex = powerColumnIndex; 404 mDurationColumnIndex = durationColumnIndex; 405 } 406 407 /** 408 * Returns true if this key should be included in an enumeration parameterized with 409 * the supplied dimensions. 410 */ matches(@owerComponentId int powerComponent, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState)411 boolean matches(@PowerComponentId int powerComponent, @ProcessState int processState, 412 @ScreenState int screenState, @PowerState int powerState) { 413 if (powerComponent != POWER_COMPONENT_ANY && this.powerComponentId != powerComponent) { 414 return false; 415 } 416 if (this.processState == PROCESS_STATE_UNSPECIFIED) { 417 // PROCESS_STATE_UNSPECIFIED is used for storing a precomputed total 418 return false; 419 } 420 if (processState != PROCESS_STATE_ANY && this.processState != processState) { 421 return false; 422 } 423 if (screenState != SCREEN_STATE_ANY && this.screenState != screenState) { 424 return false; 425 } 426 if (powerState != POWER_STATE_ANY && this.powerState != powerState) { 427 return false; 428 } 429 return true; 430 } 431 432 @SuppressWarnings("EqualsUnsafeCast") 433 @Override equals(Object o)434 public boolean equals(Object o) { 435 // Skipping null and class check for performance 436 final Key key = (Key) o; 437 return powerComponentId == key.powerComponentId 438 && processState == key.processState 439 && screenState == key.screenState 440 && powerState == key.powerState; 441 } 442 443 @Override hashCode()444 public int hashCode() { 445 int result = powerComponentId; 446 result = 31 * result + processState; 447 result = 31 * result + screenState; 448 result = 31 * result + powerState; 449 return result; 450 } 451 452 /** 453 * Returns a string suitable for use in dumpsys. 454 */ toString(@owerComponentId int powerComponent, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState)455 public static String toString(@PowerComponentId int powerComponent, 456 @ProcessState int processState, @ScreenState int screenState, 457 @PowerState int powerState) { 458 StringBuilder sb = new StringBuilder(); 459 if (powerComponent < POWER_COMPONENT_COUNT) { 460 sb.append(powerComponentIdToString(powerComponent)); 461 } else { 462 sb.append("CUSTOM/").append(powerComponent); 463 } 464 if (processState != PROCESS_STATE_UNSPECIFIED) { 465 sb.append(':'); 466 sb.append(processStateToString(processState)); 467 } 468 if (screenState != SCREEN_STATE_UNSPECIFIED) { 469 sb.append(":scr-"); 470 sb.append(sScreenStateNames[screenState]); 471 } 472 if (powerState != POWER_STATE_UNSPECIFIED) { 473 sb.append(":pwr-"); 474 sb.append(sPowerStateNames[powerState]); 475 } 476 return sb.toString(); 477 } 478 479 @Override toString()480 public String toString() { 481 return toString(powerComponentId, processState, screenState, powerState); 482 } 483 } 484 485 protected final BatteryConsumerData mData; 486 protected final PowerComponents mPowerComponents; 487 BatteryConsumer(BatteryConsumerData data, @NonNull PowerComponents powerComponents)488 protected BatteryConsumer(BatteryConsumerData data, @NonNull PowerComponents powerComponents) { 489 mData = data; 490 mPowerComponents = powerComponents; 491 } 492 BatteryConsumer(BatteryConsumerData data)493 public BatteryConsumer(BatteryConsumerData data) { 494 mData = data; 495 mPowerComponents = new PowerComponents(data); 496 } 497 498 /** 499 * Returns the name of the specified power component, e.g. "CPU", "GPU" etc. 500 */ getPowerComponentName(@owerComponentId int powerComponent)501 public String getPowerComponentName(@PowerComponentId int powerComponent) { 502 return mData.layout.getPowerComponentName(powerComponent); 503 } 504 505 /** 506 * Total power consumed by this consumer, in mAh. 507 */ getConsumedPower()508 public double getConsumedPower() { 509 return mPowerComponents.getConsumedPower(UNSPECIFIED_DIMENSIONS); 510 } 511 512 /** 513 * Returns power consumed aggregated over the specified dimensions, in mAh. 514 */ getConsumedPower(Dimensions dimensions)515 public double getConsumedPower(Dimensions dimensions) { 516 return mPowerComponents.getConsumedPower(dimensions); 517 } 518 519 /** 520 * Returns the amount of usage time aggregated over the specified dimensions, in millis. 521 */ getUsageDurationMillis(@onNull Dimensions dimensions)522 public long getUsageDurationMillis(@NonNull Dimensions dimensions) { 523 return mPowerComponents.getUsageDurationMillis(dimensions); 524 } 525 526 /** 527 * Returns indexes of all included power components. 528 */ 529 @PowerComponentId getPowerComponentIds()530 public int[] getPowerComponentIds() { 531 return mData.layout.powerComponentIds; 532 } 533 534 /** 535 * Returns keys for various power values attributed to the specified component 536 * held by this BatteryUsageStats object. 537 */ getKeys(@owerComponentId int componentId)538 public Key[] getKeys(@PowerComponentId int componentId) { 539 return mData.layout.getKeys(componentId); 540 } 541 542 /** 543 * Returns the key for the power attributed to the specified component, 544 * for all values of other dimensions such as process state. 545 */ getKey(@owerComponentId int componentId)546 public Key getKey(@PowerComponentId int componentId) { 547 return mData.layout.getKey(componentId, PROCESS_STATE_UNSPECIFIED, SCREEN_STATE_UNSPECIFIED, 548 POWER_STATE_UNSPECIFIED); 549 } 550 551 /** 552 * Returns the key for the power attributed to the specified component and process state. 553 */ getKey(@owerComponentId int componentId, @ProcessState int processState)554 public Key getKey(@PowerComponentId int componentId, @ProcessState int processState) { 555 return mData.layout.getKey(componentId, processState, SCREEN_STATE_UNSPECIFIED, 556 POWER_STATE_UNSPECIFIED); 557 } 558 559 /** 560 * Returns the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc. 561 * 562 * @param componentId The ID of the power component, e.g. 563 * {@link BatteryConsumer#POWER_COMPONENT_CPU}. 564 * @return Amount of consumed power in mAh. 565 */ getConsumedPower(@owerComponentId int componentId)566 public double getConsumedPower(@PowerComponentId int componentId) { 567 return mPowerComponents.getConsumedPower(componentId, PROCESS_STATE_ANY, 568 SCREEN_STATE_ANY, POWER_STATE_ANY); 569 } 570 571 /** 572 * Returns the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc. 573 * 574 * @param key The key of the power component, obtained by calling {@link #getKey} or 575 * {@link #getKeys} method. 576 * @return Amount of consumed power in mAh. 577 */ getConsumedPower(@onNull Key key)578 public double getConsumedPower(@NonNull Key key) { 579 return mPowerComponents.getConsumedPower(key); 580 } 581 582 /** 583 * Returns the ID of the model that was used for power estimation. 584 * 585 * @param componentId The ID of the power component, e.g. 586 * {@link BatteryConsumer#POWER_COMPONENT_CPU}. 587 * @deprecated PowerModel is no longer supported 588 */ 589 @Deprecated getPowerModel(@owerComponentId int componentId)590 public @PowerModel int getPowerModel(@PowerComponentId int componentId) { 591 return POWER_MODEL_UNDEFINED; 592 } 593 594 /** 595 * Returns the ID of the model that was used for power estimation. 596 * 597 * @param key The key of the power component, obtained by calling {@link #getKey} or 598 * {@link #getKeys} method. 599 * @deprecated PowerModel is no longer supported 600 */ 601 @Deprecated getPowerModel(@onNull BatteryConsumer.Key key)602 public @PowerModel int getPowerModel(@NonNull BatteryConsumer.Key key) { 603 return POWER_MODEL_UNDEFINED; 604 } 605 606 /** 607 * Returns the amount of drain attributed to the specified custom drain type. 608 * 609 * @param componentId The ID of the custom power component. 610 * @return Amount of consumed power in mAh. 611 * 612 * @deprecated Use getConsumedPower instead 613 */ 614 @Deprecated getConsumedPowerForCustomComponent(int componentId)615 public double getConsumedPowerForCustomComponent(int componentId) { 616 return getConsumedPower(componentId); 617 } 618 getCustomPowerComponentCount()619 public int getCustomPowerComponentCount() { 620 return mData.layout.customPowerComponentCount; 621 } 622 623 /** 624 * Returns the name of the specified power component. 625 * 626 * @param componentId The ID of the custom power component. 627 */ getCustomPowerComponentName(int componentId)628 public String getCustomPowerComponentName(int componentId) { 629 return mPowerComponents.getCustomPowerComponentName(componentId); 630 } 631 632 /** 633 * Returns the amount of time since BatteryStats reset used by the specified component, e.g. 634 * CPU, WiFi etc. 635 * 636 * @param componentId The ID of the power component, e.g. 637 * {@link UidBatteryConsumer#POWER_COMPONENT_CPU}. 638 * @return Amount of time in milliseconds. 639 */ getUsageDurationMillis(@owerComponentId int componentId)640 public long getUsageDurationMillis(@PowerComponentId int componentId) { 641 return mPowerComponents.getUsageDurationMillis(componentId, PROCESS_STATE_ANY, 642 SCREEN_STATE_ANY, POWER_STATE_ANY); 643 } 644 645 /** 646 * Returns the amount of time since BatteryStats reset used by the specified component, e.g. 647 * CPU, WiFi etc. 648 * 649 * 650 * @param key The key of the power component, obtained by calling {@link #getKey} or 651 * {@link #getKeys} method. 652 * @return Amount of time in milliseconds. 653 */ getUsageDurationMillis(@onNull Key key)654 public long getUsageDurationMillis(@NonNull Key key) { 655 return mPowerComponents.getUsageDurationMillis(key); 656 } 657 658 /** 659 * Returns the name of the specified component. Intended for logging and debugging. 660 */ powerComponentIdToString(@atteryConsumer.PowerComponent int componentId)661 public static String powerComponentIdToString(@BatteryConsumer.PowerComponent int componentId) { 662 if (componentId == POWER_COMPONENT_ANY) { 663 return "all"; 664 } 665 return sPowerComponentNames[componentId]; 666 } 667 668 /** 669 * Returns the equivalent PowerModel enum for the specified power model. 670 * {@see BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage.PowerModel} 671 */ powerModelToProtoEnum(@atteryConsumer.PowerModel int powerModel)672 public static int powerModelToProtoEnum(@BatteryConsumer.PowerModel int powerModel) { 673 switch (powerModel) { 674 case BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION: 675 return BatteryUsageStatsAtomsProto.PowerComponentModel.MEASURED_ENERGY; 676 case BatteryConsumer.POWER_MODEL_POWER_PROFILE: 677 return BatteryUsageStatsAtomsProto.PowerComponentModel.POWER_PROFILE; 678 default: 679 return BatteryUsageStatsAtomsProto.PowerComponentModel.UNDEFINED; 680 } 681 } 682 683 /** 684 * Returns the name of the specified process state. Intended for logging and debugging. 685 */ processStateToString(@atteryConsumer.ProcessState int processState)686 public static String processStateToString(@BatteryConsumer.ProcessState int processState) { 687 return sProcessStateNames[processState]; 688 } 689 690 /** 691 * Returns the human-readable name of the specified power state (on battery or not) 692 */ powerStateToString(@owerState int powerState)693 public static String powerStateToString(@PowerState int powerState) { 694 return sPowerStateNames[powerState]; 695 } 696 697 /** 698 * Returns the human-readable name of the specified screen state (on or off/doze) 699 */ screenStateToString(@creenState int screenState)700 public static String screenStateToString(@ScreenState int screenState) { 701 return sScreenStateNames[screenState]; 702 } 703 704 /** 705 * Prints the stats in a human-readable format. 706 */ dump(PrintWriter pw)707 public void dump(PrintWriter pw) { 708 dump(pw, true); 709 } 710 711 /** 712 * Prints the stats in a human-readable format. 713 * 714 * @param skipEmptyComponents if true, omit any power components with a zero amount. 715 */ dump(PrintWriter pw, boolean skipEmptyComponents)716 public abstract void dump(PrintWriter pw, boolean skipEmptyComponents); 717 718 /** Returns whether there are any atoms.proto BATTERY_CONSUMER_DATA data to write to a proto. */ hasStatsProtoData()719 boolean hasStatsProtoData() { 720 return writeStatsProtoImpl(null, /* Irrelevant fieldId: */ 0); 721 } 722 723 /** Writes the atoms.proto BATTERY_CONSUMER_DATA for this BatteryConsumer to the given proto. */ writeStatsProto(@onNull ProtoOutputStream proto, long fieldId)724 void writeStatsProto(@NonNull ProtoOutputStream proto, long fieldId) { 725 writeStatsProtoImpl(proto, fieldId); 726 } 727 728 /** 729 * Returns whether there are any atoms.proto BATTERY_CONSUMER_DATA data to write to a proto, 730 * and writes it to the given proto if it is non-null. 731 */ writeStatsProtoImpl(@ullable ProtoOutputStream proto, long fieldId)732 private boolean writeStatsProtoImpl(@Nullable ProtoOutputStream proto, long fieldId) { 733 final long totalConsumedPowerDeciCoulombs = convertMahToDeciCoulombs(getConsumedPower()); 734 735 if (totalConsumedPowerDeciCoulombs == 0) { 736 // NOTE: Strictly speaking we should also check !mPowerComponents.hasStatsProtoData(). 737 // However, that call is a bit expensive (a for loop). And the only way that 738 // totalConsumedPower can be 0 while mPowerComponents.hasStatsProtoData() is true is 739 // if POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS (which is the only negative 740 // allowed) happens to exactly equal the sum of all other components, which 741 // can't really happen in practice. 742 // So we'll just adopt the rule "if total==0, don't write any details". 743 // If negative values are used for other things in the future, this can be revisited. 744 return false; 745 } 746 if (proto == null) { 747 // We're just asked whether there is data, not to actually write it. And there is. 748 return true; 749 } 750 751 final long token = proto.start(fieldId); 752 proto.write( 753 BatteryUsageStatsAtomsProto.BatteryConsumerData.TOTAL_CONSUMED_POWER_DECI_COULOMBS, 754 totalConsumedPowerDeciCoulombs); 755 mPowerComponents.writeStatsProto(proto); 756 proto.end(token); 757 758 return true; 759 } 760 761 /** Converts charge from milliamp hours (mAh) to decicoulombs (dC). */ convertMahToDeciCoulombs(double powerMah)762 static long convertMahToDeciCoulombs(double powerMah) { 763 return (long) (powerMah * (10 * 3600 / 1000) + 0.5); 764 } 765 766 static class BatteryConsumerData { 767 private final CursorWindow mCursorWindow; 768 private final int mCursorRow; 769 public final BatteryConsumerDataLayout layout; 770 BatteryConsumerData(CursorWindow cursorWindow, int cursorRow, BatteryConsumerDataLayout layout)771 BatteryConsumerData(CursorWindow cursorWindow, int cursorRow, 772 BatteryConsumerDataLayout layout) { 773 mCursorWindow = cursorWindow; 774 mCursorRow = cursorRow; 775 this.layout = layout; 776 } 777 778 @Nullable create(CursorWindow cursorWindow, BatteryConsumerDataLayout layout)779 static BatteryConsumerData create(CursorWindow cursorWindow, 780 BatteryConsumerDataLayout layout) { 781 int cursorRow = cursorWindow.getNumRows(); 782 if (!cursorWindow.allocRow()) { 783 Slog.e(TAG, "Cannot allocate BatteryConsumerData: too many UIDs: " + cursorRow); 784 cursorRow = -1; 785 } 786 return new BatteryConsumerData(cursorWindow, cursorRow, layout); 787 } 788 hasValue(int columnIndex)789 boolean hasValue(int columnIndex) { 790 if (mCursorRow == -1) { 791 return false; 792 } 793 return mCursorWindow.getType(mCursorRow, columnIndex) != Cursor.FIELD_TYPE_NULL; 794 } 795 putInt(int columnIndex, int value)796 void putInt(int columnIndex, int value) { 797 if (mCursorRow == -1) { 798 return; 799 } 800 mCursorWindow.putLong(value, mCursorRow, columnIndex); 801 } 802 getInt(int columnIndex)803 int getInt(int columnIndex) { 804 if (mCursorRow == -1) { 805 return 0; 806 } 807 return mCursorWindow.getInt(mCursorRow, columnIndex); 808 } 809 putDouble(int columnIndex, double value)810 void putDouble(int columnIndex, double value) { 811 if (mCursorRow == -1) { 812 return; 813 } 814 mCursorWindow.putDouble(value, mCursorRow, columnIndex); 815 } 816 getDouble(int columnIndex)817 double getDouble(int columnIndex) { 818 if (mCursorRow == -1) { 819 return 0; 820 } 821 return mCursorWindow.getDouble(mCursorRow, columnIndex); 822 } 823 putLong(int columnIndex, long value)824 void putLong(int columnIndex, long value) { 825 if (mCursorRow == -1) { 826 return; 827 } 828 mCursorWindow.putLong(value, mCursorRow, columnIndex); 829 } 830 getLong(int columnIndex)831 long getLong(int columnIndex) { 832 if (mCursorRow == -1) { 833 return 0; 834 } 835 return mCursorWindow.getLong(mCursorRow, columnIndex); 836 } 837 putString(int columnIndex, String value)838 void putString(int columnIndex, String value) { 839 if (mCursorRow == -1) { 840 return; 841 } 842 mCursorWindow.putString(value, mCursorRow, columnIndex); 843 } 844 getString(int columnIndex)845 String getString(int columnIndex) { 846 if (mCursorRow == -1) { 847 return null; 848 } 849 return mCursorWindow.getString(mCursorRow, columnIndex); 850 } 851 } 852 853 static class BatteryConsumerDataLayout { 854 private static final Key[] KEY_ARRAY = new Key[0]; 855 public final String[] customPowerComponentNames; 856 public final int customPowerComponentCount; 857 public final boolean processStateDataIncluded; 858 public final boolean screenStateDataIncluded; 859 public final boolean powerStateDataIncluded; 860 public final @PowerComponentId int[] powerComponentIds; 861 public final Key[] keys; 862 public final SparseArray<Key> indexedKeys; 863 public final int totalConsumedPowerColumnIndex; 864 public final int columnCount; 865 private SparseArray<Key[]> mPerComponentKeys; 866 BatteryConsumerDataLayout(int firstColumn, String[] customPowerComponentNames, boolean includeProcessStateData, boolean includeScreenState, boolean includePowerState)867 private BatteryConsumerDataLayout(int firstColumn, String[] customPowerComponentNames, 868 boolean includeProcessStateData, boolean includeScreenState, 869 boolean includePowerState) { 870 this.customPowerComponentNames = customPowerComponentNames; 871 this.customPowerComponentCount = customPowerComponentNames.length; 872 this.processStateDataIncluded = includeProcessStateData; 873 this.screenStateDataIncluded = includeScreenState; 874 this.powerStateDataIncluded = includePowerState; 875 876 powerComponentIds = new int[POWER_COMPONENT_COUNT + customPowerComponentCount]; 877 int id = 0; 878 for (int componentId = 0; componentId < POWER_COMPONENT_COUNT; componentId++) { 879 powerComponentIds[id++] = componentId; 880 } 881 for (int i = 0; i < customPowerComponentCount; i++) { 882 powerComponentIds[id++] = FIRST_CUSTOM_POWER_COMPONENT_ID + i; 883 } 884 885 int columnIndex = firstColumn; 886 887 totalConsumedPowerColumnIndex = columnIndex++; 888 889 ArrayList<Key> keyList = new ArrayList<>(); 890 for (int screenState = 0; screenState < SCREEN_STATE_COUNT; screenState++) { 891 if (!includeScreenState && screenState != SCREEN_STATE_UNSPECIFIED) { 892 continue; 893 } 894 for (int powerState = 0; powerState < POWER_STATE_COUNT; powerState++) { 895 if (!includePowerState && powerState != POWER_STATE_UNSPECIFIED) { 896 continue; 897 } 898 for (int i = 0; i < powerComponentIds.length; i++) { 899 columnIndex = addKeys(keyList, includeProcessStateData, 900 powerComponentIds[i], screenState, powerState, columnIndex); 901 } 902 } 903 } 904 905 columnCount = columnIndex; 906 907 keys = keyList.toArray(KEY_ARRAY); 908 indexedKeys = new SparseArray<>(keys.length); 909 for (int i = 0; i < keys.length; i++) { 910 Key key = keys[i]; 911 indexedKeys.put(keyIndex(key.powerComponentId, key.processState, key.screenState, 912 key.powerState), key); 913 } 914 } 915 getPowerComponentName(@owerComponentId int powerComponentId)916 public String getPowerComponentName(@PowerComponentId int powerComponentId) { 917 if (powerComponentId < POWER_COMPONENT_COUNT) { 918 return BatteryConsumer.powerComponentIdToString(powerComponentId); 919 } else if (powerComponentId >= FIRST_CUSTOM_POWER_COMPONENT_ID && powerComponentId 920 < FIRST_CUSTOM_POWER_COMPONENT_ID + customPowerComponentCount) { 921 return customPowerComponentNames[powerComponentId 922 - FIRST_CUSTOM_POWER_COMPONENT_ID]; 923 } else { 924 throw new IllegalArgumentException( 925 "Unsupported power component " + powerComponentId); 926 } 927 } 928 addKeys(List<Key> keys, boolean includeProcessStateData, @PowerComponentId int componentId, int screenState, int powerState, int columnIndex)929 private int addKeys(List<Key> keys, boolean includeProcessStateData, 930 @PowerComponentId int componentId, int screenState, int powerState, 931 int columnIndex) { 932 keys.add(new Key(componentId, PROCESS_STATE_UNSPECIFIED, screenState, powerState, 933 columnIndex++, // power 934 columnIndex++ // usage duration 935 )); 936 937 // Declare Keys for all process states, if needed 938 if (includeProcessStateData || componentId == POWER_COMPONENT_BASE) { 939 boolean isSupported = SUPPORTED_POWER_COMPONENTS_PER_PROCESS_STATE 940 .binarySearch(componentId) >= 0 941 || componentId >= FIRST_CUSTOM_POWER_COMPONENT_ID; 942 if (isSupported) { 943 for (int processState = 0; processState < PROCESS_STATE_COUNT; processState++) { 944 if (processState == PROCESS_STATE_UNSPECIFIED) { // Already added above 945 continue; 946 } 947 keys.add(new Key(componentId, processState, screenState, powerState, 948 columnIndex++, // power 949 columnIndex++ // usage duration 950 )); 951 } 952 } 953 } 954 return columnIndex; 955 } 956 getKey(@owerComponentId int componentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState)957 Key getKey(@PowerComponentId int componentId, @ProcessState int processState, 958 @ScreenState int screenState, @PowerState int powerState) { 959 return indexedKeys.get(keyIndex(componentId, processState, screenState, powerState)); 960 } 961 getKeyOrThrow(@owerComponentId int componentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState)962 Key getKeyOrThrow(@PowerComponentId int componentId, @ProcessState int processState, 963 @ScreenState int screenState, @PowerState int powerState) { 964 Key key = getKey(componentId, processState, screenState, powerState); 965 if (key == null) { 966 throw new IllegalArgumentException( 967 "Unsupported power component ID: " + Key.toString(componentId, processState, 968 screenState, powerState)); 969 } 970 return key; 971 } 972 getKeys(@owerComponentId int componentId)973 public Key[] getKeys(@PowerComponentId int componentId) { 974 synchronized (this) { 975 if (mPerComponentKeys == null) { 976 mPerComponentKeys = new SparseArray<>(powerComponentIds.length); 977 } 978 Key[] componentKeys = mPerComponentKeys.get(componentId); 979 if (componentKeys == null) { 980 ArrayList<Key> out = new ArrayList<>(); 981 for (Key key : keys) { 982 if (key.powerComponentId == componentId) { 983 out.add(key); 984 } 985 } 986 componentKeys = out.toArray(new Key[out.size()]); 987 mPerComponentKeys.put(componentId, componentKeys); 988 } 989 return componentKeys; 990 } 991 } 992 keyIndex(@owerComponent int componentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState)993 private int keyIndex(@PowerComponent int componentId, @ProcessState int processState, 994 @ScreenState int screenState, @PowerState int powerState) { 995 // [CCCCCCPPPSSBB] 996 // C - component ID 997 // P - process state 998 // S - screen state 999 // B - power state 1000 return componentId << 7 | processState << 4 | screenState << 2 | powerState; 1001 } 1002 } 1003 createBatteryConsumerDataLayout( String[] customPowerComponentNames, boolean includeProcessStateData, boolean includeScreenStateData, boolean includePowerStateData)1004 static BatteryConsumerDataLayout createBatteryConsumerDataLayout( 1005 String[] customPowerComponentNames, 1006 boolean includeProcessStateData, boolean includeScreenStateData, 1007 boolean includePowerStateData) { 1008 int columnCount = BatteryConsumer.COLUMN_COUNT; 1009 columnCount = Math.max(columnCount, AggregateBatteryConsumer.COLUMN_COUNT); 1010 columnCount = Math.max(columnCount, UidBatteryConsumer.COLUMN_COUNT); 1011 columnCount = Math.max(columnCount, UserBatteryConsumer.COLUMN_COUNT); 1012 1013 return new BatteryConsumerDataLayout(columnCount, customPowerComponentNames, 1014 includeProcessStateData, includeScreenStateData, includePowerStateData); 1015 } 1016 1017 protected abstract static class BaseBuilder<T extends BaseBuilder<?>> { 1018 protected final BatteryConsumer.BatteryConsumerData mData; 1019 protected final PowerComponents.Builder mPowerComponentsBuilder; 1020 BaseBuilder(BatteryConsumer.BatteryConsumerData data, int consumerType, double minConsumedPowerThreshold)1021 public BaseBuilder(BatteryConsumer.BatteryConsumerData data, int consumerType, 1022 double minConsumedPowerThreshold) { 1023 mData = data; 1024 data.putLong(COLUMN_INDEX_BATTERY_CONSUMER_TYPE, consumerType); 1025 1026 mPowerComponentsBuilder = new PowerComponents.Builder(data, minConsumedPowerThreshold); 1027 } 1028 1029 @Nullable getKeys(@owerComponentId int componentId)1030 public Key[] getKeys(@PowerComponentId int componentId) { 1031 return mData.layout.getKeys(componentId); 1032 } 1033 1034 @Nullable getKey(@owerComponentId int componentId, @ProcessState int processState)1035 public Key getKey(@PowerComponentId int componentId, @ProcessState int processState) { 1036 return mData.layout.getKey(componentId, processState, SCREEN_STATE_UNSPECIFIED, 1037 POWER_STATE_UNSPECIFIED); 1038 } 1039 1040 @Nullable getKey(@owerComponentId int componentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState)1041 public Key getKey(@PowerComponentId int componentId, @ProcessState int processState, 1042 @ScreenState int screenState, @PowerState int powerState) { 1043 return mData.layout.getKey(componentId, processState, screenState, powerState); 1044 } 1045 1046 /** 1047 * Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc. 1048 * 1049 * @param componentId The ID of the power component, e.g. 1050 * {@link BatteryConsumer#POWER_COMPONENT_CPU}. 1051 * @param componentPower Amount of consumed power in mAh. 1052 * @deprecated use {@link #addConsumedPower} 1053 */ 1054 @Deprecated 1055 @NonNull setConsumedPower(@owerComponentId int componentId, double componentPower)1056 public T setConsumedPower(@PowerComponentId int componentId, double componentPower) { 1057 return setConsumedPower(componentId, componentPower, POWER_MODEL_POWER_PROFILE); 1058 } 1059 1060 /** 1061 * Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc. 1062 * 1063 * @param componentId The ID of the power component, e.g. 1064 * {@link BatteryConsumer#POWER_COMPONENT_CPU}. 1065 * @param componentPower Amount of consumed power in mAh. 1066 * @deprecated use {@link #addConsumedPower} 1067 */ 1068 @Deprecated 1069 @SuppressWarnings("unchecked") 1070 @NonNull setConsumedPower(@owerComponentId int componentId, double componentPower, @PowerModel int powerModel)1071 public T setConsumedPower(@PowerComponentId int componentId, double componentPower, 1072 @PowerModel int powerModel) { 1073 mPowerComponentsBuilder.setConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED), 1074 componentPower); 1075 return (T) this; 1076 } 1077 1078 @SuppressWarnings("unchecked") 1079 @NonNull addConsumedPower(@owerComponentId int componentId, double componentPower, @PowerModel int powerModel)1080 public T addConsumedPower(@PowerComponentId int componentId, double componentPower, 1081 @PowerModel int powerModel) { 1082 mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED), 1083 componentPower); 1084 return (T) this; 1085 } 1086 1087 @SuppressWarnings("unchecked") 1088 @NonNull setConsumedPower(Key key, double componentPower, @PowerModel int powerModel)1089 public T setConsumedPower(Key key, double componentPower, @PowerModel int powerModel) { 1090 mPowerComponentsBuilder.setConsumedPower(key, componentPower); 1091 return (T) this; 1092 } 1093 1094 @SuppressWarnings("unchecked") 1095 @NonNull addConsumedPower(@owerComponentId int componentId, double componentPower)1096 public T addConsumedPower(@PowerComponentId int componentId, double componentPower) { 1097 mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED), 1098 componentPower); 1099 return (T) this; 1100 } 1101 1102 @SuppressWarnings("unchecked") 1103 @NonNull addConsumedPower(Key key, double componentPower)1104 public T addConsumedPower(Key key, double componentPower) { 1105 mPowerComponentsBuilder.addConsumedPower(key, componentPower); 1106 return (T) this; 1107 } 1108 1109 /** 1110 * Sets the amount of time used by the specified component, e.g. CPU, WiFi etc. 1111 * 1112 * @param componentId The ID of the power component, e.g. 1113 * {@link UidBatteryConsumer#POWER_COMPONENT_CPU}. 1114 * @param componentUsageTimeMillis Amount of time in microseconds. 1115 * @deprecated use {@link #addUsageDurationMillis} 1116 */ 1117 @Deprecated 1118 @SuppressWarnings("unchecked") 1119 @NonNull setUsageDurationMillis(@owerComponentId int componentId, long componentUsageTimeMillis)1120 public T setUsageDurationMillis(@PowerComponentId int componentId, 1121 long componentUsageTimeMillis) { 1122 mPowerComponentsBuilder 1123 .setUsageDurationMillis(getKey(componentId, PROCESS_STATE_UNSPECIFIED), 1124 componentUsageTimeMillis); 1125 return (T) this; 1126 } 1127 1128 @Deprecated 1129 @SuppressWarnings("unchecked") 1130 @NonNull setUsageDurationMillis(Key key, long componentUsageTimeMillis)1131 public T setUsageDurationMillis(Key key, long componentUsageTimeMillis) { 1132 mPowerComponentsBuilder.setUsageDurationMillis(key, componentUsageTimeMillis); 1133 return (T) this; 1134 } 1135 1136 @NonNull addUsageDurationMillis(@owerComponentId int componentId, long componentUsageTimeMillis)1137 public T addUsageDurationMillis(@PowerComponentId int componentId, 1138 long componentUsageTimeMillis) { 1139 mPowerComponentsBuilder.addUsageDurationMillis( 1140 getKey(componentId, PROCESS_STATE_UNSPECIFIED), componentUsageTimeMillis); 1141 return (T) this; 1142 } 1143 1144 @SuppressWarnings("unchecked") 1145 @NonNull addUsageDurationMillis(Key key, long componentUsageTimeMillis)1146 public T addUsageDurationMillis(Key key, long componentUsageTimeMillis) { 1147 mPowerComponentsBuilder.addUsageDurationMillis(key, componentUsageTimeMillis); 1148 return (T) this; 1149 } 1150 1151 /** 1152 * Returns the total power accumulated by this builder so far. It may change 1153 * by the time the {@code build()} method is called. 1154 */ getTotalPower()1155 public double getTotalPower() { 1156 return mPowerComponentsBuilder.getTotalPower(); 1157 } 1158 } 1159 } 1160