diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 43106cff1bf..2b2ca8cfba0 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -1253,6 +1253,11 @@ public final class Utils extends com.android.settingslib.Utils { } } + public static boolean hasFingerprintHardware(Context context) { + FingerprintManager fingerprintManager = getFingerprintManagerOrNull(context); + return fingerprintManager != null && fingerprintManager.isHardwareDetected(); + } + /** * Launches an intent which may optionally have a user id defined. * @param fragment Fragment to use to launch the activity. diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java b/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java index 3e85d2c8174..6ff0413b042 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java @@ -65,12 +65,14 @@ public class SuggestionsChecks { } else if (className.equals(WifiCallingSuggestionActivity.class.getName())) { return isWifiCallingUnavailableOrEnabled(); } else if (className.equals(FingerprintSuggestionActivity.class.getName())) { - return isNotSingleFingerprintEnrolled() || !isFingerprintEnabled(); + return !Utils.hasFingerprintHardware(mContext) || !isFingerprintEnabled() + || isNotSingleFingerprintEnrolled(); } else if (className.equals(ScreenLockSuggestionActivity.class.getName())) { return isDeviceSecured(); } else if (className.equals(FingerprintEnrollSuggestionActivity.class.getName())) { - FingerprintManager manager = Utils.getFingerprintManagerOrNull(mContext); - if (manager == null || !isFingerprintEnabled()) { + final FingerprintManager manager = Utils.getFingerprintManagerOrNull(mContext); + if (manager == null || !isFingerprintEnabled() + || !Utils.hasFingerprintHardware(mContext)) { return true; } return manager.hasEnrolledFingerprints(); diff --git a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java index defd75fa32f..05c64617671 100644 --- a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java +++ b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java @@ -23,7 +23,7 @@ import android.provider.Settings; import android.support.v7.preference.Preference; import com.android.settings.R; -import com.android.settings.overlay.FeatureFactory; +import com.android.settings.Utils; import com.android.settings.search.DatabaseIndexingUtils; import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.ResultPayload; @@ -50,7 +50,7 @@ public class SwipeToNotificationPreferenceController extends GesturePreferenceCo } private static boolean isGestureAvailable(Context context) { - return context.getResources() + return Utils.hasFingerprintHardware(context) && context.getResources() .getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys); } diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java index 78c1d1ad36e..df25a507cd5 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java @@ -19,6 +19,7 @@ package com.android.settings.dashboard.suggestions; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; @@ -29,7 +30,10 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.hardware.fingerprint.FingerprintManager; + import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.Settings.AmbientDisplaySuggestionActivity; @@ -72,6 +76,12 @@ public class SuggestionFeatureProviderImplTest { private SuggestionParser mSuggestionParser; @Mock private Tile mSuggestion; + @Mock + private PackageManager mPackageManager; + @Mock + private FingerprintManager mFingerprintManager; + @Mock + private SharedPreferences mSharedPreferences; private FakeFeatureFactory mFactory; private SuggestionFeatureProviderImpl mProvider; @@ -81,7 +91,12 @@ public class SuggestionFeatureProviderImplTest { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(mContext); mFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + // Explicit casting to object due to MockitoCast bug + when((Object) mContext.getSystemService(FingerprintManager.class)) + .thenReturn(mFingerprintManager); when(mContext.getApplicationContext()).thenReturn(RuntimeEnvironment.application); + mSuggestion.intent = new Intent().setClassName("pkg", "cls"); mSuggestion.category = "category"; @@ -196,39 +211,56 @@ public class SuggestionFeatureProviderImplTest { } @Test - @Config(shadows = SettingsShadowResources.class) - public void isSuggestionCompleted_swipeToNotification_trueWhenNotAvailable() { - SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_supportSystemNavigationKeys, false); + public void isSuggestionCompleted_swipeToNotification_trueWhenNotHardwareNotAvailable() { + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(false); + when(mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys)) + .thenReturn(true); - assertThat(mProvider.isSuggestionCompleted(RuntimeEnvironment.application, - new ComponentName(RuntimeEnvironment.application, - SwipeToNotificationSuggestionActivity.class))).isTrue(); + assertThat(mProvider.isSuggestionCompleted(mContext, + new ComponentName(mContext, SwipeToNotificationSuggestionActivity.class))).isTrue(); + } + + @Test + public void isSuggestionCompleted_swipeToNotification_trueWhenNotAvailable() { + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); + when(mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys)) + .thenReturn(false); + + assertThat(mProvider.isSuggestionCompleted(mContext, + new ComponentName(mContext, SwipeToNotificationSuggestionActivity.class))).isTrue(); } @Test - @Config(shadows = SettingsShadowResources.class) public void isSuggestionCompleted_swipeToNotification_falseWhenNotVisited() { - SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_supportSystemNavigationKeys, true); + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); + when(mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys)) + .thenReturn(true); // No stored value in shared preferences if not visited yet. - assertThat(mProvider.isSuggestionCompleted(RuntimeEnvironment.application, - new ComponentName(RuntimeEnvironment.application, + assertThat(mProvider.isSuggestionCompleted(mContext, + new ComponentName(mContext, SwipeToNotificationSuggestionActivity.class))).isFalse(); } @Test - @Config(shadows = SettingsShadowResources.class) public void isSuggestionCompleted_swipeToNotification_trueWhenVisited() { - SettingsShadowResources.overrideResource( - com.android.internal.R.bool.config_supportSystemNavigationKeys, true); - mProvider.getSharedPrefs(RuntimeEnvironment.application).edit().putBoolean( - SwipeToNotificationSettings.PREF_KEY_SUGGESTION_COMPLETE, true).commit(); + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); + when(mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys)) + .thenReturn(true); + when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mSharedPreferences); + when(mSharedPreferences.getBoolean( + SwipeToNotificationSettings.PREF_KEY_SUGGESTION_COMPLETE, false)).thenReturn(true); - assertThat(mProvider.isSuggestionCompleted(RuntimeEnvironment.application, - new ComponentName(RuntimeEnvironment.application, - SwipeToNotificationSuggestionActivity.class))).isTrue(); + assertThat(mProvider.isSuggestionCompleted(mContext, + new ComponentName(mContext, SwipeToNotificationSuggestionActivity.class))).isTrue(); } @Test @@ -313,6 +345,11 @@ public class SuggestionFeatureProviderImplTest { PackageManager.DONT_KILL_APP); } + private void stubFingerprintSupported(boolean enabled) { + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) + .thenReturn(enabled); + } + @Test public void filterExclusiveSuggestions_shouldOnlyKeepFirst3() { final List suggestions = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java index 5f3c0f0c38b..e7751362ecd 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java @@ -78,6 +78,7 @@ public class SuggestionsChecksTest { public void testFingerprintEnrollmentIntroductionIsCompleteWhenFingerprintAdded() { stubFingerprintSupported(true); when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); Tile tile = createFingerprintTile(); assertThat(mSuggestionsChecks.isSuggestionComplete(tile)).isTrue(); } @@ -86,10 +87,20 @@ public class SuggestionsChecksTest { public void testFingerprintEnrollmentIntroductionIsNotCompleteWhenNoFingerprintAdded() { stubFingerprintSupported(true); when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); Tile tile = createFingerprintTile(); assertThat(mSuggestionsChecks.isSuggestionComplete(tile)).isFalse(); } + @Test + public void testFingerprintEnrollmentIntroductionIsCompleteWhenHardwareNotDetected() { + stubFingerprintSupported(true); + when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false); + when(mFingerprintManager.isHardwareDetected()).thenReturn(false); + Tile tile = createFingerprintTile(); + assertThat(mSuggestionsChecks.isSuggestionComplete(tile)).isTrue(); + } + @Test public void testFingerprintEnrollmentIntroductionIsCompleteWhenFingerprintNotSupported() { @@ -102,6 +113,7 @@ public class SuggestionsChecksTest { public void testFingerprintEnrollmentIntroductionIsCompleteWhenFingerprintDisabled() { stubFingerprintSupported(true); when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt())) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT); diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java index b00a511fd45..3b92ed1c22a 100644 --- a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java @@ -18,7 +18,9 @@ package com.android.settings.gestures; import android.content.ContentResolver; import android.content.Context; +import android.content.pm.PackageManager; import android.content.res.Resources; +import android.hardware.fingerprint.FingerprintManager; import android.provider.Settings; import com.android.settings.search.InlinePayload; @@ -52,6 +54,10 @@ public class SwipeToNotificationPreferenceControllerTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; + @Mock + private PackageManager mPackageManager; + @Mock + private FingerprintManager mFingerprintManager; private SwipeToNotificationPreferenceController mController; private static final String KEY_SWIPE_DOWN = "gesture_swipe_down_fingerprint"; @@ -60,10 +66,27 @@ public class SwipeToNotificationPreferenceControllerTest { public void setUp() { MockitoAnnotations.initMocks(this); mController = new SwipeToNotificationPreferenceController(mContext, null, KEY_SWIPE_DOWN); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + // Explicit casting to object due to MockitoCast bug + when((Object) mContext.getSystemService(FingerprintManager.class)) + .thenReturn(mFingerprintManager); + } + + @Test + public void isAvailable_hardwareNotAvailable_shouldReturnFalse() { + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(false); + when(mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys)) + .thenReturn(true); + + assertThat(mController.isAvailable()).isFalse(); } @Test public void isAvailable_configIsTrue_shouldReturnTrue() { + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); when(mContext.getResources(). getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys)) .thenReturn(true); @@ -73,6 +96,8 @@ public class SwipeToNotificationPreferenceControllerTest { @Test public void isAvailable_configIsFalse_shouldReturnFalse() { + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); when(mContext.getResources(). getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys)) .thenReturn(false); @@ -82,6 +107,8 @@ public class SwipeToNotificationPreferenceControllerTest { @Test public void testSwitchEnabled_configIsSet_shouldReturnTrue() { + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); // Set the setting to be enabled. final Context context = ShadowApplication.getInstance().getApplicationContext(); Settings.System.putInt(context.getContentResolver(), SYSTEM_NAVIGATION_KEYS_ENABLED, 1); @@ -92,6 +119,8 @@ public class SwipeToNotificationPreferenceControllerTest { @Test public void testSwitchEnabled_configIsNotSet_shouldReturnFalse() { + stubFingerprintSupported(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); // Set the setting to be disabled. final Context context = ShadowApplication.getInstance().getApplicationContext(); Settings.System.putInt(context.getContentResolver(), SYSTEM_NAVIGATION_KEYS_ENABLED, 0); @@ -139,4 +168,9 @@ public class SwipeToNotificationPreferenceControllerTest { assertThat(newValue).isEqualTo(currentValue); } + + private void stubFingerprintSupported(boolean enabled) { + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) + .thenReturn(enabled); + } }