Loading services/core/java/com/android/server/biometrics/BiometricService.java +0 −21 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.DumpUtils; import com.android.server.SystemService; import com.android.server.biometrics.sensors.CoexCoordinator; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -951,16 +950,6 @@ public class BiometricService extends SystemService { return new ArrayList<>(); } public boolean isAdvancedCoexLogicEnabled(Context context) { return Settings.Secure.getInt(context.getContentResolver(), CoexCoordinator.SETTING_ENABLE_NAME, 1) != 0; } public boolean isCoexFaceNonBypassHapticsDisabled(Context context) { return Settings.Secure.getInt(context.getContentResolver(), CoexCoordinator.FACE_HAPTIC_DISABLE, 0) != 0; } public Supplier<Long> getRequestGenerator() { final AtomicLong generator = new AtomicLong(0); return () -> generator.incrementAndGet(); Loading Loading @@ -992,14 +981,6 @@ public class BiometricService extends SystemService { mEnabledOnKeyguardCallbacks); mRequestCounter = mInjector.getRequestGenerator(); // 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)); coexCoordinator.setFaceHapticDisabledWhenNonBypass( injector.isCoexFaceNonBypassHapticsDisabled(context)); try { injector.getActivityManagerService().registerUserSwitchObserver( new UserSwitchObserver() { Loading Loading @@ -1333,7 +1314,5 @@ public class BiometricService extends SystemService { pw.println(); pw.println("CurrentSession: " + mAuthSession); pw.println(); pw.println("CoexCoordinator: " + CoexCoordinator.getInstance().toString()); pw.println(); } } services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +66 −156 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricOverlayConstants; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; import android.security.KeyStore; import android.util.EventLog; import android.util.Slog; Loading @@ -48,8 +47,6 @@ import java.util.function.Supplier; public abstract class AuthenticationClient<T> extends AcquisitionClient<T> implements AuthenticationConsumer { private static final String TAG = "Biometrics/AuthenticationClient"; // New, has not started yet public static final int STATE_NEW = 0; // Framework/HAL have started this operation Loading @@ -67,28 +64,27 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> STATE_STARTED_PAUSED_ATTEMPTED, STATE_STOPPED}) @interface State {} private static final String TAG = "Biometrics/AuthenticationClient"; protected final long mOperationId; private final boolean mIsStrongBiometric; private final boolean mRequireConfirmation; private final ActivityTaskManager mActivityTaskManager; private final BiometricManager mBiometricManager; @Nullable private final TaskStackListener mTaskStackListener; @Nullable private final TaskStackListener mTaskStackListener; private final LockoutTracker mLockoutTracker; private final boolean mIsRestricted; private final boolean mAllowBackgroundAuthentication; private final boolean mIsKeyguardBypassEnabled; protected final long mOperationId; // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update // the state. We should think of a way to improve this in the future. @State protected int mState = STATE_NEW; private long mStartTimeMs; private boolean mAuthAttempted; private boolean mAuthSuccess = false; // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update // the state. We should think of a way to improve this in the future. protected @State int mState = STATE_NEW; public AuthenticationClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, boolean restricted, @NonNull String owner, Loading @@ -111,8 +107,9 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> mIsKeyguardBypassEnabled = isKeyguardBypassEnabled; } public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) { final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode public int handleFailedAttempt(int userId) { @LockoutTracker.LockoutMode final int lockoutMode = mLockoutTracker.getLockoutModeForUser(userId); final PerformanceTracker performanceTracker = PerformanceTracker.getInstanceForSensorId(getSensorId()); Loading Loading @@ -173,14 +170,16 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> final ClientMonitorCallbackConverter listener = getListener(); if (DEBUG) Slog.v(TAG, "onAuthenticated(" + authenticated + ")" if (DEBUG) { Slog.v(TAG, "onAuthenticated(" + authenticated + ")" + ", ID:" + identifier.getBiometricId() + ", Owner: " + getOwnerString() + ", isBP: " + isBiometricPrompt() + ", listener: " + listener + ", requireConfirmation: " + mRequireConfirmation + ", user: " + getTargetUserId() + ", clientMonitor: " + toString()); + ", clientMonitor: " + this); } final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId()); if (isCryptoOperation()) { Loading Loading @@ -239,142 +238,57 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> getSensorId(), getTargetUserId(), byteToken); } final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationSucceeded(SystemClock.uptimeMillis(), this, new CoexCoordinator.Callback() { @Override public void sendAuthenticationResult(boolean addAuthTokenIfStrong) { if (addAuthTokenIfStrong && mIsStrongBiometric) { // For BP, BiometricService will add the authToken to Keystore. if (!isBiometricPrompt() && mIsStrongBiometric) { final int result = KeyStore.getInstance().addAuthToken(byteToken); if (result != KeyStore.NO_ERROR) { Slog.d(TAG, "Error adding auth token : " + result); } else { Slog.d(TAG, "addAuthToken: " + result); } } else { Slog.d(TAG, "Skipping addAuthToken"); } if (listener != null) { try { // Explicitly have if/else here to make it super obvious in case the // code is touched in the future. if (listener != null) { if (!mIsRestricted) { listener.onAuthenticationSucceeded(getSensorId(), identifier, byteToken, getTargetUserId(), mIsStrongBiometric); listener.onAuthenticationSucceeded(getSensorId(), identifier, byteToken, getTargetUserId(), mIsStrongBiometric); } else { listener.onAuthenticationSucceeded(getSensorId(), null /* identifier */, listener.onAuthenticationSucceeded(getSensorId(), null /* identifier */, byteToken, getTargetUserId(), mIsStrongBiometric); getTargetUserId(), mIsStrongBiometric); } } else { Slog.e(TAG, "Received successful auth, but client was not listening"); } } catch (RemoteException e) { Slog.e(TAG, "Unable to notify listener", e); mCallback.onClientFinished(this, false); return; } } else { Slog.w(TAG, "Client not listening"); } } @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateSuccess(); } } @Override public void handleLifecycleAfterAuth() { AuthenticationClient.this.handleLifecycleAfterAuth(true /* authenticated */); } @Override public void sendAuthenticationCanceled() { sendCancelOnly(listener); } }); } else { // not authenticated if (isBackgroundAuth) { Slog.e(TAG, "cancelling due to background auth"); cancel(); } else { // Allow system-defined limit of number of attempts before giving up final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode final int lockoutMode = handleFailedAttempt(getTargetUserId()); if (lockoutMode != LockoutTracker.LOCKOUT_NONE) { markAlreadyDone(); } final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode, new CoexCoordinator.Callback() { @Override public void sendAuthenticationResult(boolean addAuthTokenIfStrong) { if (listener != null) { try { listener.onAuthenticationFailed(getSensorId()); } catch (RemoteException e) { Slog.e(TAG, "Unable to notify listener", e); mCallback.onClientFinished(this, false); return; } } } @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateError(); } } @Override public void handleLifecycleAfterAuth() { AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */); } @Override public void sendAuthenticationCanceled() { sendCancelOnly(listener); } }); } } } /** * Only call this method on interfaces where lockout does not come from onError, I.E. the * old HIDL implementation. */ protected void onLockoutTimed(long durationMillis) { final ClientMonitorCallbackConverter listener = getListener(); final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationError(this, BiometricConstants.BIOMETRIC_ERROR_LOCKOUT, new CoexCoordinator.ErrorCallback() { @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateError(); } } }); } /** * Only call this method on interfaces where lockout does not come from onError, I.E. the * old HIDL implementation. */ protected void onLockoutPermanent() { final ClientMonitorCallbackConverter listener = getListener(); final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationError(this, BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT, new CoexCoordinator.ErrorCallback() { @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateError(); } } }); AuthenticationClient.this.handleLifecycleAfterAuth(authenticated); } private void sendCancelOnly(@Nullable ClientMonitorCallbackConverter listener) { Loading @@ -396,7 +310,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public void onAcquired(int acquiredInfo, int vendorCode) { super.onAcquired(acquiredInfo, vendorCode); final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode final int lockoutMode = mLockoutTracker.getLockoutModeForUser(getTargetUserId()); if (lockoutMode == LockoutTracker.LOCKOUT_NONE) { PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId()); Loading @@ -408,8 +322,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public void onError(@BiometricConstants.Errors int errorCode, int vendorCode) { super.onError(errorCode, vendorCode); mState = STATE_STOPPED; CoexCoordinator.getInstance().onAuthenticationError(this, errorCode, this::vibrateError); } /** Loading @@ -419,7 +331,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public void start(@NonNull ClientMonitorCallback callback) { super.start(callback); final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode final int lockoutMode = mLockoutTracker.getLockoutModeForUser(getTargetUserId()); if (lockoutMode != LockoutTracker.LOCKOUT_NONE) { Slog.v(TAG, "In lockout mode(" + lockoutMode + ") ; disallowing authentication"); Loading Loading @@ -450,12 +362,9 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> } /** * Handles lifecycle, e.g. {@link BiometricScheduler}, * {@link com.android.server.biometrics.sensors.BaseClientMonitor.Callback} after authentication * results are known. Note that this happens asynchronously from (but shortly after) * {@link #onAuthenticated(BiometricAuthenticator.Identifier, boolean, ArrayList)} and allows * {@link CoexCoordinator} a chance to invoke/delay this event. * @param authenticated * Handles lifecycle, e.g. {@link BiometricScheduler} after authentication. This is necessary * as different clients handle the lifecycle of authentication success/reject differently. I.E. * Fingerprint does not finish authentication when it is rejected. */ protected abstract void handleLifecycleAfterAuth(boolean authenticated); Loading @@ -465,7 +374,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> */ public abstract boolean wasUserDetected(); public @State int getState() { @State public int getState() { return mState; } Loading services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +3 −15 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ import java.util.function.Consumer; * interactions with the HAL before finishing. * * We currently assume (and require) that each biometric sensor have its own instance of a * {@link BiometricScheduler}. See {@link CoexCoordinator}. * {@link BiometricScheduler}. */ @MainThread public class BiometricScheduler { Loading Loading @@ -156,7 +156,6 @@ public class BiometricScheduler { private int mTotalOperationsHandled; private final int mRecentOperationsLimit; @NonNull private final List<Integer> mRecentOperations; @NonNull private final CoexCoordinator mCoexCoordinator; // Internal callback, notified when an operation is complete. Notifies the requester // that the operation is complete, before performing internal scheduler work (such as Loading @@ -165,11 +164,6 @@ public class BiometricScheduler { @Override public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { Slog.d(getTag(), "[Started] " + clientMonitor); if (clientMonitor instanceof AuthenticationClient) { mCoexCoordinator.addAuthenticationClient(mSensorType, (AuthenticationClient<?>) clientMonitor); } } @Override Loading @@ -189,10 +183,6 @@ public class BiometricScheduler { } Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success); if (clientMonitor instanceof AuthenticationClient) { mCoexCoordinator.removeAuthenticationClient(mSensorType, (AuthenticationClient<?>) clientMonitor); } if (mGestureAvailabilityDispatcher != null) { mGestureAvailabilityDispatcher.markSensorActive( Loading @@ -216,8 +206,7 @@ public class BiometricScheduler { @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull IBiometricService biometricService, int recentOperationsLimit, @NonNull CoexCoordinator coexCoordinator) { int recentOperationsLimit) { mBiometricTag = tag; mHandler = handler; mSensorType = sensorType; Loading @@ -227,7 +216,6 @@ public class BiometricScheduler { mCrashStates = new ArrayDeque<>(); mRecentOperationsLimit = recentOperationsLimit; mRecentOperations = new ArrayList<>(); mCoexCoordinator = coexCoordinator; } /** Loading @@ -244,7 +232,7 @@ public class BiometricScheduler { this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS, CoexCoordinator.getInstance()); LOG_NUM_RECENT_OPERATIONS); } @VisibleForTesting Loading services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.javadeleted 100644 → 0 +0 −525 File deleted.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java +3 −4 Original line number Diff line number Diff line Loading @@ -95,10 +95,9 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull IBiometricService biometricService, @NonNull CurrentUserRetriever currentUserRetriever, @NonNull UserSwitchCallback userSwitchCallback, @NonNull CoexCoordinator coexCoordinator) { @NonNull UserSwitchCallback userSwitchCallback) { super(tag, handler, sensorType, gestureAvailabilityDispatcher, biometricService, LOG_NUM_RECENT_OPERATIONS, coexCoordinator); LOG_NUM_RECENT_OPERATIONS); mCurrentUserRetriever = currentUserRetriever; mUserSwitchCallback = userSwitchCallback; Loading @@ -112,7 +111,7 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( ServiceManager.getService(Context.BIOMETRIC_SERVICE)), currentUserRetriever, userSwitchCallback, CoexCoordinator.getInstance()); currentUserRetriever, userSwitchCallback); } @Override Loading Loading
services/core/java/com/android/server/biometrics/BiometricService.java +0 −21 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.DumpUtils; import com.android.server.SystemService; import com.android.server.biometrics.sensors.CoexCoordinator; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -951,16 +950,6 @@ public class BiometricService extends SystemService { return new ArrayList<>(); } public boolean isAdvancedCoexLogicEnabled(Context context) { return Settings.Secure.getInt(context.getContentResolver(), CoexCoordinator.SETTING_ENABLE_NAME, 1) != 0; } public boolean isCoexFaceNonBypassHapticsDisabled(Context context) { return Settings.Secure.getInt(context.getContentResolver(), CoexCoordinator.FACE_HAPTIC_DISABLE, 0) != 0; } public Supplier<Long> getRequestGenerator() { final AtomicLong generator = new AtomicLong(0); return () -> generator.incrementAndGet(); Loading Loading @@ -992,14 +981,6 @@ public class BiometricService extends SystemService { mEnabledOnKeyguardCallbacks); mRequestCounter = mInjector.getRequestGenerator(); // 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)); coexCoordinator.setFaceHapticDisabledWhenNonBypass( injector.isCoexFaceNonBypassHapticsDisabled(context)); try { injector.getActivityManagerService().registerUserSwitchObserver( new UserSwitchObserver() { Loading Loading @@ -1333,7 +1314,5 @@ public class BiometricService extends SystemService { pw.println(); pw.println("CurrentSession: " + mAuthSession); pw.println(); pw.println("CoexCoordinator: " + CoexCoordinator.getInstance().toString()); pw.println(); } }
services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +66 −156 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricOverlayConstants; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; import android.security.KeyStore; import android.util.EventLog; import android.util.Slog; Loading @@ -48,8 +47,6 @@ import java.util.function.Supplier; public abstract class AuthenticationClient<T> extends AcquisitionClient<T> implements AuthenticationConsumer { private static final String TAG = "Biometrics/AuthenticationClient"; // New, has not started yet public static final int STATE_NEW = 0; // Framework/HAL have started this operation Loading @@ -67,28 +64,27 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> STATE_STARTED_PAUSED_ATTEMPTED, STATE_STOPPED}) @interface State {} private static final String TAG = "Biometrics/AuthenticationClient"; protected final long mOperationId; private final boolean mIsStrongBiometric; private final boolean mRequireConfirmation; private final ActivityTaskManager mActivityTaskManager; private final BiometricManager mBiometricManager; @Nullable private final TaskStackListener mTaskStackListener; @Nullable private final TaskStackListener mTaskStackListener; private final LockoutTracker mLockoutTracker; private final boolean mIsRestricted; private final boolean mAllowBackgroundAuthentication; private final boolean mIsKeyguardBypassEnabled; protected final long mOperationId; // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update // the state. We should think of a way to improve this in the future. @State protected int mState = STATE_NEW; private long mStartTimeMs; private boolean mAuthAttempted; private boolean mAuthSuccess = false; // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update // the state. We should think of a way to improve this in the future. protected @State int mState = STATE_NEW; public AuthenticationClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, boolean restricted, @NonNull String owner, Loading @@ -111,8 +107,9 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> mIsKeyguardBypassEnabled = isKeyguardBypassEnabled; } public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) { final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode public int handleFailedAttempt(int userId) { @LockoutTracker.LockoutMode final int lockoutMode = mLockoutTracker.getLockoutModeForUser(userId); final PerformanceTracker performanceTracker = PerformanceTracker.getInstanceForSensorId(getSensorId()); Loading Loading @@ -173,14 +170,16 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> final ClientMonitorCallbackConverter listener = getListener(); if (DEBUG) Slog.v(TAG, "onAuthenticated(" + authenticated + ")" if (DEBUG) { Slog.v(TAG, "onAuthenticated(" + authenticated + ")" + ", ID:" + identifier.getBiometricId() + ", Owner: " + getOwnerString() + ", isBP: " + isBiometricPrompt() + ", listener: " + listener + ", requireConfirmation: " + mRequireConfirmation + ", user: " + getTargetUserId() + ", clientMonitor: " + toString()); + ", clientMonitor: " + this); } final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId()); if (isCryptoOperation()) { Loading Loading @@ -239,142 +238,57 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> getSensorId(), getTargetUserId(), byteToken); } final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationSucceeded(SystemClock.uptimeMillis(), this, new CoexCoordinator.Callback() { @Override public void sendAuthenticationResult(boolean addAuthTokenIfStrong) { if (addAuthTokenIfStrong && mIsStrongBiometric) { // For BP, BiometricService will add the authToken to Keystore. if (!isBiometricPrompt() && mIsStrongBiometric) { final int result = KeyStore.getInstance().addAuthToken(byteToken); if (result != KeyStore.NO_ERROR) { Slog.d(TAG, "Error adding auth token : " + result); } else { Slog.d(TAG, "addAuthToken: " + result); } } else { Slog.d(TAG, "Skipping addAuthToken"); } if (listener != null) { try { // Explicitly have if/else here to make it super obvious in case the // code is touched in the future. if (listener != null) { if (!mIsRestricted) { listener.onAuthenticationSucceeded(getSensorId(), identifier, byteToken, getTargetUserId(), mIsStrongBiometric); listener.onAuthenticationSucceeded(getSensorId(), identifier, byteToken, getTargetUserId(), mIsStrongBiometric); } else { listener.onAuthenticationSucceeded(getSensorId(), null /* identifier */, listener.onAuthenticationSucceeded(getSensorId(), null /* identifier */, byteToken, getTargetUserId(), mIsStrongBiometric); getTargetUserId(), mIsStrongBiometric); } } else { Slog.e(TAG, "Received successful auth, but client was not listening"); } } catch (RemoteException e) { Slog.e(TAG, "Unable to notify listener", e); mCallback.onClientFinished(this, false); return; } } else { Slog.w(TAG, "Client not listening"); } } @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateSuccess(); } } @Override public void handleLifecycleAfterAuth() { AuthenticationClient.this.handleLifecycleAfterAuth(true /* authenticated */); } @Override public void sendAuthenticationCanceled() { sendCancelOnly(listener); } }); } else { // not authenticated if (isBackgroundAuth) { Slog.e(TAG, "cancelling due to background auth"); cancel(); } else { // Allow system-defined limit of number of attempts before giving up final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode final int lockoutMode = handleFailedAttempt(getTargetUserId()); if (lockoutMode != LockoutTracker.LOCKOUT_NONE) { markAlreadyDone(); } final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode, new CoexCoordinator.Callback() { @Override public void sendAuthenticationResult(boolean addAuthTokenIfStrong) { if (listener != null) { try { listener.onAuthenticationFailed(getSensorId()); } catch (RemoteException e) { Slog.e(TAG, "Unable to notify listener", e); mCallback.onClientFinished(this, false); return; } } } @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateError(); } } @Override public void handleLifecycleAfterAuth() { AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */); } @Override public void sendAuthenticationCanceled() { sendCancelOnly(listener); } }); } } } /** * Only call this method on interfaces where lockout does not come from onError, I.E. the * old HIDL implementation. */ protected void onLockoutTimed(long durationMillis) { final ClientMonitorCallbackConverter listener = getListener(); final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationError(this, BiometricConstants.BIOMETRIC_ERROR_LOCKOUT, new CoexCoordinator.ErrorCallback() { @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateError(); } } }); } /** * Only call this method on interfaces where lockout does not come from onError, I.E. the * old HIDL implementation. */ protected void onLockoutPermanent() { final ClientMonitorCallbackConverter listener = getListener(); final CoexCoordinator coordinator = CoexCoordinator.getInstance(); coordinator.onAuthenticationError(this, BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT, new CoexCoordinator.ErrorCallback() { @Override public void sendHapticFeedback() { if (listener != null && mShouldVibrate) { vibrateError(); } } }); AuthenticationClient.this.handleLifecycleAfterAuth(authenticated); } private void sendCancelOnly(@Nullable ClientMonitorCallbackConverter listener) { Loading @@ -396,7 +310,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public void onAcquired(int acquiredInfo, int vendorCode) { super.onAcquired(acquiredInfo, vendorCode); final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode final int lockoutMode = mLockoutTracker.getLockoutModeForUser(getTargetUserId()); if (lockoutMode == LockoutTracker.LOCKOUT_NONE) { PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId()); Loading @@ -408,8 +322,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public void onError(@BiometricConstants.Errors int errorCode, int vendorCode) { super.onError(errorCode, vendorCode); mState = STATE_STOPPED; CoexCoordinator.getInstance().onAuthenticationError(this, errorCode, this::vibrateError); } /** Loading @@ -419,7 +331,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public void start(@NonNull ClientMonitorCallback callback) { super.start(callback); final @LockoutTracker.LockoutMode int lockoutMode = @LockoutTracker.LockoutMode final int lockoutMode = mLockoutTracker.getLockoutModeForUser(getTargetUserId()); if (lockoutMode != LockoutTracker.LOCKOUT_NONE) { Slog.v(TAG, "In lockout mode(" + lockoutMode + ") ; disallowing authentication"); Loading Loading @@ -450,12 +362,9 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> } /** * Handles lifecycle, e.g. {@link BiometricScheduler}, * {@link com.android.server.biometrics.sensors.BaseClientMonitor.Callback} after authentication * results are known. Note that this happens asynchronously from (but shortly after) * {@link #onAuthenticated(BiometricAuthenticator.Identifier, boolean, ArrayList)} and allows * {@link CoexCoordinator} a chance to invoke/delay this event. * @param authenticated * Handles lifecycle, e.g. {@link BiometricScheduler} after authentication. This is necessary * as different clients handle the lifecycle of authentication success/reject differently. I.E. * Fingerprint does not finish authentication when it is rejected. */ protected abstract void handleLifecycleAfterAuth(boolean authenticated); Loading @@ -465,7 +374,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> */ public abstract boolean wasUserDetected(); public @State int getState() { @State public int getState() { return mState; } Loading
services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +3 −15 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ import java.util.function.Consumer; * interactions with the HAL before finishing. * * We currently assume (and require) that each biometric sensor have its own instance of a * {@link BiometricScheduler}. See {@link CoexCoordinator}. * {@link BiometricScheduler}. */ @MainThread public class BiometricScheduler { Loading Loading @@ -156,7 +156,6 @@ public class BiometricScheduler { private int mTotalOperationsHandled; private final int mRecentOperationsLimit; @NonNull private final List<Integer> mRecentOperations; @NonNull private final CoexCoordinator mCoexCoordinator; // Internal callback, notified when an operation is complete. Notifies the requester // that the operation is complete, before performing internal scheduler work (such as Loading @@ -165,11 +164,6 @@ public class BiometricScheduler { @Override public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { Slog.d(getTag(), "[Started] " + clientMonitor); if (clientMonitor instanceof AuthenticationClient) { mCoexCoordinator.addAuthenticationClient(mSensorType, (AuthenticationClient<?>) clientMonitor); } } @Override Loading @@ -189,10 +183,6 @@ public class BiometricScheduler { } Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success); if (clientMonitor instanceof AuthenticationClient) { mCoexCoordinator.removeAuthenticationClient(mSensorType, (AuthenticationClient<?>) clientMonitor); } if (mGestureAvailabilityDispatcher != null) { mGestureAvailabilityDispatcher.markSensorActive( Loading @@ -216,8 +206,7 @@ public class BiometricScheduler { @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull IBiometricService biometricService, int recentOperationsLimit, @NonNull CoexCoordinator coexCoordinator) { int recentOperationsLimit) { mBiometricTag = tag; mHandler = handler; mSensorType = sensorType; Loading @@ -227,7 +216,6 @@ public class BiometricScheduler { mCrashStates = new ArrayDeque<>(); mRecentOperationsLimit = recentOperationsLimit; mRecentOperations = new ArrayList<>(); mCoexCoordinator = coexCoordinator; } /** Loading @@ -244,7 +232,7 @@ public class BiometricScheduler { this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS, CoexCoordinator.getInstance()); LOG_NUM_RECENT_OPERATIONS); } @VisibleForTesting Loading
services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.javadeleted 100644 → 0 +0 −525 File deleted.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java +3 −4 Original line number Diff line number Diff line Loading @@ -95,10 +95,9 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull IBiometricService biometricService, @NonNull CurrentUserRetriever currentUserRetriever, @NonNull UserSwitchCallback userSwitchCallback, @NonNull CoexCoordinator coexCoordinator) { @NonNull UserSwitchCallback userSwitchCallback) { super(tag, handler, sensorType, gestureAvailabilityDispatcher, biometricService, LOG_NUM_RECENT_OPERATIONS, coexCoordinator); LOG_NUM_RECENT_OPERATIONS); mCurrentUserRetriever = currentUserRetriever; mUserSwitchCallback = userSwitchCallback; Loading @@ -112,7 +111,7 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( ServiceManager.getService(Context.BIOMETRIC_SERVICE)), currentUserRetriever, userSwitchCallback, CoexCoordinator.getInstance()); currentUserRetriever, userSwitchCallback); } @Override Loading