Loading src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +40 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.biometrics.fingerprint; import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED; import android.animation.Animator; import android.animation.ObjectAnimator; import android.annotation.IntDef; Loading Loading @@ -51,6 +53,7 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.IdRes; import androidx.appcompat.app.AlertDialog; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -80,6 +83,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private static final String TAG = "FingerprintEnrollEnrolling"; static final String TAG_SIDECAR = "sidecar"; static final String KEY_STATE_CANCELED = "is_canceled"; static final String KEY_STATE_PREVIOUS_ROTATION = "previous_rotation"; private static final int PROGRESS_BAR_MAX = 10000; Loading Loading @@ -134,6 +138,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private boolean mRestoring; private Vibrator mVibrator; private boolean mIsSetupWizard; private boolean mIsOrientationChanged; private boolean mIsCanceled; private AccessibilityManager mAccessibilityManager; private boolean mIsAccessibilityEnabled; Loading @@ -155,6 +160,23 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { return defaultDensity == currentDensity; } @Override public void onWindowFocusChanged(boolean hasFocus) { if (hasFocus) { return; } // By UX design, we should ensure seamless enrollment CUJ even though user rotate device. // Do NOT cancel enrollment progress after rotating, adding mIsOrientationChanged // to judge if the focus changed was triggered by rotation, current WMS has triple callbacks // (true > false > true), we need to reset mIsOrientationChanged when !hasFocus callback. if (!mIsOrientationChanged) { onCancelEnrollment(FINGERPRINT_ERROR_USER_CANCELED); } else { mIsOrientationChanged = false; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Loading Loading @@ -295,11 +317,15 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(KEY_STATE_CANCELED, mIsCanceled); outState.putInt(KEY_STATE_PREVIOUS_ROTATION, mPreviousRotation); } private void restoreSavedState(Bundle savedInstanceState) { mRestoring = true; mIsCanceled = savedInstanceState.getBoolean(KEY_STATE_CANCELED, false); mPreviousRotation = savedInstanceState.getInt(KEY_STATE_PREVIOUS_ROTATION, getDisplay().getRotation()); mIsOrientationChanged = mPreviousRotation != getDisplay().getRotation(); } @Override Loading Loading @@ -337,6 +363,19 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } } @VisibleForTesting void onCancelEnrollment(@IdRes int errorMsgId) { FingerprintErrorDialog.showErrorDialog(this, errorMsgId); mIsCanceled = true; mIsOrientationChanged = false; cancelEnrollment(); stopIconAnimation(); stopListenOrientationEvent(); if (!mCanAssumeUdfps) { mErrorText.removeCallbacks(mTouchAgainRunnable); } } @Override protected void onStop() { if (!isChangingConfigurations()) { Loading Loading @@ -556,14 +595,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override public void onEnrollmentError(int errMsgId, CharSequence errString) { FingerprintErrorDialog.showErrorDialog(this, errMsgId); mIsCanceled = true; cancelEnrollment(); stopIconAnimation(); stopListenOrientationEvent(); if (!mCanAssumeUdfps) { mErrorText.removeCallbacks(mTouchAgainRunnable); } onCancelEnrollment(errMsgId); } @Override Loading tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java +38 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.biometrics.fingerprint; import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.KEY_STATE_PREVIOUS_ROTATION; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; Loading @@ -28,14 +30,18 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.SensorProperties; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Vibrator; import android.view.Display; import android.view.Surface; import android.widget.TextView; import com.android.settings.R; Loading @@ -49,6 +55,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.android.controller.ActivityController; import java.util.ArrayList; Loading @@ -61,7 +68,10 @@ public class FingerprintEnrollEnrollingTest { @Mock private Vibrator mVibrator; @Mock private Display mMockDisplay; private FingerprintEnrollEnrolling mActivity; private Context mContext; @Before public void setUp() { Loading Loading @@ -100,6 +110,26 @@ public class FingerprintEnrollEnrollingTest { verify(mVibrator, never()).vibrate(anyInt(), anyString(), any(), anyString(), any()); } @Test public void fingerprintUdfpsOverlayEnrollment_gainFocus_shouldNotCancel() { initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL); mActivity.onEnrollmentProgressChange(1, 1); mActivity.onWindowFocusChanged(true); verify(mActivity, never()).onCancelEnrollment(anyInt()); } @Test public void fingerprintUdfpsOverlayEnrollment_loseFocus_shouldCancel() { initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL); mActivity.onEnrollmentProgressChange(1, 1); mActivity.onWindowFocusChanged(false); verify(mActivity, never()).onCancelEnrollment(anyInt()); } private void initializeActivityFor(int sensorType) { final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); final FingerprintSensorPropertiesInternal prop = Loading @@ -111,15 +141,21 @@ public class FingerprintEnrollEnrollingTest { sensorType, true /* resetLockoutRequiresHardwareAuthToken */); final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>(); final Bundle savedInstanceState = new Bundle(); savedInstanceState.putInt(KEY_STATE_PREVIOUS_ROTATION, Surface.ROTATION_90); props.add(prop); mContext = spy(RuntimeEnvironment.application); mActivity = spy(FingerprintEnrollEnrolling.class); when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props); when(mContext.getDisplay()).thenReturn(mMockDisplay); when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0); mActivity = spy(FingerprintEnrollEnrolling.class); doReturn(true).when(mActivity).shouldShowLottie(); doReturn(mFingerprintManager).when(mActivity).getSystemService(FingerprintManager.class); doReturn(mVibrator).when(mActivity).getSystemService(Vibrator.class); ActivityController.of(mActivity).create(); ActivityController.of(mActivity).create(savedInstanceState); } private EnrollmentCallback verifyAndCaptureEnrollmentCallback() { Loading Loading
src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +40 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.biometrics.fingerprint; import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED; import android.animation.Animator; import android.animation.ObjectAnimator; import android.annotation.IntDef; Loading Loading @@ -51,6 +53,7 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.IdRes; import androidx.appcompat.app.AlertDialog; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -80,6 +83,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private static final String TAG = "FingerprintEnrollEnrolling"; static final String TAG_SIDECAR = "sidecar"; static final String KEY_STATE_CANCELED = "is_canceled"; static final String KEY_STATE_PREVIOUS_ROTATION = "previous_rotation"; private static final int PROGRESS_BAR_MAX = 10000; Loading Loading @@ -134,6 +138,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private boolean mRestoring; private Vibrator mVibrator; private boolean mIsSetupWizard; private boolean mIsOrientationChanged; private boolean mIsCanceled; private AccessibilityManager mAccessibilityManager; private boolean mIsAccessibilityEnabled; Loading @@ -155,6 +160,23 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { return defaultDensity == currentDensity; } @Override public void onWindowFocusChanged(boolean hasFocus) { if (hasFocus) { return; } // By UX design, we should ensure seamless enrollment CUJ even though user rotate device. // Do NOT cancel enrollment progress after rotating, adding mIsOrientationChanged // to judge if the focus changed was triggered by rotation, current WMS has triple callbacks // (true > false > true), we need to reset mIsOrientationChanged when !hasFocus callback. if (!mIsOrientationChanged) { onCancelEnrollment(FINGERPRINT_ERROR_USER_CANCELED); } else { mIsOrientationChanged = false; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Loading Loading @@ -295,11 +317,15 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(KEY_STATE_CANCELED, mIsCanceled); outState.putInt(KEY_STATE_PREVIOUS_ROTATION, mPreviousRotation); } private void restoreSavedState(Bundle savedInstanceState) { mRestoring = true; mIsCanceled = savedInstanceState.getBoolean(KEY_STATE_CANCELED, false); mPreviousRotation = savedInstanceState.getInt(KEY_STATE_PREVIOUS_ROTATION, getDisplay().getRotation()); mIsOrientationChanged = mPreviousRotation != getDisplay().getRotation(); } @Override Loading Loading @@ -337,6 +363,19 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } } @VisibleForTesting void onCancelEnrollment(@IdRes int errorMsgId) { FingerprintErrorDialog.showErrorDialog(this, errorMsgId); mIsCanceled = true; mIsOrientationChanged = false; cancelEnrollment(); stopIconAnimation(); stopListenOrientationEvent(); if (!mCanAssumeUdfps) { mErrorText.removeCallbacks(mTouchAgainRunnable); } } @Override protected void onStop() { if (!isChangingConfigurations()) { Loading Loading @@ -556,14 +595,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override public void onEnrollmentError(int errMsgId, CharSequence errString) { FingerprintErrorDialog.showErrorDialog(this, errMsgId); mIsCanceled = true; cancelEnrollment(); stopIconAnimation(); stopListenOrientationEvent(); if (!mCanAssumeUdfps) { mErrorText.removeCallbacks(mTouchAgainRunnable); } onCancelEnrollment(errMsgId); } @Override Loading
tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java +38 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.biometrics.fingerprint; import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.KEY_STATE_PREVIOUS_ROTATION; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; Loading @@ -28,14 +30,18 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.SensorProperties; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Vibrator; import android.view.Display; import android.view.Surface; import android.widget.TextView; import com.android.settings.R; Loading @@ -49,6 +55,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.android.controller.ActivityController; import java.util.ArrayList; Loading @@ -61,7 +68,10 @@ public class FingerprintEnrollEnrollingTest { @Mock private Vibrator mVibrator; @Mock private Display mMockDisplay; private FingerprintEnrollEnrolling mActivity; private Context mContext; @Before public void setUp() { Loading Loading @@ -100,6 +110,26 @@ public class FingerprintEnrollEnrollingTest { verify(mVibrator, never()).vibrate(anyInt(), anyString(), any(), anyString(), any()); } @Test public void fingerprintUdfpsOverlayEnrollment_gainFocus_shouldNotCancel() { initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL); mActivity.onEnrollmentProgressChange(1, 1); mActivity.onWindowFocusChanged(true); verify(mActivity, never()).onCancelEnrollment(anyInt()); } @Test public void fingerprintUdfpsOverlayEnrollment_loseFocus_shouldCancel() { initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL); mActivity.onEnrollmentProgressChange(1, 1); mActivity.onWindowFocusChanged(false); verify(mActivity, never()).onCancelEnrollment(anyInt()); } private void initializeActivityFor(int sensorType) { final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); final FingerprintSensorPropertiesInternal prop = Loading @@ -111,15 +141,21 @@ public class FingerprintEnrollEnrollingTest { sensorType, true /* resetLockoutRequiresHardwareAuthToken */); final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>(); final Bundle savedInstanceState = new Bundle(); savedInstanceState.putInt(KEY_STATE_PREVIOUS_ROTATION, Surface.ROTATION_90); props.add(prop); mContext = spy(RuntimeEnvironment.application); mActivity = spy(FingerprintEnrollEnrolling.class); when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props); when(mContext.getDisplay()).thenReturn(mMockDisplay); when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0); mActivity = spy(FingerprintEnrollEnrolling.class); doReturn(true).when(mActivity).shouldShowLottie(); doReturn(mFingerprintManager).when(mActivity).getSystemService(FingerprintManager.class); doReturn(mVibrator).when(mActivity).getSystemService(Vibrator.class); ActivityController.of(mActivity).create(); ActivityController.of(mActivity).create(savedInstanceState); } private EnrollmentCallback verifyAndCaptureEnrollmentCallback() { Loading