Merge "Consolidate fingerprint overlay controllers." into sc-v2-dev am: bf5ad9066a am: b500536d14

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15750027

Change-Id: I577464a7d55b369ff2b5e7f1f685f9e4d5e4ce6a
This commit is contained in:
Joe Bolinger
2021-09-17 06:30:22 +00:00
committed by Automerger Merge Worker
18 changed files with 457 additions and 278 deletions

View File

@@ -0,0 +1,50 @@
/*
* 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.biometrics;
import android.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Common constants for biometric overlays.
* @hide
*/
public interface BiometricOverlayConstants {
/** Unknown usage. */
int REASON_UNKNOWN = 0;
/** User is about to enroll. */
int REASON_ENROLL_FIND_SENSOR = 1;
/** User is enrolling. */
int REASON_ENROLL_ENROLLING = 2;
/** Usage from BiometricPrompt. */
int REASON_AUTH_BP = 3;
/** Usage from Keyguard. */
int REASON_AUTH_KEYGUARD = 4;
/** Non-specific usage (from FingerprintManager). */
int REASON_AUTH_OTHER = 5;
@IntDef({REASON_UNKNOWN,
REASON_ENROLL_FIND_SENSOR,
REASON_ENROLL_ENROLLING,
REASON_AUTH_BP,
REASON_AUTH_KEYGUARD,
REASON_AUTH_OTHER})
@Retention(RetentionPolicy.SOURCE)
@interface ShowReason {}
}

View File

