Merge "Introduce BatteryUsageStats API"
This commit is contained in:
committed by
Android (Google) Code Review
commit
75affe2132
89
core/java/android/os/BatteryConsumer.java
Normal file
89
core/java/android/os/BatteryConsumer.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Interface for objects containing battery attribution data.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class BatteryConsumer {
|
||||
|
||||
/**
|
||||
* Power usage component, describing the particular part of the system
|
||||
* responsible for power drain.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = {"POWER_COMPONENT_"}, value = {
|
||||
POWER_COMPONENT_CPU,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public static @interface PowerComponent {
|
||||
}
|
||||
|
||||
public static final int POWER_COMPONENT_CPU = 0;
|
||||
|
||||
public static final int POWER_COMPONENT_COUNT = 1;
|
||||
|
||||
public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
|
||||
public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
|
||||
|
||||
private final PowerComponents mPowerComponents;
|
||||
|
||||
protected BatteryConsumer(@NonNull PowerComponents powerComponents) {
|
||||
mPowerComponents = powerComponents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total power consumed by this consumer, in mAh.
|
||||
*/
|
||||
public double getConsumedPower() {
|
||||
return mPowerComponents.getTotalPowerConsumed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
|
||||
*
|
||||
* @param componentId The ID of the power component, e.g.
|
||||
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
|
||||
* @return Amount of consumed power in mAh.
|
||||
*/
|
||||
public double getConsumedPower(@PowerComponent int componentId) {
|
||||
return mPowerComponents.getConsumedPower(componentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of drain attributed to the specified custom drain type.
|
||||
*
|
||||
* @param componentId The ID of the custom power component.
|
||||
* @return Amount of consumed power in mAh.
|
||||
*/
|
||||
public double getConsumedPowerForCustomComponent(int componentId) {
|
||||
return mPowerComponents.getConsumedPowerForCustomComponent(componentId);
|
||||
}
|
||||
|
||||
protected void writeToParcel(Parcel dest, int flags) {
|
||||
mPowerComponents.writeToParcel(dest, flags);
|
||||
}
|
||||
}
|
||||
@@ -160,6 +160,22 @@ public final class BatteryStatsManager {
|
||||
mBatteryStats = batteryStats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
|
||||
* and per-UID basis.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.BATTERY_STATS)
|
||||
@NonNull
|
||||
public BatteryUsageStats getBatteryUsageStats() {
|
||||
try {
|
||||
return mBatteryStats.getBatteryUsageStats();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the wifi connection RSSI has changed.
|
||||
*
|
||||
|
||||
19
core/java/android/os/BatteryUsageStats.aidl
Normal file
19
core/java/android/os/BatteryUsageStats.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
parcelable BatteryUsageStats;
|
||||
138
core/java/android/os/BatteryUsageStats.java
Normal file
138
core/java/android/os/BatteryUsageStats.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Contains a snapshot of battery attribution data, on a per-subsystem and per-UID basis.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class BatteryUsageStats implements Parcelable {
|
||||
private final double mConsumedPower;
|
||||
private final int mDischargePercentage;
|
||||
private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers;
|
||||
|
||||
private BatteryUsageStats(@NonNull Builder builder) {
|
||||
mConsumedPower = builder.mConsumedPower;
|
||||
mDischargePercentage = builder.mDischargePercentage;
|
||||
mUidBatteryConsumers = builder.mUidBatteryConsumers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Portion of battery charge drained since BatteryStats reset (e.g. due to being fully
|
||||
* charged), as percentage of the full charge in the range [0:100]
|
||||
*/
|
||||
public int getDischargePercentage() {
|
||||
return mDischargePercentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total amount of battery charge drained since BatteryStats reset (e.g. due to being fully
|
||||
* charged), in mAh
|
||||
*/
|
||||
public double getConsumedPower() {
|
||||
return mConsumedPower;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<UidBatteryConsumer> getUidBatteryConsumers() {
|
||||
return mUidBatteryConsumers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private BatteryUsageStats(@NonNull Parcel source) {
|
||||
mUidBatteryConsumers = new ArrayList<>();
|
||||
source.readParcelableList(mUidBatteryConsumers, getClass().getClassLoader());
|
||||
mConsumedPower = source.readDouble();
|
||||
mDischargePercentage = source.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeParcelableList(mUidBatteryConsumers, flags);
|
||||
dest.writeDouble(mConsumedPower);
|
||||
dest.writeInt(mDischargePercentage);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<BatteryUsageStats> CREATOR = new Creator<BatteryUsageStats>() {
|
||||
public BatteryUsageStats createFromParcel(@NonNull Parcel source) {
|
||||
return new BatteryUsageStats(source);
|
||||
}
|
||||
|
||||
public BatteryUsageStats[] newArray(int size) {
|
||||
return new BatteryUsageStats[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builder for BatteryUsageStats.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private double mConsumedPower;
|
||||
private int mDischargePercentage;
|
||||
private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a read-only object using the Builder values.
|
||||
*/
|
||||
@NonNull
|
||||
public BatteryUsageStats build() {
|
||||
return new BatteryUsageStats(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the battery discharge amount since BatteryStats reset as percentage of the full
|
||||
* charge.
|
||||
*/
|
||||
@SuppressLint("PercentageInt") // See b/174188159
|
||||
@NonNull
|
||||
public Builder setDischargePercentage(int dischargePercentage) {
|
||||
mDischargePercentage = dischargePercentage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the battery discharge amount since BatteryStats reset, in mAh.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setConsumedPower(double consumedPower) {
|
||||
mConsumedPower = consumedPower;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a UidBatteryConsumer, which represents battery attribution data for an
|
||||
* individual UID.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addUidBatteryConsumer(@NonNull UidBatteryConsumer uidBatteryConsumer) {
|
||||
mUidBatteryConsumers.add(uidBatteryConsumer);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
170
core/java/android/os/PowerComponents.java
Normal file
170
core/java/android/os/PowerComponents.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Contains details of battery attribution data broken down to individual power drain types
|
||||
* such as CPU, RAM, GPU etc.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class PowerComponents {
|
||||
|
||||
private final double mTotalPowerConsumed;
|
||||
private final double[] mPowerComponents;
|
||||
|
||||
PowerComponents(@NonNull Builder builder) {
|
||||
mTotalPowerConsumed = builder.mTotalPowerConsumed;
|
||||
mPowerComponents = builder.mPowerComponents;
|
||||
}
|
||||
|
||||
PowerComponents(@NonNull Parcel source) {
|
||||
mTotalPowerConsumed = source.readDouble();
|
||||
mPowerComponents = source.createDoubleArray();
|
||||
}
|
||||
|
||||
/** Writes contents to Parcel */
|
||||
void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeDouble(mTotalPowerConsumed);
|
||||
dest.writeDoubleArray(mPowerComponents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Total power consumed by this consumer, in mAh.
|
||||
*/
|
||||
public double getTotalPowerConsumed() {
|
||||
return mTotalPowerConsumed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
|
||||
*
|
||||
* @param componentId The ID of the power component, e.g.
|
||||
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
|
||||
* @return Amount of consumed power in mAh.
|
||||
*/
|
||||
public double getConsumedPower(@UidBatteryConsumer.PowerComponent int componentId) {
|
||||
if (componentId >= BatteryConsumer.POWER_COMPONENT_COUNT) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported power component ID: " + componentId);
|
||||
}
|
||||
try {
|
||||
return mPowerComponents[componentId];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException("Unsupported power component ID: " + componentId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of drain attributed to the specified custom drain type.
|
||||
*
|
||||
* @param componentId The ID of the custom power component.
|
||||
* @return Amount of consumed power in mAh.
|
||||
*/
|
||||
public double getConsumedPowerForCustomComponent(int componentId) {
|
||||
if (componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported custom power component ID: " + componentId);
|
||||
}
|
||||
try {
|
||||
return mPowerComponents[
|
||||
BatteryConsumer.POWER_COMPONENT_COUNT + componentId
|
||||
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported custom power component ID: " + componentId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for PowerComponents.
|
||||
*/
|
||||
static final class Builder {
|
||||
private double mTotalPowerConsumed;
|
||||
private final double[] mPowerComponents;
|
||||
|
||||
Builder(int customPowerComponentCount) {
|
||||
mPowerComponents = new double[BatteryConsumer.POWER_COMPONENT_COUNT
|
||||
+ customPowerComponentCount];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sum amount of power consumed since BatteryStats reset.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setTotalPowerConsumed(double totalPowerConsumed) {
|
||||
mTotalPowerConsumed = totalPowerConsumed;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
|
||||
*
|
||||
* @param componentId The ID of the power component, e.g.
|
||||
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
|
||||
* @param componentPower Amount of consumed power in mAh.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setConsumedPower(@UidBatteryConsumer.PowerComponent int componentId,
|
||||
double componentPower) {
|
||||
if (componentId >= BatteryConsumer.POWER_COMPONENT_COUNT) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported power component ID: " + componentId);
|
||||
}
|
||||
try {
|
||||
mPowerComponents[componentId] = componentPower;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported power component ID: " + componentId);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of drain attributed to the specified custom drain type.
|
||||
*
|
||||
* @param componentId The ID of the custom power component.
|
||||
* @param componentPower Amount of consumed power in mAh.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setConsumedPowerForCustomComponent(int componentId, double componentPower) {
|
||||
if (componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported custom power component ID: " + componentId);
|
||||
}
|
||||
try {
|
||||
mPowerComponents[BatteryConsumer.POWER_COMPONENT_COUNT + componentId
|
||||
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID] = componentPower;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported custom power component ID: " + componentId);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a read-only object out of the Builder values.
|
||||
*/
|
||||
@NonNull
|
||||
public PowerComponents build() {
|
||||
return new PowerComponents(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
145
core/java/android/os/UidBatteryConsumer.java
Normal file
145
core/java/android/os/UidBatteryConsumer.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Contains power consumption data attributed to a specific UID.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class UidBatteryConsumer extends BatteryConsumer implements Parcelable {
|
||||
|
||||
private final int mUid;
|
||||
@Nullable
|
||||
private final String mPackageWithHighestDrain;
|
||||
|
||||
public int getUid() {
|
||||
return mUid;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPackageWithHighestDrain() {
|
||||
return mPackageWithHighestDrain;
|
||||
}
|
||||
|
||||
private UidBatteryConsumer(@NonNull Builder builder) {
|
||||
super(builder.mPowerComponentsBuilder.build());
|
||||
mUid = builder.mUid;
|
||||
mPackageWithHighestDrain = builder.mPackageWithHighestDrain;
|
||||
}
|
||||
|
||||
private UidBatteryConsumer(@NonNull Parcel source) {
|
||||
super(new PowerComponents(source));
|
||||
mUid = source.readInt();
|
||||
mPackageWithHighestDrain = source.readString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents into a Parcel.
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(mUid);
|
||||
dest.writeString(mPackageWithHighestDrain);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<UidBatteryConsumer> CREATOR = new Creator<UidBatteryConsumer>() {
|
||||
public UidBatteryConsumer createFromParcel(@NonNull Parcel source) {
|
||||
return new UidBatteryConsumer(source);
|
||||
}
|
||||
|
||||
public UidBatteryConsumer[] newArray(int size) {
|
||||
return new UidBatteryConsumer[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for UidBatteryConsumer.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final PowerComponents.Builder mPowerComponentsBuilder;
|
||||
private final int mUid;
|
||||
private String mPackageWithHighestDrain;
|
||||
|
||||
public Builder(int customPowerComponentCount, int uid) {
|
||||
mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount);
|
||||
mUid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a read-only object out of the Builder values.
|
||||
*/
|
||||
@NonNull
|
||||
public UidBatteryConsumer build() {
|
||||
return new UidBatteryConsumer(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
|
||||
*
|
||||
* @param componentId The ID of the power component, e.g.
|
||||
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
|
||||
* @param componentPower Amount of consumed power in mAh.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setConsumedPower(@PowerComponent int componentId, double componentPower) {
|
||||
mPowerComponentsBuilder.setConsumedPower(componentId, componentPower);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of drain attributed to the specified custom drain type.
|
||||
*
|
||||
* @param componentId The ID of the custom power component.
|
||||
* @param componentPower Amount of consumed power in mAh.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setConsumedPowerForCustomComponent(int componentId, double componentPower) {
|
||||
mPowerComponentsBuilder.setConsumedPowerForCustomComponent(componentId, componentPower);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of power consumed since BatteryStats reset, mAh.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setConsumedPower(double consumedPower) {
|
||||
mPowerComponentsBuilder.setTotalPowerConsumed(consumedPower);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the package owned by this UID that consumed the highest amount
|
||||
* of power since BatteryStats reset.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setPackageWithHighestDrain(@Nullable String packageName) {
|
||||
mPackageWithHighestDrain = packageName;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.android.internal.app;
|
||||
import com.android.internal.os.BatteryStatsImpl;
|
||||
|
||||
import android.bluetooth.BluetoothActivityEnergyInfo;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.WorkSource;
|
||||
import android.os.connectivity.CellularBatteryStats;
|
||||
@@ -49,6 +50,9 @@ interface IBatteryStats {
|
||||
void noteResetFlashlight();
|
||||
|
||||
// Remaining methods are only used in Java.
|
||||
|
||||
BatteryUsageStats getBatteryUsageStats();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
byte[] getStatistics();
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.os;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Uses accumulated battery stats data and PowerCalculators to produce power
|
||||
* usage data attributed to subsystems and UIDs.
|
||||
*/
|
||||
public class BatteryUsageStatsProvider {
|
||||
private final Context mContext;
|
||||
private final BatteryStatsImpl mStats;
|
||||
|
||||
public BatteryUsageStatsProvider(Context context, BatteryStatsImpl stats) {
|
||||
mContext = context;
|
||||
mStats = stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a snapshot of battery attribution data.
|
||||
*/
|
||||
public BatteryUsageStats getBatteryUsageStats() {
|
||||
|
||||
// TODO(b/174186345): instead of BatteryStatsHelper, use PowerCalculators directly.
|
||||
final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(mContext,
|
||||
false /* collectBatteryBroadcast */);
|
||||
batteryStatsHelper.create((Bundle) null);
|
||||
final UserManager userManager = mContext.getSystemService(UserManager.class);
|
||||
batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
|
||||
userManager.getUserProfiles());
|
||||
|
||||
// TODO(b/174186358): read extra power component number from configuration
|
||||
final int customPowerComponentCount = 0;
|
||||
final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder()
|
||||
.setDischargePercentage(batteryStatsHelper.getStats().getDischargeAmount(0))
|
||||
.setConsumedPower(batteryStatsHelper.getTotalPower());
|
||||
|
||||
final List<BatterySipper> usageList = batteryStatsHelper.getUsageList();
|
||||
for (int i = 0; i < usageList.size(); i++) {
|
||||
final BatterySipper sipper = usageList.get(i);
|
||||
if (sipper.drainType == BatterySipper.DrainType.APP) {
|
||||
batteryUsageStatsBuilder.addUidBatteryConsumer(
|
||||
new UidBatteryConsumer.Builder(customPowerComponentCount, sipper.getUid())
|
||||
.setPackageWithHighestDrain(sipper.packageWithHighestDrain)
|
||||
.setConsumedPower(sipper.sumPower())
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU,
|
||||
sipper.cpuPowerMah)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
return batteryUsageStatsBuilder.build();
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import android.hardware.power.stats.EnergyConsumerId;
|
||||
import android.hardware.power.stats.EnergyConsumerResult;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStatsInternal;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@@ -57,6 +58,7 @@ import android.util.Slog;
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.internal.os.BatteryStatsImpl;
|
||||
import com.android.internal.os.BatteryUsageStatsProvider;
|
||||
import com.android.internal.os.BinderCallsStats;
|
||||
import com.android.internal.os.PowerProfile;
|
||||
import com.android.internal.os.RailStats;
|
||||
@@ -105,6 +107,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider;
|
||||
private final Context mContext;
|
||||
private final BatteryExternalStatsWorker mWorker;
|
||||
private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
|
||||
|
||||
private native void getLowPowerStats(RpmStats rpmStats);
|
||||
private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
|
||||
@@ -258,6 +261,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_radioScanningTimeout) * 1000L);
|
||||
mStats.setPowerProfileLocked(new PowerProfile(context));
|
||||
mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats);
|
||||
}
|
||||
|
||||
public void publish() {
|
||||
@@ -550,6 +554,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
|
||||
// Public interface...
|
||||
|
||||
/**
|
||||
* Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
|
||||
* and per-UID basis.
|
||||
*/
|
||||
public BatteryUsageStats getBatteryUsageStats() {
|
||||
mContext.enforceCallingPermission(
|
||||
android.Manifest.permission.BATTERY_STATS, null);
|
||||
return mBatteryUsageStatsProvider.getBatteryUsageStats();
|
||||
}
|
||||
|
||||
public byte[] getStatistics() {
|
||||
mContext.enforceCallingPermission(
|
||||
android.Manifest.permission.BATTERY_STATS, null);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.os;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.perftests.utils.BenchmarkState;
|
||||
import android.perftests.utils.PerfStatusReporter;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class BatteryUsageStatsPerfTest {
|
||||
|
||||
@Rule
|
||||
public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
|
||||
|
||||
/**
|
||||
* Measures the performance of {@link BatteryStatsManager#getBatteryUsageStats()},
|
||||
* which triggers a battery stats sync on every iteration.
|
||||
*/
|
||||
@Test
|
||||
public void testGetBatteryUsageStats() {
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final BatteryStatsManager batteryStatsManager =
|
||||
context.getSystemService(BatteryStatsManager.class);
|
||||
|
||||
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
BatteryUsageStats batteryUsageStats = batteryStatsManager.getBatteryUsageStats();
|
||||
|
||||
state.pauseTiming();
|
||||
|
||||
List<UidBatteryConsumer> uidBatteryConsumers =
|
||||
batteryUsageStats.getUidBatteryConsumers();
|
||||
double power = 0;
|
||||
for (int i = 0; i < uidBatteryConsumers.size(); i++) {
|
||||
UidBatteryConsumer uidBatteryConsumer = uidBatteryConsumers.get(i);
|
||||
power += uidBatteryConsumer.getConsumedPower();
|
||||
}
|
||||
|
||||
assertThat(power).isGreaterThan(0.0);
|
||||
|
||||
state.resumeTiming();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user