Merge "Add action active check for anomaly action." into oc-dr1-dev am: e7735b8d52

am: 010c9d9535

Change-Id: I5d7d02d5387b8d58d8ea6f158311c1aae659fe19
This commit is contained in:
jackqdyulei
2017-06-13 23:58:14 +00:00
committed by android-build-merger
9 changed files with 112 additions and 10 deletions

View File

@@ -24,11 +24,18 @@ import com.android.settings.fuelgauge.anomaly.Anomaly;
public interface AnomalyAction { public interface AnomalyAction {
/** /**
* handle the action when user clicks positive button * handle the action when user clicks positive button
* @param Anomaly about the app that we need to handle * @param anomaly about the app that we need to handle
* @param metricsKey key for the page that invokes the action * @param metricsKey key for the page that invokes the action
* *
* @see com.android.internal.logging.nano.MetricsProto * @see com.android.internal.logging.nano.MetricsProto
*/ */
void handlePositiveAction(Anomaly Anomaly, int metricsKey); void handlePositiveAction(Anomaly anomaly, int metricsKey);
/**
* Check whether the action is active for {@code anomaly}
* @param anomaly about the app that we need to handle
* @return {@code true} if action is active, otherwise return {@code false}
*/
boolean isActionActive(Anomaly anomaly);
int getActionType(); int getActionType();
} }

View File

@@ -45,6 +45,14 @@ public class BackgroundCheckAction implements AnomalyAction {
AppOpsManager.MODE_IGNORED); AppOpsManager.MODE_IGNORED);
} }
@Override
public boolean isActionActive(Anomaly anomaly) {
final int mode = mAppOpsManager
.checkOpNoThrow(AppOpsManager.OP_RUN_IN_BACKGROUND, anomaly.uid,
anomaly.packageName);
return mode != AppOpsManager.MODE_IGNORED && mode != AppOpsManager.MODE_ERRORED;
}
@Override @Override
public int getActionType() { public int getActionType() {
return Anomaly.AnomalyActionType.BACKGROUND_CHECK; return Anomaly.AnomalyActionType.BACKGROUND_CHECK;

View File

@@ -18,6 +18,9 @@ package com.android.settings.fuelgauge.anomaly.action;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
@@ -25,20 +28,25 @@ import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import java.util.List;
/** /**
* Force stop action for anomaly app, which means to stop the app which causes anomaly * Force stop action for anomaly app, which means to stop the app which causes anomaly
*/ */
public class ForceStopAction implements AnomalyAction { public class ForceStopAction implements AnomalyAction {
private static final String TAG = "ForceStopAction";
private Context mContext; private Context mContext;
private MetricsFeatureProvider mMetricsFeatureProvider; private MetricsFeatureProvider mMetricsFeatureProvider;
private ActivityManager mActivityManager; private ActivityManager mActivityManager;
private PackageManager mPackageManager;
public ForceStopAction(Context context) { public ForceStopAction(Context context) {
mContext = context; mContext = context;
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mActivityManager = (ActivityManager) context.getSystemService( mActivityManager = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE); Context.ACTIVITY_SERVICE);
mPackageManager = context.getPackageManager();
} }
@Override @Override
@@ -52,6 +60,18 @@ public class ForceStopAction implements AnomalyAction {
mActivityManager.forceStopPackage(packageName); mActivityManager.forceStopPackage(packageName);
} }
@Override
public boolean isActionActive(Anomaly anomaly) {
try {
ApplicationInfo info = mPackageManager.getApplicationInfo(anomaly.packageName,
PackageManager.GET_META_DATA);
return (info.flags & ApplicationInfo.FLAG_STOPPED) == 0;
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Cannot find info for app: " + anomaly.packageName);
}
return false;
}
@Override @Override
public int getActionType() { public int getActionType() {
return Anomaly.AnomalyActionType.FORCE_STOP; return Anomaly.AnomalyActionType.FORCE_STOP;

View File

@@ -17,14 +17,11 @@
package com.android.settings.fuelgauge.anomaly.checker; package com.android.settings.fuelgauge.anomaly.checker;
import android.content.Context; import android.content.Context;
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.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsHelper;
@@ -32,6 +29,8 @@ import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -47,6 +46,8 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
BatteryUtils mBatteryUtils; BatteryUtils mBatteryUtils;
@VisibleForTesting @VisibleForTesting
long mWakeLockThresholdMs; long mWakeLockThresholdMs;
@VisibleForTesting
AnomalyAction mAnomalyAction;
public WakeLockAnomalyDetector(Context context) { public WakeLockAnomalyDetector(Context context) {
this(context, new AnomalyDetectionPolicy(context)); this(context, new AnomalyDetectionPolicy(context));
@@ -57,6 +58,8 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
mContext = context; mContext = context;
mPackageManager = context.getPackageManager(); mPackageManager = context.getPackageManager();
mBatteryUtils = BatteryUtils.getInstance(context); mBatteryUtils = BatteryUtils.getInstance(context);
mAnomalyAction = AnomalyUtils.getInstance(context).getAnomalyAction(
Anomaly.AnomalyType.WAKE_LOCK);
mWakeLockThresholdMs = policy.wakeLockThreshold; mWakeLockThresholdMs = policy.wakeLockThreshold;
} }
@@ -111,8 +114,11 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
.setDisplayName(displayName) .setDisplayName(displayName)
.setPackageName(packageName) .setPackageName(packageName)
.build(); .build();
if (mAnomalyAction.isActionActive(anomaly)) {
anomalies.add(anomaly); anomalies.add(anomaly);
} }
}
} }
return anomalies; return anomalies;

