From 656c67c01d74a470ba9bebc11ba9031b923945b3 Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Tue, 9 Mar 2021 15:45:01 -0800 Subject: [PATCH] Encapsulate BatterySipper and BatteryConsumer in BatteryEntry Bug: 173745486 Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.BatteryEntryTest Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.AdvancedPowerUsageDetailTest Change-Id: I67ab825c25b85012b5713736db62e0beb4d98a16 --- .../AppBatteryPreferenceController.java | 3 +- .../fuelgauge/AdvancedPowerUsageDetail.java | 35 ++-- .../BatteryAppListPreferenceController.java | 9 +- .../settings/fuelgauge/BatteryEntry.java | 179 ++++++++++++++---- .../AdvancedPowerUsageDetailTest.java | 66 ++----- .../settings/fuelgauge/BatteryEntryTest.java | 99 ++++++++-- 6 files changed, 258 insertions(+), 133 deletions(-) diff --git a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java index 307ceb1e0a2..cc20d4b9771 100644 --- a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java @@ -114,8 +114,7 @@ public class AppBatteryPreferenceController extends BasePreferenceController final UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); final BatteryEntry entry = new BatteryEntry(mContext, null, userManager, mSipper, - mUidBatteryConsumer); - entry.defaultPackageName = mPackageName; + mUidBatteryConsumer, mPackageName); AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent, mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, mBatteryPercent); } else { diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index e8d5f3330f2..9edae9d361c 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -23,7 +23,6 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.os.BatteryStats; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; @@ -33,9 +32,7 @@ import android.view.View; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; -import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; -import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; @@ -109,48 +106,40 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements helper.getStats(); final Bundle args = new Bundle(); - final BatterySipper sipper = entry.sipper; - final BatteryStats.Uid uid = sipper.uidObj; - final boolean isTypeApp = sipper.drainType == BatterySipper.DrainType.APP; - - final long foregroundTimeMs = isTypeApp ? batteryUtils.getProcessTimeMs( - BatteryUtils.StatusType.FOREGROUND, uid, which) : sipper.usageTimeMs; - final long backgroundTimeMs = isTypeApp ? batteryUtils.getProcessTimeMs( - BatteryUtils.StatusType.BACKGROUND, uid, which) : 0; - - if (ArrayUtils.isEmpty(sipper.mPackages)) { + final long foregroundTimeMs = entry.getTimeInForegroundMs(batteryUtils); + final long backgroundTimeMs = entry.getTimeInBackgroundMs(batteryUtils); + final String packageName = entry.getDefaultPackageName(); + if (packageName == null) { // populate data for system app args.putString(EXTRA_LABEL, entry.getLabel()); args.putInt(EXTRA_ICON_ID, entry.iconId); args.putString(EXTRA_PACKAGE_NAME, null); } else { // populate data for normal app - args.putString(EXTRA_PACKAGE_NAME, entry.defaultPackageName != null - ? entry.defaultPackageName - : sipper.mPackages[0]); + args.putString(EXTRA_PACKAGE_NAME, packageName); } - args.putInt(EXTRA_UID, sipper.getUid()); + args.putInt(EXTRA_UID, entry.getUid()); args.putLong(EXTRA_BACKGROUND_TIME, backgroundTimeMs); args.putLong(EXTRA_FOREGROUND_TIME, foregroundTimeMs); args.putString(EXTRA_POWER_USAGE_PERCENT, usagePercent); - args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) sipper.totalPowerMah); + args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) entry.getConsumedPower()); new SubSettingLauncher(caller) .setDestination(AdvancedPowerUsageDetail.class.getName()) .setTitleRes(R.string.battery_details_title) .setArguments(args) .setSourceMetricsCategory(fragment.getMetricsCategory()) - .setUserHandle(new UserHandle(getUserIdToLaunchAdvancePowerUsageDetail(sipper))) + .setUserHandle(new UserHandle(getUserIdToLaunchAdvancePowerUsageDetail(entry))) .launch(); } - private static @UserIdInt - int getUserIdToLaunchAdvancePowerUsageDetail(BatterySipper bs) { - if (bs.drainType == BatterySipper.DrainType.USER) { + private static @UserIdInt int getUserIdToLaunchAdvancePowerUsageDetail( + BatteryEntry batteryEntry) { + if (batteryEntry.isUserEntry()) { return ActivityManager.getCurrentUser(); } - return UserHandle.getUserId(bs.getUid()); + return UserHandle.getUserId(batteryEntry.getUid()); } public static void startBatteryDetailPage(Activity caller, diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java index 1a9db0352b8..56a2b01c263 100644 --- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java +++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java @@ -85,15 +85,16 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro switch (msg.what) { case BatteryEntry.MSG_UPDATE_NAME_ICON: BatteryEntry entry = (BatteryEntry) msg.obj; + int uid = entry.getUid(); PowerGaugePreference pgp = (PowerGaugePreference) mAppListGroup.findPreference( - Integer.toString(entry.sipper.uidObj.getUid())); + Integer.toString(uid)); if (pgp != null) { - final int userId = UserHandle.getUserId(entry.sipper.getUid()); + final int userId = UserHandle.getUserId(uid); final UserHandle userHandle = new UserHandle(userId); pgp.setIcon(mUserManager.getBadgedIconForUser(entry.getIcon(), userHandle)); pgp.setTitle(entry.name); - if (entry.sipper.drainType == DrainType.APP) { + if (entry.isAppEntry()) { pgp.setContentDescription(entry.name); } } @@ -208,7 +209,7 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro } final UserHandle userHandle = new UserHandle(UserHandle.getUserId(sipper.getUid())); final BatteryEntry entry = new BatteryEntry(mActivity, mHandler, mUserManager, - sipper, null); + sipper, null, null); final Drawable badgedIcon = mUserManager.getBadgedIconForUser(entry.getIcon(), userHandle); final CharSequence contentDescription = mUserManager.getBadgedLabelForUser( diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java index d533c80ceec..f1b87aff810 100644 --- a/src/com/android/settings/fuelgauge/BatteryEntry.java +++ b/src/com/android/settings/fuelgauge/BatteryEntry.java @@ -25,15 +25,19 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; +import android.os.BatteryConsumer; +import android.os.BatteryStats; import android.os.Handler; import android.os.Process; import android.os.RemoteException; import android.os.UidBatteryConsumer; +import android.os.UserBatteryConsumer; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import com.android.internal.os.BatterySipper; +import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settingslib.Utils; @@ -122,13 +126,13 @@ public class BatteryEntry { } public final Context context; - public final BatterySipper sipper; - public final UidBatteryConsumer uidBatteryConsumer; + private final BatterySipper mSipper; + private final BatteryConsumer mBatteryConsumer; public String name; public Drawable icon; public int iconId; // For passing to the detail screen. - public String defaultPackageName; + private String mDefaultPackageName; static class UidToDetail { String name; @@ -137,37 +141,38 @@ public class BatteryEntry { } public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper, - UidBatteryConsumer uidBatteryConsumer) { + BatteryConsumer batteryConsumer, String packageName) { sHandler = handler; this.context = context; - this.sipper = sipper; - this.uidBatteryConsumer = uidBatteryConsumer; + this.mSipper = sipper; + this.mBatteryConsumer = batteryConsumer; + this.mDefaultPackageName = packageName; - // This condition is met when BatteryEntry is initialized from BatteryUsageStats. - // Once the conversion from BatteryStatsHelper is completed, the condition will - // always be true and can be removed. - if (uidBatteryConsumer != null) { - PackageManager pm = context.getPackageManager(); + if (batteryConsumer instanceof UidBatteryConsumer) { + UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer; int uid = uidBatteryConsumer.getUid(); - String[] packages = pm.getPackagesForUid(uid); - // Apps should only have one package - if (packages == null || packages.length != 1) { - name = uidBatteryConsumer.getPackageWithHighestDrain(); - } else { - defaultPackageName = packages[0]; + PackageManager pm = context.getPackageManager(); + if (mDefaultPackageName == null) { + String[] packages = pm.getPackagesForUid(uid); + // Apps should only have one package + if (packages != null && packages.length == 1) { + mDefaultPackageName = packages[0]; + } else { + mDefaultPackageName = uidBatteryConsumer.getPackageWithHighestDrain(); + } + } + if (mDefaultPackageName != null) { try { ApplicationInfo appInfo = - pm.getApplicationInfo(defaultPackageName, 0 /* no flags */); + pm.getApplicationInfo(mDefaultPackageName, 0 /* no flags */); name = pm.getApplicationLabel(appInfo).toString(); } catch (NameNotFoundException e) { Log.d(TAG, "PackageManager failed to retrieve ApplicationInfo for: " - + defaultPackageName); - name = defaultPackageName; + + mDefaultPackageName); + name = mDefaultPackageName; } } - if ((name == null || iconId == 0) && uid != 0) { - getQuickNameIconForUid(uid); - } + getQuickNameIconForUid(uid); return; } @@ -207,15 +212,15 @@ public class BatteryEntry { if (sipper.mPackages == null || sipper.mPackages.length != 1) { name = sipper.packageWithHighestDrain; } else { - defaultPackageName = pm.getPackagesForUid(sipper.uidObj.getUid())[0]; + mDefaultPackageName = pm.getPackagesForUid(sipper.uidObj.getUid())[0]; try { ApplicationInfo appInfo = - pm.getApplicationInfo(defaultPackageName, 0 /* no flags */); + pm.getApplicationInfo(mDefaultPackageName, 0 /* no flags */); name = pm.getApplicationLabel(appInfo).toString(); } catch (NameNotFoundException e) { Log.d(TAG, "PackageManager failed to retrieve ApplicationInfo for: " - + defaultPackageName); - name = defaultPackageName; + + mDefaultPackageName); + name = mDefaultPackageName; } } break; @@ -250,8 +255,8 @@ public class BatteryEntry { if (iconId > 0) { icon = context.getDrawable(iconId); } - if ((name == null || iconId == 0) && this.sipper.uidObj != null) { - getQuickNameIconForUid(this.sipper.uidObj.getUid()); + if ((name == null || iconId == 0) && sipper.uidObj != null) { + getQuickNameIconForUid(sipper.uidObj.getUid()); } } @@ -277,7 +282,7 @@ public class BatteryEntry { final String uidString = Integer.toString(uid); if (sUidCache.containsKey(uidString)) { UidToDetail utd = sUidCache.get(uidString); - defaultPackageName = utd.packageName; + mDefaultPackageName = utd.packageName; name = utd.name; icon = utd.icon; return; @@ -308,17 +313,17 @@ public class BatteryEntry { */ public void loadNameAndIcon() { // Bail out if the current sipper is not an App sipper. - if (sipper.uidObj == null) { + if (mSipper.uidObj == null) { return; } PackageManager pm = context.getPackageManager(); - final int uid = sipper.uidObj.getUid(); - if (sipper.mPackages == null) { - sipper.mPackages = pm.getPackagesForUid(uid); + final int uid = mSipper.uidObj.getUid(); + if (mSipper.mPackages == null) { + mSipper.mPackages = pm.getPackagesForUid(uid); } - final String[] packages = extractPackagesFromSipper(sipper); + final String[] packages = extractPackagesFromSipper(mSipper); if (packages != null) { String[] packageLabels = new String[packages.length]; System.arraycopy(packages, 0, packageLabels, 0, packages.length); @@ -340,7 +345,7 @@ public class BatteryEntry { packageLabels[i] = label.toString(); } if (ai.icon != 0) { - defaultPackageName = packages[i]; + mDefaultPackageName = packages[i]; icon = ai.loadIcon(pm); break; } @@ -368,7 +373,7 @@ public class BatteryEntry { if (nm != null) { name = nm.toString(); if (pi.applicationInfo.icon != 0) { - defaultPackageName = pkgName; + mDefaultPackageName = pkgName; icon = pi.applicationInfo.loadIcon(pm); } break; @@ -394,17 +399,113 @@ public class BatteryEntry { UidToDetail utd = new UidToDetail(); utd.name = name; utd.icon = icon; - utd.packageName = defaultPackageName; + utd.packageName = mDefaultPackageName; sUidCache.put(uidString, utd); if (sHandler != null) { sHandler.sendMessage(sHandler.obtainMessage(MSG_UPDATE_NAME_ICON, this)); } } - String[] extractPackagesFromSipper(BatterySipper sipper) { + static String[] extractPackagesFromSipper(BatterySipper sipper) { // Only use system package if uid is system uid, so it could find a consistent name and icon return sipper.getUid() == Process.SYSTEM_UID ? new String[]{PACKAGE_SYSTEM} : sipper.mPackages; } + + /** + * Returns true if this entry describes an app (UID) + */ + public boolean isAppEntry() { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return true; + } else { + return mSipper.drainType == BatterySipper.DrainType.APP; + } + } + + /** + * Returns true if this entry describes a User. + */ + public boolean isUserEntry() { + if (mBatteryConsumer instanceof UserBatteryConsumer) { + return true; + } else { + return mSipper.drainType == BatterySipper.DrainType.USER; + } + } + + /** + * Returns the package name that should be used to represent the UID described + * by this entry. + */ + public String getDefaultPackageName() { + if (mDefaultPackageName != null) { + return mDefaultPackageName; + } + if (ArrayUtils.isEmpty(mSipper.mPackages)) { + return null; + } else { + return mSipper.mPackages[0]; + } + } + + /** + * Returns the UID of the app described by this entry. + */ + public int getUid() { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return ((UidBatteryConsumer) mBatteryConsumer).getUid(); + } else if (mBatteryConsumer != null) { + return Process.INVALID_UID; + } else { + return mSipper.getUid(); + } + } + + /** + * Returns foreground foreground time (in milliseconds) that is attributed to this entry. + */ + public long getTimeInForegroundMs(BatteryUtils batteryUtils) { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs( + UidBatteryConsumer.STATE_FOREGROUND); + } else if (mBatteryConsumer != null) { + return mBatteryConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE); + } else if (mSipper.drainType == BatterySipper.DrainType.APP) { + return batteryUtils.getProcessTimeMs( + BatteryUtils.StatusType.FOREGROUND, mSipper.uidObj, + BatteryStats.STATS_SINCE_CHARGED); + } else { + return mSipper.usageTimeMs; + } + } + + /** + * Returns background activity time (in milliseconds) that is attributed to this entry. + */ + public long getTimeInBackgroundMs(BatteryUtils batteryUtils) { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs( + UidBatteryConsumer.STATE_BACKGROUND); + } else if (mBatteryConsumer != null) { + return 0; + } else if (mSipper.drainType == BatterySipper.DrainType.APP) { + return batteryUtils.getProcessTimeMs( + BatteryUtils.StatusType.BACKGROUND, mSipper.uidObj, + BatteryStats.STATS_SINCE_CHARGED); + } else { + return 0; + } + } + + /** + * Returns total amount of power (in milli-amp-hours) that is attributed to this entry. + */ + public double getConsumedPower() { + if (mBatteryConsumer != null) { + return mBatteryConsumer.getConsumedPower(); + } + return (int) mSipper.totalPowerMah; + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 8eeac8d26b0..8296c8c2bbd 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -47,7 +47,6 @@ import androidx.loader.app.LoaderManager; import androidx.preference.Preference; import androidx.recyclerview.widget.RecyclerView; -import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.SettingsActivity; @@ -114,12 +113,8 @@ public class AdvancedPowerUsageDetailTest { @Mock private BatteryEntry mBatteryEntry; @Mock - private BatterySipper mBatterySipper; - @Mock private BatteryStatsHelper mBatteryStatsHelper; @Mock - private BatteryStats.Uid mUid; - @Mock private PackageManager mPackageManager; @Mock private AppOpsManager mAppOpsManager; @@ -140,6 +135,7 @@ public class AdvancedPowerUsageDetailTest { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + when(mContext.getPackageName()).thenReturn("foo"); FakeFeatureFactory.setupForTest(); mFragment = spy(new AdvancedPowerUsageDetail()); @@ -168,19 +164,13 @@ public class AdvancedPowerUsageDetailTest { doReturn(mEntityHeaderController).when(mEntityHeaderController) .setSummary(nullable(String.class)); - doReturn(UID).when(mBatterySipper).getUid(); + when(mBatteryEntry.getUid()).thenReturn(UID); when(mBatteryEntry.getLabel()).thenReturn(APP_LABEL); - doReturn(BACKGROUND_TIME_US).when(mUid).getProcessStateTime( - eq(BatteryStats.Uid.PROCESS_STATE_BACKGROUND), anyLong(), anyInt()); - doReturn(PROCSTATE_TOP_TIME_US).when(mUid).getProcessStateTime( - eq(BatteryStats.Uid.PROCESS_STATE_TOP), anyLong(), anyInt()); - doReturn(mForegroundActivityTimer).when(mUid).getForegroundActivityTimer(); - doReturn(FOREGROUND_ACTIVITY_TIME_US).when(mForegroundActivityTimer) - .getTotalTimeLocked(anyLong(), anyInt()); - ReflectionHelpers.setField(mBatteryEntry, "sipper", mBatterySipper); + when(mBatteryEntry.getTimeInBackgroundMs(any(BatteryUtils.class))) + .thenReturn(BACKGROUND_TIME_MS); + when(mBatteryEntry.getTimeInForegroundMs(any(BatteryUtils.class))) + .thenReturn(FOREGROUND_TIME_MS); mBatteryEntry.iconId = ICON_ID; - mBatterySipper.uidObj = mUid; - mBatterySipper.drainType = BatterySipper.DrainType.APP; mFragment.mHeaderPreference = mHeaderPreference; mFragment.mState = mState; @@ -200,6 +190,7 @@ public class AdvancedPowerUsageDetailTest { Answer callable = invocation -> { mBundle = captor.getValue().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); + System.out.println("mBundle = " + mBundle); return null; }; doAnswer(callable).when(mActivity).startActivityAsUser(captor.capture(), @@ -274,27 +265,10 @@ public class AdvancedPowerUsageDetailTest { .isEqualTo(USAGE_PERCENT); } - @Test - public void testStartBatteryDetailPage_typeNotApp_hasBasicData() { - mBatterySipper.drainType = BatterySipper.DrainType.PHONE; - mBatterySipper.usageTimeMs = PHONE_FOREGROUND_TIME_MS; - - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); - - assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); - assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME)) - .isEqualTo(PHONE_FOREGROUND_TIME_MS); - assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)) - .isEqualTo(PHONE_BACKGROUND_TIME_MS); - assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT)) - .isEqualTo(USAGE_PERCENT); - } - @Test public void testStartBatteryDetailPage_NormalApp() { - mBatterySipper.mPackages = PACKAGE_NAME; - mBatteryEntry.defaultPackageName = PACKAGE_NAME[0]; + when(mBatteryEntry.getDefaultPackageName()).thenReturn(PACKAGE_NAME[0]); + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); @@ -304,7 +278,8 @@ public class AdvancedPowerUsageDetailTest { @Test public void testStartBatteryDetailPage_SystemApp() { - mBatterySipper.mPackages = null; + when(mBatteryEntry.getDefaultPackageName()).thenReturn(null); + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); @@ -316,8 +291,8 @@ public class AdvancedPowerUsageDetailTest { @Test public void testStartBatteryDetailPage_WorkApp() { final int appUid = 1010019; - mBatterySipper.mPackages = PACKAGE_NAME; - doReturn(appUid).when(mBatterySipper).getUid(); + doReturn(appUid).when(mBatteryEntry).getUid(); + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); @@ -326,8 +301,7 @@ public class AdvancedPowerUsageDetailTest { @Test public void testStartBatteryDetailPage_typeUser_startByCurrentUser() { - mBatterySipper.drainType = BatterySipper.DrainType.USER; - mBatterySipper.userId = 10; + when(mBatteryEntry.isUserEntry()).thenReturn(true); final int currentUser = 20; ShadowActivityManager.setCurrentUser(currentUser); @@ -364,18 +338,6 @@ public class AdvancedPowerUsageDetailTest { assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); } - @Test - public void testStartBatteryDetailPage_defaultPackageNull_chooseFromBatterySipper() { - mBatteryEntry.defaultPackageName = null; - mBatteryEntry.sipper.mPackages = PACKAGE_NAME; - - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); - - assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)) - .isEqualTo(PACKAGE_NAME[0]); - } - @Test public void testInitPreference_hasCorrectSummary() { Bundle bundle = new Bundle(4); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java index e40b27067cc..8531b2871f0 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java @@ -17,6 +17,8 @@ package com.android.settings.fuelgauge; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -24,8 +26,12 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.os.BatteryConsumer; +import android.os.BatteryStats; import android.os.Handler; import android.os.Process; +import android.os.SystemBatteryConsumer; +import android.os.UidBatteryConsumer; import android.os.UserManager; import com.android.internal.os.BatterySipper; @@ -61,6 +67,9 @@ public class BatteryEntryTest { @Mock private Handler mockHandler; @Mock private PackageManager mockPackageManager; @Mock private UserManager mockUserManager; + @Mock private UidBatteryConsumer mUidBatteryConsumer; + @Mock private SystemBatteryConsumer mSystemBatteryConsumer; + @Mock BatteryUtils mBatteryUtils; @Before public void stubContextToReturnMockPackageManager() { @@ -80,7 +89,7 @@ public class BatteryEntryTest { private BatteryEntry createBatteryEntryForApp() { return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForApp(), - null); + null, null); } private BatterySipper createSipperForApp() { @@ -90,11 +99,6 @@ public class BatteryEntryTest { return sipper; } - private BatteryEntry createBatteryEntryForSystem() { - return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForSystem(), - null); - } - private BatterySipper createSipperForSystem() { BatterySipper sipper = new BatterySipper(DrainType.APP, new FakeUid(SYSTEM_UID), 0 /* power use */); @@ -103,11 +107,15 @@ public class BatteryEntryTest { return sipper; } + private BatterySipper createNonAppSipper() { + return new BatterySipper(DrainType.IDLE, null, 0 /* power use */); + } + @Test public void batteryEntryForApp_shouldSetDefaultPackageNameAndLabel() throws Exception { BatteryEntry entry = createBatteryEntryForApp(); - assertThat(entry.defaultPackageName).isEqualTo(APP_DEFAULT_PACKAGE_NAME); + assertThat(entry.getDefaultPackageName()).isEqualTo(APP_DEFAULT_PACKAGE_NAME); assertThat(entry.getLabel()).isEqualTo(APP_LABEL); } @@ -146,7 +154,7 @@ public class BatteryEntryTest { final BatterySipper batterySipper = mock(BatterySipper.class); batterySipper.drainType = DrainType.AMBIENT_DISPLAY; final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, - mockUserManager, batterySipper, null); + mockUserManager, batterySipper, null, null); assertThat(entry.iconId).isEqualTo(R.drawable.ic_settings_aod); assertThat(entry.name).isEqualTo("Ambient display"); @@ -154,17 +162,82 @@ public class BatteryEntryTest { @Test public void extractPackageFromSipper_systemSipper_returnSystemPackage() { - BatteryEntry entry = createBatteryEntryForSystem(); - - assertThat(entry.extractPackagesFromSipper(entry.sipper)) + assertThat(BatteryEntry.extractPackagesFromSipper(createSipperForSystem())) .isEqualTo(new String[] {ANDROID_PACKAGE}); } @Test public void extractPackageFromSipper_normalSipper_returnDefaultPackage() { - BatteryEntry entry = createBatteryEntryForApp(); + BatterySipper sipper = createSipperForApp(); + assertThat(BatteryEntry.extractPackagesFromSipper(sipper)).isEqualTo(sipper.mPackages); + } - assertThat(entry.extractPackagesFromSipper(entry.sipper)).isEqualTo(entry.sipper.mPackages); + @Test + public void getTimeInForegroundMs_app() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, null, mUidBatteryConsumer, null); + + when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND)) + .thenReturn(100L); + + assertThat(entry.getTimeInForegroundMs(mBatteryUtils)).isEqualTo(100L); + } + + @Test + public void getTimeInForegroundMs_systemConsumer() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, createNonAppSipper(), mSystemBatteryConsumer, null); + + when(mSystemBatteryConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE)) + .thenReturn(100L); + + assertThat(entry.getTimeInForegroundMs(mBatteryUtils)).isEqualTo(100L); + } + + @Test + public void getTimeInForegroundMs_useSipper() { + final BatterySipper batterySipper = createSipperForApp(); + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, batterySipper, null, null); + + when(mBatteryUtils.getProcessTimeMs(eq(BatteryUtils.StatusType.FOREGROUND), + any(BatteryStats.Uid.class), eq(BatteryStats.STATS_SINCE_CHARGED))) + .thenReturn(100L); + assertThat(entry.getTimeInForegroundMs(mBatteryUtils)).isEqualTo(100L); + } + + @Test + public void getTimeInBackgroundMs_app() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, null, mUidBatteryConsumer, null); + + when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND)) + .thenReturn(100L); + + assertThat(entry.getTimeInBackgroundMs(mBatteryUtils)).isEqualTo(100L); + } + + @Test + public void getTimeInBackgroundMs_systemConsumer() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, createNonAppSipper(), mSystemBatteryConsumer, null); + + when(mSystemBatteryConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE)) + .thenReturn(100L); + + assertThat(entry.getTimeInBackgroundMs(mBatteryUtils)).isEqualTo(0); + } + + @Test + public void getTimeInBackgroundMs_useSipper() { + final BatterySipper batterySipper = createSipperForApp(); + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, batterySipper, null, null); + + when(mBatteryUtils.getProcessTimeMs(eq(BatteryUtils.StatusType.BACKGROUND), + any(BatteryStats.Uid.class), eq(BatteryStats.STATS_SINCE_CHARGED))) + .thenReturn(100L); + assertThat(entry.getTimeInBackgroundMs(mBatteryUtils)).isEqualTo(100L); } @Test