diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java index 23c70bb48bf..0c401b500f5 100644 --- a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java +++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java @@ -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); diff --git a/src/com/android/settings/fuelgauge/anomaly/action/LocationCheckAction.java b/src/com/android/settings/fuelgauge/anomaly/action/LocationCheckAction.java index 6779828e30b..b0e34fa9e0f 100644 --- a/src/com/android/settings/fuelgauge/anomaly/action/LocationCheckAction.java +++ b/src/com/android/settings/fuelgauge/anomaly/action/LocationCheckAction.java @@ -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; + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java index 07727c326dd..914cc2f514d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java @@ -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); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/LocationCheckActionTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/LocationCheckActionTest.java new file mode 100644 index 00000000000..234dd123401 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/action/LocationCheckActionTest.java @@ -0,0 +1,85 @@ +/* + * 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(); + } + +} diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPermissionChecker.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPermissionChecker.java new file mode 100644 index 00000000000..4f156426b47 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPermissionChecker.java @@ -0,0 +1,90 @@ +/* + * 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 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); + } + } +}