@@ -22,13 +22,6 @@ import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
* @hide
*/
oneway interface IUdfpsOverlayController {
const int REASON_UNKNOWN = 0;
const int REASON_ENROLL_FIND_SENSOR = 1;
const int REASON_ENROLL_ENROLLING = 2;
const int REASON_AUTH_BP = 3; // BiometricPrompt
const int REASON_AUTH_FPM_KEYGUARD = 4; // FingerprintManager usage from Keyguard
const int REASON_AUTH_FPM_OTHER = 5; // Other FingerprintManager usage
// Shows the overlay.
void showUdfpsOverlay(int sensorId, int reason, IUdfpsOverlayControllerCallback callback);

View File

@@ -16,7 +16,7 @@
package com.android.systemui.biometrics;
import static android.hardware.fingerprint.IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD;
import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
@@ -32,6 +32,7 @@ import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.RectF;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -240,8 +241,8 @@ public class UdfpsController implements DozeReceiver {
@NonNull IUdfpsOverlayControllerCallback callback) {
mFgExecutor.execute(() -> {
final UdfpsEnrollHelper enrollHelper;
if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
|| reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
if (reason == BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR
|| reason == BiometricOverlayConstants.REASON_ENROLL_ENROLLING) {
enrollHelper = new UdfpsEnrollHelper(mContext, reason);
} else {
enrollHelper = null;
@@ -319,7 +320,7 @@ public class UdfpsController implements DozeReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (mServerRequest != null
&& mServerRequest.mRequestReason != REASON_AUTH_FPM_KEYGUARD
&& mServerRequest.mRequestReason != REASON_AUTH_KEYGUARD
&& Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, mRequestReason: "
+ mServerRequest.mRequestReason);
@@ -763,9 +764,9 @@ public class UdfpsController implements DozeReceiver {
// This view overlaps the sensor area, so prevent it from being selectable
// during a11y.
if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
|| reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING
|| reason == IUdfpsOverlayController.REASON_AUTH_BP) {
if (reason == BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR
|| reason == BiometricOverlayConstants.REASON_ENROLL_ENROLLING
|| reason == BiometricOverlayConstants.REASON_AUTH_BP) {
mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
@@ -783,8 +784,8 @@ public class UdfpsController implements DozeReceiver {
private UdfpsAnimationViewController inflateUdfpsAnimation(int reason) {
switch (reason) {
case IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR:
case IUdfpsOverlayController.REASON_ENROLL_ENROLLING:
case BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR:
case BiometricOverlayConstants.REASON_ENROLL_ENROLLING:
UdfpsEnrollView enrollView = (UdfpsEnrollView) mInflater.inflate(
R.layout.udfps_enroll_view, null);
mView.addView(enrollView);
@@ -796,7 +797,7 @@ public class UdfpsController implements DozeReceiver {
mStatusBarOptional,
mDumpManager
);
case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD:
case BiometricOverlayConstants.REASON_AUTH_KEYGUARD:
UdfpsKeyguardView keyguardView = (UdfpsKeyguardView)
mInflater.inflate(R.layout.udfps_keyguard_view, null);
mView.addView(keyguardView);
@@ -814,7 +815,7 @@ public class UdfpsController implements DozeReceiver {
mUnlockedScreenOffAnimationController,
this
);
case IUdfpsOverlayController.REASON_AUTH_BP:
case BiometricOverlayConstants.REASON_AUTH_BP:
// note: empty controller, currently shows no visual affordance
UdfpsBpView bpView = (UdfpsBpView) mInflater.inflate(R.layout.udfps_bp_view, null);
mView.addView(bpView);
@@ -824,7 +825,7 @@ public class UdfpsController implements DozeReceiver {
mStatusBarOptional,
mDumpManager
);
case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER:
case BiometricOverlayConstants.REASON_AUTH_OTHER:
UdfpsFpmOtherView authOtherView = (UdfpsFpmOtherView)
mInflater.inflate(R.layout.udfps_fpm_other_view, null);
mView.addView(authOtherView);

View File

@@ -20,7 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.PointF;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.os.Build;
import android.os.UserHandle;
import android.provider.Settings;
@@ -119,7 +119,7 @@ public class UdfpsEnrollHelper {
}
boolean shouldShowProgressBar() {
return mEnrollReason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING;
return mEnrollReason == BiometricOverlayConstants.REASON_ENROLL_ENROLLING;
}
void onEnrollmentProgress(int remaining) {

View File

@@ -32,6 +32,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.TypedArray;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.SensorProperties;
import android.hardware.display.DisplayManager;
@@ -257,7 +258,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void dozeTimeTick() throws RemoteException {
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
mUdfpsController.dozeTimeTick();
verify(mUdfpsView).dozeTimeTick();
@@ -272,7 +273,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
@@ -295,7 +296,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
@@ -318,7 +319,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
@@ -341,7 +342,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
@@ -363,7 +364,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_MOVE is received
@@ -385,7 +386,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN multiple touches are received
@@ -405,7 +406,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void showUdfpsOverlay_addsViewToWindow() throws RemoteException {
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
verify(mWindowManager).addView(eq(mUdfpsView), any());
}
@@ -413,7 +414,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void hideUdfpsOverlay_removesViewFromWindow() throws RemoteException {
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mFgExecutor.runAllReady();
verify(mWindowManager).removeView(eq(mUdfpsView));
@@ -423,7 +424,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
public void hideUdfpsOverlay_resetsAltAuthBouncerWhenShowing() throws RemoteException {
// GIVEN overlay was showing and the udfps bouncer is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
when(mStatusBarKeyguardViewManager.isShowingAlternateAuth()).thenReturn(true);
// WHEN the overlay is hidden
@@ -437,7 +438,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void testSubscribesToOrientationChangesWhenShowingOverlay() throws Exception {
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
verify(mDisplayManager).registerDisplayListener(any(), eq(mHandler));
@@ -456,7 +457,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
@@ -480,7 +481,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
public void aodInterrupt() throws RemoteException {
// GIVEN that the overlay is showing and screen is on
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
// WHEN fingerprint is requested because of AOD interrupt
@@ -497,7 +498,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, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
@@ -512,7 +513,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, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
@@ -528,7 +529,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
public void aodInterruptScreenOff() throws RemoteException {
// GIVEN screen off
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOff();
mFgExecutor.runAllReady();
@@ -547,7 +548,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received

View File

@@ -50,7 +50,6 @@ import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorProperties;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Binder;
import android.os.Build;
import android.os.RemoteException;
@@ -62,7 +61,6 @@ import android.util.Slog;
import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import java.util.List;
@@ -541,14 +539,4 @@ public class Utils {
throw new IllegalArgumentException("Unknown strength: " + strength);
}
}
public static int getUdfpsAuthReason(@NonNull AuthenticationClient<?> client) {
if (client.isKeyguard()) {
return IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD;
} else if (client.isBiometricPrompt()) {
return IUdfpsOverlayController.REASON_AUTH_BP;
} else {
return IUdfpsOverlayController.REASON_AUTH_FPM_OTHER;
}
}
}

View File

@@ -28,6 +28,7 @@ import android.content.pm.ApplicationInfo;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.os.IBinder;
import android.os.RemoteException;
@@ -457,4 +458,14 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
public boolean wasAuthAttempted() {
return mAuthAttempted;
}
protected int getShowOverlayReason() {
if (isKeyguard()) {
return BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
} else if (isBiometricPrompt()) {
return BiometricOverlayConstants.REASON_AUTH_BP;
} else {
return BiometricOverlayConstants.REASON_AUTH_OTHER;
}
}
}

View File

@@ -19,7 +19,9 @@ package com.android.server.biometrics.sensors;
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.fingerprint.FingerprintManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
@@ -128,4 +130,15 @@ public abstract class EnrollClient<T> extends AcquisitionClient<T> implements En
public boolean interruptsPrecedingClients() {
return true;
}
protected int getOverlayReasonFromEnrollReason(@FingerprintManager.EnrollReason int reason) {
switch (reason) {
case FingerprintManager.ENROLL_FIND_SENSOR:
return BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR;
case FingerprintManager.ENROLL_ENROLL:
return BiometricOverlayConstants.REASON_ENROLL_ENROLLING;
default:
return BiometricOverlayConstants.REASON_UNKNOWN;
}
}
}

View File

@@ -0,0 +1,144 @@
/*
* 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 android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
import android.os.RemoteException;
import android.util.Slog;
import java.util.Optional;
import java.util.function.Consumer;
/**
* Single entry point & holder for controllers managing UI overlays for biometrics.
*
* For common operations, like {@link #show(int, int, AcquisitionClient)}, modalities are
* skipped if they are not present (provided as null via the constructor).
*
* Use the getters, such as {@link #ifUdfps(OverlayControllerConsumer)}, to get a controller for
* operations that are unique to a single modality.
*/
public final class SensorOverlays {
private static final String TAG = "SensorOverlays";
@NonNull private final Optional<IUdfpsOverlayController> mUdfpsOverlayController;
@NonNull private final Optional<ISidefpsController> mSidefpsController;
/**
* Create an overlay controller for each modality.
*
* @param udfpsOverlayController under display fps or null if not present on device
* @param sidefpsController side fps or null if not present on device
*/
public SensorOverlays(
@Nullable IUdfpsOverlayController udfpsOverlayController,
@Nullable ISidefpsController sidefpsController) {
mUdfpsOverlayController = Optional.ofNullable(udfpsOverlayController);
mSidefpsController = Optional.ofNullable(sidefpsController);
}
/**
* Show the overlay.
*
* @param sensorId sensor id
* @param reason reason for showing
* @param client client performing operation
*/
public void show(int sensorId, @BiometricOverlayConstants.ShowReason int reason,
@NonNull AcquisitionClient<?> client) {
if (mSidefpsController.isPresent()) {
try {
mSidefpsController.get().show();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when showing the side-fps overlay", e);
}
}
if (mUdfpsOverlayController.isPresent()) {
final IUdfpsOverlayControllerCallback callback =
new IUdfpsOverlayControllerCallback.Stub() {
@Override
public void onUserCanceled() {
client.onUserCanceled();
}
};
try {
mUdfpsOverlayController.get().showUdfpsOverlay(sensorId, reason, callback);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e);
}
}
}
/**
* Hide the overlay.
*
* @param sensorId sensor id
*/
public void hide(int sensorId) {
if (mSidefpsController.isPresent()) {
try {
mSidefpsController.get().hide();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when hiding the side-fps overlay", e);
}
}
if (mUdfpsOverlayController.isPresent()) {
try {
mUdfpsOverlayController.get().hideUdfpsOverlay(sensorId);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when hiding the UDFPS overlay", e);
}
}
}
/**
* Use the udfps controller, if present.
* @param consumer action
*/
public void ifUdfps(OverlayControllerConsumer<IUdfpsOverlayController> consumer) {
if (mUdfpsOverlayController.isPresent()) {
try {
consumer.accept(mUdfpsOverlayController.get());
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception using overlay controller", e);
}
}
}
/**
* Consumer for a biometric overlay controller.
*
* This behaves like a normal {@link Consumer} except that it will trap and log
* any thrown {@link RemoteException}.
*
* @param <T> the type of the input to the operation
**/
@FunctionalInterface
public interface OverlayControllerConsumer<T> {
/** Perform the operation. */
void accept(T t) throws RemoteException;
}
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright (C) 2020 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.fingerprint;
import android.annotation.Nullable;
import android.hardware.fingerprint.ISidefpsController;
import android.os.RemoteException;
import android.util.Slog;
/**
* Contains helper methods for side-fps fingerprint controller.
*/
public class SidefpsHelper {
private static final String TAG = "SidefpsHelper";
/**
* Shows the side-fps affordance
* @param sidefpsController controller that shows and hides the side-fps affordance
*/
public static void showOverlay(@Nullable ISidefpsController sidefpsController) {
if (sidefpsController == null) {
return;
}
try {
sidefpsController.show();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when showing the side-fps overlay", e);
}
}
/**
* Hides the side-fps affordance
* @param sidefpsController controller that shows and hides the side-fps affordance
*/
public static void hideOverlay(@Nullable ISidefpsController sidefpsController) {
if (sidefpsController == null) {
return;
}
try {
sidefpsController.hide();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when hiding the side-fps overlay", e);
}
}
}

View File

@@ -17,17 +17,12 @@
package com.android.server.biometrics.sensors.fingerprint;
import android.annotation.NonNull;
import android.annotation.Nullable;
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.
*/
@@ -68,88 +63,6 @@ public class UdfpsHelper {
}
}
public static int getReasonFromEnrollReason(@FingerprintManager.EnrollReason int reason) {
switch (reason) {
case FingerprintManager.ENROLL_FIND_SENSOR:
return IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR;
case FingerprintManager.ENROLL_ENROLL:
return IUdfpsOverlayController.REASON_ENROLL_ENROLLING;
default:
return IUdfpsOverlayController.REASON_UNKNOWN;
}
}
public static void showUdfpsOverlay(int sensorId, int reason,
@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, callback);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e);
}
}
public static void hideUdfpsOverlay(int sensorId,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
return;
}
try {
udfpsOverlayController.hideUdfpsOverlay(sensorId);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when hiding the UDFPS overlay", e);
}
}
public static void onAcquiredGood(int sensorId,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
return;
}
try {
udfpsOverlayController.onAcquiredGood(sensorId);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when sending onAcquiredGood", e);
}
}
public static void onEnrollmentProgress(int sensorId, int remaining,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
return;
}
try {
udfpsOverlayController.onEnrollmentProgress(sensorId, remaining);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when sending onEnrollmentProgress", e);
}
}
public static void onEnrollmentHelp(int sensorId,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
return;
}
try {
udfpsOverlayController.onEnrollmentHelp(sensorId);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when sending onEnrollmentHelp", e);
}
}
public static boolean isValidAcquisitionMessage(@NonNull Context context,
int acquireInfo, int vendorCode) {
return FingerprintManager.getAcquiredString(context, acquireInfo, vendorCode) != null;

View File

@@ -32,15 +32,14 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BiometricNotificationUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutConsumer;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.SensorOverlays;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
import java.util.ArrayList;
@@ -53,7 +52,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
private static final String TAG = "FingerprintAuthenticationClient";
@NonNull private final LockoutCache mLockoutCache;
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@NonNull private final SensorOverlays mSensorOverlays;
@NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
@NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
@@ -77,7 +76,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
false /* isKeyguardBypassEnabled */);
setRequestId(requestId);
mLockoutCache = lockoutCache;
mUdfpsOverlayController = udfpsOverlayController;
mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController */);
mSensorProps = sensorProps;
mALSProbeCallback = createALSCallback(false /* startWithClient */);
}
@@ -120,7 +119,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
if (authenticated) {
mState = STATE_STOPPED;
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
} else {
mState = STATE_STARTED_PAUSED_ATTEMPTED;
}
@@ -131,7 +130,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
// For UDFPS, notify SysUI that the illumination can be turned off.
// See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId()));
}
super.onAcquired(acquiredInfo, vendorCode);
@@ -145,27 +144,28 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
BiometricNotificationUtils.showBadCalibrationNotification(getContext());
}
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
}
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this),
mUdfpsOverlayController, this);
mSensorOverlays.show(getSensorId(), getShowOverlayReason(), this);
try {
mCancellationSignal = getFreshDaemon().authenticate(mOperationId);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
mCallback.onClientFinished(this, false /* success */);
}
}
@Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
try {
mCancellationSignal.cancel();
} catch (RemoteException e) {
@@ -235,7 +235,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
Slog.e(TAG, "Remote exception", e);
}
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
mCallback.onClientFinished(this, false /* success */);
}
@@ -252,7 +252,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
Slog.e(TAG, "Remote exception", e);
}
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
mCallback.onClientFinished(this, false /* success */);
}
}

