Merge "5/n: Add support for initial coex cases" into sc-dev
This commit is contained in:
@@ -73,6 +73,7 @@ import com.android.internal.os.SomeArgs;
|
|||||||
import com.android.internal.statusbar.IStatusBarService;
|
import com.android.internal.statusbar.IStatusBarService;
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
|
import com.android.server.biometrics.sensors.CoexCoordinator;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -1100,6 +1101,12 @@ public class BiometricService extends SystemService {
|
|||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAdvancedCoexLogicEnabled(Context context) {
|
||||||
|
return (Build.IS_USERDEBUG || Build.IS_ENG)
|
||||||
|
&& Settings.Secure.getInt(context.getContentResolver(),
|
||||||
|
CoexCoordinator.SETTING_ENABLE_NAME, 0) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1126,6 +1133,12 @@ public class BiometricService extends SystemService {
|
|||||||
mSettingObserver = mInjector.getSettingObserver(context, mHandler,
|
mSettingObserver = mInjector.getSettingObserver(context, mHandler,
|
||||||
mEnabledOnKeyguardCallbacks);
|
mEnabledOnKeyguardCallbacks);
|
||||||
|
|
||||||
|
// TODO(b/193089985) This logic lives here (outside of CoexCoordinator) so that it doesn't
|
||||||
|
// need to depend on context. We can remove this code once the advanced logic is enabled
|
||||||
|
// by default.
|
||||||
|
CoexCoordinator coexCoordinator = CoexCoordinator.getInstance();
|
||||||
|
coexCoordinator.setAdvancedLogicEnabled(injector.isAdvancedCoexLogicEnabled(context));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
injector.getActivityManagerService().registerUserSwitchObserver(
|
injector.getActivityManagerService().registerUserSwitchObserver(
|
||||||
new UserSwitchObserver() {
|
new UserSwitchObserver() {
|
||||||
@@ -1437,5 +1450,7 @@ public class BiometricService extends SystemService {
|
|||||||
pw.println();
|
pw.println();
|
||||||
pw.println("CurrentSession: " + mCurrentAuthSession);
|
pw.println("CurrentSession: " + mCurrentAuthSession);
|
||||||
pw.println();
|
pw.println();
|
||||||
|
pw.println("CoexCoordinator: " + CoexCoordinator.getInstance().toString());
|
||||||
|
pw.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -359,7 +359,8 @@ public class BiometricScheduler {
|
|||||||
* @param gestureAvailabilityDispatcher may be null if the sensor does not support gestures
|
* @param gestureAvailabilityDispatcher may be null if the sensor does not support gestures
|
||||||
* (such as fingerprint swipe).
|
* (such as fingerprint swipe).
|
||||||
*/
|
*/
|
||||||
public BiometricScheduler(@NonNull String tag, @SensorType int sensorType,
|
public BiometricScheduler(@NonNull String tag,
|
||||||
|
@SensorType int sensorType,
|
||||||
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
||||||
this(tag, sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface(
|
this(tag, sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS,
|
ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS,
|
||||||
|
|||||||
@@ -16,11 +16,17 @@
|
|||||||
|
|
||||||
package com.android.server.biometrics.sensors;
|
package com.android.server.biometrics.sensors;
|
||||||
|
|
||||||
|
import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE;
|
||||||
|
import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS;
|
||||||
import static com.android.server.biometrics.sensors.BiometricScheduler.sensorTypeToString;
|
import static com.android.server.biometrics.sensors.BiometricScheduler.sensorTypeToString;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.server.biometrics.sensors.fingerprint.Udfps;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -33,6 +39,8 @@ import java.util.Map;
|
|||||||
public class CoexCoordinator {
|
public class CoexCoordinator {
|
||||||
|
|
||||||
private static final String TAG = "BiometricCoexCoordinator";
|
private static final String TAG = "BiometricCoexCoordinator";
|
||||||
|
public static final String SETTING_ENABLE_NAME =
|
||||||
|
"com.android.server.biometrics.sensors.CoexCoordinator.enable";
|
||||||
private static final boolean DEBUG = true;
|
private static final boolean DEBUG = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,16 +62,30 @@ public class CoexCoordinator {
|
|||||||
|
|
||||||
private static CoexCoordinator sInstance;
|
private static CoexCoordinator sInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a singleton instance.
|
||||||
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
static CoexCoordinator getInstance() {
|
public static CoexCoordinator getInstance() {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
sInstance = new CoexCoordinator();
|
sInstance = new CoexCoordinator();
|
||||||
}
|
}
|
||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void setAdvancedLogicEnabled(boolean enabled) {
|
||||||
|
mAdvancedLogicEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void reset() {
|
||||||
|
mClientMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// SensorType to AuthenticationClient map
|
// SensorType to AuthenticationClient map
|
||||||
private final Map<Integer, AuthenticationClient<?>> mClientMap;
|
private final Map<Integer, AuthenticationClient<?>> mClientMap;
|
||||||
|
private boolean mAdvancedLogicEnabled;
|
||||||
|
|
||||||
private CoexCoordinator() {
|
private CoexCoordinator() {
|
||||||
// Singleton
|
// Singleton
|
||||||
@@ -105,8 +127,33 @@ public class CoexCoordinator {
|
|||||||
callback.sendHapticFeedback();
|
callback.sendHapticFeedback();
|
||||||
// For BP, BiometricService will add the authToken to Keystore.
|
// For BP, BiometricService will add the authToken to Keystore.
|
||||||
callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
|
callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
|
||||||
|
} else if (isUnknownClient(client)) {
|
||||||
|
// Client doesn't exist in our map for some reason. Give the user feedback so the
|
||||||
|
// device doesn't feel like it's stuck. All other cases below can assume that the
|
||||||
|
// client exists in our map.
|
||||||
|
callback.sendHapticFeedback();
|
||||||
|
callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
|
||||||
|
} else if (mAdvancedLogicEnabled && client.isKeyguard()) {
|
||||||
|
if (isSingleAuthOnly(client)) {
|
||||||
|
// Single sensor authentication
|
||||||
|
callback.sendHapticFeedback();
|
||||||
|
callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
|
||||||
|
} else {
|
||||||
|
// Multi sensor authentication
|
||||||
|
AuthenticationClient<?> udfps = mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
|
||||||
|
if (isCurrentFaceAuth(client)) {
|
||||||
|
if (isPointerDown(udfps)) {
|
||||||
|
// Face auth success while UDFPS pointer down. No callback, no haptic.
|
||||||
|
// Feedback will be provided after UDFPS result.
|
||||||
|
} else {
|
||||||
|
callback.sendHapticFeedback();
|
||||||
|
callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Keyguard, FingerprintManager, FaceManager, etc
|
// Non-keyguard authentication. For example, Fingerprint Settings use of
|
||||||
|
// FingerprintManager for highlighting fingers
|
||||||
callback.sendHapticFeedback();
|
callback.sendHapticFeedback();
|
||||||
callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
|
callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
|
||||||
}
|
}
|
||||||
@@ -123,4 +170,41 @@ public class CoexCoordinator {
|
|||||||
callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
|
callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isCurrentFaceAuth(@NonNull AuthenticationClient<?> client) {
|
||||||
|
return client == mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPointerDown(@Nullable AuthenticationClient<?> client) {
|
||||||
|
if (client instanceof Udfps) {
|
||||||
|
return ((Udfps) client).isPointerDown();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUnknownClient(@NonNull AuthenticationClient<?> client) {
|
||||||
|
for (AuthenticationClient<?> c : mClientMap.values()) {
|
||||||
|
if (c == client) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSingleAuthOnly(@NonNull AuthenticationClient<?> client) {
|
||||||
|
if (mClientMap.values().size() != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AuthenticationClient<?> c : mClientMap.values()) {
|
||||||
|
if (c != client) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "Enabled: " + mAdvancedLogicEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -494,8 +494,8 @@ public class Sensor {
|
|||||||
mToken = new Binder();
|
mToken = new Binder();
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
mSensorProperties = sensorProperties;
|
mSensorProperties = sensorProperties;
|
||||||
mScheduler = new UserAwareBiometricScheduler(tag, BiometricScheduler.SENSOR_TYPE_FACE,
|
mScheduler = new UserAwareBiometricScheduler(tag,
|
||||||
null /* gestureAvailabilityDispatcher */,
|
BiometricScheduler.SENSOR_TYPE_FACE, null /* gestureAvailabilityDispatcher */,
|
||||||
() -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL,
|
() -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL,
|
||||||
new UserAwareBiometricScheduler.UserSwitchCallback() {
|
new UserAwareBiometricScheduler.UserSwitchCallback() {
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|||||||
@@ -27,4 +27,5 @@ public interface Udfps {
|
|||||||
void onPointerDown(int x, int y, float minor, float major);
|
void onPointerDown(int x, int y, float minor, float major);
|
||||||
void onPointerUp();
|
void onPointerUp();
|
||||||
void onUiReady();
|
void onUiReady();
|
||||||
|
boolean isPointerDown();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
|||||||
@NonNull private final LockoutCache mLockoutCache;
|
@NonNull private final LockoutCache mLockoutCache;
|
||||||
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
||||||
@Nullable private ICancellationSignal mCancellationSignal;
|
@Nullable private ICancellationSignal mCancellationSignal;
|
||||||
|
private boolean mIsPointerDown;
|
||||||
|
|
||||||
FingerprintAuthenticationClient(@NonNull Context context,
|
FingerprintAuthenticationClient(@NonNull Context context,
|
||||||
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
|
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
|
||||||
@@ -143,6 +144,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
|||||||
@Override
|
@Override
|
||||||
public void onPointerDown(int x, int y, float minor, float major) {
|
public void onPointerDown(int x, int y, float minor, float major) {
|
||||||
try {
|
try {
|
||||||
|
mIsPointerDown = true;
|
||||||
getFreshDaemon().onPointerDown(0 /* pointerId */, x, y, minor, major);
|
getFreshDaemon().onPointerDown(0 /* pointerId */, x, y, minor, major);
|
||||||
if (getListener() != null) {
|
if (getListener() != null) {
|
||||||
getListener().onUdfpsPointerDown(getSensorId());
|
getListener().onUdfpsPointerDown(getSensorId());
|
||||||
@@ -155,6 +157,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
|||||||
@Override
|
@Override
|
||||||
public void onPointerUp() {
|
public void onPointerUp() {
|
||||||
try {
|
try {
|
||||||
|
mIsPointerDown = false;
|
||||||
getFreshDaemon().onPointerUp(0 /* pointerId */);
|
getFreshDaemon().onPointerUp(0 /* pointerId */);
|
||||||
if (getListener() != null) {
|
if (getListener() != null) {
|
||||||
getListener().onUdfpsPointerUp(getSensorId());
|
getListener().onUdfpsPointerUp(getSensorId());
|
||||||
@@ -164,6 +167,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPointerDown() {
|
||||||
|
return mIsPointerDown;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUiReady() {
|
public void onUiReady() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
|||||||
private final @FingerprintManager.EnrollReason int mEnrollReason;
|
private final @FingerprintManager.EnrollReason int mEnrollReason;
|
||||||
@Nullable private ICancellationSignal mCancellationSignal;
|
@Nullable private ICancellationSignal mCancellationSignal;
|
||||||
private final int mMaxTemplatesPerUser;
|
private final int mMaxTemplatesPerUser;
|
||||||
|
private boolean mIsPointerDown;
|
||||||
|
|
||||||
FingerprintEnrollClient(@NonNull Context context,
|
FingerprintEnrollClient(@NonNull Context context,
|
||||||
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
|
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
|
||||||
@@ -167,6 +168,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
|||||||
@Override
|
@Override
|
||||||
public void onPointerDown(int x, int y, float minor, float major) {
|
public void onPointerDown(int x, int y, float minor, float major) {
|
||||||
try {
|
try {
|
||||||
|
mIsPointerDown = true;
|
||||||
getFreshDaemon().onPointerDown(0 /* pointerId */, x, y, minor, major);
|
getFreshDaemon().onPointerDown(0 /* pointerId */, x, y, minor, major);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.e(TAG, "Unable to send pointer down", e);
|
Slog.e(TAG, "Unable to send pointer down", e);
|
||||||
@@ -176,12 +178,18 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
|
|||||||
@Override
|
@Override
|
||||||
public void onPointerUp() {
|
public void onPointerUp() {
|
||||||
try {
|
try {
|
||||||
|
mIsPointerDown = false;
|
||||||
getFreshDaemon().onPointerUp(0 /* pointerId */);
|
getFreshDaemon().onPointerUp(0 /* pointerId */);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.e(TAG, "Unable to send pointer up", e);
|
Slog.e(TAG, "Unable to send pointer up", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPointerDown() {
|
||||||
|
return mIsPointerDown;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUiReady() {
|
public void onUiReady() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -138,7 +138,8 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
|
|||||||
|
|
||||||
TestableBiometricScheduler(@NonNull String tag,
|
TestableBiometricScheduler(@NonNull String tag,
|
||||||
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
||||||
super(tag, BiometricScheduler.SENSOR_TYPE_FP_OTHER, gestureAvailabilityDispatcher);
|
super(tag, BiometricScheduler.SENSOR_TYPE_FP_OTHER,
|
||||||
|
gestureAvailabilityDispatcher);
|
||||||
mInternalCallback = new TestableInternalCallback();
|
mInternalCallback = new TestableInternalCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
|||||||
|
|
||||||
private final LockoutFrameworkImpl mLockoutFrameworkImpl;
|
private final LockoutFrameworkImpl mLockoutFrameworkImpl;
|
||||||
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
||||||
|
private boolean mIsPointerDown;
|
||||||
|
|
||||||
FingerprintAuthenticationClient(@NonNull Context context,
|
FingerprintAuthenticationClient(@NonNull Context context,
|
||||||
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
||||||
@@ -160,6 +161,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointerDown(int x, int y, float minor, float major) {
|
public void onPointerDown(int x, int y, float minor, float major) {
|
||||||
|
mIsPointerDown = true;
|
||||||
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
|
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
|
||||||
if (getListener() != null) {
|
if (getListener() != null) {
|
||||||
try {
|
try {
|
||||||
@@ -172,6 +174,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointerUp() {
|
public void onPointerUp() {
|
||||||
|
mIsPointerDown = false;
|
||||||
UdfpsHelper.onFingerUp(getFreshDaemon());
|
UdfpsHelper.onFingerUp(getFreshDaemon());
|
||||||
if (getListener() != null) {
|
if (getListener() != null) {
|
||||||
try {
|
try {
|
||||||
@@ -182,6 +185,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPointerDown() {
|
||||||
|
return mIsPointerDown;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUiReady() {
|
public void onUiReady() {
|
||||||
// Unsupported in HIDL.
|
// Unsupported in HIDL.
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
|
|||||||
|
|
||||||
private final boolean mIsStrongBiometric;
|
private final boolean mIsStrongBiometric;
|
||||||
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
||||||
|
private boolean mIsPointerDown;
|
||||||
|
|
||||||
public FingerprintDetectClient(@NonNull Context context,
|
public FingerprintDetectClient(@NonNull Context context,
|
||||||
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
||||||
@@ -99,14 +100,21 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointerDown(int x, int y, float minor, float major) {
|
public void onPointerDown(int x, int y, float minor, float major) {
|
||||||
|
mIsPointerDown = true;
|
||||||
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
|
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointerUp() {
|
public void onPointerUp() {
|
||||||
|
mIsPointerDown = false;
|
||||||
UdfpsHelper.onFingerUp(getFreshDaemon());
|
UdfpsHelper.onFingerUp(getFreshDaemon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPointerDown() {
|
||||||
|
return mIsPointerDown;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUiReady() {
|
public void onUiReady() {
|
||||||
// Unsupported in HIDL.
|
// Unsupported in HIDL.
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
|||||||
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
|
||||||
@Nullable private final ISidefpsController mSidefpsController;
|
@Nullable private final ISidefpsController mSidefpsController;
|
||||||
private final @FingerprintManager.EnrollReason int mEnrollReason;
|
private final @FingerprintManager.EnrollReason int mEnrollReason;
|
||||||
|
private boolean mIsPointerDown;
|
||||||
|
|
||||||
FingerprintEnrollClient(@NonNull Context context,
|
FingerprintEnrollClient(@NonNull Context context,
|
||||||
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
||||||
@@ -157,14 +158,21 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointerDown(int x, int y, float minor, float major) {
|
public void onPointerDown(int x, int y, float minor, float major) {
|
||||||
|
mIsPointerDown = true;
|
||||||
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
|
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPointerUp() {
|
public void onPointerUp() {
|
||||||
|
mIsPointerDown = false;
|
||||||
UdfpsHelper.onFingerUp(getFreshDaemon());
|
UdfpsHelper.onFingerUp(getFreshDaemon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPointerDown() {
|
||||||
|
return mIsPointerDown;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUiReady() {
|
public void onUiReady() {
|
||||||
// Unsupported in HIDL.
|
// Unsupported in HIDL.
|
||||||
|
|||||||
@@ -16,17 +16,24 @@
|
|||||||
|
|
||||||
package com.android.server.biometrics.sensors;
|
package com.android.server.biometrics.sensors;
|
||||||
|
|
||||||
|
import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE;
|
||||||
|
import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.mockito.Mockito.withSettings;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.server.biometrics.sensors.fingerprint.Udfps;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@@ -36,8 +43,12 @@ import org.mockito.MockitoAnnotations;
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
public class CoexCoordinatorTest {
|
public class CoexCoordinatorTest {
|
||||||
|
|
||||||
|
private static final String TAG = "CoexCoordinatorTest";
|
||||||
|
|
||||||
private CoexCoordinator mCoexCoordinator;
|
private CoexCoordinator mCoexCoordinator;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Context mContext;
|
||||||
@Mock
|
@Mock
|
||||||
private CoexCoordinator.Callback mCallback;
|
private CoexCoordinator.Callback mCallback;
|
||||||
|
|
||||||
@@ -45,13 +56,18 @@ public class CoexCoordinatorTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mCoexCoordinator = CoexCoordinator.getInstance();
|
mCoexCoordinator = CoexCoordinator.getInstance();
|
||||||
|
mCoexCoordinator.setAdvancedLogicEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBiometricPrompt_authSuccess() {
|
public void testBiometricPrompt_authSuccess() {
|
||||||
|
mCoexCoordinator.reset();
|
||||||
|
|
||||||
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
||||||
when(client.isBiometricPrompt()).thenReturn(true);
|
when(client.isBiometricPrompt()).thenReturn(true);
|
||||||
|
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
|
||||||
|
|
||||||
mCoexCoordinator.onAuthenticationSucceeded(client, mCallback);
|
mCoexCoordinator.onAuthenticationSucceeded(client, mCallback);
|
||||||
verify(mCallback).sendHapticFeedback();
|
verify(mCallback).sendHapticFeedback();
|
||||||
verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
|
verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
|
||||||
@@ -59,9 +75,13 @@ public class CoexCoordinatorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBiometricPrompt_authReject_whenNotLockedOut() {
|
public void testBiometricPrompt_authReject_whenNotLockedOut() {
|
||||||
|
mCoexCoordinator.reset();
|
||||||
|
|
||||||
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
||||||
when(client.isBiometricPrompt()).thenReturn(true);
|
when(client.isBiometricPrompt()).thenReturn(true);
|
||||||
|
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
|
||||||
|
|
||||||
mCoexCoordinator.onAuthenticationRejected(client, LockoutTracker.LOCKOUT_NONE, mCallback);
|
mCoexCoordinator.onAuthenticationRejected(client, LockoutTracker.LOCKOUT_NONE, mCallback);
|
||||||
verify(mCallback).sendHapticFeedback();
|
verify(mCallback).sendHapticFeedback();
|
||||||
verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
|
verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
|
||||||
@@ -69,11 +89,69 @@ public class CoexCoordinatorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBiometricPrompt_authReject_whenLockedOut() {
|
public void testBiometricPrompt_authReject_whenLockedOut() {
|
||||||
|
mCoexCoordinator.reset();
|
||||||
|
|
||||||
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
||||||
when(client.isBiometricPrompt()).thenReturn(true);
|
when(client.isBiometricPrompt()).thenReturn(true);
|
||||||
|
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
|
||||||
|
|
||||||
mCoexCoordinator.onAuthenticationRejected(client, LockoutTracker.LOCKOUT_TIMED, mCallback);
|
mCoexCoordinator.onAuthenticationRejected(client, LockoutTracker.LOCKOUT_TIMED, mCallback);
|
||||||
verify(mCallback).sendHapticFeedback();
|
verify(mCallback).sendHapticFeedback();
|
||||||
verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
|
verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeyguard_faceAuthOnly_success() {
|
||||||
|
mCoexCoordinator.reset();
|
||||||
|
|
||||||
|
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
||||||
|
when(client.isKeyguard()).thenReturn(true);
|
||||||
|
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
|
||||||
|
|
||||||
|
mCoexCoordinator.onAuthenticationSucceeded(client, mCallback);
|
||||||
|
verify(mCallback).sendHapticFeedback();
|
||||||
|
verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeyguard_faceAuth_udfpsNotTouching_faceSuccess() {
|
||||||
|
mCoexCoordinator.reset();
|
||||||
|
|
||||||
|
AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
|
||||||
|
when(faceClient.isKeyguard()).thenReturn(true);
|
||||||
|
|
||||||
|
AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
|
||||||
|
withSettings().extraInterfaces(Udfps.class));
|
||||||
|
when(udfpsClient.isKeyguard()).thenReturn(true);
|
||||||
|
when(((Udfps) udfpsClient).isPointerDown()).thenReturn(false);
|
||||||
|
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
|
||||||
|
|
||||||
|
mCoexCoordinator.onAuthenticationSucceeded(faceClient, mCallback);
|
||||||
|
verify(mCallback).sendHapticFeedback();
|
||||||
|
verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKeyguard_faceAuth_udfpsTouching_faceSuccess() {
|
||||||
|
mCoexCoordinator.reset();
|
||||||
|
|
||||||
|
AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
|
||||||
|
when(faceClient.isKeyguard()).thenReturn(true);
|
||||||
|
|
||||||
|
AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
|
||||||
|
withSettings().extraInterfaces(Udfps.class));
|
||||||
|
when(udfpsClient.isKeyguard()).thenReturn(true);
|
||||||
|
when(((Udfps) udfpsClient).isPointerDown()).thenReturn(true);
|
||||||
|
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
|
||||||
|
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
|
||||||
|
|
||||||
|
mCoexCoordinator.onAuthenticationSucceeded(faceClient, mCallback);
|
||||||
|
verify(mCallback, never()).sendHapticFeedback();
|
||||||
|
verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user