Load application icon and label from package manager if available

Bug: 185187669
Test: make SettingsRoboTests
Test: make SettingsGoogleRoboTests
Change-Id: Id612f0f1db51d538abb41fc711b9350d9a147cb8
This commit is contained in:
ykhung
2021-04-13 17:02:34 +08:00
parent 0d54b75b2c
commit db88c994b4
4 changed files with 166 additions and 3 deletions

View File

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

View File

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

View File

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

View File

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