Merge "Update wakelock detector" into oc-dr1-dev

This commit is contained in:
Lei Yu
2017-06-16 20:30:36 +00:00
committed by Android (Google) Code Review
2 changed files with 43 additions and 60 deletions

View File

@@ -21,7 +21,6 @@ import android.content.pm.PackageManager;
import android.os.BatteryStats; import android.os.BatteryStats;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import android.util.ArrayMap;
import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsHelper;
@@ -87,23 +86,10 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
continue; continue;
} }
final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = final long currentDurationMs = getCurrentDurationMs(uid, rawRealtime);
uid.getWakelockStats(); final long backgroundDurationMs = getBackgroundTotalDurationMs(uid, rawRealtime);
long maxPartialWakeLockMs = 0;
for (int iw = wakelocks.size() - 1; iw >= 0; iw--) { if (backgroundDurationMs > mWakeLockThresholdMs && currentDurationMs != 0) {
final BatteryStats.Timer timer = wakelocks.valueAt(iw).getWakeTime(
BatteryStats.WAKE_TYPE_PARTIAL);
if (timer == null) {
continue;
}
maxPartialWakeLockMs = Math.max(maxPartialWakeLockMs,
getTotalDurationMs(timer, rawRealtime));
}
// Report application as anomaly if wakelock time is too long
// TODO(b/38233034): add more attributes to detect wakelock anomaly
if (maxPartialWakeLockMs > mWakeLockThresholdMs) {
final String packageName = mBatteryUtils.getPackageName(uid.getUid()); final String packageName = mBatteryUtils.getPackageName(uid.getUid());
final CharSequence displayName = Utils.getApplicationLabel(mContext, final CharSequence displayName = Utils.getApplicationLabel(mContext,
packageName); packageName);
@@ -119,16 +105,22 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
anomalies.add(anomaly); anomalies.add(anomaly);
} }
} }
} }
return anomalies; return anomalies;
} }
@VisibleForTesting @VisibleForTesting
long getTotalDurationMs(BatteryStats.Timer timer, long rawRealtime) { long getCurrentDurationMs(BatteryStats.Uid uid, long elapsedRealtimeMs) {
if (timer == null) { BatteryStats.Timer timer = uid.getAggregatedPartialWakelockTimer();
return 0;
} return timer != null ? timer.getCurrentDurationMsLocked(elapsedRealtimeMs) : 0;
return timer.getTotalDurationMsLocked(rawRealtime); }
@VisibleForTesting
long getBackgroundTotalDurationMs(BatteryStats.Uid uid, long elapsedRealtimeMs) {
BatteryStats.Timer timer = uid.getAggregatedPartialWakelockTimer();
BatteryStats.Timer subTimer = timer != null ? timer.getSubTimer() : null;
return subTimer != null ? subTimer.getTotalDurationMsLocked(elapsedRealtimeMs) : 0;
} }
} }

View File

