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

Commit db88c994 authored by ykhung's avatar ykhung
Browse files

Load application icon and label from package manager if available

Bug: 185187669
Test: make SettingsRoboTests
Test: make SettingsGoogleRoboTests
Change-Id: Id612f0f1db51d538abb41fc711b9350d9a147cb8
parent 0d54b75b
Loading
Loading
Loading
Loading
+72 −2
Original line number Diff line number Diff line
@@ -13,29 +13,49 @@
 */
package com.android.settings.fuelgauge;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.util.Log;

import java.time.Duration;
import java.util.Comparator;

/** A container class to carry battery data in a specific time slot. */
public final class BatteryDiffEntry {
    private static final String TAG = "BatteryDiffEntry";

    /** A comparator for {@link BatteryDiffEntry} based on consumed percentage. */
    public static final Comparator<BatteryDiffEntry> COMPARATOR =
            (a, b) -> Double.compare(b.getPercentOfTotal(), a.getPercentOfTotal());

    public long mForegroundUsageTimeInMs;
    public long mBackgroundUsageTimeInMs;
    public double mConsumePower;
    // A BatteryHistEntry corresponding to this diff usage data.
    public final BatteryHistEntry mBatteryHistEntry;

    private double mTotalConsumePower;
    private double mPercentOfTotal;

    private Context mContext;
    private String mAppLabel = null;
    private Drawable mAppIcon = null;
    private boolean mIsLoaded = false;

