Initial integration of BatteryUsageStats into PowerStatsViewer
Bug: 170134969 Test: mp :PowerStatsViewer && adb shell am start -n com.android.frameworks.core.powerstatsviewer/.PowerStatsViewerActivity Change-Id: Ie409ee5de329a8e6a64f2bbf44efa49e9be3e336
This commit is contained in:
@@ -17,8 +17,12 @@
|
||||
package com.android.frameworks.core.powerstatsviewer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Process;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
@@ -58,7 +62,7 @@ public class PowerStatsData {
|
||||
private final List<Entry> mEntries = new ArrayList<>();
|
||||
|
||||
public PowerStatsData(Context context, BatteryStatsHelper batteryStatsHelper,
|
||||
String powerConsumerId) {
|
||||
BatteryUsageStats batteryUsageStats, String powerConsumerId) {
|
||||
List<BatterySipper> usageList = batteryStatsHelper.getUsageList();
|
||||
BatteryStats batteryStats = batteryStatsHelper.getStats();
|
||||
|
||||
@@ -92,14 +96,14 @@ public class PowerStatsData {
|
||||
long totalAudioTimeMs = 0;
|
||||
long totalVideoTimeMs = 0;
|
||||
|
||||
BatterySipper requestedPowerConsumer = null;
|
||||
BatterySipper requestedBatterySipper = null;
|
||||
for (BatterySipper sipper : usageList) {
|
||||
if (sipper.drainType == BatterySipper.DrainType.SCREEN) {
|
||||
totalScreenPower = sipper.sumPower();
|
||||
}
|
||||
|
||||
if (powerConsumerId(sipper).equals(powerConsumerId)) {
|
||||
requestedPowerConsumer = sipper;
|
||||
requestedBatterySipper = sipper;
|
||||
}
|
||||
|
||||
totalPowerMah += sipper.sumPower();
|
||||
@@ -136,81 +140,95 @@ public class PowerStatsData {
|
||||
totalVideoTimeMs += sipper.videoTimeMs;
|
||||
}
|
||||
|
||||
long totalScreenMeasuredEnergyUJ = batteryStats.getScreenOnEnergy();
|
||||
BatteryConsumer requestedBatteryConsumer = null;
|
||||
|
||||
if (requestedPowerConsumer == null) {
|
||||
for (BatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
|
||||
if (powerConsumerId(consumer).equals(powerConsumerId)) {
|
||||
requestedBatteryConsumer = consumer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (requestedBatterySipper == null) {
|
||||
mPowerConsumerInfo = null;
|
||||
return;
|
||||
}
|
||||
|
||||
long totalScreenMeasuredEnergyUJ = batteryStats.getScreenOnEnergy();
|
||||
|
||||
mPowerConsumerInfo = PowerConsumerInfoHelper.makePowerConsumerInfo(
|
||||
context.getPackageManager(), requestedPowerConsumer);
|
||||
context.getPackageManager(), requestedBatterySipper);
|
||||
|
||||
addEntry("Total power", EntryType.POWER,
|
||||
requestedPowerConsumer.totalSmearedPowerMah, totalSmearedPowerMah);
|
||||
maybeAddMeasuredEnergyEntry(requestedPowerConsumer.drainType, batteryStats);
|
||||
requestedBatterySipper.totalSmearedPowerMah, totalSmearedPowerMah);
|
||||
maybeAddMeasuredEnergyEntry(requestedBatterySipper.drainType, batteryStats);
|
||||
|
||||
addEntry("... excluding system", EntryType.POWER,
|
||||
requestedPowerConsumer.totalSmearedPowerMah, totalPowerExcludeSystemMah);
|
||||
requestedBatterySipper.totalSmearedPowerMah, totalPowerExcludeSystemMah);
|
||||
addEntry("Screen, smeared", EntryType.POWER,
|
||||
requestedPowerConsumer.screenPowerMah, totalScreenPower);
|
||||
requestedBatterySipper.screenPowerMah, totalScreenPower);
|
||||
if (totalScreenMeasuredEnergyUJ != BatteryStats.ENERGY_DATA_UNAVAILABLE) {
|
||||
final double measuredCharge = UJ_2_MAH * totalScreenMeasuredEnergyUJ;
|
||||
final double ratio = measuredCharge / totalScreenPower;
|
||||
addEntry("Screen, smeared (PowerStatsHal adjusted)", EntryType.POWER,
|
||||
requestedPowerConsumer.screenPowerMah * ratio, measuredCharge);
|
||||
requestedBatterySipper.screenPowerMah * ratio, measuredCharge);
|
||||
}
|
||||
addEntry("Other, smeared", EntryType.POWER,
|
||||
requestedPowerConsumer.proportionalSmearMah, totalProportionalSmearMah);
|
||||
requestedBatterySipper.proportionalSmearMah, totalProportionalSmearMah);
|
||||
addEntry("Excluding smeared", EntryType.POWER,
|
||||
requestedPowerConsumer.totalPowerMah, totalPowerMah);
|
||||
addEntry("CPU", EntryType.POWER,
|
||||
requestedPowerConsumer.cpuPowerMah, totalCpuPowerMah);
|
||||
requestedBatterySipper.totalPowerMah, totalPowerMah);
|
||||
if (requestedBatteryConsumer != null) {
|
||||
addEntry("CPU", EntryType.POWER,
|
||||
requestedBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU),
|
||||
totalCpuPowerMah);
|
||||
}
|
||||
addEntry("CPU (sipper)", EntryType.POWER,
|
||||
requestedBatterySipper.cpuPowerMah, totalCpuPowerMah);
|
||||
addEntry("System services", EntryType.POWER,
|
||||
requestedPowerConsumer.systemServiceCpuPowerMah, totalSystemServiceCpuPowerMah);
|
||||
requestedBatterySipper.systemServiceCpuPowerMah, totalSystemServiceCpuPowerMah);
|
||||
addEntry("Usage", EntryType.POWER,
|
||||
requestedPowerConsumer.usagePowerMah, totalUsagePowerMah);
|
||||
requestedBatterySipper.usagePowerMah, totalUsagePowerMah);
|
||||
addEntry("Wake lock", EntryType.POWER,
|
||||
requestedPowerConsumer.wakeLockPowerMah, totalWakeLockPowerMah);
|
||||
requestedBatterySipper.wakeLockPowerMah, totalWakeLockPowerMah);
|
||||
addEntry("Mobile radio", EntryType.POWER,
|
||||
requestedPowerConsumer.mobileRadioPowerMah, totalMobileRadioPowerMah);
|
||||
requestedBatterySipper.mobileRadioPowerMah, totalMobileRadioPowerMah);
|
||||
addEntry("WiFi", EntryType.POWER,
|
||||
requestedPowerConsumer.wifiPowerMah, totalWifiPowerMah);
|
||||
requestedBatterySipper.wifiPowerMah, totalWifiPowerMah);
|
||||
addEntry("Bluetooth", EntryType.POWER,
|
||||
requestedPowerConsumer.bluetoothPowerMah, totalBluetoothPowerMah);
|
||||
requestedBatterySipper.bluetoothPowerMah, totalBluetoothPowerMah);
|
||||
addEntry("GPS", EntryType.POWER,
|
||||
requestedPowerConsumer.gpsPowerMah, totalGpsPowerMah);
|
||||
requestedBatterySipper.gpsPowerMah, totalGpsPowerMah);
|
||||
addEntry("Camera", EntryType.POWER,
|
||||
requestedPowerConsumer.cameraPowerMah, totalCameraPowerMah);
|
||||
requestedBatterySipper.cameraPowerMah, totalCameraPowerMah);
|
||||
addEntry("Flashlight", EntryType.POWER,
|
||||
requestedPowerConsumer.flashlightPowerMah, totalFlashlightPowerMah);
|
||||
requestedBatterySipper.flashlightPowerMah, totalFlashlightPowerMah);
|
||||
addEntry("Sensors", EntryType.POWER,
|
||||
requestedPowerConsumer.sensorPowerMah, totalSensorPowerMah);
|
||||
requestedBatterySipper.sensorPowerMah, totalSensorPowerMah);
|
||||
addEntry("Audio", EntryType.POWER,
|
||||
requestedPowerConsumer.audioPowerMah, totalAudioPowerMah);
|
||||
requestedBatterySipper.audioPowerMah, totalAudioPowerMah);
|
||||
addEntry("Video", EntryType.POWER,
|
||||
requestedPowerConsumer.videoPowerMah, totalVideoPowerMah);
|
||||
requestedBatterySipper.videoPowerMah, totalVideoPowerMah);
|
||||
|
||||
addEntry("CPU time", EntryType.DURATION,
|
||||
requestedPowerConsumer.cpuTimeMs, totalCpuTimeMs);
|
||||
requestedBatterySipper.cpuTimeMs, totalCpuTimeMs);
|
||||
addEntry("CPU foreground time", EntryType.DURATION,
|
||||
requestedPowerConsumer.cpuFgTimeMs, totalCpuFgTimeMs);
|
||||
requestedBatterySipper.cpuFgTimeMs, totalCpuFgTimeMs);
|
||||
addEntry("Wake lock time", EntryType.DURATION,
|
||||
requestedPowerConsumer.wakeLockTimeMs, totalWakeLockTimeMs);
|
||||
requestedBatterySipper.wakeLockTimeMs, totalWakeLockTimeMs);
|
||||
addEntry("WiFi running time", EntryType.DURATION,
|
||||
requestedPowerConsumer.wifiRunningTimeMs, totalWifiRunningTimeMs);
|
||||
requestedBatterySipper.wifiRunningTimeMs, totalWifiRunningTimeMs);
|
||||
addEntry("Bluetooth time", EntryType.DURATION,
|
||||
requestedPowerConsumer.bluetoothRunningTimeMs, totalBluetoothRunningTimeMs);
|
||||
requestedBatterySipper.bluetoothRunningTimeMs, totalBluetoothRunningTimeMs);
|
||||
addEntry("GPS time", EntryType.DURATION,
|
||||
requestedPowerConsumer.gpsTimeMs, totalGpsTimeMs);
|
||||
requestedBatterySipper.gpsTimeMs, totalGpsTimeMs);
|
||||
addEntry("Camera time", EntryType.DURATION,
|
||||
requestedPowerConsumer.cameraTimeMs, totalCameraTimeMs);
|
||||
requestedBatterySipper.cameraTimeMs, totalCameraTimeMs);
|
||||
addEntry("Flashlight time", EntryType.DURATION,
|
||||
requestedPowerConsumer.flashlightTimeMs, totalFlashlightTimeMs);
|
||||
requestedBatterySipper.flashlightTimeMs, totalFlashlightTimeMs);
|
||||
addEntry("Audio time", EntryType.DURATION,
|
||||
requestedPowerConsumer.audioTimeMs, totalAudioTimeMs);
|
||||
requestedBatterySipper.audioTimeMs, totalAudioTimeMs);
|
||||
addEntry("Video time", EntryType.DURATION,
|
||||
requestedPowerConsumer.videoTimeMs, totalVideoTimeMs);
|
||||
requestedBatterySipper.videoTimeMs, totalVideoTimeMs);
|
||||
}
|
||||
|
||||
private boolean isSystemSipper(BatterySipper sipper) {
|
||||
@@ -272,4 +290,14 @@ public class PowerStatsData {
|
||||
public static String powerConsumerId(BatterySipper sipper) {
|
||||
return sipper.drainType + "|" + sipper.userId + "|" + sipper.getUid();
|
||||
}
|
||||
|
||||
public static String powerConsumerId(BatteryConsumer consumer) {
|
||||
if (consumer instanceof UidBatteryConsumer) {
|
||||
return BatterySipper.DrainType.APP + "|"
|
||||
+ UserHandle.getUserId(((UidBatteryConsumer) consumer).getUid()) + "|"
|
||||
+ ((UidBatteryConsumer) consumer).getUid();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.frameworks.core.powerstatsviewer;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
@@ -48,7 +50,8 @@ import java.util.Locale;
|
||||
public class PowerStatsViewerActivity extends ComponentActivity {
|
||||
private static final int POWER_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
|
||||
public static final String PREF_SELECTED_POWER_CONSUMER = "powerConsumerId";
|
||||
private static final String LOADER_ARG_POWER_CONSUMER_ID = "powerConsumerId";
|
||||
public static final int LOADER_BATTERY_STATS_HELPER = 0;
|
||||
public static final int LOADER_BATTERY_USAGE_STATS = 1;
|
||||
|
||||
private PowerStatsDataAdapter mPowerStatsDataAdapter;
|
||||
private Runnable mPowerStatsRefresh = this::periodicPowerStatsRefresh;
|
||||
@@ -63,6 +66,8 @@ public class PowerStatsViewerActivity extends ComponentActivity {
|
||||
private View mEmptyView;
|
||||
private ActivityResultLauncher<Void> mStartAppPicker = registerForActivityResult(
|
||||
PowerConsumerPickerActivity.CONTRACT, this::onApplicationSelected);
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@@ -130,19 +135,19 @@ public class PowerStatsViewerActivity extends ComponentActivity {
|
||||
}
|
||||
|
||||
private void loadPowerStats() {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(LOADER_ARG_POWER_CONSUMER_ID, mPowerConsumerId);
|
||||
LoaderManager.getInstance(this).restartLoader(0, args, new PowerStatsDataLoaderCallbacks());
|
||||
LoaderManager loaderManager = LoaderManager.getInstance(this);
|
||||
loaderManager.restartLoader(LOADER_BATTERY_STATS_HELPER, null,
|
||||
new BatteryStatsHelperLoaderCallbacks());
|
||||
loaderManager.restartLoader(LOADER_BATTERY_USAGE_STATS, null,
|
||||
new BatteryUsageStatsLoaderCallbacks());
|
||||
}
|
||||
|
||||
private static class PowerStatsDataLoader extends AsyncLoaderCompat<PowerStatsData> {
|
||||
private final String mPowerConsumerId;
|
||||
private static class BatteryStatsHelperLoader extends AsyncLoaderCompat<BatteryStatsHelper> {
|
||||
private final BatteryStatsHelper mBatteryStatsHelper;
|
||||
private final UserManager mUserManager;
|
||||
|
||||
PowerStatsDataLoader(Context context, String powerConsumerId) {
|
||||
BatteryStatsHelperLoader(Context context) {
|
||||
super(context);
|
||||
mPowerConsumerId = powerConsumerId;
|
||||
mUserManager = context.getSystemService(UserManager.class);
|
||||
mBatteryStatsHelper = new BatteryStatsHelper(context,
|
||||
false /* collectBatteryBroadcast */);
|
||||
@@ -151,68 +156,123 @@ public class PowerStatsViewerActivity extends ComponentActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PowerStatsData loadInBackground() {
|
||||
public BatteryStatsHelper loadInBackground() {
|
||||
mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
|
||||
UserHandle.myUserId());
|
||||
return new PowerStatsData(getContext(), mBatteryStatsHelper, mPowerConsumerId);
|
||||
return mBatteryStatsHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDiscardResult(PowerStatsData result) {
|
||||
protected void onDiscardResult(BatteryStatsHelper result) {
|
||||
}
|
||||
}
|
||||
|
||||
private class PowerStatsDataLoaderCallbacks implements LoaderCallbacks<PowerStatsData> {
|
||||
private class BatteryStatsHelperLoaderCallbacks implements LoaderCallbacks<BatteryStatsHelper> {
|
||||
@NonNull
|
||||
@Override
|
||||
public Loader<PowerStatsData> onCreateLoader(int id, Bundle args) {
|
||||
return new PowerStatsDataLoader(PowerStatsViewerActivity.this,
|
||||
args.getString(LOADER_ARG_POWER_CONSUMER_ID));
|
||||
public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
|
||||
return new BatteryStatsHelperLoader(PowerStatsViewerActivity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(@NonNull Loader<PowerStatsData> loader,
|
||||
PowerStatsData powerStatsData) {
|
||||
public void onLoadFinished(@NonNull Loader<BatteryStatsHelper> loader,
|
||||
BatteryStatsHelper batteryStatsHelper) {
|
||||
onBatteryStatsHelperLoaded(batteryStatsHelper);
|
||||
}
|
||||
|
||||
PowerConsumerInfoHelper.PowerConsumerInfo
|
||||
powerConsumerInfo = powerStatsData.getPowerConsumerInfo();
|
||||
if (powerConsumerInfo == null) {
|
||||
mTitleView.setText("Power consumer not found");
|
||||
@Override
|
||||
public void onLoaderReset(@NonNull Loader<BatteryStatsHelper> loader) {
|
||||
}
|
||||
}
|
||||
|
||||
private static class BatteryUsageStatsLoader extends AsyncLoaderCompat<BatteryUsageStats> {
|
||||
private final BatteryStatsManager mBatteryStatsManager;
|
||||
|
||||
BatteryUsageStatsLoader(Context context) {
|
||||
super(context);
|
||||
mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatteryUsageStats loadInBackground() {
|
||||
return mBatteryStatsManager.getBatteryUsageStats();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDiscardResult(BatteryUsageStats result) {
|
||||
}
|
||||
}
|
||||
|
||||
private class BatteryUsageStatsLoaderCallbacks implements LoaderCallbacks<BatteryUsageStats> {
|
||||
@NonNull
|
||||
@Override
|
||||
public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
|
||||
return new BatteryUsageStatsLoader(PowerStatsViewerActivity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(@NonNull Loader<BatteryUsageStats> loader,
|
||||
BatteryUsageStats batteryUsageStats) {
|
||||
onBatteryUsageStatsLoaded(batteryUsageStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(@NonNull Loader<BatteryUsageStats> loader) {
|
||||
}
|
||||
}
|
||||
|
||||
public void onBatteryStatsHelperLoaded(BatteryStatsHelper batteryStatsHelper) {
|
||||
mBatteryStatsHelper = batteryStatsHelper;
|
||||
onPowerStatsDataLoaded();
|
||||
}
|
||||
|
||||
private void onBatteryUsageStatsLoaded(BatteryUsageStats batteryUsageStats) {
|
||||
mBatteryUsageStats = batteryUsageStats;
|
||||
onPowerStatsDataLoaded();
|
||||
}
|
||||
|
||||
public void onPowerStatsDataLoaded() {
|
||||
if (mBatteryStatsHelper == null || mBatteryUsageStats == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PowerStatsData powerStatsData = new PowerStatsData(this, mBatteryStatsHelper,
|
||||
mBatteryUsageStats, mPowerConsumerId);
|
||||
|
||||
PowerConsumerInfoHelper.PowerConsumerInfo
|
||||
powerConsumerInfo = powerStatsData.getPowerConsumerInfo();
|
||||
if (powerConsumerInfo == null) {
|
||||
mTitleView.setText("Power consumer not found");
|
||||
mPackagesView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mTitleView.setText(powerConsumerInfo.label);
|
||||
if (powerConsumerInfo.details != null) {
|
||||
mDetailsView.setText(powerConsumerInfo.details);
|
||||
mDetailsView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mDetailsView.setVisibility(View.GONE);
|
||||
}
|
||||
mIconView.setImageDrawable(
|
||||
powerConsumerInfo.iconInfo.loadIcon(getPackageManager()));
|
||||
|
||||
if (powerConsumerInfo.packages != null) {
|
||||
mPackagesView.setText(powerConsumerInfo.packages);
|
||||
mPackagesView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mPackagesView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mTitleView.setText(powerConsumerInfo.label);
|
||||
if (powerConsumerInfo.details != null) {
|
||||
mDetailsView.setText(powerConsumerInfo.details);
|
||||
mDetailsView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mDetailsView.setVisibility(View.GONE);
|
||||
}
|
||||
mIconView.setImageDrawable(
|
||||
powerConsumerInfo.iconInfo.loadIcon(getPackageManager()));
|
||||
|
||||
if (powerConsumerInfo.packages != null) {
|
||||
mPackagesView.setText(powerConsumerInfo.packages);
|
||||
mPackagesView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mPackagesView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
mPowerStatsDataAdapter.setEntries(powerStatsData.getEntries());
|
||||
if (powerStatsData.getEntries().isEmpty()) {
|
||||
mEmptyView.setVisibility(View.VISIBLE);
|
||||
mPowerStatsDataView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mEmptyView.setVisibility(View.GONE);
|
||||
mPowerStatsDataView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mLoadingView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(@NonNull Loader<PowerStatsData> loader) {
|
||||
mPowerStatsDataAdapter.setEntries(powerStatsData.getEntries());
|
||||
if (powerStatsData.getEntries().isEmpty()) {
|
||||
mEmptyView.setVisibility(View.VISIBLE);
|
||||
mPowerStatsDataView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mEmptyView.setVisibility(View.GONE);
|
||||
mPowerStatsDataView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mLoadingView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private static class PowerStatsDataAdapter extends
|
||||
|
||||
Reference in New Issue
Block a user