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

Commit 97b3325e authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Begin transition from BatteryStatsHelper to BatteryUsageStats API.

For now, keep both BatteryStatsHelper and BatteryUsageStats in play.
The plan is to transition from the former to the latter, one usage
at a time.  When all is said and done, all references to
BatteryStatsHelper will be gone.

Bug: 173745486
Test: atest --host SettingsRoboTests

Change-Id: I37e1dfff0043b1845992f18d72067bb547bb69ff
parent 3deffe9f
Loading
Loading
Loading
Loading
+91 −23
Original line number Diff line number Diff line
@@ -19,9 +19,12 @@ package com.android.settings.applications.appinfo;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.Bundle;
import android.os.UidBatteryConsumer;
import android.os.UserManager;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
@@ -36,6 +39,7 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
import com.android.settings.fuelgauge.BatteryEntry;
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
import com.android.settings.fuelgauge.BatteryUsageStatsLoader;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -46,11 +50,19 @@ import java.util.ArrayList;
import java.util.List;

public class AppBatteryPreferenceController extends BasePreferenceController
        implements LoaderManager.LoaderCallbacks<BatteryStatsHelper>,
        LifecycleObserver, OnResume, OnPause {
        implements LifecycleObserver, OnResume, OnPause {

    private static final String KEY_BATTERY = "battery";

    // TODO(b/180630447): switch to BatteryUsageStatsLoader and remove all references to
    // BatteryStatsHelper and BatterySipper
    @VisibleForTesting
    final BatteryStatsHelperLoaderCallbacks mBatteryStatsHelperLoaderCallbacks =
            new BatteryStatsHelperLoaderCallbacks();
    @VisibleForTesting
    final BatteryUsageStatsLoaderCallbacks mBatteryUsageStatsLoaderCallbacks =
            new BatteryUsageStatsLoaderCallbacks();

    @VisibleForTesting
    BatterySipper mSipper;
    @VisibleForTesting
@@ -58,6 +70,11 @@ public class AppBatteryPreferenceController extends BasePreferenceController
    @VisibleForTesting
    BatteryUtils mBatteryUtils;

    @VisibleForTesting
    BatteryUsageStats mBatteryUsageStats;
    @VisibleForTesting
    UidBatteryConsumer mUidBatteryConsumer;

    private Preference mPreference;
    private final AppInfoDashboardFragment mParent;
    private String mBatteryPercent;
@@ -96,7 +113,8 @@ public class AppBatteryPreferenceController extends BasePreferenceController
        if (isBatteryStatsAvailable()) {
            final UserManager userManager =
                    (UserManager) mContext.getSystemService(Context.USER_SERVICE);
            final BatteryEntry entry = new BatteryEntry(mContext, null, userManager, mSipper);
            final BatteryEntry entry = new BatteryEntry(mContext, null, userManager, mSipper,
                    mUidBatteryConsumer);
            entry.defaultPackageName = mPackageName;
            AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent,
                    mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, mBatteryPercent);
@@ -110,48 +128,48 @@ public class AppBatteryPreferenceController extends BasePreferenceController
    @Override
    public void onResume() {
        mParent.getLoaderManager().restartLoader(
                mParent.LOADER_BATTERY, Bundle.EMPTY, this);
                AppInfoDashboardFragment.LOADER_BATTERY, Bundle.EMPTY,
                mBatteryStatsHelperLoaderCallbacks);
        mParent.getLoaderManager().restartLoader(
                AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS, Bundle.EMPTY,
                mBatteryUsageStatsLoaderCallbacks);
    }

    @Override
    public void onPause() {
        mParent.getLoaderManager().destroyLoader(mParent.LOADER_BATTERY);
        mParent.getLoaderManager().destroyLoader(AppInfoDashboardFragment.LOADER_BATTERY);
        mParent.getLoaderManager().destroyLoader(
                AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS);
    }

    @Override
    public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
        return new BatteryStatsHelperLoader(mContext);
    private void onLoadFinished() {
        // Wait for both loaders to finish before proceeding.
        if (mBatteryHelper == null || mBatteryUsageStats == null) {
            return;
        }

    @Override
    public void onLoadFinished(Loader<BatteryStatsHelper> loader,
            BatteryStatsHelper batteryHelper) {
        mBatteryHelper = batteryHelper;
        final PackageInfo packageInfo = mParent.getPackageInfo();
        if (packageInfo != null) {
            mSipper = findTargetSipper(batteryHelper, packageInfo.applicationInfo.uid);
            mSipper = findTargetSipper(mBatteryHelper, packageInfo.applicationInfo.uid);
            mUidBatteryConsumer = findTargetUidBatteryConsumer(mBatteryUsageStats,
                    packageInfo.applicationInfo.uid);
            if (mParent.getActivity() != null) {
                updateBattery();
            }
        }
    }

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

    @VisibleForTesting
    void updateBattery() {
        mPreference.setEnabled(true);
        if (isBatteryStatsAvailable()) {
            final int dischargeAmount = mBatteryHelper.getStats().getDischargeAmount(
                    BatteryStats.STATS_SINCE_CHARGED);
            final int dischargePercentage = mBatteryUsageStats.getDischargePercentage();

            final List<BatterySipper> usageList = new ArrayList<>(mBatteryHelper.getUsageList());
            final double hiddenAmount = mBatteryUtils.removeHiddenBatterySippers(usageList);
            final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent(
                    mSipper.totalPowerMah, mBatteryHelper.getTotalPower(), hiddenAmount,
                    dischargeAmount);
                    mUidBatteryConsumer.getConsumedPower(), mBatteryUsageStats.getConsumedPower(),
                    hiddenAmount, dischargePercentage);
            mBatteryPercent = Utils.formatPercentage(percentOfMax);
            mPreference.setSummary(mContext.getString(R.string.battery_summary, mBatteryPercent));
        } else {
@@ -161,7 +179,7 @@ public class AppBatteryPreferenceController extends BasePreferenceController

    @VisibleForTesting
    boolean isBatteryStatsAvailable() {
        return mBatteryHelper != null && mSipper != null;
        return mBatteryHelper != null && mSipper != null && mUidBatteryConsumer != null;
    }

    @VisibleForTesting
@@ -176,4 +194,54 @@ public class AppBatteryPreferenceController extends BasePreferenceController
        return null;
    }

    @VisibleForTesting
    UidBatteryConsumer findTargetUidBatteryConsumer(BatteryUsageStats batteryUsageStats, int uid) {
        final List<UidBatteryConsumer> usageList = batteryUsageStats.getUidBatteryConsumers();
        for (int i = 0, size = usageList.size(); i < size; i++) {
            final UidBatteryConsumer consumer = usageList.get(i);
            if (consumer.getUid() == uid) {
                return consumer;
            }
        }
        return null;
    }

    private class BatteryStatsHelperLoaderCallbacks
            implements LoaderManager.LoaderCallbacks<BatteryStatsHelper> {
        @Override
        public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
            return new BatteryStatsHelperLoader(mContext);
        }

        @Override
        public void onLoadFinished(Loader<BatteryStatsHelper> loader,
                BatteryStatsHelper batteryHelper) {
            mBatteryHelper = batteryHelper;
            AppBatteryPreferenceController.this.onLoadFinished();
        }

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

    private class BatteryUsageStatsLoaderCallbacks
            implements LoaderManager.LoaderCallbacks<BatteryUsageStats> {
        @Override
        @NonNull
        public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
            return new BatteryUsageStatsLoader(mContext);
        }

        @Override
        public void onLoadFinished(Loader<BatteryUsageStats> loader,
                BatteryUsageStats batteryUsageStats) {
            mBatteryUsageStats = batteryUsageStats;
            AppBatteryPreferenceController.this.onLoadFinished();
        }

        @Override
        public void onLoaderReset(Loader<BatteryUsageStats> loader) {
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
    static final int LOADER_CHART_DATA = 2;
    static final int LOADER_STORAGE = 3;
    static final int LOADER_BATTERY = 4;
    static final int LOADER_BATTERY_USAGE_STATS = 5;

    public static final String ARG_PACKAGE_NAME = "package";
    public static final String ARG_PACKAGE_UID = "uid";
+1 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
                }
                final UserHandle userHandle = new UserHandle(UserHandle.getUserId(sipper.getUid()));
                final BatteryEntry entry = new BatteryEntry(mActivity, mHandler, mUserManager,
                        sipper);
                        sipper, null);
                final Drawable badgedIcon = mUserManager.getBadgedIconForUser(entry.getIcon(),
                        userHandle);
                final CharSequence contentDescription = mUserManager.getBadgedLabelForUser(
+34 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Process;
import android.os.RemoteException;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
@@ -122,6 +123,7 @@ public class BatteryEntry {

    public final Context context;
    public final BatterySipper sipper;
    public final UidBatteryConsumer uidBatteryConsumer;

    public String name;
    public Drawable icon;
@@ -134,10 +136,41 @@ public class BatteryEntry {
        Drawable icon;
    }

    public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper) {
    public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper,
            UidBatteryConsumer uidBatteryConsumer) {
        sHandler = handler;
        this.context = context;
        this.sipper = sipper;
        this.uidBatteryConsumer = uidBatteryConsumer;

        // This condition is met when BatteryEntry is initialized from BatteryUsageStats.
        // Once the conversion from BatteryStatsHelper is completed, the condition will
        // always be true and can be removed.
        if (uidBatteryConsumer != null) {
            PackageManager pm = context.getPackageManager();
            int uid = uidBatteryConsumer.getUid();
            String[] packages = pm.getPackagesForUid(uid);
            // Apps should only have one package
            if (packages == null || packages.length != 1) {
                name = uidBatteryConsumer.getPackageWithHighestDrain();
            } else {
                defaultPackageName = packages[0];
                try {
                    ApplicationInfo appInfo =
                            pm.getApplicationInfo(defaultPackageName, 0 /* no flags */);
                    name = pm.getApplicationLabel(appInfo).toString();
                } catch (NameNotFoundException e) {
                    Log.d(TAG, "PackageManager failed to retrieve ApplicationInfo for: "
                            + defaultPackageName);
                    name = defaultPackageName;
                }
            }
            if ((name == null || iconId == 0) && uid != 0) {
                getQuickNameIconForUid(uid);
            }
            return;
        }

        switch (sipper.drainType) {
            case IDLE:
                name = context.getResources().getString(R.string.power_idle);
+44 −0
Original line number Diff line number Diff line
/*
 * 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.settings.fuelgauge;

import android.content.Context;
import android.os.BatteryStatsManager;
import android.os.BatteryUsageStats;

import com.android.settingslib.utils.AsyncLoaderCompat;

/**
 * Loader to get new {@link BatteryUsageStats} in the background
 */
public class BatteryUsageStatsLoader extends AsyncLoaderCompat<BatteryUsageStats> {
    private final BatteryStatsManager mBatteryStatsManager;

    public BatteryUsageStatsLoader(Context context) {
        super(context);
        mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
    }

    @Override
    public BatteryUsageStats loadInBackground() {
        return mBatteryStatsManager.getBatteryUsageStats();
    }

    @Override
    protected void onDiscardResult(BatteryUsageStats result) {
    }
}
Loading