View File

@@ -17,9 +17,7 @@
package com.android.settings.fuelgauge.anomaly.checker; package com.android.settings.fuelgauge.anomaly.checker;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager;
import android.os.BatteryStats; import android.os.BatteryStats;
import android.os.SystemClock;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.ArrayMap; import android.util.ArrayMap;
@@ -30,6 +28,8 @@ import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -41,6 +41,8 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
private static final String TAG = "WakeupAlarmAnomalyDetector"; private static final String TAG = "WakeupAlarmAnomalyDetector";
@VisibleForTesting @VisibleForTesting
BatteryUtils mBatteryUtils; BatteryUtils mBatteryUtils;
@VisibleForTesting
AnomalyAction mAnomalyAction;
private long mWakeupAlarmThreshold; private long mWakeupAlarmThreshold;
private Context mContext; private Context mContext;
@@ -52,6 +54,8 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
WakeupAlarmAnomalyDetector(Context context, AnomalyDetectionPolicy policy) { WakeupAlarmAnomalyDetector(Context context, AnomalyDetectionPolicy policy) {
mContext = context; mContext = context;
mBatteryUtils = BatteryUtils.getInstance(context); mBatteryUtils = BatteryUtils.getInstance(context);
mAnomalyAction = AnomalyUtils.getInstance(context).getAnomalyAction(
Anomaly.AnomalyType.WAKEUP_ALARM);
mWakeupAlarmThreshold = policy.wakeupAlarmThreshold; mWakeupAlarmThreshold = policy.wakeupAlarmThreshold;
} }
@@ -91,10 +95,13 @@ public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
.setDisplayName(displayName) .setDisplayName(displayName)
.setPackageName(packageName) .setPackageName(packageName)
.build(); .build();
if (mAnomalyAction.isActionActive(anomaly)) {
anomalies.add(anomaly); anomalies.add(anomaly);
} }
} }
} }
}
return anomalies; return anomalies;
} }

View File

@@ -16,6 +16,8 @@
package com.android.settings.fuelgauge.anomaly.action; package com.android.settings.fuelgauge.anomaly.action;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -69,4 +71,20 @@ public class BackgroundCheckActionTest {
verify(mAppOpsManagerr).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME, verify(mAppOpsManagerr).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME,
AppOpsManager.MODE_IGNORED); AppOpsManager.MODE_IGNORED);
} }
@Test
public void testIsActionActive_modeAllowed_returnTrue() {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManagerr).checkOpNoThrow(
AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME);
assertThat(mBackgroundCheckAction.isActionActive(mAnomaly)).isTrue();
}
@Test
public void testIsActionActive_modeIgnored_returnFalse() {
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManagerr).checkOpNoThrow(
AppOpsManager.OP_RUN_IN_BACKGROUND, UID, PACKAGE_NAME);
assertThat(mBackgroundCheckAction.isActionActive(mAnomaly)).isFalse();
}
} }

View File

@@ -16,11 +16,15 @@
package com.android.settings.fuelgauge.anomaly.action; package com.android.settings.fuelgauge.anomaly.action;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
@@ -44,15 +48,22 @@ public class ForceStopActionTest {
private Context mContext; private Context mContext;
@Mock @Mock
private ActivityManager mActivityManager; private ActivityManager mActivityManager;
@Mock
private ApplicationInfo mApplicationInfo;
@Mock
private PackageManager mPackageManager;
private Anomaly mAnomaly; private Anomaly mAnomaly;
private ForceStopAction mForceStopAction; private ForceStopAction mForceStopAction;
@Before @Before
public void setUp() { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext); FakeFeatureFactory.setupForTest(mContext);
doReturn(mActivityManager).when(mContext).getSystemService(Context.ACTIVITY_SERVICE); doReturn(mActivityManager).when(mContext).getSystemService(Context.ACTIVITY_SERVICE);
doReturn(mPackageManager).when(mContext).getPackageManager();
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME,
PackageManager.GET_META_DATA);
mAnomaly = new Anomaly.Builder() mAnomaly = new Anomaly.Builder()
.setPackageName(PACKAGE_NAME) .setPackageName(PACKAGE_NAME)
@@ -66,4 +77,18 @@ public class ForceStopActionTest {
verify(mActivityManager).forceStopPackage(PACKAGE_NAME); verify(mActivityManager).forceStopPackage(PACKAGE_NAME);
} }
@Test
public void testIsActionActive_appStopped_returnFalse() {
mApplicationInfo.flags = ApplicationInfo.FLAG_STOPPED;
assertThat(mForceStopAction.isActionActive(mAnomaly)).isFalse();
}
@Test
public void testIsActionActive_appRunning_returnTrue() {
mApplicationInfo.flags = 0;
assertThat(mForceStopAction.isActionActive(mAnomaly)).isTrue();
}
} }

