Merge "Add Foreground Service time to battery usage" into oc-mr1-dev

This commit is contained in:
Michael Wachenschwanz
2017-07-24 19:02:12 +00:00
committed by Android (Google) Code Review
5 changed files with 82 additions and 42 deletions

View File

@@ -53,14 +53,16 @@ public class BatteryUtils {
public static final int SDK_NULL = -1; public static final int SDK_NULL = -1;
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({StatusType.FOREGROUND, @IntDef({StatusType.SCREEN_USAGE,
StatusType.FOREGROUND,
StatusType.BACKGROUND, StatusType.BACKGROUND,
StatusType.ALL StatusType.ALL
}) })
public @interface StatusType { public @interface StatusType {
int FOREGROUND = 0; int SCREEN_USAGE = 0;
int BACKGROUND = 1; int FOREGROUND = 1;
int ALL = 2; int BACKGROUND = 2;
int ALL = 3;
} }
private static final String TAG = "BatteryUtils"; private static final String TAG = "BatteryUtils";
@@ -96,6 +98,8 @@ public class BatteryUtils {
} }
switch (type) { switch (type) {
case StatusType.SCREEN_USAGE:
return getScreenUsageTimeMs(uid, which);
case StatusType.FOREGROUND: case StatusType.FOREGROUND:
return getProcessForegroundTimeMs(uid, which); return getProcessForegroundTimeMs(uid, which);
case StatusType.BACKGROUND: case StatusType.BACKGROUND:
@@ -107,6 +111,29 @@ public class BatteryUtils {
return 0; return 0;
} }
private long getScreenUsageTimeMs(BatteryStats.Uid uid, int which, long rawRealTimeUs) {
final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP};
Log.v(TAG, "package: " + mPackageManager.getNameForUid(uid.getUid()));
long timeUs = 0;
for (int type : foregroundTypes) {
final long localTime = uid.getProcessStateTime(type, rawRealTimeUs, which);
Log.v(TAG, "type: " + type + " time(us): " + localTime);
timeUs += localTime;
}
Log.v(TAG, "foreground time(us): " + timeUs);
// Return the min value of STATE_TOP time and foreground activity time, since both of these
// time have some errors
return convertUsToMs(
Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)));
}
private long getScreenUsageTimeMs(BatteryStats.Uid uid, int which) {
final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
return getScreenUsageTimeMs(uid, which, rawRealTimeUs);
}
private long getProcessBackgroundTimeMs(BatteryStats.Uid uid, int which) { private long getProcessBackgroundTimeMs(BatteryStats.Uid uid, int which) {
final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime()); final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
final long timeUs = uid.getProcessStateTime( final long timeUs = uid.getProcessStateTime(
@@ -119,21 +146,8 @@ public class BatteryUtils {
private long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) { private long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime()); final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP}; return getScreenUsageTimeMs(uid, which, rawRealTimeUs)
Log.v(TAG, "package: " + mPackageManager.getNameForUid(uid.getUid())); + convertUsToMs(getForegroundServiceTotalTimeUs(uid, rawRealTimeUs));
long timeUs = 0;
for (int type : foregroundTypes) {
final long localTime = uid.getProcessStateTime(type, rawRealTimeUs, which);
Log.v(TAG, "type: " + type + " time(us): " + localTime);
timeUs += localTime;
}
Log.v(TAG, "foreground time(us): " + timeUs);
// Return the min value of STATE_TOP time and foreground activity time, since both of these
// time have some errors.
return convertUsToMs(
Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)));
} }
/** /**
@@ -183,7 +197,7 @@ public class BatteryUtils {
for (int i = 0, size = sippers.size(); i < size; i++) { for (int i = 0, size = sippers.size(); i < size; i++) {
final BatteryStats.Uid uid = sippers.get(i).uidObj; final BatteryStats.Uid uid = sippers.get(i).uidObj;
if (uid != null) { if (uid != null) {
final long timeMs = getProcessTimeMs(StatusType.FOREGROUND, uid, final long timeMs = getProcessTimeMs(StatusType.SCREEN_USAGE, uid,
BatteryStats.STATS_SINCE_CHARGED); BatteryStats.STATS_SINCE_CHARGED);
activityTimeArray.put(uid.getUid(), timeMs); activityTimeArray.put(uid.getUid(), timeMs);
totalActivityTimeMs += timeMs; totalActivityTimeMs += timeMs;
@@ -388,5 +402,15 @@ public class BatteryUtils {
return 0; return 0;
} }
@VisibleForTesting
long getForegroundServiceTotalTimeUs(BatteryStats.Uid uid, long rawRealtimeUs) {
final BatteryStats.Timer timer = uid.getForegroundServiceTimer();
if (timer != null) {
return timer.getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
}
return 0;
}
} }

View File

@@ -714,7 +714,7 @@ public class PowerUsageSummary extends PowerUsageBase implements
preference.setSummary( preference.setSummary(
(sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper)) (sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper))
? timeSequence ? timeSequence
: TextUtils.expandTemplate(getText(R.string.battery_screen_usage), : TextUtils.expandTemplate(getText(R.string.battery_used_for),
timeSequence)); timeSequence));
} }
} }

View File

@@ -87,10 +87,17 @@ public class AdvancedPowerUsageDetailTest {
private static final int ICON_ID = 123; private static final int ICON_ID = 123;
private static final int UID = 1; private static final int UID = 1;
private static final int POWER_MAH = 150; private static final int POWER_MAH = 150;
private static final long BACKGROUND_TIME_US = 100 * 1000;
private static final long FOREGROUND_TIME_US = 200 * 1000;
private static final long BACKGROUND_TIME_MS = 100; private static final long BACKGROUND_TIME_MS = 100;
private static final long FOREGROUND_TIME_MS = 200; private static final long FOREGROUND_ACTIVITY_TIME_MS = 123;
private static final long FOREGROUND_SERVICE_TIME_MS = 444;
private static final long FOREGROUND_TIME_MS =
FOREGROUND_ACTIVITY_TIME_MS + FOREGROUND_SERVICE_TIME_MS;
private static final long PROCSTATE_TOP_TIME_MS = FOREGROUND_ACTIVITY_TIME_MS;
private static final long BACKGROUND_TIME_US = BACKGROUND_TIME_MS * 1000;
private static final long FOREGROUND_ACTIVITY_TIME_US = FOREGROUND_ACTIVITY_TIME_MS * 1000;
private static final long FOREGROUND_SERVICE_TIME_US = FOREGROUND_SERVICE_TIME_MS * 1000;
private static final long FOREGROUND_TIME_US = FOREGROUND_TIME_MS * 1000;
private static final long PROCSTATE_TOP_TIME_US = PROCSTATE_TOP_TIME_MS * 1000;
private static final long PHONE_FOREGROUND_TIME_MS = 250 * 1000; private static final long PHONE_FOREGROUND_TIME_MS = 250 * 1000;
private static final long PHONE_BACKGROUND_TIME_MS = 0; private static final long PHONE_BACKGROUND_TIME_MS = 0;
@@ -123,7 +130,9 @@ public class AdvancedPowerUsageDetailTest {
@Mock @Mock
private AnomalySummaryPreferenceController mAnomalySummaryPreferenceController; private AnomalySummaryPreferenceController mAnomalySummaryPreferenceController;
@Mock @Mock
private BatteryStats.Timer mTimer; private BatteryStats.Timer mForegroundActivityTimer;
@Mock
private BatteryUtils mBatteryUtils;
private Context mContext; private Context mContext;
private Preference mForegroundPreference; private Preference mForegroundPreference;
private Preference mBackgroundPreference; private Preference mBackgroundPreference;
@@ -171,10 +180,11 @@ public class AdvancedPowerUsageDetailTest {
doReturn(APP_LABEL).when(mBatteryEntry).getLabel(); doReturn(APP_LABEL).when(mBatteryEntry).getLabel();
doReturn(BACKGROUND_TIME_US).when(mUid).getProcessStateTime( doReturn(BACKGROUND_TIME_US).when(mUid).getProcessStateTime(
eq(BatteryStats.Uid.PROCESS_STATE_BACKGROUND), anyLong(), anyInt()); eq(BatteryStats.Uid.PROCESS_STATE_BACKGROUND), anyLong(), anyInt());
doReturn(FOREGROUND_TIME_US).when(mUid).getProcessStateTime( doReturn(PROCSTATE_TOP_TIME_US).when(mUid).getProcessStateTime(
eq(BatteryStats.Uid.PROCESS_STATE_TOP), anyLong(), anyInt()); eq(BatteryStats.Uid.PROCESS_STATE_TOP), anyLong(), anyInt());
doReturn(mTimer).when(mUid).getForegroundActivityTimer(); doReturn(mForegroundActivityTimer).when(mUid).getForegroundActivityTimer();
doReturn(FOREGROUND_TIME_US).when(mTimer).getTotalTimeLocked(anyLong(), anyInt()); doReturn(FOREGROUND_ACTIVITY_TIME_US).when(mForegroundActivityTimer)
.getTotalTimeLocked(anyLong(), anyInt());
ReflectionHelpers.setField(mBatteryEntry, "sipper", mBatterySipper); ReflectionHelpers.setField(mBatteryEntry, "sipper", mBatterySipper);
mBatteryEntry.iconId = ICON_ID; mBatteryEntry.iconId = ICON_ID;
mBatterySipper.uidObj = mUid; mBatterySipper.uidObj = mUid;
@@ -189,6 +199,10 @@ public class AdvancedPowerUsageDetailTest {
doReturn(mPackageManager).when(mTestActivity).getPackageManager(); doReturn(mPackageManager).when(mTestActivity).getPackageManager();
doReturn(mAppOpsManager).when(mTestActivity).getSystemService(Context.APP_OPS_SERVICE); doReturn(mAppOpsManager).when(mTestActivity).getSystemService(Context.APP_OPS_SERVICE);
mBatteryUtils = spy(BatteryUtils.getInstance(mTestActivity));
doReturn(FOREGROUND_SERVICE_TIME_US).when(mBatteryUtils).getForegroundServiceTotalTimeUs(
any(BatteryStats.Uid.class), anyLong());
final ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class); final ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
Answer<Void> callable = invocation -> { Answer<Void> callable = invocation -> {
@@ -263,8 +277,8 @@ public class AdvancedPowerUsageDetailTest {
@Test @Test
public void testStartBatteryDetailPage_hasBasicData() { public void testStartBatteryDetailPage_hasBasicData() {
AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0, AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, mBatteryUtils, null,
mBatteryEntry, USAGE_PERCENT, mAnomalies); mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT, mAnomalies);
assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)).isEqualTo( assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)).isEqualTo(
@@ -282,8 +296,8 @@ public class AdvancedPowerUsageDetailTest {
mBatterySipper.drainType = BatterySipper.DrainType.PHONE; mBatterySipper.drainType = BatterySipper.DrainType.PHONE;
mBatterySipper.usageTimeMs = PHONE_FOREGROUND_TIME_MS; mBatterySipper.usageTimeMs = PHONE_FOREGROUND_TIME_MS;
AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0, AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, mBatteryUtils, null,
mBatteryEntry, USAGE_PERCENT, null); mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT, null);
assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME)).isEqualTo( assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME)).isEqualTo(
@@ -300,8 +314,8 @@ public class AdvancedPowerUsageDetailTest {
public void testStartBatteryDetailPage_NormalApp() { public void testStartBatteryDetailPage_NormalApp() {
mBatterySipper.mPackages = PACKAGE_NAME; mBatterySipper.mPackages = PACKAGE_NAME;
mBatteryEntry.defaultPackageName = PACKAGE_NAME[0]; mBatteryEntry.defaultPackageName = PACKAGE_NAME[0];
AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0, AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, mBatteryUtils, null,
mBatteryEntry, USAGE_PERCENT, mAnomalies); mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT, mAnomalies);
assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo( assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo(
PACKAGE_NAME[0]); PACKAGE_NAME[0]);
@@ -312,8 +326,8 @@ public class AdvancedPowerUsageDetailTest {
@Test @Test
public void testStartBatteryDetailPage_SystemApp() { public void testStartBatteryDetailPage_SystemApp() {
mBatterySipper.mPackages = null; mBatterySipper.mPackages = null;
AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0, AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, mBatteryUtils, null,
mBatteryEntry, USAGE_PERCENT, null); mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT, null);
assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_LABEL)).isEqualTo(APP_LABEL); assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_LABEL)).isEqualTo(APP_LABEL);
assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_ICON_ID)).isEqualTo(ICON_ID); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_ICON_ID)).isEqualTo(ICON_ID);
@@ -327,8 +341,8 @@ public class AdvancedPowerUsageDetailTest {
final int appUid = 1010019; final int appUid = 1010019;
mBatterySipper.mPackages = PACKAGE_NAME; mBatterySipper.mPackages = PACKAGE_NAME;
doReturn(appUid).when(mBatterySipper).getUid(); doReturn(appUid).when(mBatterySipper).getUid();
AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0, AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, mBatteryUtils, null,
mBatteryEntry, USAGE_PERCENT, null); mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT, null);
verify(mTestActivity).startPreferencePanelAsUser( verify(mTestActivity).startPreferencePanelAsUser(
nullable(Fragment.class), nullable(String.class), nullable(Bundle.class), anyInt(), nullable(Fragment.class), nullable(String.class), nullable(Bundle.class), anyInt(),

View File

@@ -195,6 +195,8 @@ public class BatteryUtilsTest {
doReturn(mAppOpsManager).when(shadowContext).getSystemService(Context.APP_OPS_SERVICE); doReturn(mAppOpsManager).when(shadowContext).getSystemService(Context.APP_OPS_SERVICE);
mBatteryUtils = spy(new BatteryUtils(shadowContext)); mBatteryUtils = spy(new BatteryUtils(shadowContext));
mBatteryUtils.mPowerUsageFeatureProvider = mProvider; mBatteryUtils.mPowerUsageFeatureProvider = mProvider;
doReturn(0L).when(mBatteryUtils).getForegroundServiceTotalTimeUs(
any(BatteryStats.Uid.class), anyLong());
} }
@Test @Test
@@ -453,7 +455,7 @@ public class BatteryUtilsTest {
if (!isUidNull) { if (!isUidNull) {
final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS); final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS);
doReturn(topTime).when(mBatteryUtils).getProcessTimeMs( doReturn(topTime).when(mBatteryUtils).getProcessTimeMs(
eq(BatteryUtils.StatusType.FOREGROUND), eq(uid), anyInt()); eq(BatteryUtils.StatusType.SCREEN_USAGE), eq(uid), anyInt());
doReturn(uidCode).when(uid).getUid(); doReturn(uidCode).when(uid).getUid();
sipper.uidObj = uid; sipper.uidObj = uid;
} }

View File

@@ -337,13 +337,13 @@ public class PowerUsageSummaryTest {
@Test @Test
public void testSetUsageSummary_timeMoreThanOneMinute_normalApp_setScreenSummary() { public void testSetUsageSummary_timeMoreThanOneMinute_normalApp_setScreenSummary() {
mNormalBatterySipper.usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS; mNormalBatterySipper.usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS;
doReturn(mRealContext.getText(R.string.battery_screen_usage)).when(mFragment).getText( doReturn(mRealContext.getText(R.string.battery_used_for)).when(mFragment).getText(
R.string.battery_screen_usage); R.string.battery_used_for);
doReturn(mRealContext).when(mFragment).getContext(); doReturn(mRealContext).when(mFragment).getContext();
mFragment.setUsageSummary(mPreference, mNormalBatterySipper); mFragment.setUsageSummary(mPreference, mNormalBatterySipper);
assertThat(mPreference.getSummary().toString()).isEqualTo("Screen usage 2m"); assertThat(mPreference.getSummary().toString()).isEqualTo("Used for 2m");
} }
@Test @Test