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

Commit dff144ad authored by jackqdyulei's avatar jackqdyulei
Browse files

Turn on bluetooth anomaly detector

Since the related bug in battery stats is fixed, it is safe to
turn it on.

Also fix a bug in LocationCheckAction. In PermissionChecker we should
use permission name to check, not permission group name.

Bug: 64255601
Test: RunSettingsRoboTests
Change-Id: Ief8b5dc98f8a7ae462eb84936f6f61d626d7cddd
parent 0782535d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ public class AnomalyDetectionPolicy {
        wakeupAlarmDetectionEnabled = mParserWrapper.getBoolean(KEY_WAKEUP_ALARM_DETECTION_ENABLED,
                false);
        bluetoothScanDetectionEnabled = mParserWrapper.getBoolean(
                KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, false);
                KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true);
        wakeLockThreshold = mParserWrapper.getLong(KEY_WAKELOCK_THRESHOLD,
                DateUtils.HOUR_IN_MILLIS);
        wakeupAlarmThreshold = mParserWrapper.getLong(KEY_WAKEUP_ALARM_THRESHOLD, 60);
+16 −5
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.settings.fuelgauge.anomaly.action;

import android.Manifest;
import android.content.Context;
import android.content.pm.permission.RuntimePermissionPresenter;
import android.support.annotation.VisibleForTesting;
import android.support.v4.content.PermissionChecker;

import com.android.internal.logging.nano.MetricsProto;
@@ -29,13 +31,17 @@ import com.android.settings.fuelgauge.anomaly.Anomaly;
public class LocationCheckAction extends AnomalyAction {

    private static final String TAG = "LocationCheckAction";
    private static final String LOCATION_PERMISSION = "android.permission-group.LOCATION";

    private final RuntimePermissionPresenter mRuntimePermissionPresenter;

    public LocationCheckAction(Context context) {
        this(context, RuntimePermissionPresenter.getInstance(context));
    }

    @VisibleForTesting
    LocationCheckAction(Context context, RuntimePermissionPresenter runtimePermissionPresenter) {
        super(context);
        mRuntimePermissionPresenter = RuntimePermissionPresenter.getInstance(context);
        mRuntimePermissionPresenter = runtimePermissionPresenter;
        mActionMetricKey = MetricsProto.MetricsEvent.ACTION_APP_LOCATION_CHECK;
    }

@@ -43,17 +49,22 @@ public class LocationCheckAction extends AnomalyAction {
    public void handlePositiveAction(Anomaly anomaly, int contextMetricsKey) {
        super.handlePositiveAction(anomaly, contextMetricsKey);
        mRuntimePermissionPresenter.revokeRuntimePermission(anomaly.packageName,
                LOCATION_PERMISSION);
                Manifest.permission_group.LOCATION);
    }

    @Override
    public boolean isActionActive(Anomaly anomaly) {
        return PermissionChecker.checkPermission(mContext, LOCATION_PERMISSION, -1, anomaly.uid,
                anomaly.packageName) == PermissionChecker.PERMISSION_GRANTED;
        return isPermissionGranted(anomaly, Manifest.permission.ACCESS_COARSE_LOCATION)
                || isPermissionGranted(anomaly, Manifest.permission.ACCESS_FINE_LOCATION);
    }

    @Override
    public int getActionType() {
        return Anomaly.AnomalyActionType.LOCATION_CHECK;
    }