@@ -31,7 +31,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.BatteryStats; import android.os.BatteryStats;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.ArrayMap;
import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsHelper;
@@ -64,6 +63,7 @@ public class WakeLockAnomalyDetectorTest {
private static final int ANOMALY_UID = 111; private static final int ANOMALY_UID = 111;
private static final int NORMAL_UID = 222; private static final int NORMAL_UID = 222;
private static final int TARGET_UID = 333; private static final int TARGET_UID = 333;
private static final int INACTIVE_UID = 444;
@Mock @Mock
private BatteryStatsHelper mBatteryStatsHelper; private BatteryStatsHelper mBatteryStatsHelper;
@Mock @Mock
@@ -71,19 +71,9 @@ public class WakeLockAnomalyDetectorTest {
@Mock @Mock
private BatterySipper mTargetSipper; private BatterySipper mTargetSipper;
@Mock @Mock
private BatteryStats.Timer mAnomalyTimer;
@Mock
private BatteryStats.Uid.Wakelock mAnomalyWakelock;
@Mock
private BatterySipper mNormalSipper; private BatterySipper mNormalSipper;
@Mock @Mock
private BatteryStats.Timer mNormalTimer; private BatterySipper mInactiveSipper;
@Mock
private BatteryStats.Timer mTargetTimer;
@Mock
private BatteryStats.Uid.Wakelock mNormalWakelock;
@Mock
private BatteryStats.Uid.Wakelock mTargetWakelock;
@Mock @Mock
private BatteryStats.Uid mAnomalyUid; private BatteryStats.Uid mAnomalyUid;
@Mock @Mock
@@ -91,6 +81,8 @@ public class WakeLockAnomalyDetectorTest {
@Mock @Mock
private BatteryStats.Uid mTargetUid; private BatteryStats.Uid mTargetUid;
@Mock @Mock
private BatteryStats.Uid mInactiveUid;
@Mock
private BatteryUtils mBatteryUtils; private BatteryUtils mBatteryUtils;
@Mock @Mock
private PackageManager mPackageManager; private PackageManager mPackageManager;
@@ -101,9 +93,6 @@ public class WakeLockAnomalyDetectorTest {
@Mock @Mock
private AnomalyAction mAnomalyAction; private AnomalyAction mAnomalyAction;
private ArrayMap<String, BatteryStats.Uid.Wakelock> mAnomalyWakelocks;
private ArrayMap<String, BatteryStats.Uid.Wakelock> mNormalWakelocks;
private ArrayMap<String, BatteryStats.Uid.Wakelock> mTargetWakelocks;
private WakeLockAnomalyDetector mWakelockAnomalyDetector; private WakeLockAnomalyDetector mWakelockAnomalyDetector;
private Context mContext; private Context mContext;
private List<BatterySipper> mUsageList; private List<BatterySipper> mUsageList;
@@ -121,42 +110,44 @@ public class WakeLockAnomalyDetectorTest {
.getApplicationInfo(nullable(String.class), anyInt()); .getApplicationInfo(nullable(String.class), anyInt());
doReturn(true).when(mAnomalyAction).isActionActive(any()); doReturn(true).when(mAnomalyAction).isActionActive(any());
mWakelockAnomalyDetector = spy(new WakeLockAnomalyDetector(mContext, mPolicy));
mWakelockAnomalyDetector.mBatteryUtils = mBatteryUtils;
mWakelockAnomalyDetector.mAnomalyAction = mAnomalyAction;
mAnomalySipper.uidObj = mAnomalyUid; mAnomalySipper.uidObj = mAnomalyUid;
mAnomalyWakelocks = new ArrayMap<>(); doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector)
mAnomalyWakelocks.put("", mAnomalyWakelock); .getBackgroundTotalDurationMs(eq(mAnomalyUid), anyLong());
doReturn(mAnomalyWakelocks).when(mAnomalyUid).getWakelockStats(); doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getCurrentDurationMs(
doReturn(mAnomalyTimer).when(mAnomalyWakelock).getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); eq(mAnomalyUid), anyLong());
doReturn(ANOMALY_UID).when(mAnomalyUid).getUid(); doReturn(ANOMALY_UID).when(mAnomalyUid).getUid();
mNormalSipper.uidObj = mNormalUid; mNormalSipper.uidObj = mNormalUid;
mNormalWakelocks = new ArrayMap<>(); doReturn(NORMAL_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector)
mNormalWakelocks.put("", mNormalWakelock); .getBackgroundTotalDurationMs(eq(mNormalUid), anyLong());
doReturn(mNormalTimer).when(mNormalWakelock).getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); doReturn(0L).when(mWakelockAnomalyDetector).getCurrentDurationMs(eq(mNormalUid),
doReturn(mNormalWakelocks).when(mNormalUid).getWakelockStats(); anyLong());
doReturn(NORMAL_UID).when(mNormalUid).getUid(); doReturn(NORMAL_UID).when(mNormalUid).getUid();
mTargetSipper.uidObj = mTargetUid; mTargetSipper.uidObj = mTargetUid;
mTargetWakelocks = new ArrayMap<>(); doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector)
mTargetWakelocks.put("", mTargetWakelock); .getBackgroundTotalDurationMs(eq(mTargetUid), anyLong());
doReturn(mTargetTimer).when(mTargetWakelock).getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getCurrentDurationMs(
doReturn(mTargetWakelocks).when(mTargetUid).getWakelockStats(); eq(mTargetUid), anyLong());
doReturn(TARGET_UID).when(mTargetUid).getUid(); doReturn(TARGET_UID).when(mTargetUid).getUid();
mInactiveSipper.uidObj = mInactiveUid;
doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector)
.getBackgroundTotalDurationMs(eq(mInactiveUid), anyLong());
doReturn(0L).when(mWakelockAnomalyDetector).getCurrentDurationMs(eq(mInactiveUid),
anyLong());
doReturn(INACTIVE_UID).when(mInactiveUid).getUid();
mUsageList = new ArrayList<>(); mUsageList = new ArrayList<>();
mUsageList.add(mAnomalySipper); mUsageList.add(mAnomalySipper);
mUsageList.add(mNormalSipper); mUsageList.add(mNormalSipper);
mUsageList.add(mTargetSipper); mUsageList.add(mTargetSipper);
mUsageList.add(mInactiveSipper);
doReturn(mUsageList).when(mBatteryStatsHelper).getUsageList(); doReturn(mUsageList).when(mBatteryStatsHelper).getUsageList();
mWakelockAnomalyDetector = spy(new WakeLockAnomalyDetector(mContext, mPolicy));
mWakelockAnomalyDetector.mBatteryUtils = mBatteryUtils;
mWakelockAnomalyDetector.mAnomalyAction = mAnomalyAction;
doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getTotalDurationMs(
eq(mAnomalyTimer), anyLong());
doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getTotalDurationMs(
eq(mTargetTimer), anyLong());
doReturn(NORMAL_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getTotalDurationMs(
eq(mNormalTimer), anyLong());
} }
@Test @Test