Merge "Initial integration of BatteryUsageStats into PowerStatsViewer"

This commit is contained in:
TreeHugger Robot
2020-12-11 03:12:21 +00:00
committed by Android (Google) Code Review
2 changed files with 176 additions and 88 deletions

View File

@@ -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 "";
}
}
}

View File

@@ -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