Loading src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java +28 −7 Original line number Diff line number Diff line Loading @@ -16,26 +16,47 @@ package com.android.settings.fuelgauge.anomaly.action; import android.content.Context; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; /** * Interface for anomaly action, which is triggered if we need to handle the anomaly * Abstract class for anomaly action, which is triggered if we need to handle the anomaly */ public interface AnomalyAction { public abstract class AnomalyAction { protected Context mContext; protected int mActionMetricKey; private MetricsFeatureProvider mMetricsFeatureProvider; public AnomalyAction(Context context) { mContext = context; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } /** * handle the action when user clicks positive button * @param anomaly about the app that we need to handle * @param metricsKey key for the page that invokes the action * * @param anomaly about the app that we need to handle * @param contextMetricsKey key for the page that invokes the action * @see com.android.internal.logging.nano.MetricsProto */ void handlePositiveAction(Anomaly anomaly, int metricsKey); public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { mMetricsFeatureProvider.action(mContext, mActionMetricKey, anomaly.packageName, Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, contextMetricsKey)); } /** * 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(); public abstract boolean isActionActive(Anomaly anomaly); public abstract int getActionType(); } src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckAction.java +7 −9 Original line number Diff line number Diff line Loading @@ -19,28 +19,26 @@ package com.android.settings.fuelgauge.anomaly.action; import android.app.AppOpsManager; import android.content.Context; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; /** * Background check action for anomaly app, which means to stop app running in the background */ public class BackgroundCheckAction implements AnomalyAction { public class BackgroundCheckAction extends AnomalyAction { private Context mContext; private MetricsFeatureProvider mMetricsFeatureProvider; private AppOpsManager mAppOpsManager; public BackgroundCheckAction(Context context) { mContext = context; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); super(context); mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mActionMetricKey = MetricsProto.MetricsEvent.ACTION_APP_BACKGROUND_CHECK; } @Override public void handlePositiveAction(Anomaly anomaly, int metricsKey) { // TODO(b/37681923): add metric log here if possible public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { super.handlePositiveAction(anomaly, contextMetricsKey); mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, anomaly.uid, anomaly.packageName, AppOpsManager.MODE_IGNORED); } Loading src/com/android/settings/fuelgauge/anomaly/action/ForceStopAction.java +6 −17 Original line number Diff line number Diff line Loading @@ -21,43 +21,32 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.util.Log; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.Anomaly; 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 */ public class ForceStopAction implements AnomalyAction { public class ForceStopAction extends AnomalyAction { private static final String TAG = "ForceStopAction"; private Context mContext; private MetricsFeatureProvider mMetricsFeatureProvider; private ActivityManager mActivityManager; private PackageManager mPackageManager; public ForceStopAction(Context context) { mContext = context; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); super(context); mActivityManager = (ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE); mPackageManager = context.getPackageManager(); mActionMetricKey = MetricsProto.MetricsEvent.ACTION_APP_FORCE_STOP; } @Override public void handlePositiveAction(Anomaly anomaly, int metricsKey) { final String packageName = anomaly.packageName; // force stop the package mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_FORCE_STOP, packageName, Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey)); public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { super.handlePositiveAction(anomaly, contextMetricsKey); mActivityManager.forceStopPackage(packageName); mActivityManager.forceStopPackage(anomaly.packageName); } @Override Loading src/com/android/settings/fuelgauge/anomaly/action/LocationCheckAction.java +6 −6 Original line number Diff line number Diff line Loading @@ -20,28 +20,28 @@ import android.content.Context; import android.content.pm.permission.RuntimePermissionPresenter; import android.support.v4.content.PermissionChecker; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; /** * Location action for anomaly app, which means to turn off location permission for this app */ public class LocationCheckAction implements AnomalyAction { public class LocationCheckAction extends AnomalyAction { private static final String TAG = "LocationCheckAction"; private static final String LOCATION_PERMISSION = "android.permission-group.LOCATION"; private final Context mContext; private final RuntimePermissionPresenter mRuntimePermissionPresenter; public LocationCheckAction(Context context) { mContext = context; super(context); mRuntimePermissionPresenter = RuntimePermissionPresenter.getInstance(context); mActionMetricKey = MetricsProto.MetricsEvent.ACTION_APP_LOCATION_CHECK; } @Override public void handlePositiveAction(Anomaly anomaly, int metricsKey) { public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { super.handlePositiveAction(anomaly, contextMetricsKey); mRuntimePermissionPresenter.revokeRuntimePermission(anomaly.packageName, LOCATION_PERMISSION); } Loading tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/AnomalyActionTest.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.fuelgauge.anomaly.action; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import android.app.AppOpsManager; import android.content.Context; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.TestConfig; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class AnomalyActionTest { private static final String PACKAGE_NAME = "com.android.app"; private static final int UID = 111; private static final int ACTION_KEY = 2; private static final int METRIC_KEY = 3; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock private AppOpsManager mAppOpsManagerr; private Anomaly mAnomaly; private TestAnomalyAction mTestAnomalyAction; private FakeFeatureFactory mFeatureFactory; @Before public void setUp() { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(mContext); mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); doReturn(mAppOpsManagerr).when(mContext).getSystemService(Context.APP_OPS_SERVICE); mAnomaly = new Anomaly.Builder() .setUid(UID) .setPackageName(PACKAGE_NAME) .build(); mTestAnomalyAction = new TestAnomalyAction(mContext); } @Test public void testHandlePositiveAction_logAction() { mTestAnomalyAction.handlePositiveAction(mAnomaly, METRIC_KEY); verify(mFeatureFactory.metricsFeatureProvider).action(mContext, ACTION_KEY, PACKAGE_NAME, Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, METRIC_KEY)); } /** * Test class for {@link AnomalyAction} */ public class TestAnomalyAction extends AnomalyAction { public TestAnomalyAction(Context context) { super(context); mActionMetricKey = ACTION_KEY; } @Override public boolean isActionActive(Anomaly anomaly) { return false; } @Override public int getActionType() { return 0; } } } Loading
src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java +28 −7 Original line number Diff line number Diff line Loading @@ -16,26 +16,47 @@ package com.android.settings.fuelgauge.anomaly.action; import android.content.Context; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; /** * Interface for anomaly action, which is triggered if we need to handle the anomaly * Abstract class for anomaly action, which is triggered if we need to handle the anomaly */ public interface AnomalyAction { public abstract class AnomalyAction { protected Context mContext; protected int mActionMetricKey; private MetricsFeatureProvider mMetricsFeatureProvider; public AnomalyAction(Context context) { mContext = context; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } /** * handle the action when user clicks positive button * @param anomaly about the app that we need to handle * @param metricsKey key for the page that invokes the action * * @param anomaly about the app that we need to handle * @param contextMetricsKey key for the page that invokes the action * @see com.android.internal.logging.nano.MetricsProto */ void handlePositiveAction(Anomaly anomaly, int metricsKey); public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { mMetricsFeatureProvider.action(mContext, mActionMetricKey, anomaly.packageName, Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, contextMetricsKey)); } /** * 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(); public abstract boolean isActionActive(Anomaly anomaly); public abstract int getActionType(); }
src/com/android/settings/fuelgauge/anomaly/action/BackgroundCheckAction.java +7 −9 Original line number Diff line number Diff line Loading @@ -19,28 +19,26 @@ package com.android.settings.fuelgauge.anomaly.action; import android.app.AppOpsManager; import android.content.Context; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; /** * Background check action for anomaly app, which means to stop app running in the background */ public class BackgroundCheckAction implements AnomalyAction { public class BackgroundCheckAction extends AnomalyAction { private Context mContext; private MetricsFeatureProvider mMetricsFeatureProvider; private AppOpsManager mAppOpsManager; public BackgroundCheckAction(Context context) { mContext = context; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); super(context); mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mActionMetricKey = MetricsProto.MetricsEvent.ACTION_APP_BACKGROUND_CHECK; } @Override public void handlePositiveAction(Anomaly anomaly, int metricsKey) { // TODO(b/37681923): add metric log here if possible public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { super.handlePositiveAction(anomaly, contextMetricsKey); mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, anomaly.uid, anomaly.packageName, AppOpsManager.MODE_IGNORED); } Loading
src/com/android/settings/fuelgauge/anomaly/action/ForceStopAction.java +6 −17 Original line number Diff line number Diff line Loading @@ -21,43 +21,32 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.util.Log; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.fuelgauge.anomaly.Anomaly; 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 */ public class ForceStopAction implements AnomalyAction { public class ForceStopAction extends AnomalyAction { private static final String TAG = "ForceStopAction"; private Context mContext; private MetricsFeatureProvider mMetricsFeatureProvider; private ActivityManager mActivityManager; private PackageManager mPackageManager; public ForceStopAction(Context context) { mContext = context; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); super(context); mActivityManager = (ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE); mPackageManager = context.getPackageManager(); mActionMetricKey = MetricsProto.MetricsEvent.ACTION_APP_FORCE_STOP; } @Override public void handlePositiveAction(Anomaly anomaly, int metricsKey) { final String packageName = anomaly.packageName; // force stop the package mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_FORCE_STOP, packageName, Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey)); public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { super.handlePositiveAction(anomaly, contextMetricsKey); mActivityManager.forceStopPackage(packageName); mActivityManager.forceStopPackage(anomaly.packageName); } @Override Loading
src/com/android/settings/fuelgauge/anomaly/action/LocationCheckAction.java +6 −6 Original line number Diff line number Diff line Loading @@ -20,28 +20,28 @@ import android.content.Context; import android.content.pm.permission.RuntimePermissionPresenter; import android.support.v4.content.PermissionChecker; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; /** * Location action for anomaly app, which means to turn off location permission for this app */ public class LocationCheckAction implements AnomalyAction { public class LocationCheckAction extends AnomalyAction { private static final String TAG = "LocationCheckAction"; private static final String LOCATION_PERMISSION = "android.permission-group.LOCATION"; private final Context mContext; private final RuntimePermissionPresenter mRuntimePermissionPresenter; public LocationCheckAction(Context context) { mContext = context; super(context); mRuntimePermissionPresenter = RuntimePermissionPresenter.getInstance(context); mActionMetricKey = MetricsProto.MetricsEvent.ACTION_APP_LOCATION_CHECK; } @Override public void handlePositiveAction(Anomaly anomaly, int metricsKey) { public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) { super.handlePositiveAction(anomaly, contextMetricsKey); mRuntimePermissionPresenter.revokeRuntimePermission(anomaly.packageName, LOCATION_PERMISSION); } Loading
tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/AnomalyActionTest.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.fuelgauge.anomaly.action; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import android.app.AppOpsManager; import android.content.Context; import android.util.Pair; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.TestConfig; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class AnomalyActionTest { private static final String PACKAGE_NAME = "com.android.app"; private static final int UID = 111; private static final int ACTION_KEY = 2; private static final int METRIC_KEY = 3; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock private AppOpsManager mAppOpsManagerr; private Anomaly mAnomaly; private TestAnomalyAction mTestAnomalyAction; private FakeFeatureFactory mFeatureFactory; @Before public void setUp() { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(mContext); mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); doReturn(mAppOpsManagerr).when(mContext).getSystemService(Context.APP_OPS_SERVICE); mAnomaly = new Anomaly.Builder() .setUid(UID) .setPackageName(PACKAGE_NAME) .build(); mTestAnomalyAction = new TestAnomalyAction(mContext); } @Test public void testHandlePositiveAction_logAction() { mTestAnomalyAction.handlePositiveAction(mAnomaly, METRIC_KEY); verify(mFeatureFactory.metricsFeatureProvider).action(mContext, ACTION_KEY, PACKAGE_NAME, Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, METRIC_KEY)); } /** * Test class for {@link AnomalyAction} */ public class TestAnomalyAction extends AnomalyAction { public TestAnomalyAction(Context context) { super(context); mActionMetricKey = ACTION_KEY; } @Override public boolean isActionActive(Anomaly anomaly) { return false; } @Override public int getActionType() { return 0; } } }