Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a43389c authored by Diya Bera's avatar Diya Bera Committed by Android (Google) Code Review
Browse files

Merge "Correct mIsPromptShowing value when auth fails" into udc-dev

parents bb0278a3 1f3e3d55
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
        private PromptInfo mPromptInfo;
        private ButtonInfo mNegativeButtonInfo;
        private Context mContext;
        private IAuthService mService;

        /**
         * Creates a builder for a {@link BiometricPrompt} dialog.
@@ -211,6 +212,18 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
            return this;
        }

        /**
         * @param service
         * @return This builder.
         * @hide
         */
        @RequiresPermission(TEST_BIOMETRIC)
        @NonNull
        public Builder setService(@NonNull IAuthService service) {
            mService = service;
            return this;
        }

        /**
         * Sets an optional title, subtitle, and/or description that will override other text when
         * the user is authenticating with PIN/pattern/password. Currently for internal use only.
@@ -472,7 +485,9 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
                throw new IllegalArgumentException("Can't have both negative button behavior"
                        + " and device credential enabled");
            }
            return new BiometricPrompt(mContext, mPromptInfo, mNegativeButtonInfo);
            mService = (mService == null) ? IAuthService.Stub.asInterface(
                    ServiceManager.getService(Context.AUTH_SERVICE)) : mService;
            return new BiometricPrompt(mContext, mPromptInfo, mNegativeButtonInfo, mService);
        }
    }

@@ -521,7 +536,6 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
        public void onAuthenticationFailed() {
            mExecutor.execute(() -> {
                mAuthenticationCallback.onAuthenticationFailed();
                mIsPromptShowing = false;
            });
        }

@@ -604,12 +618,12 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan

    private boolean mIsPromptShowing;

    private BiometricPrompt(Context context, PromptInfo promptInfo, ButtonInfo negativeButtonInfo) {
    private BiometricPrompt(Context context, PromptInfo promptInfo, ButtonInfo negativeButtonInfo,
            IAuthService service) {
        mContext = context;
        mPromptInfo = promptInfo;
        mNegativeButtonInfo = negativeButtonInfo;
        mService = IAuthService.Stub.asInterface(
                ServiceManager.getService(Context.AUTH_SERVICE));
        mService = service;
        mIsPromptShowing = false;
    }

+102 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 android.hardware.biometrics;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.RemoteException;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.MockitoRule;

import java.util.concurrent.Executor;


@Presubmit
@RunWith(MockitoJUnitRunner.class)
public class BiometricPromptTest {
    @Rule
    public final MockitoRule mockito = MockitoJUnit.rule();

    @Mock
    private Context mContext;
    @Mock
    private IAuthService mService;
    private BiometricPrompt mBiometricPrompt;

    private CancellationSignal mCancellationSignal;

    private final TestLooper mLooper = new TestLooper();
    private final Handler mHandler = new Handler(mLooper.getLooper());
    private final Executor mExecutor = mHandler::post;

    @Before
    public void setUp() throws RemoteException {
        mBiometricPrompt = new BiometricPrompt.Builder(mContext)
                .setUseDefaultSubtitle()
                .setUseDefaultTitle()
                .setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG
                        | BiometricManager.Authenticators.DEVICE_CREDENTIAL)
                .setService(mService)
                .build();

        mCancellationSignal = new CancellationSignal();
        when(mService.authenticate(any(), anyLong(), anyInt(), any(), anyString(), any()))
                .thenReturn(0L);
        when(mContext.getPackageName()).thenReturn("BiometricPromptTest");
    }

    @Test
    public void testCancellationAfterAuthenticationFailed() throws RemoteException {
        ArgumentCaptor<IBiometricServiceReceiver> biometricServiceReceiverCaptor =
                ArgumentCaptor.forClass(IBiometricServiceReceiver.class);
        BiometricPrompt.AuthenticationCallback callback =
                new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode, CharSequence errString) {
                super.onAuthenticationError(errorCode, errString);
            }};
        mBiometricPrompt.authenticate(mCancellationSignal, mExecutor, callback);
        mLooper.dispatchAll();

        verify(mService).authenticate(any(), anyLong(), anyInt(),
                biometricServiceReceiverCaptor.capture(), anyString(), any());

        biometricServiceReceiverCaptor.getValue().onAuthenticationFailed();
        mLooper.dispatchAll();
        mCancellationSignal.cancel();

        verify(mService).cancelAuthentication(any(), anyString(), anyLong());
    }
}
+1 −0
Original line number Diff line number Diff line
include /services/core/java/com/android/server/biometrics/OWNERS