Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43afb664 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add metric action log for anomaly action" into oc-dr1-dev

parents 9df70249 ac29684b
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -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();
}
+7 −9
Original line number Diff line number Diff line
@@ -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);
    }
+6 −17
Original line number Diff line number Diff line
@@ -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
+6 −6
Original line number Diff line number Diff line
@@ -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);
    }
+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;
        }
    }
}