View File

@@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors.fingerprint.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.fingerprint.ISession;
@@ -31,7 +32,7 @@ import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.DetectionConsumer;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
import com.android.server.biometrics.sensors.SensorOverlays;
/**
* Performs fingerprint detection without exposing any matching information (e.g. accept/reject
@@ -42,8 +43,7 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det
private static final String TAG = "FingerprintDetectClient";
private final boolean mIsStrongBiometric;
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@NonNull private final SensorOverlays mSensorOverlays;
@Nullable private ICancellationSignal mCancellationSignal;
FingerprintDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
@@ -57,7 +57,7 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det
BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
setRequestId(requestId);
mIsStrongBiometric = isStrongBiometric;
mUdfpsOverlayController = udfpsOverlayController;
mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController*/);
}
@Override
@@ -68,7 +68,8 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det
@Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
try {
mCancellationSignal.cancel();
} catch (RemoteException e) {
@@ -79,14 +80,13 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(),
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD,
mUdfpsOverlayController, this);
mSensorOverlays.show(getSensorId(), BiometricOverlayConstants.REASON_AUTH_KEYGUARD, this);
try {
mCancellationSignal = getFreshDaemon().detectInteraction();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting finger detect", e);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
mCallback.onClientFinished(this, false /* success */);
}
}

