Merge "Fix missing time-in-foreground and time-in-background for some apps" into sc-dev
diff --git a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
index 79cae92..1f0777a 100644
--- a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
@@ -118,7 +118,8 @@
final UserManager userManager =
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
final BatteryEntry entry = new BatteryEntry(mContext, /* handler */null, userManager,
- mUidBatteryConsumer, /* isHidden */ false, /* packages */ null, mPackageName);
+ mUidBatteryConsumer, /* isHidden */ false,
+ mUidBatteryConsumer.getUid(), /* packages */ null, mPackageName);
AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent,
entry, mBatteryPercent);
} else {
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 891b6d6..1dc572d 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -55,6 +55,7 @@
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
/**
@@ -66,6 +67,7 @@
static final boolean USE_FAKE_DATA = false;
private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 20;
private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10;
+ private static final String MEDIASERVER_PACKAGE_NAME = "mediaserver";
private final String mPreferenceKey;
@VisibleForTesting
@@ -303,27 +305,17 @@
final ArrayList<BatteryEntry> results = new ArrayList<>();
final List<UidBatteryConsumer> uidBatteryConsumers =
mBatteryUsageStats.getUidBatteryConsumers();
+
+ // Sort to have all apps with "real" UIDs first, followed by apps that are supposed
+ // to be combined with the real ones.
+ uidBatteryConsumers.sort(Comparator.comparingInt(
+ consumer -> consumer.getUid() == getRealUid(consumer) ? 0 : 1));
+
for (int i = 0, size = uidBatteryConsumers.size(); i < size; i++) {
final UidBatteryConsumer consumer = uidBatteryConsumers.get(i);
- int realUid = consumer.getUid();
+ final int uid = getRealUid(consumer);
- // Check if this UID is a shared GID. If so, we combine it with the OWNER's
- // actual app UID.
- if (isSharedGid(consumer.getUid())) {
- realUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
- UserHandle.getAppIdFromSharedAppGid(consumer.getUid()));
- }
-
- // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc).
- if (isSystemUid(realUid)
- && !"mediaserver".equals(consumer.getPackageWithHighestDrain())) {
- // Use the system UID for all UIDs running in their own sandbox that
- // are not apps. We exclude mediaserver because we already are expected to
- // report that as a separate item.
- realUid = Process.SYSTEM_UID;
- }
-
- final String[] packages = mPackageManager.getPackagesForUid(consumer.getUid());
+ final String[] packages = mPackageManager.getPackagesForUid(uid);
if (mBatteryUtils.shouldHideUidBatteryConsumerUnconditionally(consumer, packages)) {
continue;
}
@@ -333,11 +325,11 @@
continue;
}
- final int index = batteryEntryList.indexOfKey(realUid);
+ final int index = batteryEntryList.indexOfKey(uid);
if (index < 0) {
// New entry.
- batteryEntryList.put(realUid, new BatteryEntry(mContext, mHandler, mUserManager,
- consumer, isHidden, packages, null, loadDataInBackground));
+ batteryEntryList.put(uid, new BatteryEntry(mContext, mHandler, mUserManager,
+ consumer, isHidden, uid, packages, null, loadDataInBackground));
} else {
// Combine BatterySippers if we already have one with this UID.
final BatteryEntry existingSipper = batteryEntryList.valueAt(index);
@@ -385,7 +377,8 @@
for (int i = 0, size = userBatteryConsumers.size(); i < size; i++) {
final UserBatteryConsumer consumer = userBatteryConsumers.get(i);
results.add(new BatteryEntry(mContext, mHandler, mUserManager,
- consumer, /* isHidden */ true, null, null, loadDataInBackground));
+ consumer, /* isHidden */ true, Process.INVALID_UID, null, null,
+ loadDataInBackground));
}
}
@@ -400,6 +393,27 @@
return results;
}
+ private int getRealUid(UidBatteryConsumer consumer) {
+ int realUid = consumer.getUid();
+
+ // Check if this UID is a shared GID. If so, we combine it with the OWNER's
+ // actual app UID.
+ if (isSharedGid(consumer.getUid())) {
+ realUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
+ UserHandle.getAppIdFromSharedAppGid(consumer.getUid()));
+ }
+
+ // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc).
+ if (isSystemUid(realUid)
+ && !MEDIASERVER_PACKAGE_NAME.equals(consumer.getPackageWithHighestDrain())) {
+ // Use the system UID for all UIDs running in their own sandbox that
+ // are not apps. We exclude mediaserver because we already are expected to
+ // report that as a separate item.
+ realUid = Process.SYSTEM_UID;
+ }
+ return realUid;
+ }
+
@VisibleForTesting
void setUsageSummary(Preference preference, BatteryEntry entry) {
// Only show summary when usage time is longer than one minute
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 78ab962..0478c8b 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -159,12 +159,15 @@
private final Context mContext;
private final BatteryConsumer mBatteryConsumer;
+ private final int mUid;
private final boolean mIsHidden;
@ConvertUtils.ConsumerType
private final int mConsumerType;
@BatteryConsumer.PowerComponent
private final int mPowerComponentId;
private long mUsageDurationMs;
+ private long mTimeInForegroundMs;
+ private long mTimeInBackgroundMs;
public String name;
public Drawable icon;
@@ -180,13 +183,13 @@
}
public BatteryEntry(Context context, Handler handler, UserManager um,
- @NonNull BatteryConsumer batteryConsumer, boolean isHidden, String[] packages,
+ @NonNull BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
String packageName) {
- this(context, handler, um, batteryConsumer, isHidden, packages, packageName, true);
+ this(context, handler, um, batteryConsumer, isHidden, uid, packages, packageName, true);
}
public BatteryEntry(Context context, Handler handler, UserManager um,
- @NonNull BatteryConsumer batteryConsumer, boolean isHidden, String[] packages,
+ @NonNull BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
String packageName, boolean loadDataInBackground) {
sHandler = handler;
mContext = context;
@@ -196,11 +199,11 @@
mPowerComponentId = -1;
if (batteryConsumer instanceof UidBatteryConsumer) {
+ mUid = uid;
mConsumerType = ConvertUtils.CONSUMER_TYPE_UID_BATTERY;
mConsumedPower = batteryConsumer.getConsumedPower();
UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
- int uid = uidBatteryConsumer.getUid();
if (mDefaultPackageName == null) {
// Apps should only have one package
if (packages != null && packages.length == 1) {
@@ -222,7 +225,12 @@
}
}
getQuickNameIconForUid(uid, packages, loadDataInBackground);
+ mTimeInForegroundMs =
+ uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND);
+ mTimeInBackgroundMs =
+ uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND);
} else if (batteryConsumer instanceof UserBatteryConsumer) {
+ mUid = Process.INVALID_UID;
mConsumerType = ConvertUtils.CONSUMER_TYPE_USER_BATTERY;
mConsumedPower = batteryConsumer.getConsumedPower();
final NameAndIcon nameAndIcon = getNameAndIconFromUserId(
@@ -239,6 +247,7 @@
double appsPowerMah, long usageDurationMs) {
mContext = context;
mBatteryConsumer = null;
+ mUid = Process.INVALID_UID;
mIsHidden = false;
mPowerComponentId = powerComponentId;
mConsumedPower =
@@ -261,6 +270,7 @@
double devicePowerMah, double appsPowerMah) {
mContext = context;
mBatteryConsumer = null;
+ mUid = Process.INVALID_UID;
mIsHidden = false;
mPowerComponentId = powerComponentId;
@@ -438,7 +448,7 @@
*/
public String getKey() {
if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return Integer.toString(((UidBatteryConsumer) mBatteryConsumer).getUid());
+ return Integer.toString(mUid);
} else if (mBatteryConsumer instanceof UserBatteryConsumer) {
return "U|" + ((UserBatteryConsumer) mBatteryConsumer).getUserId();
} else {
@@ -482,11 +492,7 @@
* Returns the UID of the app described by this entry.
*/
public int getUid() {
- if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return ((UidBatteryConsumer) mBatteryConsumer).getUid();
- } else {
- return Process.INVALID_UID;
- }
+ return mUid;
}
/**
@@ -494,8 +500,7 @@
*/
public long getTimeInForegroundMs() {
if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs(
- UidBatteryConsumer.STATE_FOREGROUND);
+ return mTimeInForegroundMs;
} else {
return mUsageDurationMs;
}
@@ -506,8 +511,7 @@
*/
public long getTimeInBackgroundMs() {
if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs(
- UidBatteryConsumer.STATE_BACKGROUND);
+ return mTimeInBackgroundMs;
} else {
return 0;
}
@@ -526,9 +530,15 @@
*/
public void add(BatteryConsumer batteryConsumer) {
mConsumedPower += batteryConsumer.getConsumedPower();
- if (mDefaultPackageName == null && batteryConsumer instanceof UidBatteryConsumer) {
- mDefaultPackageName =
- ((UidBatteryConsumer) batteryConsumer).getPackageWithHighestDrain();
+ if (batteryConsumer instanceof UidBatteryConsumer) {
+ UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
+ mTimeInForegroundMs += uidBatteryConsumer.getTimeInStateMs(
+ UidBatteryConsumer.STATE_FOREGROUND);
+ mTimeInBackgroundMs += uidBatteryConsumer.getTimeInStateMs(
+ UidBatteryConsumer.STATE_BACKGROUND);
+ if (mDefaultPackageName == null) {
+ mDefaultPackageName = uidBatteryConsumer.getPackageWithHighestDrain();
+ }
}
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
index e0f8ba7..96f0ec7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
@@ -93,7 +93,7 @@
when(consumer.getUid()).thenReturn(APP_UID);
when(consumer.getPackageWithHighestDrain()).thenReturn(highDrainPackage);
return new BatteryEntry(mMockContext, mockHandler, mockUserManager,
- consumer, false, packages, packageName);
+ consumer, false, APP_UID, packages, packageName);
}
private BatteryEntry createAggregateBatteryEntry(int powerComponentId) {
@@ -108,7 +108,7 @@
UserBatteryConsumer consumer = mock(UserBatteryConsumer.class);
when(consumer.getUserId()).thenReturn(userId);
return new BatteryEntry(mMockContext, mockHandler, mockUserManager,
- consumer, false, null, null);
+ consumer, false, 0, null, null);
}
@Test
@@ -169,12 +169,12 @@
@Test
public void getTimeInForegroundMs_app() {
- final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
- mockUserManager, mUidBatteryConsumer, false, null, null);
-
when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND))
.thenReturn(100L);
+ final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
+ mockUserManager, mUidBatteryConsumer, false, 0, null, null);
+
assertThat(entry.getTimeInForegroundMs()).isEqualTo(100L);
}
@@ -188,12 +188,12 @@
@Test
public void getTimeInBackgroundMs_app() {
- final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
- mockUserManager, mUidBatteryConsumer, false, null, null);
-
when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND))
.thenReturn(100L);
+ final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
+ mockUserManager, mUidBatteryConsumer, false, 0, null, null);
+
assertThat(entry.getTimeInBackgroundMs()).isEqualTo(100L);
}