Load application icon and label for UID battery consumer type
Bug: 185187669 Test: make SettingsRoboTests Test: make SettingsGoogleRoboTests Change-Id: Idb77a1bd48f7f4b66b86ff12c166a204d17bd9ec
This commit is contained in:
@@ -22,6 +22,8 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
@@ -42,9 +44,11 @@ public final class BatteryDiffEntry {
|
|||||||
private double mPercentOfTotal;
|
private double mPercentOfTotal;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private String mAppLabel = null;
|
private String mDefaultPackageName = null;
|
||||||
private Drawable mAppIcon = null;
|
|
||||||
private boolean mIsLoaded = false;
|
@VisibleForTesting String mAppLabel = null;
|
||||||
|
@VisibleForTesting Drawable mAppIcon = null;
|
||||||
|
@VisibleForTesting boolean mIsLoaded = false;
|
||||||
|
|
||||||
public BatteryDiffEntry(
|
public BatteryDiffEntry(
|
||||||
Context context,
|
Context context,
|
||||||
@@ -84,13 +88,28 @@ public final class BatteryDiffEntry {
|
|||||||
/** Gets the app label name for this entry. */
|
/** Gets the app label name for this entry. */
|
||||||
public String getAppLabel() {
|
public String getAppLabel() {
|
||||||
loadLabelAndIcon();
|
loadLabelAndIcon();
|
||||||
return mAppLabel;
|
// Returns default applicationn label if we cannot find it.
|
||||||
|
return mAppLabel == null || mAppLabel.length() == 0
|
||||||
|
? mBatteryHistEntry.mAppLabel
|
||||||
|
: mAppLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the app icon {@link Drawable} for this entry. */
|
/** Gets the app icon {@link Drawable} for this entry. */
|
||||||
public Drawable getAppIcon() {
|
public Drawable getAppIcon() {
|
||||||
loadLabelAndIcon();
|
loadLabelAndIcon();
|
||||||
return mAppIcon;
|
if (mBatteryHistEntry.mConsumerType !=
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY) {
|
||||||
|
return mAppIcon;
|
||||||
|
}
|
||||||
|
// Returns default application icon if UID_BATTERY icon is null.
|
||||||
|
return mAppIcon == null
|
||||||
|
? mContext.getPackageManager().getDefaultActivityIcon()
|
||||||
|
: mAppIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the searching package name for UID battery type. */
|
||||||
|
public String getPackageName() {
|
||||||
|
return mDefaultPackageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadLabelAndIcon() {
|
private void loadLabelAndIcon() {
|
||||||
@@ -127,7 +146,46 @@ public final class BatteryDiffEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadNameAndIconForUid() {
|
private void loadNameAndIconForUid() {
|
||||||
// TODO(b/185187669) fetch label and icon for UID battery type
|
final String packageName = mBatteryHistEntry.mPackageName;
|
||||||
|
final PackageManager packageManager = mContext.getPackageManager();
|
||||||
|
// Gets the application label from PackageManager.
|
||||||
|
if (packageName != null && packageName.length() != 0) {
|
||||||
|
try {
|
||||||
|
final ApplicationInfo appInfo =
|
||||||
|
packageManager.getApplicationInfo(packageName, /*no flags*/ 0);
|
||||||
|
mAppLabel = packageManager.getApplicationLabel(appInfo).toString();
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
Log.e(TAG, "failed to retrieve ApplicationInfo for: " + packageName);
|
||||||
|
mAppLabel = packageName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int uid = (int) mBatteryHistEntry.mUid;
|
||||||
|
final String[] packages = packageManager.getPackagesForUid(uid);
|
||||||
|
// Loads special defined application label and icon if available.
|
||||||
|
if (packages == null || packages.length == 0) {
|
||||||
|
final BatteryEntry.NameAndIcon nameAndIcon =
|
||||||
|
BatteryEntry.getNameAndIconFromUid(mContext, mAppLabel, uid);
|
||||||
|
mAppLabel = nameAndIcon.name;
|
||||||
|
mAppIcon = nameAndIcon.icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BatteryEntry.NameAndIcon nameAndIcon =
|
||||||
|
BatteryEntry.loadNameAndIcon(
|
||||||
|
mContext, uid, /*uid=*/ null, /*batteryEntry=*/ null,
|
||||||
|
packageName, mAppLabel, mAppIcon);
|
||||||
|
// Clears BatteryEntry internal cache since we will have another one.
|
||||||
|
BatteryEntry.clearUidCache();
|
||||||
|
if (nameAndIcon != null) {
|
||||||
|
mAppLabel = getNonNull(mAppLabel, nameAndIcon.name);
|
||||||
|
mAppIcon = getNonNull(mAppIcon, nameAndIcon.icon);
|
||||||
|
mDefaultPackageName = nameAndIcon.packageName;
|
||||||
|
if (mDefaultPackageName != null
|
||||||
|
&& !mDefaultPackageName.equals(nameAndIcon.packageName)) {
|
||||||
|
Log.w(TAG, String.format("found different package: %s | %s",
|
||||||
|
mDefaultPackageName, nameAndIcon.packageName));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -144,4 +202,8 @@ public final class BatteryDiffEntry {
|
|||||||
mBatteryHistEntry.mPackageName, mBatteryHistEntry.mUid));
|
mBatteryHistEntry.mPackageName, mBatteryHistEntry.mUid));
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <T> T getNonNull(T originalObj, T newObj) {
|
||||||
|
return newObj != null ? newObj : originalObj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -111,7 +111,8 @@ public class BatteryEntry {
|
|||||||
}
|
}
|
||||||
final NameAndIcon nameAndIcon =
|
final NameAndIcon nameAndIcon =
|
||||||
BatteryEntry.loadNameAndIcon(
|
BatteryEntry.loadNameAndIcon(
|
||||||
be.mContext, be.getUid(), sHandler, be, be.mDefaultPackageName);
|
be.mContext, be.getUid(), sHandler, be,
|
||||||
|
be.mDefaultPackageName, be.name, be.icon);
|
||||||
if (nameAndIcon != null) {
|
if (nameAndIcon != null) {
|
||||||
be.icon = getNonNull(be.icon, nameAndIcon.icon);
|
be.icon = getNonNull(be.icon, nameAndIcon.icon);
|
||||||
be.name = getNonNull(be.name, nameAndIcon.name);
|
be.name = getNonNull(be.name, nameAndIcon.name);
|
||||||
@@ -274,6 +275,7 @@ public class BatteryEntry {
|
|||||||
icon = mContext.getPackageManager().getDefaultActivityIcon();
|
icon = mContext.getPackageManager().getDefaultActivityIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoids post the loading icon and label in the background request.
|
||||||
if (sHandler != null && loadDataInBackground) {
|
if (sHandler != null && loadDataInBackground) {
|
||||||
synchronized (sRequestQueue) {
|
synchronized (sRequestQueue) {
|
||||||
sRequestQueue.add(this);
|
sRequestQueue.add(this);
|
||||||
@@ -289,9 +291,9 @@ public class BatteryEntry {
|
|||||||
int uid,
|
int uid,
|
||||||
Handler handler,
|
Handler handler,
|
||||||
BatteryEntry batteryEntry,
|
BatteryEntry batteryEntry,
|
||||||
String defaultPackageName) {
|
String defaultPackageName,
|
||||||
String name = null;
|
String name,
|
||||||
Drawable icon = null;
|
Drawable icon) {
|
||||||
// Bail out if the current sipper is not an App sipper.
|
// Bail out if the current sipper is not an App sipper.
|
||||||
if (uid == 0 || uid == Process.INVALID_UID) {
|
if (uid == 0 || uid == Process.INVALID_UID) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -22,6 +22,9 @@ import static org.mockito.Mockito.spy;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.SystemBatteryConsumer;
|
import android.os.SystemBatteryConsumer;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
|
||||||
@@ -41,14 +44,18 @@ import java.util.List;
|
|||||||
public final class BatteryDiffEntryTest {
|
public final class BatteryDiffEntryTest {
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@Mock
|
|
||||||
private UserManager mockUserManager;
|
@Mock private ApplicationInfo mockAppInfo;
|
||||||
|
@Mock private PackageManager mockPackageManager;
|
||||||
|
@Mock private UserManager mockUserManager;
|
||||||
|
@Mock private Drawable mockDrawable;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
doReturn(mockUserManager).when(mContext).getSystemService(UserManager.class);
|
doReturn(mockUserManager).when(mContext).getSystemService(UserManager.class);
|
||||||
|
doReturn(mockPackageManager).when(mContext).getPackageManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -96,9 +103,8 @@ public final class BatteryDiffEntryTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testLoadLabelAndIcon_forSystemBattery_returnExpectedResult() {
|
public void testLoadLabelAndIcon_forSystemBattery_returnExpectedResult() {
|
||||||
// Generates fake testing data.
|
// Generates fake testing data.
|
||||||
final ContentValues values = new ContentValues();
|
final ContentValues values = getContentValuesWithType(
|
||||||
values.put("consumerType",
|
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
||||||
Integer.valueOf(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY));
|
|
||||||
values.put("drainType",
|
values.put("drainType",
|
||||||
Integer.valueOf(SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY));
|
Integer.valueOf(SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY));
|
||||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
@@ -112,9 +118,8 @@ public final class BatteryDiffEntryTest {
|
|||||||
public void testLoadLabelAndIcon_forUserBattery_returnExpectedResult() {
|
public void testLoadLabelAndIcon_forUserBattery_returnExpectedResult() {
|
||||||
doReturn(null).when(mockUserManager).getUserInfo(1001);
|
doReturn(null).when(mockUserManager).getUserInfo(1001);
|
||||||
// Generates fake testing data.
|
// Generates fake testing data.
|
||||||
final ContentValues values = new ContentValues();
|
final ContentValues values = getContentValuesWithType(
|
||||||
values.put("consumerType",
|
ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
|
||||||
Integer.valueOf(ConvertUtils.CONSUMER_TYPE_USER_BATTERY));
|
|
||||||
values.put("userId", Integer.valueOf(1001));
|
values.put("userId", Integer.valueOf(1001));
|
||||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
@@ -124,6 +129,77 @@ public final class BatteryDiffEntryTest {
|
|||||||
assertThat(entry.getAppIcon()).isNull();
|
assertThat(entry.getAppIcon()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppLabel_loadDataFromApplicationInfo() throws Exception {
|
||||||
|
final String expectedAppLabel = "fake app label";
|
||||||
|
final String fakePackageName = "com.fake.google.com";
|
||||||
|
final ContentValues values = getContentValuesWithType(
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
|
values.put("uid", /*invalid uid*/ 10001);
|
||||||
|
values.put("packageName", fakePackageName);
|
||||||
|
doReturn(mockAppInfo).when(mockPackageManager)
|
||||||
|
.getApplicationInfo(fakePackageName, 0);
|
||||||
|
doReturn(expectedAppLabel).when(mockPackageManager)
|
||||||
|
.getApplicationLabel(mockAppInfo);
|
||||||
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
|
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||||
|
|
||||||
|
assertThat(entry.getAppLabel()).isEqualTo(expectedAppLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppLabel_loadDataFromPreDefinedNameAndUid() {
|
||||||
|
final ContentValues values = getContentValuesWithType(
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
|
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||||
|
|
||||||
|
assertThat(entry.getAppLabel()).isEqualTo("Android OS");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppLabel_nullAppLabel_returnAppLabelInBatteryHistEntry() {
|
||||||
|
final String expectedAppLabel = "fake app label";
|
||||||
|
final ContentValues values = getContentValuesWithType(
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
|
values.put("appLabel", expectedAppLabel);
|
||||||
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
|
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||||
|
|
||||||
|
entry.mIsLoaded = true;
|
||||||
|
assertThat(entry.getAppLabel()).isEqualTo(expectedAppLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppIcon_nonUidConsumer_returnAppIconInBatteryDiffEntry() {
|
||||||
|
final ContentValues values = getContentValuesWithType(
|
||||||
|
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
||||||
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
|
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||||
|
|
||||||
|
entry.mIsLoaded = true;
|
||||||
|
entry.mAppIcon = mockDrawable;
|
||||||
|
assertThat(entry.getAppIcon()).isEqualTo(mockDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppIcon_uidConsumerWithNullIcon_returnDefaultActivityIcon() {
|
||||||
|
final ContentValues values = getContentValuesWithType(
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
doReturn(mockDrawable).when(mockPackageManager).getDefaultActivityIcon();
|
||||||
|
|
||||||
|
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||||
|
|
||||||
|
entry.mIsLoaded = true;
|
||||||
|
entry.mAppIcon = null;
|
||||||
|
assertThat(entry.getAppIcon()).isEqualTo(mockDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
private BatteryDiffEntry createBatteryDiffEntry(
|
private BatteryDiffEntry createBatteryDiffEntry(
|
||||||
double consumePower, BatteryHistEntry batteryHistEntry) {
|
double consumePower, BatteryHistEntry batteryHistEntry) {
|
||||||
final BatteryDiffEntry entry = new BatteryDiffEntry(
|
final BatteryDiffEntry entry = new BatteryDiffEntry(
|
||||||
@@ -135,4 +211,10 @@ public final class BatteryDiffEntryTest {
|
|||||||
entry.setTotalConsumePower(100.0);
|
entry.setTotalConsumePower(100.0);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ContentValues getContentValuesWithType(int consumerType) {
|
||||||
|
final ContentValues values = new ContentValues();
|
||||||
|
values.put("consumerType", Integer.valueOf(consumerType));
|
||||||
|
return values;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user