View File

@@ -39,8 +39,8 @@ import com.android.server.biometrics.sensors.BiometricNotificationUtils;
import com.android.server.biometrics.sensors.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient;
import com.android.server.biometrics.sensors.SensorOverlays;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.SidefpsHelper;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
@@ -49,8 +49,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
private static final String TAG = "FingerprintEnrollClient";
@NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private final ISidefpsController mSidefpsController;
@NonNull private final SensorOverlays mSensorOverlays;
private final @FingerprintManager.EnrollReason int mEnrollReason;
@Nullable private ICancellationSignal mCancellationSignal;
@@ -63,7 +62,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
@NonNull byte[] hardwareAuthToken, @NonNull String owner,
@NonNull BiometricUtils<Fingerprint> utils, int sensorId,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@Nullable IUdfpsOverlayController udfpsOvelayController,
@Nullable IUdfpsOverlayController udfpsOverlayController,
@Nullable ISidefpsController sidefpsController,
int maxTemplatesPerUser, @FingerprintManager.EnrollReason int enrollReason) {
// UDFPS haptics occur when an image is acquired (instead of when the result is known)
@@ -71,8 +70,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
!sensorProps.isAnyUdfpsType() /* shouldVibrate */);
mSensorProps = sensorProps;
mUdfpsOverlayController = udfpsOvelayController;
mSidefpsController = sidefpsController;
mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
mMaxTemplatesPerUser = maxTemplatesPerUser;
mEnrollReason = enrollReason;
@@ -91,11 +89,11 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
super.onEnrollResult(identifier, remaining);
UdfpsHelper.onEnrollmentProgress(getSensorId(), remaining, mUdfpsOverlayController);
mSensorOverlays.ifUdfps(
controller -> controller.onEnrollmentProgress(getSensorId(), remaining));
if (remaining == 0) {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mSensorOverlays.hide(getSensorId());
}
}
@@ -106,12 +104,14 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD
&& mSensorProps.isAnyUdfpsType()) {
vibrateSuccess();
UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId()));
}
if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) {
UdfpsHelper.onEnrollmentHelp(getSensorId(), mUdfpsOverlayController);
}
mSensorOverlays.ifUdfps(controller -> {
if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) {
controller.onEnrollmentHelp(getSensorId());
}
});
super.onAcquired(acquiredInfo, vendorCode);
}
@@ -120,8 +120,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
public void onError(int errorCode, int vendorCode) {
super.onError(errorCode, vendorCode);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mSensorOverlays.hide(getSensorId());
}
@Override
@@ -133,8 +132,8 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
@Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mSensorOverlays.hide(getSensorId());
if (mCancellationSignal != null) {
try {
mCancellationSignal.cancel();
@@ -149,10 +148,8 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(),
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
mUdfpsOverlayController, this);
SidefpsHelper.showOverlay(mSidefpsController);
mSensorOverlays.show(getSensorId(), getOverlayReasonFromEnrollReason(mEnrollReason), this);
BiometricNotificationUtils.cancelBadCalibrationNotification(getContext());
try {
mCancellationSignal = getFreshDaemon().enroll(

View File

@@ -31,11 +31,11 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BiometricNotificationUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.SensorOverlays;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
@@ -52,7 +52,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
private static final String TAG = "Biometrics/FingerprintAuthClient";
private final LockoutFrameworkImpl mLockoutFrameworkImpl;
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@NonNull private final SensorOverlays mSensorOverlays;
@NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
@NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
@@ -76,7 +76,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
false /* isKeyguardBypassEnabled */);
setRequestId(requestId);
mLockoutFrameworkImpl = lockoutTracker;
mUdfpsOverlayController = udfpsOverlayController;
mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController */);
mSensorProps = sensorProps;
mALSProbeCallback = createALSCallback(false /* startWithClient */);
}
@@ -112,7 +112,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
if (authenticated) {
mState = STATE_STOPPED;
resetFailedAttempts(getTargetUserId());
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
} else {
mState = STATE_STARTED_PAUSED_ATTEMPTED;
final @LockoutTracker.LockoutMode int lockoutMode =
@@ -125,7 +125,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
// Send the error, but do not invoke the FinishCallback yet. Since lockout is not
// controlled by the HAL, the framework must stop the sensor before finishing the
// client.
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
onErrorInternal(errorCode, 0 /* vendorCode */, false /* finish */);
cancel();
}
@@ -140,7 +140,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
BiometricNotificationUtils.showBadCalibrationNotification(getContext());
}
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
}
private void resetFailedAttempts(int userId) {
@@ -168,8 +168,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this),
mUdfpsOverlayController, this);
mSensorOverlays.show(getSensorId(), getShowOverlayReason(), this);
try {
// GroupId was never used. In fact, groupId is always the same as userId.
getFreshDaemon().authenticate(mOperationId, getTargetUserId());
@@ -177,14 +177,15 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
Slog.e(TAG, "Remote exception when requesting auth", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
mCallback.onClientFinished(this, false /* success */);
}
}
@Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
try {
getFreshDaemon().cancel();
} catch (RemoteException e) {

View File

@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -33,6 +34,7 @@ import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.PerformanceTracker;
import com.android.server.biometrics.sensors.SensorOverlays;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
@@ -48,7 +50,7 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
private static final String TAG = "FingerprintDetectClient";
private final boolean mIsStrongBiometric;
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@NonNull private final SensorOverlays mSensorOverlays;
private boolean mIsPointerDown;
public FingerprintDetectClient(@NonNull Context context,
@@ -61,13 +63,14 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FINGERPRINT,
BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
setRequestId(requestId);
mUdfpsOverlayController = udfpsOverlayController;
mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController */);
mIsStrongBiometric = isStrongBiometric;
}
@Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
try {
getFreshDaemon().cancel();
} catch (RemoteException e) {
@@ -86,16 +89,15 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(),
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD,
mUdfpsOverlayController, this);
mSensorOverlays.show(getSensorId(), BiometricOverlayConstants.REASON_AUTH_KEYGUARD, this);
try {
getFreshDaemon().authenticate(0 /* operationId */, getTargetUserId());
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting auth", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
mSensorOverlays.hide(getSensorId());
mCallback.onClientFinished(this, false /* success */);
}
}

