From f9a4ec89dcd9e037304538da6552f4738f79eb59 Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Thu, 3 Dec 2020 19:06:17 -0800 Subject: [PATCH] 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 --- .../core/powerstatsviewer/PowerStatsData.java | 102 +++++++---- .../PowerStatsViewerActivity.java | 162 ++++++++++++------ 2 files changed, 176 insertions(+), 88 deletions(-) diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java index 7aeb86ae0cb17..6d8e2c59be972 100644 --- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java +++ b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java @@ -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 mEntries = new ArrayList<>(); public PowerStatsData(Context context, BatteryStatsHelper batteryStatsHelper, - String powerConsumerId) { + BatteryUsageStats batteryUsageStats, String powerConsumerId) { List 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 ""; + } + } } diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java index 05679101f86a8..91533913e35d5 100644 --- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java +++ b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java @@ -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 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 { - private final String mPowerConsumerId; + private static class BatteryStatsHelperLoader extends AsyncLoaderCompat { 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 { + private class BatteryStatsHelperLoaderCallbacks implements LoaderCallbacks { @NonNull @Override - public Loader onCreateLoader(int id, Bundle args) { - return new PowerStatsDataLoader(PowerStatsViewerActivity.this, - args.getString(LOADER_ARG_POWER_CONSUMER_ID)); + public Loader onCreateLoader(int id, Bundle args) { + return new BatteryStatsHelperLoader(PowerStatsViewerActivity.this); } @Override - public void onLoadFinished(@NonNull Loader loader, - PowerStatsData powerStatsData) { + public void onLoadFinished(@NonNull Loader 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 loader) { + } + } + + private static class BatteryUsageStatsLoader extends AsyncLoaderCompat { + 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 { + @NonNull + @Override + public Loader onCreateLoader(int id, Bundle args) { + return new BatteryUsageStatsLoader(PowerStatsViewerActivity.this); + } + + @Override + public void onLoadFinished(@NonNull Loader loader, + BatteryUsageStats batteryUsageStats) { + onBatteryUsageStatsLoaded(batteryUsageStats); + } + + @Override + public void onLoaderReset(@NonNull Loader 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 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