    public BatteryDiffEntry(
            Context context,
            long foregroundUsageTimeInMs,
            long backgroundUsageTimeInMs,
            double consumePower,
            BatteryHistEntry batteryHistEntry) {
        mContext = context;
        mConsumePower = consumePower;
        mForegroundUsageTimeInMs = foregroundUsageTimeInMs;
        mBackgroundUsageTimeInMs = backgroundUsageTimeInMs;
        mConsumePower = consumePower;
        mBatteryHistEntry = batteryHistEntry;
    }

@@ -54,12 +74,62 @@ public final class BatteryDiffEntry {
    /** Clones a new instance. */
    public BatteryDiffEntry clone() {
        return new BatteryDiffEntry(
            this.mContext,
            this.mForegroundUsageTimeInMs,
            this.mBackgroundUsageTimeInMs,
            this.mConsumePower,
            this.mBatteryHistEntry /*same instance*/);
    }

    /** Gets the app label name for this entry. */
    public String getAppLabel() {
        loadLabelAndIcon();
        return mAppLabel;
    }

    /** Gets the app icon {@link Drawable} for this entry. */
    public Drawable getAppIcon() {
        loadLabelAndIcon();
        return mAppIcon;
    }

    private void loadLabelAndIcon() {
        if (mIsLoaded) {
            return;
        }
        mIsLoaded = true;
        // Loads application icon and label based on consumer type.
        switch (mBatteryHistEntry.mConsumerType) {
            case ConvertUtils.CONSUMER_TYPE_USER_BATTERY:
                final BatteryEntry.NameAndIcon nameAndIconForUser =
                    BatteryEntry.getNameAndIconFromUserId(
                        mContext, (int) mBatteryHistEntry.mUserId);
                if (nameAndIconForUser != null) {
                    mAppIcon = nameAndIconForUser.icon;
                    mAppLabel = nameAndIconForUser.name;
                }
                break;
            case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
                final BatteryEntry.NameAndIcon nameAndIconForSystem =
                    BatteryEntry.getNameAndIconFromDrainType(
                        mContext, mBatteryHistEntry.mDrainType);
                if (nameAndIconForSystem != null) {
                    mAppLabel = nameAndIconForSystem.name;
                    if (nameAndIconForSystem.iconId != 0) {
                        mAppIcon = mContext.getDrawable(nameAndIconForSystem.iconId);
                    }
                }
                break;
            case ConvertUtils.CONSUMER_TYPE_UID_BATTERY:
                loadNameAndIconForUid();
                break;
        }
    }

    private void loadNameAndIconForUid() {
        // TODO(b/185187669) fetch label and icon for UID battery type
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder()
+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import android.annotation.IntDef;
import android.content.ContentValues;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.content.Context;
import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserBatteryConsumer;
@@ -138,6 +139,7 @@ public final class ConvertUtils {

    /** Gets indexed battery usage data for each corresponding time slot. */
    public static Map<Integer, List<BatteryDiffEntry>> getIndexedUsageMap(
            final Context context,
            final int timeSlotSize,
            final long[] batteryHistoryKeys,
            final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
@@ -234,6 +236,7 @@ public final class ConvertUtils {
                }
                batteryDiffEntryList.add(
                    new BatteryDiffEntry(
                        context,
                        foregroundUsageTimeInMs,
                        backgroundUsageTimeInMs,
                        consumePower,
+86 −0
Original line number Diff line number Diff line
@@ -17,17 +17,45 @@ package com.android.settings.fuelgauge;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

import android.content.Context;
import android.content.ContentValues;
import android.os.SystemBatteryConsumer;
import android.os.UserManager;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@RunWith(RobolectricTestRunner.class)
public final class BatteryDiffEntryTest {

    private Context mContext;
    @Mock
    private UserManager mockUserManager;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = spy(RuntimeEnvironment.application);
        doReturn(mockUserManager).when(mContext).getSystemService(UserManager.class);
    }

    @Test
    public void testSetTotalConsumePower_returnExpectedResult() {
        final BatteryDiffEntry entry =
            new BatteryDiffEntry(
                mContext,
                /*foregroundUsageTimeInMs=*/ 10001L,
                /*backgroundUsageTimeInMs=*/ 20002L,
                /*consumePower=*/ 22.0,
@@ -41,6 +69,7 @@ public final class BatteryDiffEntryTest {
    public void testSetTotalConsumePower_setZeroValue_returnsZeroValue() {
        final BatteryDiffEntry entry =
            new BatteryDiffEntry(
                mContext,
                /*foregroundUsageTimeInMs=*/ 10001L,
                /*backgroundUsageTimeInMs=*/ 20002L,
                /*consumePower=*/ 22.0,
@@ -49,4 +78,61 @@ public final class BatteryDiffEntryTest {

        assertThat(entry.getPercentOfTotal()).isEqualTo(0);
    }

    @Test
    public void testComparator_sortCollectionsInDescOrder() {
        final List<BatteryDiffEntry> entryList = new ArrayList<>();
        // Generates fake testing data.
        entryList.add(createBatteryDiffEntry(30, /*batteryHistEntry=*/ null));
        entryList.add(createBatteryDiffEntry(20, /*batteryHistEntry=*/ null));
        entryList.add(createBatteryDiffEntry(10, /*batteryHistEntry=*/ null));
        Collections.sort(entryList, BatteryDiffEntry.COMPARATOR);

        assertThat(entryList.get(0).getPercentOfTotal()).isEqualTo(30);
        assertThat(entryList.get(1).getPercentOfTotal()).isEqualTo(20);
        assertThat(entryList.get(2).getPercentOfTotal()).isEqualTo(10);
    }

    @Test
    public void testLoadLabelAndIcon_forSystemBattery_returnExpectedResult() {
        // Generates fake testing data.
        final ContentValues values = new ContentValues();
        values.put("consumerType",
            Integer.valueOf(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY));
        values.put("drainType",
            Integer.valueOf(SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY));
        final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);

        final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);

        assertThat(entry.getAppLabel()).isEqualTo("Ambient display");
    }

    @Test
    public void testLoadLabelAndIcon_forUserBattery_returnExpectedResult() {
        doReturn(null).when(mockUserManager).getUserInfo(1001);
        // Generates fake testing data.
        final ContentValues values = new ContentValues();
        values.put("consumerType",
            Integer.valueOf(ConvertUtils.CONSUMER_TYPE_USER_BATTERY));
        values.put("userId", Integer.valueOf(1001));
        final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);

        final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);

        assertThat(entry.getAppLabel()).isEqualTo("Removed user");
        assertThat(entry.getAppIcon()).isNull();
    }

    private BatteryDiffEntry createBatteryDiffEntry(
        double consumePower, BatteryHistEntry batteryHistEntry) {
        final BatteryDiffEntry entry = new BatteryDiffEntry(
            mContext,
            /*foregroundUsageTimeInMs=*/ 0,
            /*backgroundUsageTimeInMs=*/ 0,
            consumePower,
            batteryHistEntry);
        entry.setTotalConsumePower(100.0);
        return entry;
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -19,8 +19,10 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.spy;

import android.content.ContentValues;
import android.content.Context;
import android.os.BatteryConsumer;
import android.os.BatteryManager;
import android.os.BatteryUsageStats;
@@ -47,6 +49,7 @@ import java.util.TimeZone;
@RunWith(RobolectricTestRunner.class)
public final class ConvertUtilsTest {

    private Context mContext;
    @Mock
    private BatteryUsageStats mBatteryUsageStats;
    @Mock
@@ -63,6 +66,7 @@ public final class ConvertUtilsTest {
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = spy(RuntimeEnvironment.application);
    }

    @Test
@@ -208,7 +212,7 @@ public final class ConvertUtilsTest {

        final Map<Integer, List<BatteryDiffEntry>> resultMap =
            ConvertUtils.getIndexedUsageMap(
                timeSlotSize, batteryHistoryKeys, batteryHistoryMap);
                mContext, timeSlotSize, batteryHistoryKeys, batteryHistoryMap);

        assertThat(resultMap).hasSize(3);
        // Verifies the first timestamp result.