Merge changes from topic "blog"
* changes: Send AoD context changed notification to HAL. Connect SysUI sessions with biometric operations logs.
This commit is contained in:
@@ -53,6 +53,7 @@ import android.hardware.biometrics.IBiometricSensorReceiver;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiver;
|
||||
import android.hardware.biometrics.IBiometricSysuiReceiver;
|
||||
import android.hardware.biometrics.PromptInfo;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
@@ -64,6 +65,7 @@ import android.util.Slog;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.server.biometrics.log.BiometricFrameworkStatsLogger;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -681,16 +683,18 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
+ ", Latency: " + latency);
|
||||
}
|
||||
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_AUTHENTICATED,
|
||||
final OperationContext operationContext = new OperationContext();
|
||||
operationContext.isCrypto = isCrypto();
|
||||
BiometricFrameworkStatsLogger.getInstance().authenticate(
|
||||
operationContext,
|
||||
statsModality(),
|
||||
mUserId,
|
||||
isCrypto(),
|
||||
BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
mPreAuthInfo.confirmationRequested,
|
||||
FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
|
||||
latency,
|
||||
mDebugEnabled,
|
||||
-1 /* sensorId */,
|
||||
latency,
|
||||
FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
|
||||
mPreAuthInfo.confirmationRequested,
|
||||
mUserId,
|
||||
-1f /* ambientLightLux */);
|
||||
} else {
|
||||
final long latency = System.currentTimeMillis() - mStartTimeMs;
|
||||
@@ -711,17 +715,18 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
+ ", Latency: " + latency);
|
||||
}
|
||||
// Auth canceled
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ERROR_OCCURRED,
|
||||
final OperationContext operationContext = new OperationContext();
|
||||
operationContext.isCrypto = isCrypto();
|
||||
BiometricFrameworkStatsLogger.getInstance().error(
|
||||
operationContext,
|
||||
statsModality(),
|
||||
mUserId,
|
||||
isCrypto(),
|
||||
BiometricsProtoEnums.ACTION_AUTHENTICATE,
|
||||
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
error,
|
||||
0 /* vendorCode */,
|
||||
mDebugEnabled,
|
||||
latency,
|
||||
-1 /* sensorId */);
|
||||
error,
|
||||
0 /* vendorCode */,
|
||||
mUserId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.server.biometrics.log;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
@@ -26,11 +28,21 @@ import java.util.function.Consumer;
|
||||
* logging or optimizations.
|
||||
*/
|
||||
public interface BiometricContext {
|
||||
/** Gets the context source. */
|
||||
static BiometricContext getInstance() {
|
||||
return BiometricContextProvider.sInstance.get();
|
||||
/** Gets the context source from the system context. */
|
||||
static BiometricContext getInstance(@NonNull Context context) {
|
||||
return BiometricContextProvider.defaultProvider(context);
|
||||
}
|
||||
|
||||
/** Update the given context with the most recent values and return it. */
|
||||
OperationContext updateContext(@NonNull OperationContext operationContext,
|
||||
boolean isCryptoOperation);
|
||||
|
||||
/** The session id for keyguard entry, if active, or null. */
|
||||
@Nullable Integer getKeyguardEntrySessionId();
|
||||
|
||||
/** The session id for biometric prompt usage, if active, or null. */
|
||||
@Nullable Integer getBiometricPromptSessionId();
|
||||
|
||||
/** If the display is in AOD. */
|
||||
boolean isAoD();
|
||||
|
||||
|
||||
@@ -18,16 +18,22 @@ package com.android.server.biometrics.log;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.StatusBarManager;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.IBiometricContextListener;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.hardware.display.AmbientDisplayConfiguration;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Singleton;
|
||||
import android.os.ServiceManager.ServiceNotFoundException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.InstanceId;
|
||||
import com.android.internal.statusbar.ISessionListener;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -41,22 +47,41 @@ class BiometricContextProvider implements BiometricContext {
|
||||
|
||||
private static final String TAG = "BiometricContextProvider";
|
||||
|
||||
static final Singleton<BiometricContextProvider> sInstance =
|
||||
new Singleton<BiometricContextProvider>() {
|
||||
@Override
|
||||
protected BiometricContextProvider create() {
|
||||
return new BiometricContextProvider(IStatusBarService.Stub.asInterface(
|
||||
ServiceManager.getService(
|
||||
private static final int SESSION_TYPES =
|
||||
StatusBarManager.SESSION_KEYGUARD | StatusBarManager.SESSION_BIOMETRIC_PROMPT;
|
||||
|
||||
private static BiometricContextProvider sInstance;
|
||||
|
||||
static BiometricContextProvider defaultProvider(@NonNull Context context) {
|
||||
synchronized (BiometricContextProvider.class) {
|
||||
if (sInstance == null) {
|
||||
try {
|
||||
sInstance = new BiometricContextProvider(
|
||||
new AmbientDisplayConfiguration(context),
|
||||
IStatusBarService.Stub.asInterface(ServiceManager.getServiceOrThrow(
|
||||
Context.STATUS_BAR_SERVICE)), null /* handler */);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
throw new IllegalStateException("Failed to find required service", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private final Map<OperationContext, Consumer<OperationContext>> mSubscribers =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
@Nullable
|
||||
private final Map<Integer, InstanceId> mSession = new ConcurrentHashMap<>();
|
||||
|
||||
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
||||
private boolean mIsDozing = false;
|
||||
|
||||
@VisibleForTesting
|
||||
BiometricContextProvider(@NonNull IStatusBarService service, @Nullable Handler handler) {
|
||||
BiometricContextProvider(@NonNull AmbientDisplayConfiguration ambientDisplayConfiguration,
|
||||
@NonNull IStatusBarService service, @Nullable Handler handler) {
|
||||
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
|
||||
try {
|
||||
service.setBiometicContextListener(new IBiometricContextListener.Stub() {
|
||||
@Override
|
||||
@@ -73,16 +98,70 @@ class BiometricContextProvider implements BiometricContext {
|
||||
}
|
||||
}
|
||||
});
|
||||
service.registerSessionListener(SESSION_TYPES, new ISessionListener.Stub() {
|
||||
@Override
|
||||
public void onSessionStarted(int sessionType, InstanceId instance) {
|
||||
mSession.put(sessionType, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionEnded(int sessionType, InstanceId instance) {
|
||||
final InstanceId id = mSession.remove(sessionType);
|
||||
if (id != null && instance != null && id.getId() != instance.getId()) {
|
||||
Slog.w(TAG, "session id mismatch");
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Unable to register biometric context listener", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean mIsDozing = false;
|
||||
@Override
|
||||
public OperationContext updateContext(@NonNull OperationContext operationContext,
|
||||
boolean isCryptoOperation) {
|
||||
operationContext.isAoD = isAoD();
|
||||
operationContext.isCrypto = isCryptoOperation;
|
||||
setFirstSessionId(operationContext);
|
||||
return operationContext;
|
||||
}
|
||||
|
||||
private void setFirstSessionId(@NonNull OperationContext operationContext) {
|
||||
Integer sessionId = getKeyguardEntrySessionId();
|
||||
if (sessionId != null) {
|
||||
operationContext.id = sessionId;
|
||||
operationContext.reason = OperationReason.KEYGUARD;
|
||||
return;
|
||||
}
|
||||
|
||||
sessionId = getBiometricPromptSessionId();
|
||||
if (sessionId != null) {
|
||||
operationContext.id = sessionId;
|
||||
operationContext.reason = OperationReason.BIOMETRIC_PROMPT;
|
||||
return;
|
||||
}
|
||||
|
||||
operationContext.id = 0;
|
||||
operationContext.reason = OperationReason.UNKNOWN;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Integer getKeyguardEntrySessionId() {
|
||||
final InstanceId id = mSession.get(StatusBarManager.SESSION_KEYGUARD);
|
||||
return id != null ? id.getId() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Integer getBiometricPromptSessionId() {
|
||||
final InstanceId id = mSession.get(StatusBarManager.SESSION_BIOMETRIC_PROMPT);
|
||||
return id != null ? id.getId() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAoD() {
|
||||
return mIsDozing;
|
||||
return mIsDozing && mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,7 +177,7 @@ class BiometricContextProvider implements BiometricContext {
|
||||
|
||||
private void notifySubscribers() {
|
||||
mSubscribers.forEach((context, consumer) -> {
|
||||
context.isAoD = mIsDozing;
|
||||
context.isAoD = isAoD();
|
||||
consumer.accept(context);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.server.biometrics.log;
|
||||
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
@@ -33,42 +35,49 @@ public class BiometricFrameworkStatsLogger {
|
||||
|
||||
private BiometricFrameworkStatsLogger() {}
|
||||
|
||||
/** Shared instance. */
|
||||
public static BiometricFrameworkStatsLogger getInstance() {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
/** {@see FrameworkStatsLog.BIOMETRIC_ACQUIRED}. */
|
||||
public void acquired(
|
||||
public void acquired(OperationContext operationContext,
|
||||
int statsModality, int statsAction, int statsClient, boolean isDebug,
|
||||
int acquiredInfo, int vendorCode, boolean isCrypto, int targetUserId) {
|
||||
int acquiredInfo, int vendorCode, int targetUserId) {
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ACQUIRED,
|
||||
statsModality,
|
||||
targetUserId,
|
||||
isCrypto,
|
||||
operationContext.isCrypto,
|
||||
statsAction,
|
||||
statsClient,
|
||||
acquiredInfo,
|
||||
vendorCode,
|
||||
isDebug,
|
||||
-1 /* sensorId */);
|
||||
-1 /* sensorId */,
|
||||
operationContext.id,
|
||||
sessionType(operationContext.reason),
|
||||
operationContext.isAoD);
|
||||
}
|
||||
|
||||
/** {@see FrameworkStatsLog.BIOMETRIC_AUTHENTICATED}. */
|
||||
public void authenticate(
|
||||
public void authenticate(OperationContext operationContext,
|
||||
int statsModality, int statsAction, int statsClient, boolean isDebug, long latency,
|
||||
boolean authenticated, int authState, boolean requireConfirmation, boolean isCrypto,
|
||||
int targetUserId, boolean isBiometricPrompt, float ambientLightLux) {
|
||||
int authState, boolean requireConfirmation,
|
||||
int targetUserId, float ambientLightLux) {
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_AUTHENTICATED,
|
||||
statsModality,
|
||||
targetUserId,
|
||||
isCrypto,
|
||||
operationContext.isCrypto,
|
||||
statsClient,
|
||||
requireConfirmation,
|
||||
authState,
|
||||
sanitizeLatency(latency),
|
||||
isDebug,
|
||||
-1 /* sensorId */,
|
||||
ambientLightLux);
|
||||
ambientLightLux,
|
||||
operationContext.id,
|
||||
sessionType(operationContext.reason),
|
||||
operationContext.isAoD);
|
||||
}
|
||||
|
||||
/** {@see FrameworkStatsLog.BIOMETRIC_ENROLLED}. */
|
||||
@@ -84,20 +93,23 @@ public class BiometricFrameworkStatsLogger {
|
||||
}
|
||||
|
||||
/** {@see FrameworkStatsLog.BIOMETRIC_ERROR_OCCURRED}. */
|
||||
public void error(
|
||||
public void error(OperationContext operationContext,
|
||||
int statsModality, int statsAction, int statsClient, boolean isDebug, long latency,
|
||||
int error, int vendorCode, boolean isCrypto, int targetUserId) {
|
||||
int error, int vendorCode, int targetUserId) {
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ERROR_OCCURRED,
|
||||
statsModality,
|
||||
targetUserId,
|
||||
isCrypto,
|
||||
operationContext.isCrypto,
|
||||
statsAction,
|
||||
statsClient,
|
||||
error,
|
||||
vendorCode,
|
||||
isDebug,
|
||||
sanitizeLatency(latency),
|
||||
-1 /* sensorId */);
|
||||
-1 /* sensorId */,
|
||||
operationContext.id,
|
||||
sessionType(operationContext.reason),
|
||||
operationContext.isAoD);
|
||||
}
|
||||
|
||||
/** {@see FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED}. */
|
||||
@@ -123,4 +135,14 @@ public class BiometricFrameworkStatsLogger {
|
||||
}
|
||||
return latency;
|
||||
}
|
||||
|
||||
private static int sessionType(@OperationReason byte reason) {
|
||||
if (reason == OperationReason.BIOMETRIC_PROMPT) {
|
||||
return BiometricsProtoEnums.SESSION_TYPE_BIOMETRIC_PROMPT;
|
||||
}
|
||||
if (reason == OperationReason.KEYGUARD) {
|
||||
return BiometricsProtoEnums.SESSION_TYPE_KEYGUARD_ENTRY;
|
||||
}
|
||||
return BiometricsProtoEnums.SESSION_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.util.Slog;
|
||||
@@ -144,8 +145,8 @@ public class BiometricLogger {
|
||||
}
|
||||
|
||||
/** Log an acquisition event. */
|
||||
public void logOnAcquired(Context context,
|
||||
int acquiredInfo, int vendorCode, boolean isCrypto, int targetUserId) {
|
||||
public void logOnAcquired(Context context, OperationContext operationContext,
|
||||
int acquiredInfo, int vendorCode, int targetUserId) {
|
||||
if (!mShouldLogMetrics) {
|
||||
return;
|
||||
}
|
||||
@@ -165,7 +166,7 @@ public class BiometricLogger {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Acquired! Modality: " + mStatsModality
|
||||
+ ", User: " + targetUserId
|
||||
+ ", IsCrypto: " + isCrypto
|
||||
+ ", IsCrypto: " + operationContext.isCrypto
|
||||
+ ", Action: " + mStatsAction
|
||||
+ ", Client: " + mStatsClient
|
||||
+ ", AcquiredInfo: " + acquiredInfo
|
||||
@@ -176,14 +177,14 @@ public class BiometricLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
mSink.acquired(mStatsModality, mStatsAction, mStatsClient,
|
||||
mSink.acquired(operationContext, mStatsModality, mStatsAction, mStatsClient,
|
||||
Utils.isDebugEnabled(context, targetUserId),
|
||||
acquiredInfo, vendorCode, isCrypto, targetUserId);
|
||||
acquiredInfo, vendorCode, targetUserId);
|
||||
}
|
||||
|
||||
/** Log an error during an operation. */
|
||||
public void logOnError(Context context,
|
||||
int error, int vendorCode, boolean isCrypto, int targetUserId) {
|
||||
public void logOnError(Context context, OperationContext operationContext,
|
||||
int error, int vendorCode, int targetUserId) {
|
||||
if (!mShouldLogMetrics) {
|
||||
return;
|
||||
}
|
||||
@@ -194,7 +195,7 @@ public class BiometricLogger {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Error! Modality: " + mStatsModality
|
||||
+ ", User: " + targetUserId
|
||||
+ ", IsCrypto: " + isCrypto
|
||||
+ ", IsCrypto: " + operationContext.isCrypto
|
||||
+ ", Action: " + mStatsAction
|
||||
+ ", Client: " + mStatsClient
|
||||
+ ", Error: " + error
|
||||
@@ -208,14 +209,14 @@ public class BiometricLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
mSink.error(mStatsModality, mStatsAction, mStatsClient,
|
||||
mSink.error(operationContext, mStatsModality, mStatsAction, mStatsClient,
|
||||
Utils.isDebugEnabled(context, targetUserId), latency,
|
||||
error, vendorCode, isCrypto, targetUserId);
|
||||
error, vendorCode, targetUserId);
|
||||
}
|
||||
|
||||
/** Log authentication attempt. */
|
||||
public void logOnAuthenticated(Context context,
|
||||
boolean authenticated, boolean requireConfirmation, boolean isCrypto,
|
||||
public void logOnAuthenticated(Context context, OperationContext operationContext,
|
||||
boolean authenticated, boolean requireConfirmation,
|
||||
int targetUserId, boolean isBiometricPrompt) {
|
||||
if (!mShouldLogMetrics) {
|
||||
return;
|
||||
@@ -241,7 +242,7 @@ public class BiometricLogger {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Authenticated! Modality: " + mStatsModality
|
||||
+ ", User: " + targetUserId
|
||||
+ ", IsCrypto: " + isCrypto
|
||||
+ ", IsCrypto: " + operationContext.isCrypto
|
||||
+ ", Client: " + mStatsClient
|
||||
+ ", RequireConfirmation: " + requireConfirmation
|
||||
+ ", State: " + authState
|
||||
@@ -255,10 +256,9 @@ public class BiometricLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
mSink.authenticate(mStatsModality, mStatsAction, mStatsClient,
|
||||
mSink.authenticate(operationContext, mStatsModality, mStatsAction, mStatsClient,
|
||||
Utils.isDebugEnabled(context, targetUserId),
|
||||
latency, authenticated, authState, requireConfirmation, isCrypto,
|
||||
targetUserId, isBiometricPrompt, mLastAmbientLux);
|
||||
latency, authState, requireConfirmation, targetUserId, mLastAmbientLux);
|
||||
}
|
||||
|
||||
/** Log enrollment outcome. */
|
||||
|
||||
@@ -110,8 +110,8 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement
|
||||
// that do not handle lockout under the HAL. In these cases, ensure that the framework only
|
||||
// sends errors once per ClientMonitor.
|
||||
if (mShouldSendErrorToClient) {
|
||||
getLogger().logOnError(getContext(), errorCode, vendorCode,
|
||||
isCryptoOperation(), getTargetUserId());
|
||||
getLogger().logOnError(getContext(), getOperationContext(),
|
||||
errorCode, vendorCode, getTargetUserId());
|
||||
try {
|
||||
if (getListener() != null) {
|
||||
mShouldSendErrorToClient = false;
|
||||
@@ -169,8 +169,8 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement
|
||||
|
||||
protected final void onAcquiredInternal(int acquiredInfo, int vendorCode,
|
||||
boolean shouldSend) {
|
||||
getLogger().logOnAcquired(getContext(), acquiredInfo, vendorCode,
|
||||
isCryptoOperation(), getTargetUserId());
|
||||
getLogger().logOnAcquired(getContext(), getOperationContext(),
|
||||
acquiredInfo, vendorCode, getTargetUserId());
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Acquired: " + acquiredInfo + " " + vendorCode
|
||||
+ ", shouldSend: " + shouldSend);
|
||||
|
||||
@@ -166,8 +166,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
@Override
|
||||
public void onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
||||
boolean authenticated, ArrayList<Byte> hardwareAuthToken) {
|
||||
getLogger().logOnAuthenticated(getContext(), authenticated, mRequireConfirmation,
|
||||
isCryptoOperation(), getTargetUserId(), isBiometricPrompt());
|
||||
getLogger().logOnAuthenticated(getContext(), getOperationContext(),
|
||||
authenticated, mRequireConfirmation, getTargetUserId(), isBiometricPrompt());
|
||||
|
||||
final ClientMonitorCallbackConverter listener = getListener();
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public abstract class HalClientMonitor<T> extends BaseClientMonitor {
|
||||
protected final Supplier<T> mLazyDaemon;
|
||||
|
||||
@NonNull
|
||||
protected final OperationContext mOperationContext = new OperationContext();
|
||||
private final OperationContext mOperationContext = new OperationContext();
|
||||
|
||||
/**
|
||||
* @param context system_server context
|
||||
@@ -82,6 +82,23 @@ public abstract class HalClientMonitor<T> extends BaseClientMonitor {
|
||||
super.destroy();
|
||||
|
||||
// subclasses should do this earlier in most cases, but ensure it happens now
|
||||
unsubscribeBiometricContext();
|
||||
}
|
||||
|
||||
protected OperationContext getOperationContext() {
|
||||
return getBiometricContext().updateContext(mOperationContext, isCryptoOperation());
|
||||
}
|
||||
|
||||
protected ClientMonitorCallback getBiometricContextUnsubscriber() {
|
||||
return new ClientMonitorCallback() {
|
||||
@Override
|
||||
public void onClientFinished(@NonNull BaseClientMonitor monitor, boolean success) {
|
||||
unsubscribeBiometricContext();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected void unsubscribeBiometricContext() {
|
||||
getBiometricContext().unsubscribe(mOperationContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.server.ServiceThread;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.biometrics.Utils;
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||
@@ -645,7 +646,7 @@ public class FaceService extends SystemService {
|
||||
try {
|
||||
final SensorProps[] props = face.getSensorProps();
|
||||
final FaceProvider provider = new FaceProvider(getContext(), props, instance,
|
||||
mLockoutResetDispatcher);
|
||||
mLockoutResetDispatcher, BiometricContext.getInstance(getContext()));
|
||||
mServiceProviders.add(provider);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
|
||||
|
||||
@@ -26,8 +26,6 @@ import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricFaceConstants;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
import android.hardware.face.FaceAuthenticationFrame;
|
||||
import android.hardware.face.FaceManager;
|
||||
@@ -157,13 +155,8 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
final AidlSession session = getFreshDaemon();
|
||||
|
||||
if (session.hasContextMethods()) {
|
||||
final OperationContext context = new OperationContext();
|
||||
// TODO: add reason, id
|
||||
context.id = 0;
|
||||
context.reason = OperationReason.UNKNOWN;
|
||||
context.isAoD = getBiometricContext().isAoD();
|
||||
context.isCrypto = isCryptoOperation();
|
||||
return session.getSession().authenticateWithContext(mOperationId, context);
|
||||
return session.getSession().authenticateWithContext(
|
||||
mOperationId, getOperationContext());
|
||||
} else {
|
||||
return session.getSession().authenticate(mOperationId);
|
||||
}
|
||||
@@ -282,8 +275,8 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT;
|
||||
getLogger().logOnError(getContext(), error, 0 /* vendorCode */,
|
||||
isCryptoOperation(), getTargetUserId());
|
||||
getLogger().logOnError(getContext(), getOperationContext(),
|
||||
error, 0 /* vendorCode */, getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
@@ -298,8 +291,8 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
|
||||
getLogger().logOnError(getContext(), error, 0 /* vendorCode */,
|
||||
isCryptoOperation(), getTargetUserId());
|
||||
getLogger().logOnError(getContext(), getOperationContext(),
|
||||
error, 0 /* vendorCode */, getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
|
||||
@@ -22,8 +22,6 @@ import android.content.Context;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
@@ -116,13 +114,7 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements
|
||||
final AidlSession session = getFreshDaemon();
|
||||
|
||||
if (session.hasContextMethods()) {
|
||||
final OperationContext context = new OperationContext();
|
||||
// TODO: add reason, id
|
||||
context.id = 0;
|
||||
context.reason = OperationReason.UNKNOWN;
|
||||
context.isAoD = getBiometricContext().isAoD();
|
||||
context.isCrypto = isCryptoOperation();
|
||||
return session.getSession().detectInteractionWithContext(context);
|
||||
return session.getSession().detectInteractionWithContext(getOperationContext());
|
||||
} else {
|
||||
return session.getSession().detectInteraction();
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@ import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricFaceConstants;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.hardware.biometrics.face.EnrollmentType;
|
||||
import android.hardware.biometrics.face.Feature;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
@@ -200,14 +198,8 @@ public class FaceEnrollClient extends EnrollClient<AidlSession> {
|
||||
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
|
||||
|
||||
if (session.hasContextMethods()) {
|
||||
final OperationContext context = new OperationContext();
|
||||
// TODO: add reason, id
|
||||
context.id = 0;
|
||||
context.reason = OperationReason.UNKNOWN;
|
||||
context.isAoD = getBiometricContext().isAoD();
|
||||
context.isCrypto = isCryptoOperation();
|
||||
return session.getSession().enrollWithContext(
|
||||
hat, EnrollmentType.DEFAULT, features, mHwPreviewHandle, context);
|
||||
hat, EnrollmentType.DEFAULT, features, mHwPreviewHandle, getOperationContext());
|
||||
} else {
|
||||
return session.getSession().enroll(hat, EnrollmentType.DEFAULT, features,
|
||||
mHwPreviewHandle);
|
||||
|
||||
@@ -90,7 +90,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
@NonNull private final BiometricTaskStackListener mTaskStackListener;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
|
||||
@NonNull private final BiometricContext mBiometricContext;
|
||||
@Nullable private IFace mDaemon;
|
||||
|
||||
private final class BiometricTaskStackListener extends TaskStackListener {
|
||||
@@ -128,7 +128,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
public FaceProvider(@NonNull Context context, @NonNull SensorProps[] props,
|
||||
@NonNull String halInstanceName,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher) {
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
mContext = context;
|
||||
mHalInstanceName = halInstanceName;
|
||||
mSensors = new SparseArray<>();
|
||||
@@ -137,6 +138,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mLockoutResetDispatcher = lockoutResetDispatcher;
|
||||
mActivityTaskManager = ActivityTaskManager.getInstance();
|
||||
mTaskStackListener = new BiometricTaskStackListener();
|
||||
mBiometricContext = biometricContext;
|
||||
|
||||
for (SensorProps prop : props) {
|
||||
final int sensorId = prop.commonProps.sensorId;
|
||||
@@ -156,7 +158,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
prop.supportsDetectInteraction, prop.halControlsPreview,
|
||||
false /* resetLockoutRequiresChallenge */);
|
||||
final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
|
||||
internalProp, lockoutResetDispatcher);
|
||||
internalProp, lockoutResetDispatcher, mBiometricContext);
|
||||
|
||||
mSensors.put(sensorId, sensor);
|
||||
Slog.d(getTag(), "Added: " + internalProp);
|
||||
@@ -242,7 +244,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
|
||||
scheduleForSensor(sensorId, client);
|
||||
@@ -253,7 +255,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mHandler.post(() -> {
|
||||
final InvalidationRequesterClient<Face> client =
|
||||
new InvalidationRequesterClient<>(mContext, userId, sensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext),
|
||||
mBiometricContext,
|
||||
FaceUtils.getInstance(sensorId));
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -294,7 +297,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mSensors.get(sensorId).getLazySession(), userId, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mSensors.get(sensorId).getAuthenticatorIds(), callback);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -324,7 +327,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
new ClientMonitorCallbackConverter(receiver), userId, opPackageName, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance());
|
||||
mBiometricContext);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
}
|
||||
@@ -337,7 +340,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mSensors.get(sensorId).getLazySession(), token, userId, opPackageName, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), challenge);
|
||||
mBiometricContext, challenge);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
}
|
||||
@@ -358,7 +361,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
ENROLL_TIMEOUT_SEC, previewSurface, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENROLL,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), maxTemplatesPerUser, debugConsent);
|
||||
mBiometricContext, maxTemplatesPerUser, debugConsent);
|
||||
scheduleForSensor(sensorId, client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
|
||||
@@ -391,7 +394,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mSensors.get(sensorId).getLazySession(),
|
||||
token, id, callback, userId, opPackageName, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
BiometricContext.getInstance(), isStrongBiometric);
|
||||
mBiometricContext, isStrongBiometric);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
|
||||
@@ -416,7 +419,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
userId, operationId, restricted, opPackageName, cookie,
|
||||
false /* requireConfirmation */, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
BiometricContext.getInstance(), isStrongBiometric,
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
scheduleForSensor(sensorId, client);
|
||||
@@ -472,7 +475,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
opPackageName, FaceUtils.getInstance(sensorId), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -486,7 +489,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), hardwareAuthToken,
|
||||
mBiometricContext, hardwareAuthToken,
|
||||
mSensors.get(sensorId).getLockoutCache(), mLockoutResetDispatcher);
|
||||
|
||||
scheduleForSensor(sensorId, client);
|
||||
@@ -508,7 +511,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mSensors.get(sensorId).getLazySession(), token,
|
||||
new ClientMonitorCallbackConverter(receiver), userId,
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext), mBiometricContext,
|
||||
feature, enabled, hardwareAuthToken);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -527,7 +530,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), token, callback, userId,
|
||||
mContext.getOpPackageName(), sensorId, BiometricLogger.ofUnknown(mContext),
|
||||
BiometricContext.getInstance());
|
||||
mBiometricContext);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
}
|
||||
@@ -550,7 +553,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), enrolledList,
|
||||
mBiometricContext, enrolledList,
|
||||
FaceUtils.getInstance(sensorId),
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
scheduleForSensor(sensorId, client, callback);
|
||||
|
||||
@@ -476,7 +476,8 @@ public class Sensor {
|
||||
|
||||
Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
|
||||
@NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher) {
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
mTag = tag;
|
||||
mProvider = provider;
|
||||
mContext = context;
|
||||
@@ -492,7 +493,7 @@ public class Sensor {
|
||||
public StopUserClient<?> getStopUserClient(int userId) {
|
||||
return new FaceStopUserClient(mContext, mLazySession, mToken, userId,
|
||||
mSensorProperties.sensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext), biometricContext,
|
||||
() -> mCurrentSession = null);
|
||||
}
|
||||
|
||||
@@ -529,7 +530,7 @@ public class Sensor {
|
||||
|
||||
return new FaceStartUserClient(mContext, provider::getHalInstance,
|
||||
mToken, newUserId, mSensorProperties.sensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext), biometricContext,
|
||||
resultController, userStartedCallback);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -119,6 +119,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
|
||||
@Nullable private IBiometricsFace mDaemon;
|
||||
@NonNull private final HalResultController mHalResultController;
|
||||
@NonNull private final BiometricContext mBiometricContext;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
private int mCurrentUserId = UserHandle.USER_NULL;
|
||||
@@ -155,6 +156,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
@NonNull private final LockoutHalImpl mLockoutTracker;
|
||||
@NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
|
||||
|
||||
HalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
|
||||
@NonNull BiometricScheduler scheduler, @NonNull LockoutHalImpl lockoutTracker,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher) {
|
||||
@@ -337,12 +339,14 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
@NonNull FaceSensorPropertiesInternal sensorProps,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull Handler handler,
|
||||
@NonNull BiometricScheduler scheduler) {
|
||||
@NonNull BiometricScheduler scheduler,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
mSensorProperties = sensorProps;
|
||||
mContext = context;
|
||||
mSensorId = sensorProps.sensorId;
|
||||
mScheduler = scheduler;
|
||||
mHandler = handler;
|
||||
mBiometricContext = biometricContext;
|
||||
mUsageStats = new UsageStats(context);
|
||||
mAuthenticatorIds = new HashMap<>();
|
||||
mLazyDaemon = Face10.this::getDaemon;
|
||||
@@ -367,7 +371,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
final Handler handler = new Handler(Looper.getMainLooper());
|
||||
return new Face10(context, sensorProps, lockoutResetDispatcher, handler,
|
||||
new BiometricScheduler(TAG, BiometricScheduler.SENSOR_TYPE_FACE,
|
||||
null /* gestureAvailabilityTracker */));
|
||||
null /* gestureAvailabilityTracker */),
|
||||
BiometricContext.getInstance(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -538,7 +543,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
opPackageName, mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), sSystemClock.millis());
|
||||
mBiometricContext, sSystemClock.millis());
|
||||
mGeneratedChallengeCache = client;
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
@@ -570,7 +575,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
mLazyDaemon, token, userId, opPackageName, mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance());
|
||||
mBiometricContext);
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
|
||||
@@ -601,7 +606,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
ENROLL_TIMEOUT_SEC, previewSurface, mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENROLL,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance());
|
||||
mBiometricContext);
|
||||
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
@@ -649,8 +654,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
mLazyDaemon, token, requestId, receiver, userId, operationId, restricted,
|
||||
opPackageName, cookie, false /* requireConfirmation */, mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
BiometricContext.getInstance(), isStrongBiometric, mLockoutTracker, mUsageStats,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
mBiometricContext, isStrongBiometric, mLockoutTracker,
|
||||
mUsageStats, allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -685,7 +690,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
FaceUtils.getLegacyInstance(mSensorId), mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), mAuthenticatorIds);
|
||||
mBiometricContext, mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -703,7 +708,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
FaceUtils.getLegacyInstance(mSensorId), mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), mAuthenticatorIds);
|
||||
mBiometricContext, mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -722,7 +727,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), hardwareAuthToken);
|
||||
mBiometricContext, hardwareAuthToken);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -744,7 +749,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
final FaceSetFeatureClient client = new FaceSetFeatureClient(mContext,
|
||||
mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
|
||||
opPackageName, mSensorId, BiometricLogger.ofUnknown(mContext),
|
||||
BiometricContext.getInstance(), feature, enabled, hardwareAuthToken, faceId);
|
||||
mBiometricContext,
|
||||
feature, enabled, hardwareAuthToken, faceId);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -764,7 +770,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
final int faceId = faces.get(0).getBiometricId();
|
||||
final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext, mLazyDaemon,
|
||||
token, listener, userId, opPackageName, mSensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext), mBiometricContext,
|
||||
feature, faceId);
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
@@ -793,7 +799,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), enrolledList,
|
||||
mBiometricContext, enrolledList,
|
||||
FaceUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client, callback);
|
||||
});
|
||||
@@ -918,7 +924,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), hasEnrolled, mAuthenticatorIds);
|
||||
mBiometricContext, hasEnrolled, mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
|
||||
|
||||
@@ -83,6 +83,7 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.server.ServiceThread;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.biometrics.Utils;
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||
@@ -815,7 +816,8 @@ public class FingerprintService extends SystemService {
|
||||
UserHandle.USER_CURRENT) != 0) {
|
||||
fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(),
|
||||
mFingerprintStateCallback, hidlSensor,
|
||||
mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
|
||||
mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
|
||||
BiometricContext.getInstance(getContext()));
|
||||
} else {
|
||||
fingerprint21 = Fingerprint21.newInstance(getContext(),
|
||||
mFingerprintStateCallback, hidlSensor, mHandler,
|
||||
@@ -843,7 +845,8 @@ public class FingerprintService extends SystemService {
|
||||
final FingerprintProvider provider =
|
||||
new FingerprintProvider(getContext(), mFingerprintStateCallback, props,
|
||||
instance, mLockoutResetDispatcher,
|
||||
mGestureAvailabilityDispatcher);
|
||||
mGestureAvailabilityDispatcher,
|
||||
BiometricContext.getInstance(getContext()));
|
||||
mServiceProviders.add(provider);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricFingerprintConstants;
|
||||
import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
@@ -108,7 +108,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@NonNull
|
||||
@Override
|
||||
protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
|
||||
return new ClientMonitorCompositeCallback(mALSProbeCallback, callback);
|
||||
return new ClientMonitorCompositeCallback(mALSProbeCallback,
|
||||
getBiometricContextUnsubscriber(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,12 +179,17 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
final AidlSession session = getFreshDaemon();
|
||||
|
||||
if (session.hasContextMethods()) {
|
||||
// TODO: add reason, id
|
||||
mOperationContext.id = 0;
|
||||
mOperationContext.reason = OperationReason.UNKNOWN;
|
||||
mOperationContext.isAoD = getBiometricContext().isAoD();
|
||||
mOperationContext.isCrypto = isCryptoOperation();
|
||||
return session.getSession().authenticateWithContext(mOperationId, mOperationContext);
|
||||
final OperationContext opContext = getOperationContext();
|
||||
final ICancellationSignal cancel = session.getSession().authenticateWithContext(
|
||||
mOperationId, opContext);
|
||||
getBiometricContext().subscribe(opContext, ctx -> {
|
||||
try {
|
||||
session.getSession().onContextChanged(ctx);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Unable to notify context changed", e);
|
||||
}
|
||||
});
|
||||
return cancel;
|
||||
} else {
|
||||
return session.getSession().authenticate(mOperationId);
|
||||
}
|
||||
@@ -192,6 +198,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@Override
|
||||
protected void stopHalOperation() {
|
||||
mSensorOverlays.hide(getSensorId());
|
||||
unsubscribeBiometricContext();
|
||||
|
||||
if (mCancellationSignal != null) {
|
||||
try {
|
||||
mCancellationSignal.cancel();
|
||||
@@ -221,7 +229,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
context.y = y;
|
||||
context.minor = minor;
|
||||
context.major = major;
|
||||
context.isAoD = false; // TODO; get value
|
||||
context.isAoD = getBiometricContext().isAoD();
|
||||
session.getSession().onPointerDownWithContext(context);
|
||||
} else {
|
||||
session.getSession().onPointerDown(0 /* pointerId */, x, y, minor, major);
|
||||
@@ -279,8 +287,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
|
||||
getLogger().logOnError(getContext(), error, 0 /* vendorCode */,
|
||||
isCryptoOperation(), getTargetUserId());
|
||||
getLogger().logOnError(getContext(), getOperationContext(),
|
||||
error, 0 /* vendorCode */, getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
@@ -298,8 +306,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
|
||||
// Lockout metrics are logged as an error code.
|
||||
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
|
||||
getLogger().logOnError(getContext(), error, 0 /* vendorCode */,
|
||||
isCryptoOperation(), getTargetUserId());
|
||||
getLogger().logOnError(getContext(), getOperationContext(),
|
||||
error, 0 /* vendorCode */, getTargetUserId());
|
||||
|
||||
try {
|
||||
getListener().onError(getSensorId(), getCookie(), error, 0 /* vendorCode */);
|
||||
|
||||
@@ -21,8 +21,6 @@ import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricOverlayConstants;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -99,13 +97,7 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements
|
||||
final AidlSession session = getFreshDaemon();
|
||||
|
||||
if (session.hasContextMethods()) {
|
||||
final OperationContext context = new OperationContext();
|
||||
// TODO: add reason, id
|
||||
context.id = 0;
|
||||
context.reason = OperationReason.UNKNOWN;
|
||||
context.isAoD = getBiometricContext().isAoD();
|
||||
context.isCrypto = isCryptoOperation();
|
||||
return session.getSession().detectInteractionWithContext(context);
|
||||
return session.getSession().detectInteractionWithContext(getOperationContext());
|
||||
} else {
|
||||
return session.getSession().detectInteraction();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.hardware.biometrics.BiometricFingerprintConstants;
|
||||
import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
@@ -39,6 +38,8 @@ import android.util.Slog;
|
||||
import com.android.server.biometrics.HardwareAuthTokenUtils;
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.log.BiometricLogger;
|
||||
import com.android.server.biometrics.log.CallbackWithProbe;
|
||||
import com.android.server.biometrics.log.Probe;
|
||||
import com.android.server.biometrics.sensors.BiometricNotificationUtils;
|
||||
import com.android.server.biometrics.sensors.BiometricUtils;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallback;
|
||||
@@ -58,6 +59,7 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
|
||||
|
||||
@NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
|
||||
@NonNull private final SensorOverlays mSensorOverlays;
|
||||
@NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
|
||||
|
||||
private final @FingerprintManager.EnrollReason int mEnrollReason;
|
||||
@Nullable private ICancellationSignal mCancellationSignal;
|
||||
@@ -83,6 +85,8 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
|
||||
mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
|
||||
mMaxTemplatesPerUser = maxTemplatesPerUser;
|
||||
|
||||
mALSProbeCallback = getLogger().createALSCallback(false /* startWithClient */);
|
||||
|
||||
mEnrollReason = enrollReason;
|
||||
if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
|
||||
getLogger().disableMetrics();
|
||||
@@ -92,8 +96,8 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
|
||||
@NonNull
|
||||
@Override
|
||||
protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
|
||||
return new ClientMonitorCompositeCallback(
|
||||
getLogger().createALSCallback(true /* startWithClient */), callback);
|
||||
return new ClientMonitorCompositeCallback(mALSProbeCallback,
|
||||
getBiometricContextUnsubscriber(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,22 +145,6 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
|
||||
>= mMaxTemplatesPerUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopHalOperation() {
|
||||
mSensorOverlays.hide(getSensorId());
|
||||
|
||||
if (mCancellationSignal != null) {
|
||||
try {
|
||||
mCancellationSignal.cancel();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception when requesting cancel", e);
|
||||
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
|
||||
0 /* vendorCode */);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
mSensorOverlays.show(getSensorId(), getOverlayReasonFromEnrollReason(mEnrollReason), this);
|
||||
@@ -178,22 +166,44 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
|
||||
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
|
||||
|
||||
if (session.hasContextMethods()) {
|
||||
final OperationContext context = new OperationContext();
|
||||
// TODO: add reason, id
|
||||
context.id = 0;
|
||||
context.reason = OperationReason.UNKNOWN;
|
||||
context.isAoD = getBiometricContext().isAoD();
|
||||
context.isCrypto = isCryptoOperation();
|
||||
return session.getSession().enrollWithContext(hat, context);
|
||||
final OperationContext opContext = getOperationContext();
|
||||
final ICancellationSignal cancel = session.getSession().enrollWithContext(
|
||||
hat, opContext);
|
||||
getBiometricContext().subscribe(opContext, ctx -> {
|
||||
try {
|
||||
session.getSession().onContextChanged(ctx);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Unable to notify context changed", e);
|
||||
}
|
||||
});
|
||||
return cancel;
|
||||
} else {
|
||||
return session.getSession().enroll(hat);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopHalOperation() {
|
||||
mSensorOverlays.hide(getSensorId());
|
||||
unsubscribeBiometricContext();
|
||||
|
||||
if (mCancellationSignal != null) {
|
||||
try {
|
||||
mCancellationSignal.cancel();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception when requesting cancel", e);
|
||||
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
|
||||
0 /* vendorCode */);
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPointerDown(int x, int y, float minor, float major) {
|
||||
try {
|
||||
mIsPointerDown = true;
|
||||
mALSProbeCallback.getProbe().enable();
|
||||
|
||||
final AidlSession session = getFreshDaemon();
|
||||
if (session.hasContextMethods()) {
|
||||
@@ -203,7 +213,7 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
|
||||
context.y = y;
|
||||
context.minor = minor;
|
||||
context.major = major;
|
||||
context.isAoD = false;
|
||||
context.isAoD = getBiometricContext().isAoD();
|
||||
session.getSession().onPointerDownWithContext(context);
|
||||
} else {
|
||||
session.getSession().onPointerDown(0 /* pointerId */, x, y, minor, major);
|
||||
@@ -217,6 +227,7 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
|
||||
public void onPointerUp() {
|
||||
try {
|
||||
mIsPointerDown = false;
|
||||
mALSProbeCallback.getProbe().disable();
|
||||
|
||||
final AidlSession session = getFreshDaemon();
|
||||
if (session.hasContextMethods()) {
|
||||
|
||||
@@ -101,7 +101,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
@NonNull private final BiometricTaskStackListener mTaskStackListener;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
|
||||
@NonNull private final BiometricContext mBiometricContext;
|
||||
@Nullable private IFingerprint mDaemon;
|
||||
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private ISidefpsController mSidefpsController;
|
||||
@@ -144,7 +144,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback,
|
||||
@NonNull SensorProps[] props, @NonNull String halInstanceName,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
mContext = context;
|
||||
mFingerprintStateCallback = fingerprintStateCallback;
|
||||
mHalInstanceName = halInstanceName;
|
||||
@@ -153,6 +154,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mLockoutResetDispatcher = lockoutResetDispatcher;
|
||||
mActivityTaskManager = ActivityTaskManager.getInstance();
|
||||
mTaskStackListener = new BiometricTaskStackListener();
|
||||
mBiometricContext = biometricContext;
|
||||
|
||||
final List<SensorLocationInternal> workaroundLocations = getWorkaroundSensorProps(context);
|
||||
|
||||
@@ -184,7 +186,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
location.sensorRadius))
|
||||
.collect(Collectors.toList()));
|
||||
final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
|
||||
internalProp, lockoutResetDispatcher, gestureAvailabilityDispatcher);
|
||||
internalProp, lockoutResetDispatcher, gestureAvailabilityDispatcher,
|
||||
mBiometricContext);
|
||||
|
||||
mSensors.put(sensorId, sensor);
|
||||
Slog.d(getTag(), "Added: " + internalProp);
|
||||
@@ -303,7 +306,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -313,7 +316,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mHandler.post(() -> {
|
||||
final InvalidationRequesterClient<Fingerprint> client =
|
||||
new InvalidationRequesterClient<>(mContext, userId, sensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext),
|
||||
mBiometricContext,
|
||||
FingerprintUtils.getInstance(sensorId));
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -327,7 +331,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), hardwareAuthToken,
|
||||
mBiometricContext, hardwareAuthToken,
|
||||
mSensors.get(sensorId).getLockoutCache(), mLockoutResetDispatcher);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
@@ -343,7 +347,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
new ClientMonitorCallbackConverter(receiver), userId, opPackageName,
|
||||
sensorId, createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance());
|
||||
mBiometricContext);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
}
|
||||
@@ -358,7 +362,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
userId, opPackageName, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), challenge);
|
||||
mBiometricContext, challenge);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
}
|
||||
@@ -378,7 +382,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENROLL,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mSensors.get(sensorId).getSensorProperties(),
|
||||
mUdfpsOverlayController, mSidefpsController, maxTemplatesPerUser, enrollReason);
|
||||
scheduleForSensor(sensorId, client, new ClientMonitorCallback() {
|
||||
@@ -419,7 +423,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mSensors.get(sensorId).getLazySession(), token, id, callback, userId,
|
||||
opPackageName, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mUdfpsOverlayController, isStrongBiometric);
|
||||
scheduleForSensor(sensorId, client, mFingerprintStateCallback);
|
||||
});
|
||||
@@ -439,7 +443,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
userId, operationId, restricted, opPackageName, cookie,
|
||||
false /* requireConfirmation */, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
BiometricContext.getInstance(), isStrongBiometric,
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
|
||||
mUdfpsOverlayController, mSidefpsController, allowBackgroundAuthentication,
|
||||
mSensors.get(sensorId).getSensorProperties());
|
||||
@@ -503,7 +507,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
scheduleForSensor(sensorId, client, mFingerprintStateCallback);
|
||||
});
|
||||
@@ -520,7 +524,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
enrolledList, FingerprintUtils.getInstance(sensorId),
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
scheduleForSensor(sensorId, client, new ClientMonitorCompositeCallback(callback,
|
||||
@@ -559,7 +563,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
mSensors.get(sensorId).getLazySession(), userId, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mSensors.get(sensorId).getAuthenticatorIds(), callback);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
|
||||
@@ -429,7 +429,8 @@ public class Sensor {
|
||||
Sensor(@NonNull String tag, @NonNull FingerprintProvider provider, @NonNull Context context,
|
||||
@NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
mTag = tag;
|
||||
mProvider = provider;
|
||||
mContext = context;
|
||||
@@ -447,7 +448,7 @@ public class Sensor {
|
||||
public StopUserClient<?> getStopUserClient(int userId) {
|
||||
return new FingerprintStopUserClient(mContext, mLazySession, mToken,
|
||||
userId, mSensorProperties.sensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext), biometricContext,
|
||||
() -> mCurrentSession = null);
|
||||
}
|
||||
|
||||
@@ -484,7 +485,7 @@ public class Sensor {
|
||||
|
||||
return new FingerprintStartUserClient(mContext, provider::getHalInstance,
|
||||
mToken, newUserId, mSensorProperties.sensorId,
|
||||
BiometricLogger.ofUnknown(mContext), BiometricContext.getInstance(),
|
||||
BiometricLogger.ofUnknown(mContext), biometricContext,
|
||||
resultController, userStartedCallback);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -120,6 +120,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
@NonNull private final HalResultController mHalResultController;
|
||||
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private ISidefpsController mSidefpsController;
|
||||
@NonNull private final BiometricContext mBiometricContext;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
private int mCurrentUserId = UserHandle.USER_NULL;
|
||||
@@ -320,15 +321,18 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Fingerprint21(@NonNull Context context,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback,
|
||||
@NonNull FingerprintSensorPropertiesInternal sensorProps,
|
||||
@NonNull BiometricScheduler scheduler,
|
||||
@NonNull Handler handler,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull HalResultController controller) {
|
||||
@NonNull HalResultController controller,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
mContext = context;
|
||||
mFingerprintStateCallback = fingerprintStateCallback;
|
||||
mBiometricContext = biometricContext;
|
||||
|
||||
mSensorProperties = sensorProps;
|
||||
mSensorId = sensorProps.sensorId;
|
||||
@@ -370,7 +374,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
final HalResultController controller = new HalResultController(sensorProps.sensorId,
|
||||
context, handler, scheduler);
|
||||
return new Fingerprint21(context, fingerprintStateCallback, sensorProps, scheduler, handler,
|
||||
lockoutResetDispatcher, controller);
|
||||
lockoutResetDispatcher, controller, BiometricContext.getInstance(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -497,7 +501,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mContext.getOpPackageName(), mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
this::getCurrentUser, hasEnrolled, mAuthenticatorIds, force);
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
@@ -544,7 +548,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
userId, mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), mLockoutTracker);
|
||||
mBiometricContext, mLockoutTracker);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -559,7 +563,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance());
|
||||
mBiometricContext);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -573,7 +577,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_UNKNOWN,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance());
|
||||
mBiometricContext);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
@@ -594,7 +598,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENROLL,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(),
|
||||
mBiometricContext,
|
||||
mUdfpsOverlayController, mSidefpsController,
|
||||
enrollReason);
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
|
||||
@@ -636,7 +640,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mLazyDaemon, token, id, listener, userId, opPackageName,
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
BiometricContext.getInstance(), mUdfpsOverlayController, isStrongBiometric);
|
||||
mBiometricContext, mUdfpsOverlayController,
|
||||
isStrongBiometric);
|
||||
mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
|
||||
});
|
||||
|
||||
@@ -657,7 +662,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
restricted, opPackageName, cookie, false /* requireConfirmation */,
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
BiometricContext.getInstance(), isStrongBiometric,
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mTaskStackListener, mLockoutTracker,
|
||||
mUdfpsOverlayController, mSidefpsController,
|
||||
allowBackgroundAuthentication, mSensorProperties);
|
||||
@@ -702,7 +707,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), mAuthenticatorIds);
|
||||
mBiometricContext, mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
|
||||
});
|
||||
}
|
||||
@@ -722,7 +727,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), mAuthenticatorIds);
|
||||
mBiometricContext, mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
|
||||
});
|
||||
}
|
||||
@@ -739,7 +744,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
BiometricContext.getInstance(), enrolledList,
|
||||
mBiometricContext, enrolledList,
|
||||
FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client, callback);
|
||||
});
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.AuthenticationConsumer;
|
||||
import com.android.server.biometrics.sensors.BaseClientMonitor;
|
||||
import com.android.server.biometrics.sensors.BiometricScheduler;
|
||||
@@ -247,7 +248,8 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback,
|
||||
@NonNull FingerprintSensorPropertiesInternal sensorProps,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
Slog.d(TAG, "Creating Fingerprint23Mock!");
|
||||
|
||||
final Handler handler = new Handler(Looper.getMainLooper());
|
||||
@@ -256,7 +258,7 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
|
||||
final MockHalResultController controller =
|
||||
new MockHalResultController(sensorProps.sensorId, context, handler, scheduler);
|
||||
return new Fingerprint21UdfpsMock(context, fingerprintStateCallback, sensorProps, scheduler,
|
||||
handler, lockoutResetDispatcher, controller);
|
||||
handler, lockoutResetDispatcher, controller, biometricContext);
|
||||
}
|
||||
|
||||
private static abstract class FakeFingerRunnable implements Runnable {
|
||||
@@ -385,9 +387,10 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
|
||||
@NonNull TestableBiometricScheduler scheduler,
|
||||
@NonNull Handler handler,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull MockHalResultController controller) {
|
||||
@NonNull MockHalResultController controller,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
super(context, fingerprintStateCallback, sensorProps, scheduler, handler,
|
||||
lockoutResetDispatcher, controller);
|
||||
lockoutResetDispatcher, controller, biometricContext);
|
||||
mScheduler = scheduler;
|
||||
mScheduler.init(this);
|
||||
mHandler = handler;
|
||||
|
||||
@@ -130,8 +130,9 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
|
||||
@Override
|
||||
public void onAuthenticated(BiometricAuthenticator.Identifier identifier, boolean authenticated,
|
||||
ArrayList<Byte> hardwareAuthToken) {
|
||||
getLogger().logOnAuthenticated(getContext(), authenticated, false /* requireConfirmation */,
|
||||
isCryptoOperation(), getTargetUserId(), false /* isBiometricPrompt */);
|
||||
getLogger().logOnAuthenticated(getContext(), getOperationContext(),
|
||||
authenticated, false /* requireConfirmation */,
|
||||
getTargetUserId(), false /* isBiometricPrompt */);
|
||||
|
||||
// Do not distinguish between success/failures.
|
||||
vibrateSuccess();
|
||||
|
||||
@@ -158,6 +158,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
|
||||
@GuardedBy("mLock")
|
||||
private IUdfpsHbmListener mUdfpsHbmListener;
|
||||
@GuardedBy("mLock")
|
||||
private IBiometricContextListener mBiometricContextListener;
|
||||
|
||||
@GuardedBy("mCurrentRequestAddTilePackages")
|
||||
private final ArrayMap<String, Long> mCurrentRequestAddTilePackages = new ArrayMap<>();
|
||||
@@ -897,6 +899,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
@Override
|
||||
public void setBiometicContextListener(IBiometricContextListener listener) {
|
||||
enforceStatusBarService();
|
||||
synchronized (mLock) {
|
||||
mBiometricContextListener = listener;
|
||||
}
|
||||
if (mBar != null) {
|
||||
try {
|
||||
mBar.setBiometicContextListener(listener);
|
||||
@@ -1327,6 +1332,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
mHandler.post(() -> {
|
||||
synchronized (mLock) {
|
||||
setUdfpsHbmListener(mUdfpsHbmListener);
|
||||
setBiometicContextListener(mBiometricContextListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,18 +19,25 @@ package com.android.server.biometrics.log;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.StatusBarManager;
|
||||
import android.hardware.biometrics.IBiometricContextListener;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.common.OperationReason;
|
||||
import android.hardware.display.AmbientDisplayConfiguration;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.logging.InstanceId;
|
||||
import com.android.internal.statusbar.ISessionListener;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -56,6 +63,10 @@ public class BiometricContextProviderTest {
|
||||
|
||||
@Mock
|
||||
private IStatusBarService mStatusBarService;
|
||||
@Mock
|
||||
private ISessionListener mSessionListener;
|
||||
@Mock
|
||||
private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
||||
|
||||
private OperationContext mOpContext = new OperationContext();
|
||||
private IBiometricContextListener mListener;
|
||||
@@ -63,11 +74,17 @@ public class BiometricContextProviderTest {
|
||||
|
||||
@Before
|
||||
public void setup() throws RemoteException {
|
||||
mProvider = new BiometricContextProvider(mStatusBarService, null /* handler */);
|
||||
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||
mProvider = new BiometricContextProvider(mAmbientDisplayConfiguration, mStatusBarService,
|
||||
null /* handler */);
|
||||
ArgumentCaptor<IBiometricContextListener> captor =
|
||||
ArgumentCaptor.forClass(IBiometricContextListener.class);
|
||||
verify(mStatusBarService).setBiometicContextListener(captor.capture());
|
||||
mListener = captor.getValue();
|
||||
ArgumentCaptor<ISessionListener> sessionCaptor =
|
||||
ArgumentCaptor.forClass(ISessionListener.class);
|
||||
verify(mStatusBarService).registerSessionListener(anyInt(), sessionCaptor.capture());
|
||||
mSessionListener = sessionCaptor.getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,6 +93,12 @@ public class BiometricContextProviderTest {
|
||||
assertThat(mProvider.isAoD()).isTrue();
|
||||
mListener.onDozeChanged(false);
|
||||
assertThat(mProvider.isAoD()).isFalse();
|
||||
|
||||
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(false);
|
||||
mListener.onDozeChanged(true);
|
||||
assertThat(mProvider.isAoD()).isFalse();
|
||||
mListener.onDozeChanged(false);
|
||||
assertThat(mProvider.isAoD()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,4 +135,84 @@ public class BiometricContextProviderTest {
|
||||
verify(emptyConsumer, never()).accept(any());
|
||||
verify(nonEmptyConsumer).accept(same(mOpContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSessionId() throws RemoteException {
|
||||
final int keyguardSessionId = 10;
|
||||
final int bpSessionId = 20;
|
||||
|
||||
assertThat(mProvider.getBiometricPromptSessionId()).isNull();
|
||||
assertThat(mProvider.getKeyguardEntrySessionId()).isNull();
|
||||
|
||||
mSessionListener.onSessionStarted(StatusBarManager.SESSION_KEYGUARD,
|
||||
InstanceId.fakeInstanceId(keyguardSessionId));
|
||||
|
||||
assertThat(mProvider.getBiometricPromptSessionId()).isNull();
|
||||
assertThat(mProvider.getKeyguardEntrySessionId()).isEqualTo(keyguardSessionId);
|
||||
|
||||
mSessionListener.onSessionStarted(StatusBarManager.SESSION_BIOMETRIC_PROMPT,
|
||||
InstanceId.fakeInstanceId(bpSessionId));
|
||||
|
||||
assertThat(mProvider.getBiometricPromptSessionId()).isEqualTo(bpSessionId);
|
||||
assertThat(mProvider.getKeyguardEntrySessionId()).isEqualTo(keyguardSessionId);
|
||||
|
||||
mSessionListener.onSessionEnded(StatusBarManager.SESSION_KEYGUARD,
|
||||
InstanceId.fakeInstanceId(keyguardSessionId));
|
||||
|
||||
assertThat(mProvider.getBiometricPromptSessionId()).isEqualTo(bpSessionId);
|
||||
assertThat(mProvider.getKeyguardEntrySessionId()).isNull();
|
||||
|
||||
mSessionListener.onSessionEnded(StatusBarManager.SESSION_BIOMETRIC_PROMPT,
|
||||
InstanceId.fakeInstanceId(bpSessionId));
|
||||
|
||||
assertThat(mProvider.getBiometricPromptSessionId()).isNull();
|
||||
assertThat(mProvider.getKeyguardEntrySessionId()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() throws RemoteException {
|
||||
mListener.onDozeChanged(false);
|
||||
OperationContext context = mProvider.updateContext(mOpContext, false /* crypto */);
|
||||
|
||||
// default state when nothing has been set
|
||||
assertThat(context).isSameInstanceAs(mOpContext);
|
||||
assertThat(mOpContext.id).isEqualTo(0);
|
||||
assertThat(mOpContext.reason).isEqualTo(OperationReason.UNKNOWN);
|
||||
assertThat(mOpContext.isAoD).isEqualTo(false);
|
||||
assertThat(mOpContext.isCrypto).isEqualTo(false);
|
||||
|
||||
for (int type : List.of(StatusBarManager.SESSION_BIOMETRIC_PROMPT,
|
||||
StatusBarManager.SESSION_KEYGUARD)) {
|
||||
final int id = 40 + type;
|
||||
final boolean aod = (type & 1) == 0;
|
||||
|
||||
mListener.onDozeChanged(aod);
|
||||
mSessionListener.onSessionStarted(type, InstanceId.fakeInstanceId(id));
|
||||
context = mProvider.updateContext(mOpContext, false /* crypto */);
|
||||
assertThat(context).isSameInstanceAs(mOpContext);
|
||||
assertThat(mOpContext.id).isEqualTo(id);
|
||||
assertThat(mOpContext.reason).isEqualTo(reason(type));
|
||||
assertThat(mOpContext.isAoD).isEqualTo(aod);
|
||||
assertThat(mOpContext.isCrypto).isEqualTo(false);
|
||||
|
||||
mSessionListener.onSessionEnded(type, InstanceId.fakeInstanceId(id));
|
||||
}
|
||||
|
||||
context = mProvider.updateContext(mOpContext, false /* crypto */);
|
||||
assertThat(context).isSameInstanceAs(mOpContext);
|
||||
assertThat(mOpContext.id).isEqualTo(0);
|
||||
assertThat(mOpContext.reason).isEqualTo(OperationReason.UNKNOWN);
|
||||
assertThat(mOpContext.isAoD).isEqualTo(false);
|
||||
assertThat(mOpContext.isCrypto).isEqualTo(false);
|
||||
}
|
||||
|
||||
private static byte reason(int type) {
|
||||
if (type == StatusBarManager.SESSION_BIOMETRIC_PROMPT) {
|
||||
return OperationReason.BIOMETRIC_PROMPT;
|
||||
}
|
||||
if (type == StatusBarManager.SESSION_KEYGUARD) {
|
||||
return OperationReason.KEYGUARD;
|
||||
}
|
||||
return OperationReason.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.hardware.Sensor;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.input.InputSensorInfo;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.testing.TestableContext;
|
||||
@@ -68,10 +69,12 @@ public class BiometricLoggerTest {
|
||||
@Mock
|
||||
private BaseClientMonitor mClient;
|
||||
|
||||
private OperationContext mOpContext;
|
||||
private BiometricLogger mLogger;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mOpContext = new OperationContext();
|
||||
mContext.addMockSystemService(SensorManager.class, mSensorManager);
|
||||
when(mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(
|
||||
new Sensor(new InputSensorInfo("", "", 0, 0, Sensor.TYPE_LIGHT, 0, 0, 0, 0, 0, 0,
|
||||
@@ -93,14 +96,13 @@ public class BiometricLoggerTest {
|
||||
|
||||
final int acquiredInfo = 2;
|
||||
final int vendorCode = 3;
|
||||
final boolean isCrypto = true;
|
||||
final int targetUserId = 9;
|
||||
|
||||
mLogger.logOnAcquired(mContext, acquiredInfo, vendorCode, isCrypto, targetUserId);
|
||||
mLogger.logOnAcquired(mContext, mOpContext, acquiredInfo, vendorCode, targetUserId);
|
||||
|
||||
verify(mSink).acquired(
|
||||
verify(mSink).acquired(eq(mOpContext),
|
||||
eq(DEFAULT_MODALITY), eq(DEFAULT_ACTION), eq(DEFAULT_CLIENT), anyBoolean(),
|
||||
eq(acquiredInfo), eq(vendorCode), eq(isCrypto), eq(targetUserId));
|
||||
eq(acquiredInfo), eq(vendorCode), eq(targetUserId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,17 +111,16 @@ public class BiometricLoggerTest {
|
||||
|
||||
final boolean authenticated = true;
|
||||
final boolean requireConfirmation = false;
|
||||
final boolean isCrypto = false;
|
||||
final int targetUserId = 11;
|
||||
final boolean isBiometricPrompt = true;
|
||||
|
||||
mLogger.logOnAuthenticated(mContext,
|
||||
authenticated, requireConfirmation, isCrypto, targetUserId, isBiometricPrompt);
|
||||
mLogger.logOnAuthenticated(mContext, mOpContext,
|
||||
authenticated, requireConfirmation, targetUserId, isBiometricPrompt);
|
||||
|
||||
verify(mSink).authenticate(
|
||||
verify(mSink).authenticate(eq(mOpContext),
|
||||
eq(DEFAULT_MODALITY), eq(DEFAULT_ACTION), eq(DEFAULT_CLIENT), anyBoolean(),
|
||||
anyLong(), eq(authenticated), anyInt(), eq(requireConfirmation), eq(isCrypto),
|
||||
eq(targetUserId), eq(isBiometricPrompt), anyFloat());
|
||||
anyLong(), anyInt(), eq(requireConfirmation),
|
||||
eq(targetUserId), anyFloat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,14 +144,13 @@ public class BiometricLoggerTest {
|
||||
|
||||
final int error = 7;
|
||||
final int vendorCode = 11;
|
||||
final boolean isCrypto = false;
|
||||
final int targetUserId = 9;
|
||||
|
||||
mLogger.logOnError(mContext, error, vendorCode, isCrypto, targetUserId);
|
||||
mLogger.logOnError(mContext, mOpContext, error, vendorCode, targetUserId);
|
||||
|
||||
verify(mSink).error(
|
||||
verify(mSink).error(eq(mOpContext),
|
||||
eq(DEFAULT_MODALITY), eq(DEFAULT_ACTION), eq(DEFAULT_CLIENT), anyBoolean(),
|
||||
anyLong(), eq(error), eq(vendorCode), eq(isCrypto), eq(targetUserId));
|
||||
anyLong(), eq(error), eq(vendorCode), eq(targetUserId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -175,38 +175,34 @@ public class BiometricLoggerTest {
|
||||
|
||||
private void testDisabledMetrics(boolean isBadConfig) {
|
||||
mLogger.disableMetrics();
|
||||
mLogger.logOnAcquired(mContext,
|
||||
mLogger.logOnAcquired(mContext, mOpContext,
|
||||
0 /* acquiredInfo */,
|
||||
1 /* vendorCode */,
|
||||
true /* isCrypto */,
|
||||
8 /* targetUserId */);
|
||||
mLogger.logOnAuthenticated(mContext,
|
||||
mLogger.logOnAuthenticated(mContext, mOpContext,
|
||||
true /* authenticated */,
|
||||
true /* requireConfirmation */,
|
||||
false /* isCrypto */,
|
||||
4 /* targetUserId */,
|
||||
true/* isBiometricPrompt */);
|
||||
mLogger.logOnEnrolled(2 /* targetUserId */,
|
||||
10 /* latency */,
|
||||
true /* enrollSuccessful */);
|
||||
mLogger.logOnError(mContext,
|
||||
mLogger.logOnError(mContext, mOpContext,
|
||||
4 /* error */,
|
||||
0 /* vendorCode */,
|
||||
false /* isCrypto */,
|
||||
6 /* targetUserId */);
|
||||
|
||||
verify(mSink, never()).acquired(
|
||||
verify(mSink, never()).acquired(eq(mOpContext),
|
||||
anyInt(), anyInt(), anyInt(), anyBoolean(),
|
||||
anyInt(), anyInt(), anyBoolean(), anyInt());
|
||||
verify(mSink, never()).authenticate(
|
||||
anyInt(), anyInt(), anyInt());
|
||||
verify(mSink, never()).authenticate(eq(mOpContext),
|
||||
anyInt(), anyInt(), anyInt(), anyBoolean(),
|
||||
anyLong(), anyBoolean(), anyInt(), anyBoolean(),
|
||||
anyBoolean(), anyInt(), anyBoolean(), anyFloat());
|
||||
anyLong(), anyInt(), anyBoolean(), anyInt(), anyFloat());
|
||||
verify(mSink, never()).enroll(
|
||||
anyInt(), anyInt(), anyInt(), anyInt(), anyLong(), anyBoolean(), anyFloat());
|
||||
verify(mSink, never()).error(
|
||||
verify(mSink, never()).error(eq(mOpContext),
|
||||
anyInt(), anyInt(), anyInt(), anyBoolean(),
|
||||
anyLong(), anyInt(), anyInt(), anyBoolean(), anyInt());
|
||||
anyLong(), anyInt(), anyInt(), anyInt());
|
||||
|
||||
mLogger.logUnknownEnrollmentInFramework();
|
||||
mLogger.logUnknownEnrollmentInHal();
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
package com.android.server.biometrics.sensors.face.aidl;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -47,6 +48,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -57,7 +59,6 @@ public class FaceAuthenticationClientTest {
|
||||
|
||||
private static final int USER_ID = 12;
|
||||
private static final long OP_ID = 32;
|
||||
private static final boolean HAS_AOD = true;
|
||||
|
||||
@Rule
|
||||
public final TestableContext mContext = new TestableContext(
|
||||
@@ -89,7 +90,8 @@ public class FaceAuthenticationClientTest {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mBiometricContext.isAoD()).thenReturn(HAS_AOD);
|
||||
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
|
||||
i -> i.getArgument(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,11 +108,12 @@ public class FaceAuthenticationClientTest {
|
||||
final FaceAuthenticationClient client = createClient(2);
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
|
||||
InOrder order = inOrder(mHal, mBiometricContext);
|
||||
order.verify(mBiometricContext).updateContext(
|
||||
mOperationContextCaptor.capture(), anyBoolean());
|
||||
order.verify(mHal).authenticateWithContext(
|
||||
eq(OP_ID), same(mOperationContextCaptor.getValue()));
|
||||
verify(mHal, never()).authenticate(anyLong());
|
||||
|
||||
final OperationContext opContext = mOperationContextCaptor.getValue();
|
||||
assertThat(opContext.isAoD).isEqualTo(HAS_AOD);
|
||||
}
|
||||
|
||||
private FaceAuthenticationClient createClient(int version) throws RemoteException {
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
package com.android.server.biometrics.sensors.face.aidl;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -43,6 +44,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -52,7 +54,6 @@ import org.mockito.junit.MockitoRule;
|
||||
public class FaceDetectClientTest {
|
||||
|
||||
private static final int USER_ID = 12;
|
||||
private static final boolean HAS_AOD = true;
|
||||
|
||||
@Rule
|
||||
public final TestableContext mContext = new TestableContext(
|
||||
@@ -80,7 +81,8 @@ public class FaceDetectClientTest {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mBiometricContext.isAoD()).thenReturn(HAS_AOD);
|
||||
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
|
||||
i -> i.getArgument(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,11 +99,11 @@ public class FaceDetectClientTest {
|
||||
final FaceDetectClient client = createClient(2);
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).detectInteractionWithContext(mOperationContextCaptor.capture());
|
||||
InOrder order = inOrder(mHal, mBiometricContext);
|
||||
order.verify(mBiometricContext).updateContext(
|
||||
mOperationContextCaptor.capture(), anyBoolean());
|
||||
order.verify(mHal).detectInteractionWithContext(same(mOperationContextCaptor.getValue()));
|
||||
verify(mHal, never()).detectInteraction();
|
||||
|
||||
final OperationContext opContext = mOperationContextCaptor.getValue();
|
||||
assertThat(opContext.isAoD).isEqualTo(HAS_AOD);
|
||||
}
|
||||
|
||||
private FaceDetectClient createClient(int version) throws RemoteException {
|
||||
|
||||
@@ -17,11 +17,15 @@
|
||||
package com.android.server.biometrics.sensors.face.aidl;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyByte;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
import android.hardware.face.Face;
|
||||
import android.os.IBinder;
|
||||
@@ -38,8 +42,12 @@ import com.android.server.biometrics.sensors.BiometricUtils;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallback;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -71,10 +79,18 @@ public class FaceEnrollClientTest {
|
||||
private ClientMonitorCallback mCallback;
|
||||
@Mock
|
||||
private Sensor.HalSessionCallback mHalSessionCallback;
|
||||
@Captor
|
||||
private ArgumentCaptor<OperationContext> mOperationContextCaptor;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
|
||||
i -> i.getArgument(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enrollNoContext_v1() throws RemoteException {
|
||||
final FaceEnrollClient client = createClient(1);
|
||||
@@ -89,7 +105,11 @@ public class FaceEnrollClientTest {
|
||||
final FaceEnrollClient client = createClient(2);
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).enrollWithContext(any(), anyByte(), any(), any(), any());
|
||||
InOrder order = inOrder(mHal, mBiometricContext);
|
||||
order.verify(mBiometricContext).updateContext(
|
||||
mOperationContextCaptor.capture(), anyBoolean());
|
||||
order.verify(mHal).enrollWithContext(any(), anyByte(), any(), any(),
|
||||
same(mOperationContextCaptor.getValue()));
|
||||
verify(mHal, never()).enroll(any(), anyByte(), any(), any());
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.BiometricScheduler;
|
||||
import com.android.server.biometrics.sensors.HalClientMonitor;
|
||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||
@@ -60,6 +61,8 @@ public class FaceProviderTest {
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private IFace mDaemon;
|
||||
@Mock
|
||||
private BiometricContext mBiometricContext;
|
||||
|
||||
private SensorProps[] mSensorProps;
|
||||
private LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@@ -89,7 +92,7 @@ public class FaceProviderTest {
|
||||
mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
|
||||
|
||||
mFaceProvider = new TestableFaceProvider(mDaemon, mContext, mSensorProps, TAG,
|
||||
mLockoutResetDispatcher);
|
||||
mLockoutResetDispatcher, mBiometricContext);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@@ -139,8 +142,9 @@ public class FaceProviderTest {
|
||||
@NonNull Context context,
|
||||
@NonNull SensorProps[] props,
|
||||
@NonNull String halInstanceName,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher) {
|
||||
super(context, props, halInstanceName, lockoutResetDispatcher);
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
super(context, props, halInstanceName, lockoutResetDispatcher, biometricContext);
|
||||
mDaemon = daemon;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import android.platform.test.annotations.Presubmit;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.BiometricScheduler;
|
||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||
|
||||
@@ -70,6 +71,8 @@ public class Face10Test {
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private BiometricScheduler mScheduler;
|
||||
@Mock
|
||||
private BiometricContext mBiometricContext;
|
||||
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
private LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@@ -100,7 +103,8 @@ public class Face10Test {
|
||||
resetLockoutRequiresChallenge);
|
||||
|
||||
Face10.sSystemClock = Clock.fixed(Instant.ofEpochMilli(100), ZoneId.of("PST"));
|
||||
mFace10 = new Face10(mContext, sensorProps, mLockoutResetDispatcher, mHandler, mScheduler);
|
||||
mFace10 = new Face10(mContext, sensorProps, mLockoutResetDispatcher, mHandler, mScheduler,
|
||||
mBiometricContext);
|
||||
mBinder = new Binder();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ import static org.mockito.Mockito.anyFloat;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.anyLong;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -56,6 +58,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -68,7 +71,6 @@ public class FingerprintAuthenticationClientTest {
|
||||
|
||||
private static final int USER_ID = 8;
|
||||
private static final long OP_ID = 7;
|
||||
private static final boolean HAS_AOD = true;
|
||||
private static final int POINTER_ID = 0;
|
||||
private static final int TOUCH_X = 8;
|
||||
private static final int TOUCH_Y = 20;
|
||||
@@ -107,6 +109,8 @@ public class FingerprintAuthenticationClientTest {
|
||||
private ArgumentCaptor<OperationContext> mOperationContextCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<PointerContext> mPointerContextCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<Consumer<OperationContext>> mContextInjector;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@@ -115,7 +119,8 @@ public class FingerprintAuthenticationClientTest {
|
||||
public void setup() {
|
||||
when(mBiometricLogger.createALSCallback(anyBoolean())).thenAnswer(i ->
|
||||
new CallbackWithProbe<>(mLuxProbe, i.getArgument(0)));
|
||||
when(mBiometricContext.isAoD()).thenReturn(HAS_AOD);
|
||||
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
|
||||
i -> i.getArgument(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -132,11 +137,12 @@ public class FingerprintAuthenticationClientTest {
|
||||
final FingerprintAuthenticationClient client = createClient(2);
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
|
||||
InOrder order = inOrder(mHal, mBiometricContext);
|
||||
order.verify(mBiometricContext).updateContext(
|
||||
mOperationContextCaptor.capture(), anyBoolean());
|
||||
order.verify(mHal).authenticateWithContext(
|
||||
eq(OP_ID), same(mOperationContextCaptor.getValue()));
|
||||
verify(mHal, never()).authenticate(anyLong());
|
||||
|
||||
final OperationContext opContext = mOperationContextCaptor.getValue();
|
||||
assertThat(opContext.isAoD).isEqualTo(HAS_AOD);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -204,6 +210,23 @@ public class FingerprintAuthenticationClientTest {
|
||||
verify(mLuxProbe, times(2)).enable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notifyHalWhenContextChanges() throws RemoteException {
|
||||
final FingerprintAuthenticationClient client = createClient();
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
|
||||
OperationContext opContext = mOperationContextCaptor.getValue();
|
||||
|
||||
// fake an update to the context
|
||||
verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
|
||||
mContextInjector.getValue().accept(opContext);
|
||||
verify(mHal).onContextChanged(eq(opContext));
|
||||
|
||||
client.stopHalOperation();
|
||||
verify(mBiometricContext).unsubscribe(same(opContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showHideOverlay_cancel() throws RemoteException {
|
||||
showHideOverlay(c -> c.cancel());
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
package com.android.server.biometrics.sensors.fingerprint.aidl;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -42,6 +45,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -51,7 +55,6 @@ import org.mockito.junit.MockitoRule;
|
||||
public class FingerprintDetectClientTest {
|
||||
|
||||
private static final int USER_ID = 8;
|
||||
private static final boolean HAS_AOD = true;
|
||||
|
||||
@Rule
|
||||
public final TestableContext mContext = new TestableContext(
|
||||
@@ -81,7 +84,8 @@ public class FingerprintDetectClientTest {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mBiometricContext.isAoD()).thenReturn(HAS_AOD);
|
||||
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
|
||||
i -> i.getArgument(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,7 +104,10 @@ public class FingerprintDetectClientTest {
|
||||
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).detectInteractionWithContext(mOperationContextCaptor.capture());
|
||||
InOrder order = inOrder(mHal, mBiometricContext);
|
||||
order.verify(mBiometricContext).updateContext(
|
||||
mOperationContextCaptor.capture(), anyBoolean());
|
||||
order.verify(mHal).detectInteractionWithContext(same(mOperationContextCaptor.getValue()));
|
||||
verify(mHal, never()).detectInteraction();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,15 @@ package com.android.server.biometrics.sensors.fingerprint.aidl;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -44,14 +48,18 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.log.BiometricLogger;
|
||||
import com.android.server.biometrics.log.CallbackWithProbe;
|
||||
import com.android.server.biometrics.log.Probe;
|
||||
import com.android.server.biometrics.sensors.BiometricUtils;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallback;
|
||||
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -96,14 +104,26 @@ public class FingerprintEnrollClientTest {
|
||||
private ClientMonitorCallback mCallback;
|
||||
@Mock
|
||||
private Sensor.HalSessionCallback mHalSessionCallback;
|
||||
@Mock
|
||||
private Probe mLuxProbe;
|
||||
@Captor
|
||||
private ArgumentCaptor<OperationContext> mOperationContextCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<PointerContext> mPointerContextCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<Consumer<OperationContext>> mContextInjector;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mBiometricLogger.createALSCallback(anyBoolean())).thenAnswer(i ->
|
||||
new CallbackWithProbe<>(mLuxProbe, i.getArgument(0)));
|
||||
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
|
||||
i -> i.getArgument(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enrollNoContext_v1() throws RemoteException {
|
||||
final FingerprintEnrollClient client = createClient(1);
|
||||
@@ -120,7 +140,10 @@ public class FingerprintEnrollClientTest {
|
||||
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).enrollWithContext(any(), mOperationContextCaptor.capture());
|
||||
InOrder order = inOrder(mHal, mBiometricContext);
|
||||
order.verify(mBiometricContext).updateContext(
|
||||
mOperationContextCaptor.capture(), anyBoolean());
|
||||
order.verify(mHal).enrollWithContext(any(), same(mOperationContextCaptor.getValue()));
|
||||
verify(mHal, never()).enroll(any());
|
||||
}
|
||||
|
||||
@@ -171,6 +194,41 @@ public class FingerprintEnrollClientTest {
|
||||
assertThat(pContext.pointerId).isEqualTo(POINTER_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void luxProbeWhenFingerDown() throws RemoteException {
|
||||
final FingerprintEnrollClient client = createClient();
|
||||
client.start(mCallback);
|
||||
|
||||
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
|
||||
verify(mLuxProbe).enable();
|
||||
|
||||
client.onAcquired(2, 0);
|
||||
verify(mLuxProbe, never()).disable();
|
||||
|
||||
client.onPointerUp();
|
||||
verify(mLuxProbe).disable();
|
||||
|
||||
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
|
||||
verify(mLuxProbe, times(2)).enable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notifyHalWhenContextChanges() throws RemoteException {
|
||||
final FingerprintEnrollClient client = createClient();
|
||||
client.start(mCallback);
|
||||
|
||||
verify(mHal).enrollWithContext(any(), mOperationContextCaptor.capture());
|
||||
OperationContext opContext = mOperationContextCaptor.getValue();
|
||||
|
||||
// fake an update to the context
|
||||
verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
|
||||
mContextInjector.getValue().accept(opContext);
|
||||
verify(mHal).onContextChanged(eq(opContext));
|
||||
|
||||
client.stopHalOperation();
|
||||
verify(mBiometricContext).unsubscribe(same(opContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showHideOverlay_cancel() throws RemoteException {
|
||||
showHideOverlay(c -> c.cancel());
|
||||
|
||||
@@ -40,6 +40,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.BiometricScheduler;
|
||||
import com.android.server.biometrics.sensors.HalClientMonitor;
|
||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||
@@ -71,6 +72,8 @@ public class FingerprintProviderTest {
|
||||
private GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
|
||||
@Mock
|
||||
private FingerprintStateCallback mFingerprintStateCallback;
|
||||
@Mock
|
||||
private BiometricContext mBiometricContext;
|
||||
|
||||
private SensorProps[] mSensorProps;
|
||||
private LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@@ -105,7 +108,7 @@ public class FingerprintProviderTest {
|
||||
|
||||
mFingerprintProvider = new TestableFingerprintProvider(mDaemon, mContext,
|
||||
mFingerprintStateCallback, mSensorProps, TAG, mLockoutResetDispatcher,
|
||||
mGestureAvailabilityDispatcher);
|
||||
mGestureAvailabilityDispatcher, mBiometricContext);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@@ -157,9 +160,10 @@ public class FingerprintProviderTest {
|
||||
@NonNull SensorProps[] props,
|
||||
@NonNull String halInstanceName,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
|
||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
super(context, fingerprintStateCallback, props, halInstanceName, lockoutResetDispatcher,
|
||||
gestureAvailabilityDispatcher);
|
||||
gestureAvailabilityDispatcher, biometricContext);
|
||||
mDaemon = daemon;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.BiometricScheduler;
|
||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||
import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
|
||||
@@ -70,6 +71,8 @@ public class Fingerprint21Test {
|
||||
private BiometricScheduler mScheduler;
|
||||
@Mock
|
||||
private FingerprintStateCallback mFingerprintStateCallback;
|
||||
@Mock
|
||||
private BiometricContext mBiometricContext;
|
||||
|
||||
private LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
private Fingerprint21 mFingerprint21;
|
||||
@@ -101,7 +104,7 @@ public class Fingerprint21Test {
|
||||
|
||||
mFingerprint21 = new TestableFingerprint21(mContext, mFingerprintStateCallback, sensorProps,
|
||||
mScheduler, new Handler(Looper.getMainLooper()), mLockoutResetDispatcher,
|
||||
mHalResultController);
|
||||
mHalResultController, mBiometricContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,9 +129,10 @@ public class Fingerprint21Test {
|
||||
@NonNull FingerprintSensorPropertiesInternal sensorProps,
|
||||
@NonNull BiometricScheduler scheduler, @NonNull Handler handler,
|
||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||
@NonNull HalResultController controller) {
|
||||
@NonNull HalResultController controller,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
super(context, fingerprintStateCallback, sensorProps, scheduler, handler,
|
||||
lockoutResetDispatcher, controller);
|
||||
lockoutResetDispatcher, controller, biometricContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user