View File

@@ -35,7 +35,7 @@ import com.android.server.biometrics.sensors.BiometricNotificationUtils;
import com.android.server.biometrics.sensors.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient;
import com.android.server.biometrics.sensors.fingerprint.SidefpsHelper;
import com.android.server.biometrics.sensors.SensorOverlays;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
@@ -49,8 +49,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
private static final String TAG = "FingerprintEnrollClient";
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private final ISidefpsController mSidefpsController;
@NonNull private final SensorOverlays mSensorOverlays;
private final @FingerprintManager.EnrollReason int mEnrollReason;
private boolean mIsPointerDown;
@@ -65,8 +64,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
timeoutSec, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
true /* shouldVibrate */);
mUdfpsOverlayController = udfpsOverlayController;
mSidefpsController = sidefpsController;
mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
mEnrollReason = enrollReason;
if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
@@ -95,10 +93,8 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(),
UdfpsHelper.getReasonFromEnrollReason(mEnrollReason),
mUdfpsOverlayController, this);
SidefpsHelper.showOverlay(mSidefpsController);
mSensorOverlays.show(getSensorId(), getOverlayReasonFromEnrollReason(mEnrollReason), this);
BiometricNotificationUtils.cancelBadCalibrationNotification(getContext());
try {
// GroupId was never used. In fact, groupId is always the same as userId.
@@ -107,16 +103,15 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
Slog.e(TAG, "Remote exception when requesting enroll", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mSensorOverlays.hide(getSensorId());
mCallback.onClientFinished(this, false /* success */);
}
}
@Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mSensorOverlays.hide(getSensorId());
try {
getFreshDaemon().cancel();
} catch (RemoteException e) {
@@ -131,11 +126,11 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
super.onEnrollResult(identifier, remaining);
UdfpsHelper.onEnrollmentProgress(getSensorId(), remaining, mUdfpsOverlayController);
mSensorOverlays.ifUdfps(
controller -> controller.onEnrollmentProgress(getSensorId(), remaining));
if (remaining == 0) {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mSensorOverlays.hide(getSensorId());
}
}
@@ -143,17 +138,18 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
public void onAcquired(int acquiredInfo, int vendorCode) {
super.onAcquired(acquiredInfo, vendorCode);
if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) {
UdfpsHelper.onEnrollmentHelp(getSensorId(), mUdfpsOverlayController);
}
mSensorOverlays.ifUdfps(controller -> {
if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) {
controller.onEnrollmentHelp(getSensorId());
}
});
}
@Override
public void onError(int errorCode, int vendorCode) {
super.onError(errorCode, vendorCode);
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
SidefpsHelper.hideOverlay(mSidefpsController);
mSensorOverlays.hide(getSensorId());
}
@Override

