Merge changes from topic "udfps-transition" into sc-dev
* changes: Hide Udfps Overlay together with system transitions Slight cleanup for UdfpsController
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package android.hardware.fingerprint;
|
||||
|
||||
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
|
||||
|
||||
/**
|
||||
* Interface for interacting with the under-display fingerprint sensor (UDFPS) overlay.
|
||||
* @hide
|
||||
@@ -28,7 +30,7 @@ oneway interface IUdfpsOverlayController {
|
||||
const int REASON_AUTH_FPM_OTHER = 5; // Other FingerprintManager usage
|
||||
|
||||
// Shows the overlay.
|
||||
void showUdfpsOverlay(int sensorId, int reason);
|
||||
void showUdfpsOverlay(int sensorId, int reason, IUdfpsOverlayControllerCallback callback);
|
||||
|
||||
// Hides the overlay.
|
||||
void hideUdfpsOverlay(int sensorId);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 android.hardware.fingerprint;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IUdfpsOverlayControllerCallback {
|
||||
// Notify system_server if the user cancels a UDFPS-related operation (enroll, auth)
|
||||
void onUserCanceled();
|
||||
}
|
||||
@@ -20,7 +20,10 @@ import static com.android.internal.util.Preconditions.checkArgument;
|
||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
@@ -29,6 +32,8 @@ import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.SystemClock;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -91,11 +96,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
private long mTouchLogTime;
|
||||
|
||||
@Nullable private UdfpsView mView;
|
||||
// Indicates whether the overlay has been requested.
|
||||
private boolean mIsOverlayRequested;
|
||||
// Reason the overlay has been requested. See IUdfpsOverlayController for definitions.
|
||||
private int mRequestReason;
|
||||
@Nullable UdfpsEnrollHelper mEnrollHelper;
|
||||
// The current request from FingerprintService. Null if no current request.
|
||||
@Nullable ServerRequest mServerRequest;
|
||||
|
||||
// The fingerprint AOD trigger doesn't provide an ACTION_UP/ACTION_CANCEL event to tell us when
|
||||
// to turn off high brightness mode. To get around this limitation, the state of the AOD
|
||||
@@ -104,39 +106,84 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
private boolean mIsAodInterruptActive;
|
||||
@Nullable private Runnable mCancelAodTimeoutAction;
|
||||
|
||||
/**
|
||||
* Keeps track of state within a single FingerprintService request. Note that this state
|
||||
* persists across configuration changes, etc, since it is considered a single request.
|
||||
*
|
||||
* TODO: Perhaps we can move more global variables into here
|
||||
*/
|
||||
private static class ServerRequest {
|
||||
// Reason the overlay has been requested. See IUdfpsOverlayController for definitions.
|
||||
final int mRequestReason;
|
||||
@NonNull final IUdfpsOverlayControllerCallback mCallback;
|
||||
@Nullable final UdfpsEnrollHelper mEnrollHelper;
|
||||
|
||||
ServerRequest(int requestReason, @NonNull IUdfpsOverlayControllerCallback callback,
|
||||
@Nullable UdfpsEnrollHelper enrollHelper) {
|
||||
mRequestReason = requestReason;
|
||||
mCallback = callback;
|
||||
mEnrollHelper = enrollHelper;
|
||||
}
|
||||
|
||||
void onEnrollmentProgress(int remaining) {
|
||||
if (mEnrollHelper != null) {
|
||||
mEnrollHelper.onEnrollmentProgress(remaining);
|
||||
}
|
||||
}
|
||||
|
||||
void onEnrollmentHelp() {
|
||||
if (mEnrollHelper != null) {
|
||||
mEnrollHelper.onEnrollmentHelp();
|
||||
}
|
||||
}
|
||||
|
||||
void onUserCanceled() {
|
||||
try {
|
||||
mCallback.onUserCanceled();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Remote exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
|
||||
@Override
|
||||
public void showUdfpsOverlay(int sensorId, int reason) {
|
||||
public void showUdfpsOverlay(int sensorId, int reason,
|
||||
@NonNull IUdfpsOverlayControllerCallback callback) {
|
||||
final UdfpsEnrollHelper enrollHelper;
|
||||
if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
|
||||
|| reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
|
||||
mEnrollHelper = new UdfpsEnrollHelper(mContext, reason);
|
||||
enrollHelper = new UdfpsEnrollHelper(mContext, reason);
|
||||
} else {
|
||||
mEnrollHelper = null;
|
||||
enrollHelper = null;
|
||||
}
|
||||
UdfpsController.this.showOverlay(reason);
|
||||
|
||||
mServerRequest = new ServerRequest(reason, callback, enrollHelper);
|
||||
updateOverlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideUdfpsOverlay(int sensorId) {
|
||||
UdfpsController.this.hideOverlay();
|
||||
mServerRequest = null;
|
||||
updateOverlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnrollmentProgress(int sensorId, int remaining) {
|
||||
if (mEnrollHelper == null) {
|
||||
Log.e(TAG, "onEnrollProgress received but helper is null");
|
||||
if (mServerRequest == null) {
|
||||
Log.e(TAG, "onEnrollProgress received but serverRequest is null");
|
||||
return;
|
||||
}
|
||||
mEnrollHelper.onEnrollmentProgress(remaining);
|
||||
mServerRequest.onEnrollmentProgress(remaining);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnrollmentHelp(int sensorId) {
|
||||
if (mEnrollHelper == null) {
|
||||
Log.e(TAG, "onEnrollmentHelp received but helper is null");
|
||||
if (mServerRequest == null) {
|
||||
Log.e(TAG, "onEnrollmentHelp received but serverRequest is null");
|
||||
return;
|
||||
}
|
||||
mEnrollHelper.onEnrollmentHelp();
|
||||
mServerRequest.onEnrollmentHelp();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,6 +212,19 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
return (float) Math.sqrt(Math.pow(vx, 2.0) + Math.pow(vy, 2.0));
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (mServerRequest != null
|
||||
&& Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
|
||||
Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received");
|
||||
mServerRequest.onUserCanceled();
|
||||
mServerRequest = null;
|
||||
updateOverlay();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private final UdfpsView.OnTouchListener mOnTouchListener = (view, event) -> {
|
||||
UdfpsView udfpsView = (UdfpsView) view;
|
||||
@@ -280,6 +340,10 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
mCoreLayoutParams.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||
|
||||
mFingerprintManager.setUdfpsOverlayController(new UdfpsOverlayController());
|
||||
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
|
||||
context.registerReceiver(mBroadcastReceiver, filter);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -314,27 +378,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
mSensorProps.sensorLocationY + mSensorProps.sensorRadius);
|
||||
}
|
||||
|
||||
private void showOverlay(int reason) {
|
||||
if (mIsOverlayRequested) {
|
||||
return;
|
||||
}
|
||||
mIsOverlayRequested = true;
|
||||
mRequestReason = reason;
|
||||
updateOverlay();
|
||||
}
|
||||
|
||||
private void hideOverlay() {
|
||||
if (!mIsOverlayRequested) {
|
||||
return;
|
||||
}
|
||||
mIsOverlayRequested = false;
|
||||
mRequestReason = IUdfpsOverlayController.REASON_UNKNOWN;
|
||||
updateOverlay();
|
||||
}
|
||||
|
||||
private void updateOverlay() {
|
||||
if (mIsOverlayRequested) {
|
||||
showUdfpsOverlay(mRequestReason);
|
||||
if (mServerRequest != null) {
|
||||
showUdfpsOverlay(mServerRequest.mRequestReason);
|
||||
} else {
|
||||
hideUdfpsOverlay();
|
||||
}
|
||||
@@ -427,7 +473,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
case IUdfpsOverlayController.REASON_ENROLL_ENROLLING: {
|
||||
final UdfpsAnimationViewEnroll view = (UdfpsAnimationViewEnroll)
|
||||
inflater.inflate(R.layout.udfps_animation_view_enroll, null, false);
|
||||
view.setEnrollHelper(mEnrollHelper);
|
||||
view.setEnrollHelper(mServerRequest.mEnrollHelper);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
@@ -89,6 +90,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
private StatusBarStateController mStatusBarStateController;
|
||||
@Mock
|
||||
private StatusBar mStatusBar;
|
||||
@Mock
|
||||
private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback;
|
||||
|
||||
private FakeExecutor mFgExecutor;
|
||||
|
||||
@@ -152,7 +155,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void dozeTimeTick() throws RemoteException {
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
mUdfpsController.dozeTimeTick();
|
||||
verify(mUdfpsView).dozeTimeTick();
|
||||
@@ -161,7 +164,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void showUdfpsOverlay_addsViewToWindow() throws RemoteException {
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
verify(mWindowManager).addView(eq(mUdfpsView), any());
|
||||
}
|
||||
@@ -169,7 +172,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void hideUdfpsOverlay_removesViewFromWindow() throws RemoteException {
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
|
||||
mFgExecutor.runAllReady();
|
||||
verify(mWindowManager).removeView(eq(mUdfpsView));
|
||||
@@ -183,7 +186,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
|
||||
// GIVEN that the overlay is showing
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
// WHEN ACTION_DOWN is received
|
||||
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
|
||||
@@ -205,7 +208,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
public void aodInterrupt() throws RemoteException {
|
||||
// GIVEN that the overlay is showing
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
// WHEN fingerprint is requested because of AOD interrupt
|
||||
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
|
||||
@@ -221,7 +224,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
public void cancelAodInterrupt() throws RemoteException {
|
||||
// GIVEN AOD interrupt
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||
// WHEN it is cancelled
|
||||
@@ -234,7 +237,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
public void aodInterruptTimeout() throws RemoteException {
|
||||
// GIVEN AOD interrupt
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||
// WHEN it times out
|
||||
@@ -247,7 +250,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void registersAndUnregistersViewForCallbacks() throws RemoteException {
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD);
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
verify(mStatusBarStateController).addCallback(mUdfpsController.mStatusBarStateListener);
|
||||
verify(mStatusBar).addExpansionChangedListener(
|
||||
|
||||
@@ -80,6 +80,18 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement
|
||||
onErrorInternal(errorCode, vendorCode, true /* finish */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the caller that the operation was canceled by the user. Note that the actual
|
||||
* operation still needs to wait for the HAL to send ERROR_CANCELED.
|
||||
*/
|
||||
public void onUserCanceled() {
|
||||
// Send USER_CANCELED, but do not finish. Wait for the HAL to respond with ERROR_CANCELED,
|
||||
// which then finishes the AcquisitionClient's lifecycle.
|
||||
onErrorInternal(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED, 0 /* vendorCode */,
|
||||
false /* finish */);
|
||||
stopHalOperation();
|
||||
}
|
||||
|
||||
protected void onErrorInternal(int errorCode, int vendorCode, boolean finish) {
|
||||
// In some cases, the framework will send an error to the caller before a true terminal
|
||||
// case (success, failure, or error) is received from the HAL (e.g. versions of fingerprint
|
||||
|
||||
@@ -22,9 +22,12 @@ import android.content.Context;
|
||||
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.biometrics.sensors.AcquisitionClient;
|
||||
|
||||
/**
|
||||
* Contains helper methods for under-display fingerprint HIDL.
|
||||
*/
|
||||
@@ -77,12 +80,22 @@ public class UdfpsHelper {
|
||||
}
|
||||
|
||||
public static void showUdfpsOverlay(int sensorId, int reason,
|
||||
@Nullable IUdfpsOverlayController udfpsOverlayController) {
|
||||
@Nullable IUdfpsOverlayController udfpsOverlayController,
|
||||
@NonNull AcquisitionClient<?> client) {
|
||||
if (udfpsOverlayController == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final IUdfpsOverlayControllerCallback callback =
|
||||
new IUdfpsOverlayControllerCallback.Stub() {
|
||||
@Override
|
||||
public void onUserCanceled() {
|
||||
client.onUserCanceled();
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
udfpsOverlayController.showUdfpsOverlay(sensorId, reason);
|
||||
udfpsOverlayController.showUdfpsOverlay(sensorId, reason, callback);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this),
|
||||
mUdfpsOverlayController);
|
||||
mUdfpsOverlayController, this);
|
||||
try {
|
||||
mCancellationSignal = getFreshDaemon().authenticate(mSequentialId, mOperationId);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -72,7 +72,7 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> {
|
||||
protected void startHalOperation() {
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(),
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD,
|
||||
mUdfpsOverlayController);
|
||||
mUdfpsOverlayController, this);
|
||||
try {
|
||||
mCancellationSignal = getFreshDaemon().detectInteraction(mSequentialId);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -121,7 +121,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
||||
protected void startHalOperation() {
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(),
|
||||
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
|
||||
mUdfpsOverlayController);
|
||||
mUdfpsOverlayController, this);
|
||||
try {
|
||||
mCancellationSignal = getFreshDaemon().enroll(mSequentialId,
|
||||
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken));
|
||||
|
||||
@@ -120,7 +120,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this),
|
||||
mUdfpsOverlayController);
|
||||
mUdfpsOverlayController, this);
|
||||
try {
|
||||
// GroupId was never used. In fact, groupId is always the same as userId.
|
||||
getFreshDaemon().authenticate(mOperationId, getTargetUserId());
|
||||
|
||||
@@ -85,7 +85,7 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
|
||||
protected void startHalOperation() {
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(),
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD,
|
||||
mUdfpsOverlayController);
|
||||
mUdfpsOverlayController, this);
|
||||
try {
|
||||
getFreshDaemon().authenticate(0 /* operationId */, getTargetUserId());
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -84,7 +84,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
||||
protected void startHalOperation() {
|
||||
UdfpsHelper.showUdfpsOverlay(getSensorId(),
|
||||
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
|
||||
mUdfpsOverlayController);
|
||||
mUdfpsOverlayController, this);
|
||||
try {
|
||||
// GroupId was never used. In fact, groupId is always the same as userId.
|
||||
getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec);
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.server.biometrics.sensors;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.os.IBinder;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@Presubmit
|
||||
@SmallTest
|
||||
public class AcquisitionClientTest {
|
||||
|
||||
private static final int TEST_SENSOR_ID = 100;
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private IBinder mToken;
|
||||
@Mock
|
||||
private ClientMonitorCallbackConverter mClientCallback;
|
||||
@Mock
|
||||
private BaseClientMonitor.Callback mSchedulerCallback;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserCanceled() throws Exception {
|
||||
// Start an AcquisitionClient
|
||||
final TestAcquisitionClient client = new TestAcquisitionClient(mContext, Object::new,
|
||||
mToken, mClientCallback);
|
||||
client.start(mSchedulerCallback);
|
||||
assertTrue(client.mHalOperationRunning);
|
||||
verify(mSchedulerCallback).onClientStarted(eq(client));
|
||||
|
||||
// Pretend that it got canceled by the user.
|
||||
client.onUserCanceled();
|
||||
verify(mSchedulerCallback, never()).onClientFinished(any(), anyBoolean());
|
||||
verify(mClientCallback).onError(eq(TEST_SENSOR_ID),
|
||||
anyInt(),
|
||||
eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
|
||||
eq(0) /* vendorCode */);
|
||||
assertFalse(client.mHalOperationRunning);
|
||||
|
||||
// Pretend that the HAL responded with ERROR_CANCELED
|
||||
client.onError(BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0 /* vendorCode */);
|
||||
verifyNoMoreInteractions(mClientCallback);
|
||||
verify(mSchedulerCallback).onClientFinished(eq(client), anyBoolean());
|
||||
}
|
||||
|
||||
private static class TestAcquisitionClient extends AcquisitionClient<Object> {
|
||||
boolean mHalOperationRunning;
|
||||
|
||||
public TestAcquisitionClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<Object> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter callback) {
|
||||
super(context, lazyDaemon, token, callback, 0 /* userId */, "Test", 0 /* cookie */,
|
||||
TEST_SENSOR_ID /* sensorId */, 0 /* statsModality */, 0 /* statsAction */,
|
||||
0 /* statsClient */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NonNull Callback callback) {
|
||||
super.start(callback);
|
||||
startHalOperation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopHalOperation() {
|
||||
mHalOperationRunning = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
mHalOperationRunning = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user