Move Fingerprint settings to biometrics/fingerprint

Bug: 110589286

Test: make -j56 RunSettingsRoboTests
Test: adb shell am start -a android.settings.FINGERPRINT_ENROLL still works
Test: adb shell am start -a android.settings.FINGERPRINT_SETUP still works
Change-Id: If33b557137cae7b57e4a0e906ee95032bc589436
This commit is contained in:
Kevin Chyn
2018-06-25 16:50:52 -07:00
parent fde790bf2c
commit 871e55fc54
44 changed files with 63 additions and 62 deletions

View File

@@ -0,0 +1,73 @@
/*
* 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.biometrics.fingerprint;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.Dialog;
import android.hardware.fingerprint.Fingerprint;
import com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment;
import com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.DeleteFingerprintDialog;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowFragment;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.util.FragmentTestUtil;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = ShadowFragment.class)
public class DeleteFingerprintDialogTest {
@Mock
private Fingerprint mFingerprint;
@Mock
private FingerprintSettingsFragment mTarget;
private DeleteFingerprintDialog mFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFragment = spy(DeleteFingerprintDialog.newInstance(mFingerprint, mTarget));
}
@Test
public void launchDialog_clickPositive_shouldDeleteFingerprint() {
FragmentTestUtil.startFragment(mFragment);
mFragment.onClick(mFragment.getDialog(), Dialog.BUTTON_POSITIVE);
verify(mTarget).deleteFingerPrint(mFingerprint);
}
@Test
public void launchDialog_clickNegative_shouldDoNothing() {
FragmentTestUtil.startFragment(mFragment);
mFragment.onClick(mFragment.getDialog(), Dialog.BUTTON_NEGATIVE);
verify(mTarget, never()).deleteFingerPrint(mFingerprint);
}
}

View File

@@ -0,0 +1,124 @@
/*
* 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.biometrics.fingerprint;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application;
import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
import android.media.AudioAttributes;
import android.os.CancellationSignal;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settings.testutils.shadow.ShadowVibrator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import java.util.concurrent.TimeUnit;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {
SettingsShadowResourcesImpl.class,
ShadowUtils.class,
ShadowVibrator.class})
public class FingerprintEnrollEnrollingTest {
@Mock
private FingerprintManager mFingerprintManager;
private FingerprintEnrollEnrolling mActivity;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setFingerprintManager(mFingerprintManager);
ShadowVibrator.addToServiceMap();
FakeFeatureFactory.setupForTest();
mActivity = Robolectric.buildActivity(
FingerprintEnrollEnrolling.class,
new Intent()
// Set the challenge token so the confirm screen will not be shown
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]))
.setup().get();
}
@After
public void tearDown() {
ShadowUtils.reset();
ShadowVibrator.reset();
}
@Test
public void fingerprintEnrollHelp_shouldShowHelpTextAndVibrate() {
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentHelp(
FingerprintManager.FINGERPRINT_ERROR_UNABLE_TO_PROCESS,
"test enrollment help");
TextView errorText = mActivity.findViewById(R.id.error_text);
assertThat(errorText.getText()).isEqualTo("test enrollment help");
Robolectric.getForegroundThreadScheduler().advanceBy(2, TimeUnit.MILLISECONDS);
ShadowVibrator shadowVibrator =
Shadow.extract(application.getSystemService(Vibrator.class));
verify(shadowVibrator.delegate).vibrate(
anyInt(),
nullable(String.class),
any(VibrationEffect.class),
nullable(AudioAttributes.class));
}
private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
ArgumentCaptor<EnrollmentCallback> callbackCaptor =
ArgumentCaptor.forClass(EnrollmentCallback.class);
verify(mFingerprintManager).enroll(
any(byte[].class),
any(CancellationSignal.class),
anyInt(),
anyInt(),
callbackCaptor.capture());
return callbackCaptor.getValue();
}
}

View File

@@ -0,0 +1,163 @@
/*
* 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.biometrics.fingerprint;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
import android.os.CancellationSignal;
import android.widget.Button;
import com.android.settings.R;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowActivity.IntentForResult;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class, ShadowUtils.class})
public class FingerprintEnrollFindSensorTest {
@Mock
private FingerprintManager mFingerprintManager;
private FingerprintEnrollFindSensor mActivity;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setFingerprintManager(mFingerprintManager);
FakeFeatureFactory.setupForTest();
mActivity = Robolectric.buildActivity(
FingerprintEnrollFindSensor.class,
new Intent()
// Set the challenge token so the confirm screen will not be shown
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]))
.setup().get();
}
@After
public void tearDown() {
ShadowUtils.reset();
}
@Test
public void enrollFingerprint_shouldProceed() {
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
IntentForResult startedActivity =
shadowActivity.getNextStartedActivityForResult();
assertThat(startedActivity).named("Next activity 1").isNotNull();
assertThat(startedActivity.intent.getComponent())
.isEqualTo(new ComponentName(application, FingerprintEnrollEnrolling.class));
}
@Test
public void enrollFingerprintTwice_shouldStartOneEnrolling() {
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentProgress(123); // A second enroll should be a no-op
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
IntentForResult startedActivity =
shadowActivity.getNextStartedActivityForResult();
assertThat(startedActivity).named("Next activity 1").isNotNull();
assertThat(startedActivity.intent.getComponent())
.isEqualTo(new ComponentName(application, FingerprintEnrollEnrolling.class));
// Should only start one next activity
assertThat(shadowActivity.getNextStartedActivityForResult()).named("Next activity 2")
.isNull();
}
// Use a non-default resource qualifier to load the test layout in
// robotests/res/layout-mcc999/fingerprint_enroll_find_sensor. This layout is a copy of the
// regular find sensor layout, with the animation removed.
@Config(qualifiers = "mcc999")
@Test
public void layoutWithoutAnimation_shouldNotCrash() {
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
IntentForResult startedActivity =
shadowActivity.getNextStartedActivityForResult();
assertThat(startedActivity).named("Next activity").isNotNull();
assertThat(startedActivity.intent.getComponent())
.isEqualTo(new ComponentName(application, FingerprintEnrollEnrolling.class));
}
@Test
public void clickSkip_shouldReturnResultSkip() {
Button skipButton = mActivity.findViewById(R.id.skip_button);
skipButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
assertThat(shadowActivity.getResultCode()).named("result code")
.isEqualTo(FingerprintEnrollBase.RESULT_SKIP);
}
private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
ArgumentCaptor<EnrollmentCallback> callbackCaptor =
ArgumentCaptor.forClass(EnrollmentCallback.class);
verify(mFingerprintManager).enroll(
any(byte[].class),
any(CancellationSignal.class),
anyInt(),
anyInt(),
callbackCaptor.capture());
return callbackCaptor.getValue();
}
@Test
public void onActivityResult_withNullIntentShouldNotCrash() {
// this should not crash
mActivity.onActivityResult(FingerprintEnrollFindSensor.CONFIRM_REQUEST, Activity.RESULT_OK,
null);
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(Activity.RESULT_CANCELED);
}
}

View File

@@ -0,0 +1,110 @@
/*
* 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.biometrics.fingerprint;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(SettingsRobolectricTestRunner.class)
public class FingerprintEnrollSuggestionActivityTest {
@Mock
private Context mContext;
@Mock
private PackageManager mPackageManager;
@Mock
private FingerprintManager mFingerprintManager;
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getSystemService(eq(Context.DEVICE_POLICY_SERVICE)))
.thenReturn(mDevicePolicyManager);
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt())).thenReturn(0);
when(mContext.getSystemService(Context.FINGERPRINT_SERVICE))
.thenReturn(mFingerprintManager);
}
@Test
public void testFingerprintEnrollmentIntroductionIsCompleteWhenFingerprintAdded() {
stubFingerprintSupported(true);
when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(true);
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
assertThat(FingerprintEnrollSuggestionActivity.isSuggestionComplete(mContext)).isTrue();
}
@Test
public void testFingerprintEnrollmentIntroductionIsNotCompleteWhenNoFingerprintAdded() {
stubFingerprintSupported(true);
when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false);
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
assertThat(FingerprintEnrollSuggestionActivity.isSuggestionComplete(mContext)).isFalse();
}
@Test
public void testFingerprintEnrollmentIntroductionIsCompleteWhenHardwareNotDetected() {
stubFingerprintSupported(true);
when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false);
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
assertThat(FingerprintEnrollSuggestionActivity.isSuggestionComplete(mContext)).isTrue();
}
@Test
public void testFingerprintEnrollmentIntroductionIsCompleteWhenFingerprintNotSupported() {
stubFingerprintSupported(false);
assertThat(FingerprintEnrollSuggestionActivity.isSuggestionComplete(mContext)).isTrue();
}
@Test
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);
assertThat(FingerprintEnrollSuggestionActivity.isSuggestionComplete(mContext)).isTrue();
}
private void stubFingerprintSupported(boolean enabled) {
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(enabled);
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.biometrics.fingerprint;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.net.Uri;
import android.view.TextureView.SurfaceTextureListener;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class FingerprintLocationAnimationVideoViewTest {
private FingerprintLocationAnimationVideoView mView;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
final Context context = RuntimeEnvironment.application;
mView = spy(new FingerprintLocationAnimationVideoView(context, null));
}
@Test
public void onSurfaceTextureAvailable_nullMediaPlayer_shouldNotCrash() {
mView.onFinishInflate();
final SurfaceTextureListener listener = mView.getSurfaceTextureListener();
when(mView.createMediaPlayer(any(Context.class), any(Uri.class))).thenReturn(null);
listener.onSurfaceTextureAvailable(mock(SurfaceTexture.class), 48, 48);
// should not crash
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.biometrics.fingerprint;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import com.android.settings.R;
import com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintPreference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import androidx.preference.PreferenceViewHolder;
@RunWith(SettingsRobolectricTestRunner.class)
public class FingerprintPreferenceTest {
@Mock
private FingerprintPreference.OnDeleteClickListener mOnDeleteClickListener;
private Context mContext;
private FingerprintPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mPreference = new FingerprintPreference(mContext, mOnDeleteClickListener);
}
@Test
public void shouldShowDeleteButton() {
assertThat(mPreference.getSecondTargetResId()).isEqualTo(R.layout.preference_widget_delete);
}
@Test
public void bindAndClickDeleteButton_shouldInvokeOnDeleteListener() {
final FrameLayout layout = new FrameLayout(mContext);
LayoutInflater.from(mContext).inflate(mPreference.getSecondTargetResId(), layout, true);
final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(layout);
mPreference.onBindViewHolder(holder);
final View view = layout.findViewById(R.id.delete_button);
assertThat(view).isNotNull();
view.performClick();
verify(mOnDeleteClickListener).onDeleteClick(mPreference);
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2018 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.biometrics.fingerprint;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserManager;
import com.android.internal.widget.LockPatternUtils;
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.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
public class FingerprintProfileStatusPreferenceControllerTest {
private static final int FAKE_PROFILE_USER_ID = 1234;
@Mock
private PackageManager mPackageManager;
@Mock
private LockPatternUtils mLockPatternUtils;
@Mock
private FingerprintManager mFingerprintManager;
@Mock
private UserManager mUm;
private FakeFeatureFactory mFeatureFactory;
private Context mContext;
private FingerprintProfileStatusPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
ShadowApplication.getInstance().setSystemService(Context.FINGERPRINT_SERVICE,
mFingerprintManager);
ShadowApplication.getInstance().setSystemService(Context.USER_SERVICE, mUm);
mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
.thenReturn(mLockPatternUtils);
when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {1234});
mController = new FingerprintProfileStatusPreferenceController(mContext);
}
@Test
public void getUserId_shouldReturnProfileId() {
assertThat(mController.getUserId()).isEqualTo(FAKE_PROFILE_USER_ID);
}
@Test
public void isUserSupported_separateChallengeAllowed_true() {
when(mLockPatternUtils.isSeparateProfileChallengeAllowed(anyInt())).thenReturn(true);
assertThat(mController.isUserSupported()).isTrue();
}
@Test
public void isUserSupported_separateChallengeNotAllowed_false() {
when(mLockPatternUtils.isSeparateProfileChallengeAllowed(anyInt())).thenReturn(false);
assertThat(mController.isUserSupported()).isFalse();
}
@Test
public void getAvailabilityStatus_userNotSupported_DISABLED() {
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mLockPatternUtils.isSeparateProfileChallengeAllowed(anyInt())).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2018 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.biometrics.fingerprint;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserManager;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
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.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import java.util.Collections;
import androidx.preference.Preference;
@RunWith(SettingsRobolectricTestRunner.class)
public class FingerprintStatusPreferenceControllerTest {
@Mock
private LockPatternUtils mLockPatternUtils;
@Mock
private FingerprintManager mFingerprintManager;
@Mock
private UserManager mUm;
@Mock
private PackageManager mPackageManager;
private FakeFeatureFactory mFeatureFactory;
private Context mContext;
private FingerprintStatusPreferenceController mController;
private Preference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
ShadowApplication.getInstance().setSystemService(Context.FINGERPRINT_SERVICE,
mFingerprintManager);
ShadowApplication.getInstance().setSystemService(Context.USER_SERVICE, mUm);
mPreference = new Preference(mContext);
mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
.thenReturn(mLockPatternUtils);
when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {1234});
mController = new FingerprintStatusPreferenceController(mContext);
}
@Test
public void getAvailabilityStatus_noFingerprintManger_DISABLED() {
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_hasFingerprintManger_AVAILABLE() {
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void updateState_notSupported_shouldDoNothing() {
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isFalse();
}
@Test
public void updateState_noFingerprint_shouldShowDefaultSummary() {
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
mController.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(
mContext.getString(R.string.security_settings_fingerprint_preference_summary_none));
assertThat(mPreference.isVisible()).isTrue();
assertThat(mPreference.getOnPreferenceClickListener()).isNotNull();
}
@Test
public void updateState_hasFingerprint_shouldShowSummary() {
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
.thenReturn(Collections.singletonList(mock(Fingerprint.class)));
mController.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(mContext.getResources().getQuantityString(
R.plurals.security_settings_fingerprint_preference_summary, 1, 1));
assertThat(mPreference.isVisible()).isTrue();
assertThat(mPreference.getOnPreferenceClickListener()).isNotNull();
}
}

View File

@@ -0,0 +1,87 @@
/*
* 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.biometrics.fingerprint;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.view.View;
import android.widget.Button;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowKeyguardManager;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {ShadowLockPatternUtils.class, ShadowUserManager.class})
public class FingerprintSuggestionActivityTest {
@Mock
private UserInfo mUserInfo;
private ActivityController<FingerprintSuggestionActivity> mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest();
final Intent intent = new Intent();
mController = Robolectric.buildActivity(FingerprintSuggestionActivity.class, intent);
ShadowUserManager.getShadow().setUserInfo(0, mUserInfo);
}
@Test
public void testKeyguardSecure_shouldFinishWithFingerprintResultSkip() {
getShadowKeyguardManager().setIsKeyguardSecure(true);
mController.create().resume();
final Button cancelButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
assertThat(cancelButton.getText().toString()).isEqualTo("Cancel");
assertThat(cancelButton.getVisibility()).named("Cancel visible").isEqualTo(View.VISIBLE);
cancelButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
assertThat(shadowActivity.getResultCode()).named("Result code")
.isEqualTo(Activity.RESULT_CANCELED);
}
private ShadowKeyguardManager getShadowKeyguardManager() {
return Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2017 Google Inc.
*
* 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.biometrics.fingerprint;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.AlertDialog;
import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.widget.Button;
import com.android.settings.R;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowAlertDialog;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class, ShadowUtils.class})
public class SetupFingerprintEnrollFindSensorTest {
@Mock
private FingerprintManager mFingerprintManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setFingerprintManager(mFingerprintManager);
FakeFeatureFactory.setupForTest();
}
@After
public void tearDown() {
ShadowUtils.reset();
}
@Test
public void fingerprintEnroll_showsAlert_whenClickingSkip() {
final Intent intent = new Intent()
// Set the challenge token so the confirm screen will not be shown
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
final SetupFingerprintEnrollFindSensor activity =
Robolectric.buildActivity(SetupFingerprintEnrollFindSensor.class,
intent).setup().get();
final Button skipButton = activity.findViewById(R.id.skip_button);
skipButton.performClick();
final AlertDialog alertDialog = ShadowAlertDialog.getLatestAlertDialog();
assertNotNull(alertDialog);
final ShadowAlertDialog shadowAlertDialog = Shadows.shadowOf(alertDialog);
final int titleRes = R.string.setup_fingerprint_enroll_skip_title;
assertEquals(application.getString(titleRes), shadowAlertDialog.getTitle());
}
}

View File

@@ -0,0 +1,242 @@
/*
* 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.biometrics.fingerprint;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.KeyguardManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.view.View;
import android.widget.Button;
import com.android.settings.R;
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollIntroductionTest.ShadowStorageManagerWrapper;
import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
import com.android.settings.password.SetupSkipDialog;
import com.android.settings.password.StorageManagerWrapper;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowFingerprintManager;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowActivity.IntentForResult;
import org.robolectric.shadows.ShadowKeyguardManager;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {
ShadowFingerprintManager.class,
ShadowLockPatternUtils.class,
ShadowStorageManagerWrapper.class,
ShadowUserManager.class
})
public class SetupFingerprintEnrollIntroductionTest {
@Mock
private UserInfo mUserInfo;
private ActivityController<SetupFingerprintEnrollIntroduction> mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Shadows.shadowOf(application.getPackageManager())
.setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true);
ShadowFingerprintManager.addToServiceMap();
FakeFeatureFactory.setupForTest();
final Intent intent = new Intent();
mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent);
ShadowUserManager.getShadow().setUserInfo(0, mUserInfo);
}
@After
public void tearDown() {
ShadowStorageManagerWrapper.reset();
ShadowFingerprintManager.reset();
}
@Test
public void testKeyguardNotSecure_shouldFinishWithSetupSkipDialogResultSkip() {
getShadowKeyguardManager().setIsKeyguardSecure(false);
mController.create().resume();
final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
skipButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
assertThat(shadowActivity.getResultCode()).named("Result code")
.isEqualTo(SetupSkipDialog.RESULT_SKIP);
}
@Test
public void testKeyguardSecure_shouldFinishWithFingerprintResultSkip() {
getShadowKeyguardManager().setIsKeyguardSecure(true);
mController.create().resume();
final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
skipButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
assertThat(shadowActivity.getResultCode()).named("Result code")
.isEqualTo(FingerprintEnrollBase.RESULT_SKIP);
}
@Test
public void testBackKeyPress_shouldSetIntentDataIfLockScreenAdded() {
getShadowKeyguardManager().setIsKeyguardSecure(false);
mController.create().resume();
getShadowKeyguardManager().setIsKeyguardSecure(true);
SetupFingerprintEnrollIntroduction activity = mController.get();
activity.onBackPressed();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getResultIntent()).isNotNull();
assertThat(shadowActivity.getResultIntent().hasExtra(
SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isTrue();
}
@Test
public void testBackKeyPress_shouldNotSetIntentDataIfLockScreenPresentBeforeLaunch() {
getShadowKeyguardManager().setIsKeyguardSecure(true);
mController.create().resume();
SetupFingerprintEnrollIntroduction activity = mController.get();
activity.onBackPressed();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getResultIntent()).isNull();
}
@Test
public void testCancelClicked_shouldSetIntentDataIfLockScreenAdded() {
getShadowKeyguardManager().setIsKeyguardSecure(false);
SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
final Button skipButton = activity.findViewById(R.id.fingerprint_cancel_button);
getShadowKeyguardManager().setIsKeyguardSecure(true);
skipButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getResultIntent()).isNotNull();
assertThat(shadowActivity.getResultIntent().hasExtra(
SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isTrue();
}
@Test
public void testCancelClicked_shouldNotSetIntentDataIfLockScreenPresentBeforeLaunch() {
getShadowKeyguardManager().setIsKeyguardSecure(true);
SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
final Button skipButton = activity.findViewById(R.id.fingerprint_cancel_button);
skipButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getResultIntent()).isNull();
}
@Test
public void testOnResultFromFindSensor_shouldNotSetIntentDataIfLockScreenPresentBeforeLaunch() {
getShadowKeyguardManager().setIsKeyguardSecure(true);
SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
activity.onActivityResult(FingerprintEnrollIntroduction.FINGERPRINT_FIND_SENSOR_REQUEST,
FingerprintEnrollBase.RESULT_FINISHED, null);
assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
}
@Test
public void testOnResultFromFindSensor_shouldSetIntentDataIfLockScreenAdded() {
getShadowKeyguardManager().setIsKeyguardSecure(false);
SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
getShadowKeyguardManager().setIsKeyguardSecure(true);
activity.onActivityResult(FingerprintEnrollIntroduction.FINGERPRINT_FIND_SENSOR_REQUEST,
FingerprintEnrollBase.RESULT_FINISHED, null);
assertThat(Shadows.shadowOf(activity).getResultIntent()).isNotNull();
}
@Test
public void testOnResultFromFindSensor_shouldNotSetIntentDataIfLockScreenNotAdded() {
getShadowKeyguardManager().setIsKeyguardSecure(false);
SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
activity.onActivityResult(FingerprintEnrollIntroduction.FINGERPRINT_FIND_SENSOR_REQUEST,
FingerprintEnrollBase.RESULT_FINISHED, null);
assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
}
@Test
public void testLockPattern() {
ShadowStorageManagerWrapper.sIsFileEncrypted = false;
mController.create().postCreate(null).resume();
SetupFingerprintEnrollIntroduction activity = mController.get();
final Button nextButton = activity.findViewById(R.id.fingerprint_next_button);
nextButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult();
assertThat(startedActivity).isNotNull();
assertThat(startedActivity.intent.hasExtra(
SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isFalse();
}
private ShadowKeyguardManager getShadowKeyguardManager() {
return Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
}
@Implements(StorageManagerWrapper.class)
public static class ShadowStorageManagerWrapper {
private static boolean sIsFileEncrypted = true;
public static void reset() {
sIsFileEncrypted = true;
}
@Implementation
public static boolean isFileEncryptedNativeOrEmulated() {
return sIsFileEncrypted;
}
}
}