    private boolean isPermissionGranted(Anomaly anomaly, String permission) {
        return PermissionChecker.checkPermission(mContext, permission, -1, anomaly.uid,
                anomaly.packageName) == PermissionChecker.PERMISSION_GRANTED;
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ public class AnomalyDetectionPolicyTest {
        assertThat(anomalyDetectionPolicy.wakeLockThreshold).isEqualTo(DateUtils.HOUR_IN_MILLIS);
        assertThat(anomalyDetectionPolicy.wakeupAlarmDetectionEnabled).isFalse();
        assertThat(anomalyDetectionPolicy.wakeupAlarmThreshold).isEqualTo(60);
        assertThat(anomalyDetectionPolicy.bluetoothScanDetectionEnabled).isFalse();
        assertThat(anomalyDetectionPolicy.bluetoothScanDetectionEnabled).isTrue();
        assertThat(anomalyDetectionPolicy.bluetoothScanThreshold).isEqualTo(
                30 * DateUtils.MINUTE_IN_MILLIS);
    }
@@ -114,7 +114,7 @@ public class AnomalyDetectionPolicyTest {
        doReturn(true).when(mKeyValueListParserWrapper).getBoolean(
                AnomalyDetectionPolicy.KEY_WAKEUP_ALARM_DETECTION_ENABLED, false);
        doReturn(true).when(mKeyValueListParserWrapper).getBoolean(
                AnomalyDetectionPolicy.KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, false);
                AnomalyDetectionPolicy.KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true);

        return new AnomalyDetectionPolicy(mContext, mKeyValueListParserWrapper);
    }
+85 −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 com.google.common.truth.Truth.assertThat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;

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 com.android.settings.testutils.shadow.ShadowPermissionChecker;

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, shadows =
        ShadowPermissionChecker.class)
public class LocationCheckActionTest {
    private static final String PACKAGE_NAME = "com.android.app";
    private static final int UID = 12345;

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Context mContext;
    private Anomaly mAnomaly;
    private LocationCheckAction mLocationCheckAction;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        FakeFeatureFactory.setupForTest(mContext);
        mLocationCheckAction = new LocationCheckAction(mContext, null);
        mAnomaly = new Anomaly.Builder()
                .setType(Anomaly.AnomalyType.BLUETOOTH_SCAN)
                .setPackageName(PACKAGE_NAME)
                .setUid(UID)
                .build();
        ShadowPermissionChecker.clear();
    }

    @Test
    public void testIsActionActive_coarseLocationGranted_returnTrue() {
        ShadowPermissionChecker.addPermission(Manifest.permission.ACCESS_COARSE_LOCATION, -1, UID,
                PACKAGE_NAME, PackageManager.PERMISSION_GRANTED);

        assertThat(mLocationCheckAction.isActionActive(mAnomaly)).isTrue();
    }

    @Test
    public void testIsActionActive_fineLocationGranted_returnTrue() {
        ShadowPermissionChecker.addPermission(Manifest.permission.ACCESS_FINE_LOCATION, -1, UID,
                PACKAGE_NAME, PackageManager.PERMISSION_GRANTED);

        assertThat(mLocationCheckAction.isActionActive(mAnomaly)).isTrue();
    }

    @Test
    public void testIsActionActive_noLocationGranted_returnFalse() {
        assertThat(mLocationCheckAction.isActionActive(mAnomaly)).isFalse();
    }

}
+90 −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.testutils.shadow;

import android.content.Context;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.content.PermissionChecker;
import android.text.TextUtils;

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * This class provides shadow for API that is not supported in current roboletric
 */
@Implements(PermissionChecker.class)
public class ShadowPermissionChecker {

    private static Map<PermissionInfo, Integer> sPermissions = new HashMap<>();

    public static void clear() {
        sPermissions.clear();
    }

    public static void addPermission(String permission, int pid, int uid, String packageName,
            int permissionValue) {
        sPermissions.put(new PermissionInfo(permission, pid, uid, packageName), permissionValue);
    }

    @Implementation
    public static int checkPermission(@NonNull Context context, @NonNull String permission,
            int pid, int uid, String packageName) {
        return sPermissions.getOrDefault(new PermissionInfo(permission, pid, uid, packageName),
                PackageManager.PERMISSION_DENIED);
    }

    private static class PermissionInfo {
        private final int mPid;
        private final int mUid;
        private final String mPackageName;
        private final String mPermission;

        public PermissionInfo(String permission, int pid, int uid, String packageName) {
            mPid = pid;
            mUid = uid;
            mPackageName = packageName;
            mPermission = permission;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof PermissionInfo)) {
                return false;
            }

            final PermissionInfo other = (PermissionInfo) obj;
            return mPid == other.mPid
                    && mUid == other.mUid
                    && TextUtils.equals(mPackageName, other.mPackageName)
                    && TextUtils.equals(mPermission, other.mPermission);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mPid, mUid, mPackageName, mPermission);
        }
    }
}