Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9a4ec89 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

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
parent ac73ea0c
Loading
Loading
Loading
Loading
+65 −37
Original line number Diff line number Diff line
@@ -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;

        for (BatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
            if (powerConsumerId(consumer).equals(powerConsumerId)) {
                requestedBatteryConsumer = consumer;
                break;
            }
        }

        if (requestedPowerConsumer == null) {
        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);
                requestedBatterySipper.totalPowerMah, totalPowerMah);
        if (requestedBatteryConsumer != null) {
            addEntry("CPU", EntryType.POWER,
                requestedPowerConsumer.cpuPowerMah, totalCpuPowerMah);
                    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 "";
        }
    }
}
+108 −48
Original line number Diff line number Diff line
@@ -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,28 +156,88 @@ 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<BatteryStatsHelper> loader,
                BatteryStatsHelper batteryStatsHelper) {
            onBatteryStatsHelperLoaded(batteryStatsHelper);
        }

        @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
        public void onLoadFinished(@NonNull Loader<PowerStatsData> loader,
                PowerStatsData powerStatsData) {
        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();
@@ -210,11 +275,6 @@ public class PowerStatsViewerActivity extends ComponentActivity {
        mLoadingView.setVisibility(View.GONE);
    }

        @Override
        public void onLoaderReset(@NonNull Loader<PowerStatsData> loader) {
        }
    }

    private static class PowerStatsDataAdapter extends
            RecyclerView.Adapter<PowerStatsDataAdapter.ViewHolder> {
        public static class ViewHolder extends RecyclerView.ViewHolder {