View File

@@ -19,6 +19,7 @@ package com.android.settings.fuelgauge.anomaly.checker;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
@@ -39,6 +40,7 @@ import com.android.settings.TestConfig;
import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -96,6 +98,8 @@ public class WakeLockAnomalyDetectorTest {
private ApplicationInfo mApplicationInfo; private ApplicationInfo mApplicationInfo;
@Mock @Mock
private AnomalyDetectionPolicy mPolicy; private AnomalyDetectionPolicy mPolicy;
@Mock
private AnomalyAction mAnomalyAction;
private ArrayMap<String, BatteryStats.Uid.Wakelock> mAnomalyWakelocks; private ArrayMap<String, BatteryStats.Uid.Wakelock> mAnomalyWakelocks;
private ArrayMap<String, BatteryStats.Uid.Wakelock> mNormalWakelocks; private ArrayMap<String, BatteryStats.Uid.Wakelock> mNormalWakelocks;
@@ -115,6 +119,7 @@ public class WakeLockAnomalyDetectorTest {
doReturn(mPackageManager).when(mContext).getPackageManager(); doReturn(mPackageManager).when(mContext).getPackageManager();
doReturn(mApplicationInfo).when(mPackageManager) doReturn(mApplicationInfo).when(mPackageManager)
.getApplicationInfo(nullable(String.class), anyInt()); .getApplicationInfo(nullable(String.class), anyInt());
doReturn(true).when(mAnomalyAction).isActionActive(any());
mAnomalySipper.uidObj = mAnomalyUid; mAnomalySipper.uidObj = mAnomalyUid;
mAnomalyWakelocks = new ArrayMap<>(); mAnomalyWakelocks = new ArrayMap<>();
@@ -145,6 +150,7 @@ public class WakeLockAnomalyDetectorTest {
mWakelockAnomalyDetector = spy(new WakeLockAnomalyDetector(mContext, mPolicy)); mWakelockAnomalyDetector = spy(new WakeLockAnomalyDetector(mContext, mPolicy));
mWakelockAnomalyDetector.mBatteryUtils = mBatteryUtils; mWakelockAnomalyDetector.mBatteryUtils = mBatteryUtils;
mWakelockAnomalyDetector.mAnomalyAction = mAnomalyAction;
doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getTotalDurationMs( doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getTotalDurationMs(
eq(mAnomalyTimer), anyLong()); eq(mAnomalyTimer), anyLong());
doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getTotalDurationMs( doReturn(ANOMALY_WAKELOCK_TIME_MS).when(mWakelockAnomalyDetector).getTotalDurationMs(

View File

@@ -38,6 +38,7 @@ import com.android.settings.TestConfig;
import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy; import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;
import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -85,6 +86,8 @@ public class WakeupAlarmAnomalyDetectorTest {
private BatteryStats.Counter mCounter; private BatteryStats.Counter mCounter;
@Mock @Mock
private AnomalyDetectionPolicy mPolicy; private AnomalyDetectionPolicy mPolicy;
@Mock
private AnomalyAction mAnomalyAction;
private WakeupAlarmAnomalyDetector mWakeupAlarmAnomalyDetector; private WakeupAlarmAnomalyDetector mWakeupAlarmAnomalyDetector;
private Context mContext; private Context mContext;
@@ -100,6 +103,7 @@ public class WakeupAlarmAnomalyDetectorTest {
doReturn(false).when(mBatteryUtils).shouldHideSipper(any()); doReturn(false).when(mBatteryUtils).shouldHideSipper(any());
doReturn(RUNNING_TIME_MS).when(mBatteryUtils).calculateRunningTimeBasedOnStatsType(any(), doReturn(RUNNING_TIME_MS).when(mBatteryUtils).calculateRunningTimeBasedOnStatsType(any(),
anyInt()); anyInt());
doReturn(true).when(mAnomalyAction).isActionActive(any());
mAnomalySipper.uidObj = mAnomalyUid; mAnomalySipper.uidObj = mAnomalyUid;
doReturn(ANOMALY_UID).when(mAnomalyUid).getUid(); doReturn(ANOMALY_UID).when(mAnomalyUid).getUid();
@@ -116,6 +120,7 @@ public class WakeupAlarmAnomalyDetectorTest {
mWakeupAlarmAnomalyDetector = spy(new WakeupAlarmAnomalyDetector(mContext, mPolicy)); mWakeupAlarmAnomalyDetector = spy(new WakeupAlarmAnomalyDetector(mContext, mPolicy));
mWakeupAlarmAnomalyDetector.mBatteryUtils = mBatteryUtils; mWakeupAlarmAnomalyDetector.mBatteryUtils = mBatteryUtils;
mWakeupAlarmAnomalyDetector.mAnomalyAction = mAnomalyAction;
} }
@Test @Test