Remove confirm button when falling back to fingerprint auth.
Fix: 186283063 Test: atest AuthBiometricFaceToFingerprintViewTest Test: manual (fail face auth and verify button disappers) Change-Id: I57f018e41b598fe8b2a9bccb37cdd369491e266b
This commit is contained in:
@@ -26,9 +26,11 @@ import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
@@ -97,6 +99,11 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
AuthBiometricFaceToFingerprintView(Context context, AttributeSet attrs, Injector injector) {
|
||||
super(context, attrs, injector);
|
||||
}
|
||||
|
||||
void setFingerprintSensorProps(@NonNull FingerprintSensorPropertiesInternal sensorProps) {
|
||||
if (!sensorProps.isAnyUdfpsType()) {
|
||||
return;
|
||||
@@ -135,19 +142,28 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
|
||||
protected IconController getIconController() {
|
||||
if (mActiveSensorType == TYPE_FINGERPRINT) {
|
||||
if (!(mIconController instanceof UdfpsIconController)) {
|
||||
mIconController = new UdfpsIconController(getContext(), mIconView, mIndicatorView);
|
||||
mIconController = createUdfpsIconController();
|
||||
}
|
||||
return mIconController;
|
||||
}
|
||||
return super.getIconController();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected IconController createUdfpsIconController() {
|
||||
return new UdfpsIconController(getContext(), mIconView, mIndicatorView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(int newState) {
|
||||
if (mState == STATE_HELP || mState == STATE_ERROR) {
|
||||
mActiveSensorType = TYPE_FINGERPRINT;
|
||||
|
||||
setRequireConfirmation(false);
|
||||
mConfirmButton.setEnabled(false);
|
||||
mConfirmButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
super.updateState(newState);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.R;
|
||||
|
||||
public class AuthBiometricFaceView extends AuthBiometricView {
|
||||
@@ -148,6 +149,11 @@ public class AuthBiometricFaceView extends AuthBiometricView {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
AuthBiometricFaceView(Context context, AttributeSet attrs, Injector injector) {
|
||||
super(context, attrs, injector);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDelayAfterAuthenticatedDurationMs() {
|
||||
return HIDE_DELAY_MS;
|
||||
|
||||
@@ -612,7 +612,7 @@ public abstract class AuthBiometricView extends LinearLayout {
|
||||
mIndicatorView.setTextColor(mTextColorError);
|
||||
mIndicatorView.setVisibility(View.VISIBLE);
|
||||
mIndicatorView.setSelected(true);
|
||||
mHandler.postDelayed(resetMessageRunnable, BiometricPrompt.HIDE_DIALOG_DELAY);
|
||||
mHandler.postDelayed(resetMessageRunnable, mInjector.getDelayAfterError());
|
||||
|
||||
Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.systemui.biometrics;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
@SmallTest
|
||||
public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
|
||||
|
||||
@Mock AuthBiometricView.Callback mCallback;
|
||||
|
||||
private AuthBiometricFaceToFingerprintView mFaceToFpView;
|
||||
|
||||
@Mock private Button mNegativeButton;
|
||||
@Mock private Button mCancelButton;
|
||||
@Mock private Button mConfirmButton;
|
||||
@Mock private Button mUseCredentialButton;
|
||||
@Mock private Button mTryAgainButton;
|
||||
|
||||
@Mock private TextView mTitleView;
|
||||
@Mock private TextView mSubtitleView;
|
||||
@Mock private TextView mDescriptionView;
|
||||
@Mock private TextView mIndicatorView;
|
||||
@Mock private ImageView mIconView;
|
||||
@Mock private View mIconHolderView;
|
||||
|
||||
@Mock private TextView mErrorView;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFaceToFpView = new TestableView(mContext);
|
||||
mFaceToFpView.mIconController = mock(AuthBiometricFaceView.IconController.class);
|
||||
mFaceToFpView.setCallback(mCallback);
|
||||
|
||||
mFaceToFpView.mNegativeButton = mNegativeButton;
|
||||
mFaceToFpView.mCancelButton = mCancelButton;
|
||||
mFaceToFpView.mUseCredentialButton = mUseCredentialButton;
|
||||
mFaceToFpView.mConfirmButton = mConfirmButton;
|
||||
mFaceToFpView.mTryAgainButton = mTryAgainButton;
|
||||
|
||||
mFaceToFpView.mIndicatorView = mErrorView;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStateUpdated_whenDialogAnimatedIn() {
|
||||
mFaceToFpView.onDialogAnimatedIn();
|
||||
verify(mFaceToFpView.mIconController)
|
||||
.updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIconUpdatesState_whenDialogStateUpdated() {
|
||||
mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
|
||||
verify(mFaceToFpView.mIconController)
|
||||
.updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
|
||||
|
||||
mFaceToFpView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATED);
|
||||
verify(mFaceToFpView.mIconController).updateState(
|
||||
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING),
|
||||
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStateUpdated_whenSwitchToFingerprint() {
|
||||
mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
|
||||
verify(mFaceToFpView.mIconController)
|
||||
.updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
|
||||
|
||||
mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_ERROR);
|
||||
mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
|
||||
|
||||
InOrder order = inOrder(mFaceToFpView.mIconController);
|
||||
order.verify(mFaceToFpView.mIconController).updateState(
|
||||
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING),
|
||||
eq(AuthBiometricFaceToFingerprintView.STATE_ERROR));
|
||||
order.verify(mFaceToFpView.mIconController).updateState(
|
||||
eq(AuthBiometricFaceToFingerprintView.STATE_ERROR),
|
||||
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
|
||||
|
||||
verify(mConfirmButton).setVisibility(eq(View.GONE));
|
||||
}
|
||||
|
||||
public class TestableView extends AuthBiometricFaceToFingerprintView {
|
||||
public TestableView(Context context) {
|
||||
super(context, null, new MockInjector());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDelayAfterAuthenticatedDurationMs() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IconController createUdfpsIconController() {
|
||||
return mIconController;
|
||||
}
|
||||
}
|
||||
|
||||
private class MockInjector extends AuthBiometricView.Injector {
|
||||
@Override
|
||||
public Button getNegativeButton() {
|
||||
return mNegativeButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button getCancelButton() {
|
||||
return mCancelButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button getUseCredentialButton() {
|
||||
return mUseCredentialButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button getConfirmButton() {
|
||||
return mConfirmButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button getTryAgainButton() {
|
||||
return mTryAgainButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getTitleView() {
|
||||
return mTitleView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getSubtitleView() {
|
||||
return mSubtitleView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getDescriptionView() {
|
||||
return mDescriptionView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextView getIndicatorView() {
|
||||
return mIndicatorView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageView getIconView() {
|
||||
return mIconView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getIconHolderView() {
|
||||
return mIconHolderView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDelayAfterError() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMediumToLargeAnimationDurationMs() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user