View File

@@ -0,0 +1,129 @@
/*
* 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 com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@Presubmit
@SmallTest
public class SensorOverlaysTest {
private static final int SENSOR_ID = 11;
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
@Mock private IUdfpsOverlayController mUdfpsOverlayController;
@Mock private ISidefpsController mSidefpsController;
@Mock private AcquisitionClient<?> mAcquisitionClient;
@Test
public void noopWhenBothNull() {
final SensorOverlays useless = new SensorOverlays(null, null);
useless.show(SENSOR_ID, 2, null);
useless.hide(SENSOR_ID);
}
@Test
public void testProvidesUdfps() {
final List<IUdfpsOverlayController> udfps = new ArrayList<>();
SensorOverlays sensorOverlays = new SensorOverlays(null, mSidefpsController);
sensorOverlays.ifUdfps(udfps::add);
assertThat(udfps).isEmpty();
sensorOverlays = new SensorOverlays(mUdfpsOverlayController, mSidefpsController);
sensorOverlays.ifUdfps(udfps::add);
assertThat(udfps).containsExactly(mUdfpsOverlayController);
}
@Test
public void testShow() throws Exception {
testShow(mUdfpsOverlayController, mSidefpsController);
}
@Test
public void testShowUdfps() throws Exception {
testShow(mUdfpsOverlayController, null);
}
@Test
public void testShowSidefps() throws Exception {
testShow(null, mSidefpsController);
}
private void testShow(IUdfpsOverlayController udfps, ISidefpsController sidefps)
throws Exception {
final SensorOverlays sensorOverlays = new SensorOverlays(udfps, sidefps);
final int reason = BiometricOverlayConstants.REASON_UNKNOWN;
sensorOverlays.show(SENSOR_ID, reason, mAcquisitionClient);
if (udfps != null) {
verify(mUdfpsOverlayController).showUdfpsOverlay(eq(SENSOR_ID), eq(reason), any());
}
if (sidefps != null) {
verify(mSidefpsController).show();
}
}
@Test
public void testHide() throws Exception {
testHide(mUdfpsOverlayController, mSidefpsController);
}
@Test
public void testHideUdfps() throws Exception {
testHide(mUdfpsOverlayController, null);
}
@Test
public void testHideSidefps() throws Exception {
testHide(null, mSidefpsController);
}
private void testHide(IUdfpsOverlayController udfps, ISidefpsController sidefps)
throws Exception {
final SensorOverlays sensorOverlays = new SensorOverlays(udfps, sidefps);
sensorOverlays.hide(SENSOR_ID);
if (udfps != null) {
verify(mUdfpsOverlayController).hideUdfpsOverlay(eq(SENSOR_ID));
}
if (sidefps != null) {
verify(mSidefpsController).hide();
}
}
}