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:
@@ -13,29 +13,49 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.fuelgauge;
|
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.time.Duration;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
/** A container class to carry battery data in a specific time slot. */
|
/** A container class to carry battery data in a specific time slot. */
|
||||||
public final class BatteryDiffEntry {
|
public final class BatteryDiffEntry {
|
||||||
private static final String TAG = "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 mForegroundUsageTimeInMs;
|
||||||
public long mBackgroundUsageTimeInMs;
|
public long mBackgroundUsageTimeInMs;
|
||||||
public double mConsumePower;
|
public double mConsumePower;
|
||||||
// A BatteryHistEntry corresponding to this diff usage data.
|
// A BatteryHistEntry corresponding to this diff usage data.
|
||||||
public final BatteryHistEntry mBatteryHistEntry;
|
public final BatteryHistEntry mBatteryHistEntry;
|
||||||
|
|
||||||
private double mTotalConsumePower;
|
private double mTotalConsumePower;
|
||||||
private double mPercentOfTotal;
|
private double mPercentOfTotal;
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private String mAppLabel = null;
|
||||||
|
private Drawable mAppIcon = null;
|
||||||
|
private boolean mIsLoaded = false;
|
||||||
|
|
||||||
public BatteryDiffEntry(
|
public BatteryDiffEntry(
|
||||||
|
Context context,
|
||||||
long foregroundUsageTimeInMs,
|
long foregroundUsageTimeInMs,
|
||||||
long backgroundUsageTimeInMs,
|
long backgroundUsageTimeInMs,
|
||||||
double consumePower,
|
double consumePower,
|
||||||
BatteryHistEntry batteryHistEntry) {
|
BatteryHistEntry batteryHistEntry) {
|
||||||
|
mContext = context;
|
||||||
|
mConsumePower = consumePower;
|
||||||
mForegroundUsageTimeInMs = foregroundUsageTimeInMs;
|
mForegroundUsageTimeInMs = foregroundUsageTimeInMs;
|
||||||
mBackgroundUsageTimeInMs = backgroundUsageTimeInMs;
|
mBackgroundUsageTimeInMs = backgroundUsageTimeInMs;
|
||||||
mConsumePower = consumePower;
|
|
||||||
mBatteryHistEntry = batteryHistEntry;
|
mBatteryHistEntry = batteryHistEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,12 +74,62 @@ public final class BatteryDiffEntry {
|
|||||||
/** Clones a new instance. */
|
/** Clones a new instance. */
|
||||||
public BatteryDiffEntry clone() {
|
public BatteryDiffEntry clone() {
|
||||||
return new BatteryDiffEntry(
|
return new BatteryDiffEntry(
|
||||||
|
this.mContext,
|
||||||
this.mForegroundUsageTimeInMs,
|
this.mForegroundUsageTimeInMs,
|
||||||
this.mBackgroundUsageTimeInMs,
|
this.mBackgroundUsageTimeInMs,
|
||||||
this.mConsumePower,
|
this.mConsumePower,
|
||||||
this.mBatteryHistEntry /*same instance*/);
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder builder = new StringBuilder()
|
final StringBuilder builder = new StringBuilder()
|
||||||
|
@@ -17,6 +17,7 @@ import android.annotation.IntDef;
|
|||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.os.BatteryConsumer;
|
import android.os.BatteryConsumer;
|
||||||
import android.os.BatteryUsageStats;
|
import android.os.BatteryUsageStats;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.SystemBatteryConsumer;
|
import android.os.SystemBatteryConsumer;
|
||||||
import android.os.UidBatteryConsumer;
|
import android.os.UidBatteryConsumer;
|
||||||
import android.os.UserBatteryConsumer;
|
import android.os.UserBatteryConsumer;
|
||||||
@@ -138,6 +139,7 @@ public final class ConvertUtils {
|
|||||||
|
|
||||||
/** Gets indexed battery usage data for each corresponding time slot. */
|
/** Gets indexed battery usage data for each corresponding time slot. */
|
||||||
public static Map<Integer, List<BatteryDiffEntry>> getIndexedUsageMap(
|
public static Map<Integer, List<BatteryDiffEntry>> getIndexedUsageMap(
|
||||||
|
final Context context,
|
||||||
final int timeSlotSize,
|
final int timeSlotSize,
|
||||||
final long[] batteryHistoryKeys,
|
final long[] batteryHistoryKeys,
|
||||||
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
|
final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
|
||||||
@@ -234,6 +236,7 @@ public final class ConvertUtils {
|
|||||||
}
|
}
|
||||||
batteryDiffEntryList.add(
|
batteryDiffEntryList.add(
|
||||||
new BatteryDiffEntry(
|
new BatteryDiffEntry(
|
||||||
|
context,
|
||||||
foregroundUsageTimeInMs,
|
foregroundUsageTimeInMs,
|
||||||
backgroundUsageTimeInMs,
|
backgroundUsageTimeInMs,
|
||||||
consumePower,
|
consumePower,
|
||||||
|
@@ -17,17 +17,45 @@ package com.android.settings.fuelgauge;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public final class BatteryDiffEntryTest {
|
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
|
@Test
|
||||||
public void testSetTotalConsumePower_returnExpectedResult() {
|
public void testSetTotalConsumePower_returnExpectedResult() {
|
||||||
final BatteryDiffEntry entry =
|
final BatteryDiffEntry entry =
|
||||||
new BatteryDiffEntry(
|
new BatteryDiffEntry(
|
||||||
|
mContext,
|
||||||
/*foregroundUsageTimeInMs=*/ 10001L,
|
/*foregroundUsageTimeInMs=*/ 10001L,
|
||||||
/*backgroundUsageTimeInMs=*/ 20002L,
|
/*backgroundUsageTimeInMs=*/ 20002L,
|
||||||
/*consumePower=*/ 22.0,
|
/*consumePower=*/ 22.0,
|
||||||
@@ -41,6 +69,7 @@ public final class BatteryDiffEntryTest {
|
|||||||
public void testSetTotalConsumePower_setZeroValue_returnsZeroValue() {
|
public void testSetTotalConsumePower_setZeroValue_returnsZeroValue() {
|
||||||
final BatteryDiffEntry entry =
|
final BatteryDiffEntry entry =
|
||||||
new BatteryDiffEntry(
|
new BatteryDiffEntry(
|
||||||
|
mContext,
|
||||||
/*foregroundUsageTimeInMs=*/ 10001L,
|
/*foregroundUsageTimeInMs=*/ 10001L,
|
||||||
/*backgroundUsageTimeInMs=*/ 20002L,
|
/*backgroundUsageTimeInMs=*/ 20002L,
|
||||||
/*consumePower=*/ 22.0,
|
/*consumePower=*/ 22.0,
|
||||||
@@ -49,4 +78,61 @@ public final class BatteryDiffEntryTest {
|
|||||||
|
|
||||||
assertThat(entry.getPercentOfTotal()).isEqualTo(0);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,8 +19,10 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.BatteryConsumer;
|
import android.os.BatteryConsumer;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.os.BatteryUsageStats;
|
import android.os.BatteryUsageStats;
|
||||||
@@ -47,6 +49,7 @@ import java.util.TimeZone;
|
|||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public final class ConvertUtilsTest {
|
public final class ConvertUtilsTest {
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
@Mock
|
@Mock
|
||||||
private BatteryUsageStats mBatteryUsageStats;
|
private BatteryUsageStats mBatteryUsageStats;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -63,6 +66,7 @@ public final class ConvertUtilsTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -208,7 +212,7 @@ public final class ConvertUtilsTest {
|
|||||||
|
|
||||||
final Map<Integer, List<BatteryDiffEntry>> resultMap =
|
final Map<Integer, List<BatteryDiffEntry>> resultMap =
|
||||||
ConvertUtils.getIndexedUsageMap(
|
ConvertUtils.getIndexedUsageMap(
|
||||||
timeSlotSize, batteryHistoryKeys, batteryHistoryMap);
|
mContext, timeSlotSize, batteryHistoryKeys, batteryHistoryMap);
|
||||||
|
|
||||||
assertThat(resultMap).hasSize(3);
|
assertThat(resultMap).hasSize(3);
|
||||||
// Verifies the first timestamp result.
|
// Verifies the first timestamp result.
|
||||||
|
Reference in New Issue
Block a user