Merge "Add logging for Biometrics"
This commit is contained in:
@@ -19,6 +19,7 @@ package com.android.server.biometrics;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.security.KeyStore;
|
||||
@@ -71,6 +72,11 @@ public abstract class AuthenticationClient extends ClientMonitor {
|
||||
stop(false /* initiatedByClient */);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsAction() {
|
||||
return BiometricsProtoEnums.ACTION_AUTHENTICATE;
|
||||
}
|
||||
|
||||
public boolean isBiometricPrompt() {
|
||||
return getCookie() != 0;
|
||||
}
|
||||
@@ -79,9 +85,17 @@ public abstract class AuthenticationClient extends ClientMonitor {
|
||||
return mRequireConfirmation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCryptoOperation() {
|
||||
return mOpId != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
|
||||
boolean authenticated, ArrayList<Byte> token) {
|
||||
super.logOnAuthenticated(authenticated, mRequireConfirmation, getTargetUserId(),
|
||||
isBiometricPrompt());
|
||||
|
||||
final BiometricServiceBase.ServiceListener listener = getListener();
|
||||
|
||||
mMetricsLogger.action(mMetrics.actionBiometricAuth(), authenticated);
|
||||
@@ -142,10 +156,7 @@ public abstract class AuthenticationClient extends ClientMonitor {
|
||||
final int errorCode = lockoutMode == LOCKOUT_TIMED
|
||||
? BiometricConstants.BIOMETRIC_ERROR_LOCKOUT
|
||||
: BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
|
||||
if (listener != null) {
|
||||
listener.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */,
|
||||
getCookie());
|
||||
}
|
||||
onError(getHalDeviceId(), errorCode, 0 /* vendorCode */);
|
||||
} else {
|
||||
// Don't send onAuthenticationFailed if we're in lockout, it causes a
|
||||
// janky UI on Keyguard/BiometricPrompt since "authentication failed"
|
||||
|
||||
@@ -41,6 +41,7 @@ import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricPrompt;
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
|
||||
import android.hardware.biometrics.IBiometricService;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiver;
|
||||
@@ -64,6 +65,7 @@ import android.security.KeyStore;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
import android.util.StatsLog;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
@@ -309,6 +311,7 @@ public class BiometricService extends SystemService {
|
||||
// Continue authentication with the same modality/modalities after "try again" is
|
||||
// pressed
|
||||
final int mModality;
|
||||
final boolean mRequireConfirmation;
|
||||
|
||||
// The current state, which can be either idle, called, or started
|
||||
private int mState = STATE_AUTH_IDLE;
|
||||
@@ -316,10 +319,13 @@ public class BiometricService extends SystemService {
|
||||
// the authentication.
|
||||
byte[] mTokenEscrow;
|
||||
|
||||
// Timestamp when hardware authentication occurred
|
||||
private long mAuthenticatedTimeMs;
|
||||
|
||||
AuthSession(HashMap<Integer, Integer> modalities, IBinder token, long sessionId,
|
||||
int userId, IBiometricServiceReceiver receiver, String opPackageName,
|
||||
Bundle bundle, int callingUid, int callingPid, int callingUserId,
|
||||
int modality) {
|
||||
int modality, boolean requireConfirmation) {
|
||||
mModalitiesWaiting = modalities;
|
||||
mToken = token;
|
||||
mSessionId = sessionId;
|
||||
@@ -331,6 +337,11 @@ public class BiometricService extends SystemService {
|
||||
mCallingPid = callingPid;
|
||||
mCallingUserId = callingUserId;
|
||||
mModality = modality;
|
||||
mRequireConfirmation = requireConfirmation;
|
||||
}
|
||||
|
||||
boolean isCrypto() {
|
||||
return mSessionId != 0;
|
||||
}
|
||||
|
||||
boolean containsCookie(int cookie) {
|
||||
@@ -412,6 +423,7 @@ public class BiometricService extends SystemService {
|
||||
mCurrentAuthSession.mState = STATE_AUTH_IDLE;
|
||||
mCurrentAuthSession = null;
|
||||
} else {
|
||||
mCurrentAuthSession.mAuthenticatedTimeMs = System.currentTimeMillis();
|
||||
// Store the auth token and submit it to keystore after the confirmation
|
||||
// button has been pressed.
|
||||
mCurrentAuthSession.mTokenEscrow = token;
|
||||
@@ -557,6 +569,8 @@ public class BiometricService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
logDialogDismissed(reason);
|
||||
|
||||
if (reason != BiometricPrompt.DISMISSED_REASON_POSITIVE) {
|
||||
// Positive button is used by passive modalities as a "confirm" button,
|
||||
// do not send to client
|
||||
@@ -599,6 +613,77 @@ public class BiometricService extends SystemService {
|
||||
mCurrentAuthSession.mModality);
|
||||
});
|
||||
}
|
||||
|
||||
private void logDialogDismissed(int reason) {
|
||||
if (reason == BiometricPrompt.DISMISSED_REASON_POSITIVE) {
|
||||
// Explicit auth, authentication confirmed.
|
||||
// Latency in this case is authenticated -> confirmed. <Biometric>Service
|
||||
// should have the first half (first acquired -> authenticated).
|
||||
final long latency = System.currentTimeMillis()
|
||||
- mCurrentAuthSession.mAuthenticatedTimeMs;
|
||||
|
||||
if (LoggableMonitor.DEBUG) {
|
||||
Slog.v(LoggableMonitor.TAG, "Confirmed! Modality: " + statsModality()
|
||||
+ ", User: " + mCurrentAuthSession.mUserId
|
||||
+ ", IsCrypto: " + mCurrentAuthSession.isCrypto()
|
||||
+ ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
|
||||
+ ", RequireConfirmation: "
|
||||
+ mCurrentAuthSession.mRequireConfirmation
|
||||
+ ", State: " + StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED
|
||||
+ ", Latency: " + latency);
|
||||
}
|
||||
|
||||
StatsLog.write(StatsLog.BIOMETRIC_AUTHENTICATED,
|
||||
statsModality(),
|
||||
mCurrentAuthSession.mUserId,
|
||||
mCurrentAuthSession.isCrypto(),
|
||||
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
mCurrentAuthSession.mRequireConfirmation,
|
||||
StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
|
||||
latency);
|
||||
} else {
|
||||
int error = reason == BiometricPrompt.DISMISSED_REASON_NEGATIVE
|
||||
? BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON
|
||||
: reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL
|
||||
? BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED
|
||||
: 0;
|
||||
if (LoggableMonitor.DEBUG) {
|
||||
Slog.v(LoggableMonitor.TAG, "Dismissed! Modality: " + statsModality()
|
||||
+ ", User: " + mCurrentAuthSession.mUserId
|
||||
+ ", IsCrypto: " + mCurrentAuthSession.isCrypto()
|
||||
+ ", Action: " + BiometricsProtoEnums.ACTION_AUTHENTICATE
|
||||
+ ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
|
||||
+ ", Error: " + error);
|
||||
}
|
||||
// Auth canceled
|
||||
StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
|
||||
statsModality(),
|
||||
mCurrentAuthSession.mUserId,
|
||||
mCurrentAuthSession.isCrypto(),
|
||||
BiometricsProtoEnums.ACTION_AUTHENTICATE,
|
||||
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
error,
|
||||
0 /* vendorCode */);
|
||||
}
|
||||
}
|
||||
|
||||
private int statsModality() {
|
||||
int modality = 0;
|
||||
if (mCurrentAuthSession == null) {
|
||||
return BiometricsProtoEnums.MODALITY_UNKNOWN;
|
||||
}
|
||||
if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_FINGERPRINT)
|
||||
!= 0) {
|
||||
modality |= BiometricsProtoEnums.MODALITY_FINGERPRINT;
|
||||
}
|
||||
if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_IRIS) != 0) {
|
||||
modality |= BiometricsProtoEnums.MODALITY_IRIS;
|
||||
}
|
||||
if ((mCurrentAuthSession.mModality & BiometricAuthenticator.TYPE_FACE) != 0) {
|
||||
modality |= BiometricsProtoEnums.MODALITY_FACE;
|
||||
}
|
||||
return modality;
|
||||
}
|
||||
};
|
||||
|
||||
@Override // Binder call
|
||||
@@ -818,7 +903,11 @@ public class BiometricService extends SystemService {
|
||||
try {
|
||||
boolean requireConfirmation = bundle.getBoolean(
|
||||
BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true /* default */);
|
||||
|
||||
if ((modality & TYPE_FACE) != 0) {
|
||||
// Check if the user has forced confirmation to be required in Settings.
|
||||
requireConfirmation = requireConfirmation
|
||||
|| mSettingObserver.getFaceAlwaysRequireConfirmation();
|
||||
}
|
||||
// Generate random cookies to pass to the services that should prepare to start
|
||||
// authenticating. Store the cookie here and wait for all services to "ack"
|
||||
// with the cookie. Once all cookies are received, we can show the prompt
|
||||
@@ -830,7 +919,7 @@ public class BiometricService extends SystemService {
|
||||
authenticators.put(modality, cookie);
|
||||
mPendingAuthSession = new AuthSession(authenticators, token, sessionId, userId,
|
||||
receiver, opPackageName, bundle, callingUid, callingPid, callingUserId,
|
||||
modality);
|
||||
modality, requireConfirmation);
|
||||
mPendingAuthSession.mState = STATE_AUTH_CALLED;
|
||||
// No polymorphism :(
|
||||
if ((modality & TYPE_FINGERPRINT) != 0) {
|
||||
@@ -842,9 +931,6 @@ public class BiometricService extends SystemService {
|
||||
Slog.w(TAG, "Iris unsupported");
|
||||
}
|
||||
if ((modality & TYPE_FACE) != 0) {
|
||||
// Check if the user has forced confirmation to be required in Settings.
|
||||
requireConfirmation = requireConfirmation
|
||||
|| mSettingObserver.getFaceAlwaysRequireConfirmation();
|
||||
mFaceService.prepareForAuthentication(requireConfirmation,
|
||||
token, sessionId, userId, mInternalReceiver, opPackageName,
|
||||
cookie, callingUid, callingPid, callingUserId);
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.IBiometricService;
|
||||
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
|
||||
@@ -55,6 +56,7 @@ import android.os.UserManager;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.StatsLog;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
@@ -220,8 +222,16 @@ public abstract class BiometricServiceBase extends SystemService
|
||||
*/
|
||||
protected void notifyClientActiveCallbacks(boolean isActive) {}
|
||||
|
||||
protected abstract int statsModality();
|
||||
|
||||
protected abstract class AuthenticationClientImpl extends AuthenticationClient {
|
||||
|
||||
// Used to check if the public API that was invoked was from FingerprintManager. Only
|
||||
// to be overridden by FingerprintService.
|
||||
protected boolean isFingerprint() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public AuthenticationClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
|
||||
IBinder token, ServiceListener listener, int targetUserId, int groupId, long opId,
|
||||
boolean restricted, String owner, int cookie, boolean requireConfirmation) {
|
||||
@@ -229,6 +239,19 @@ public abstract class BiometricServiceBase extends SystemService
|
||||
groupId, opId, restricted, owner, cookie, requireConfirmation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsClient() {
|
||||
if (isKeyguard(getOwnerString())) {
|
||||
return BiometricsProtoEnums.CLIENT_KEYGUARD;
|
||||
} else if (isBiometricPrompt()) {
|
||||
return BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT;
|
||||
} else if (isFingerprint()) {
|
||||
return BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER;
|
||||
} else {
|
||||
return BiometricsProtoEnums.CLIENT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
try {
|
||||
@@ -296,7 +319,7 @@ public abstract class BiometricServiceBase extends SystemService
|
||||
}
|
||||
}
|
||||
|
||||
protected class RemovalClientImpl extends RemovalClient {
|
||||
protected abstract class RemovalClientImpl extends RemovalClient {
|
||||
private boolean mShouldNotify;
|
||||
|
||||
public RemovalClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
|
||||
@@ -318,7 +341,7 @@ public abstract class BiometricServiceBase extends SystemService
|
||||
}
|
||||
}
|
||||
|
||||
protected class EnumerateClientImpl extends EnumerateClient {
|
||||
protected abstract class EnumerateClientImpl extends EnumerateClient {
|
||||
|
||||
public EnumerateClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
|
||||
IBinder token, ServiceListener listener, int groupId, int userId,
|
||||
@@ -600,6 +623,8 @@ public abstract class BiometricServiceBase extends SystemService
|
||||
mHALDeathCount++;
|
||||
handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
|
||||
0 /*vendorCode */);
|
||||
|
||||
StatsLog.write(StatsLog.BIOMETRIC_HAL_DEATH_REPORTED, statsModality());
|
||||
}
|
||||
|
||||
protected ClientMonitor getCurrentClient() {
|
||||
@@ -653,7 +678,6 @@ public abstract class BiometricServiceBase extends SystemService
|
||||
} else {
|
||||
updateActiveGroup(mCurrentUserId, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import java.util.NoSuchElementException;
|
||||
* the current client. Subclasses are responsible for coordinating the interaction with
|
||||
* the biometric's HAL for the specific action (e.g. authenticate, enroll, enumerate, etc.).
|
||||
*/
|
||||
public abstract class ClientMonitor implements IBinder.DeathRecipient {
|
||||
public abstract class ClientMonitor extends LoggableMonitor implements IBinder.DeathRecipient {
|
||||
protected static final int ERROR_ESRCH = 3; // Likely HAL is dead. See errno.h.
|
||||
protected static final boolean DEBUG = BiometricServiceBase.DEBUG;
|
||||
private static final AudioAttributes FINGERPRINT_SONFICATION_ATTRIBUTES =
|
||||
@@ -157,6 +157,7 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient {
|
||||
* @return true if client should be removed
|
||||
*/
|
||||
public boolean onAcquired(int acquiredInfo, int vendorCode) {
|
||||
super.logOnAcquired(acquiredInfo, vendorCode, getTargetUserId());
|
||||
try {
|
||||
if (mListener != null) {
|
||||
mListener.onAcquired(getHalDeviceId(), acquiredInfo, vendorCode);
|
||||
@@ -180,6 +181,7 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient {
|
||||
* @return true if client should be removed
|
||||
*/
|
||||
public boolean onError(long deviceId, int error, int vendorCode) {
|
||||
super.logOnError(error, vendorCode, getTargetUserId());
|
||||
try {
|
||||
if (mListener != null) {
|
||||
mListener.onError(deviceId, error, vendorCode, getCookie());
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.biometrics;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
@@ -50,6 +51,11 @@ public abstract class EnrollClient extends ClientMonitor {
|
||||
mDisabledFeatures = Arrays.copyOf(disabledFeatures, disabledFeatures.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsAction() {
|
||||
return BiometricsProtoEnums.ACTION_ENROLL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEnrollResult(BiometricAuthenticator.Identifier identifier,
|
||||
int remaining) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.biometrics;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
@@ -37,6 +38,11 @@ public abstract class EnumerateClient extends ClientMonitor {
|
||||
owner, 0 /* cookie */);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsAction() {
|
||||
return BiometricsProtoEnums.ACTION_ENUMERATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int start() {
|
||||
// The biometric template ids will be removed when we get confirmation from the HAL
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.biometrics;
|
||||
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.util.Slog;
|
||||
import android.util.StatsLog;
|
||||
|
||||
/**
|
||||
* Abstract class that adds logging functionality to the ClientMonitor classes.
|
||||
*/
|
||||
public abstract class LoggableMonitor {
|
||||
|
||||
public static final String TAG = "BiometricStats";
|
||||
public static final boolean DEBUG = true;
|
||||
|
||||
private long mFirstAcquireTimeMs;
|
||||
|
||||
/**
|
||||
* Only valid for AuthenticationClient.
|
||||
* @return true if the client is authenticating for a crypto operation.
|
||||
*/
|
||||
protected boolean isCryptoOperation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return One of {@link BiometricsProtoEnums} MODALITY_* constants.
|
||||
*/
|
||||
protected abstract int statsModality();
|
||||
|
||||
/**
|
||||
* Action == enroll, authenticate, remove, enumerate.
|
||||
* @return One of {@link BiometricsProtoEnums} ACTION_* constants.
|
||||
*/
|
||||
protected abstract int statsAction();
|
||||
|
||||
/**
|
||||
* Only matters for AuthenticationClient. Should only be overridden in
|
||||
* {@link BiometricServiceBase}, which determines if a client is for BiometricPrompt, Keyguard,
|
||||
* etc.
|
||||
* @return one of {@link BiometricsProtoEnums} CLIENT_* constants.
|
||||
*/
|
||||
protected int statsClient() {
|
||||
return BiometricsProtoEnums.CLIENT_UNKNOWN;
|
||||
}
|
||||
|
||||
protected final void logOnAcquired(int acquiredInfo, int vendorCode, int targetUserId) {
|
||||
if (statsModality() == BiometricsProtoEnums.MODALITY_FACE) {
|
||||
if (acquiredInfo == FaceManager.FACE_ACQUIRED_START) {
|
||||
mFirstAcquireTimeMs = System.currentTimeMillis();
|
||||
}
|
||||
} else if (acquiredInfo == BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
|
||||
if (mFirstAcquireTimeMs == 0) {
|
||||
mFirstAcquireTimeMs = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Acquired! Modality: " + statsModality()
|
||||
+ ", User: " + targetUserId
|
||||
+ ", IsCrypto: " + isCryptoOperation()
|
||||
+ ", Action: " + statsAction()
|
||||
+ ", Client: " + statsClient()
|
||||
+ ", AcquiredInfo: " + acquiredInfo
|
||||
+ ", VendorCode: " + vendorCode);
|
||||
}
|
||||
StatsLog.write(StatsLog.BIOMETRIC_ACQUIRED,
|
||||
statsModality(),
|
||||
targetUserId,
|
||||
isCryptoOperation(),
|
||||
statsAction(),
|
||||
statsClient(),
|
||||
acquiredInfo,
|
||||
0 /* vendorCode */); // Don't log vendorCode for now
|
||||
}
|
||||
|
||||
protected final void logOnError(int error, int vendorCode, int targetUserId) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Error! Modality: " + statsModality()
|
||||
+ ", User: " + targetUserId
|
||||
+ ", IsCrypto: " + isCryptoOperation()
|
||||
+ ", Action: " + statsAction()
|
||||
+ ", Client: " + statsClient()
|
||||
+ ", Error: " + error
|
||||
+ ", VendorCode: " + vendorCode);
|
||||
}
|
||||
StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
|
||||
statsModality(),
|
||||
targetUserId,
|
||||
isCryptoOperation(),
|
||||
statsAction(),
|
||||
statsClient(),
|
||||
error,
|
||||
vendorCode);
|
||||
}
|
||||
|
||||
protected final void logOnAuthenticated(boolean authenticated, boolean requireConfirmation,
|
||||
int targetUserId, boolean isBiometricPrompt) {
|
||||
int authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__UNKNOWN;
|
||||
if (!authenticated) {
|
||||
authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__REJECTED;
|
||||
} else {
|
||||
// Authenticated
|
||||
if (isBiometricPrompt && requireConfirmation) {
|
||||
authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__PENDING_CONFIRMATION;
|
||||
} else {
|
||||
authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED;
|
||||
}
|
||||
}
|
||||
|
||||
// Only valid if we have a first acquired time, otherwise set to -1
|
||||
final long latency = mFirstAcquireTimeMs != 0
|
||||
? (System.currentTimeMillis() - mFirstAcquireTimeMs)
|
||||
: -1;
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Authenticated! Modality: " + statsModality()
|
||||
+ ", User: " + targetUserId
|
||||
+ ", IsCrypto: " + isCryptoOperation()
|
||||
+ ", Client: " + statsClient()
|
||||
+ ", RequireConfirmation: " + requireConfirmation
|
||||
+ ", State: " + authState
|
||||
+ ", Latency: " + latency);
|
||||
}
|
||||
|
||||
StatsLog.write(StatsLog.BIOMETRIC_AUTHENTICATED,
|
||||
statsModality(),
|
||||
targetUserId,
|
||||
isCryptoOperation(),
|
||||
statsClient(),
|
||||
requireConfirmation,
|
||||
authState,
|
||||
latency);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.android.server.biometrics;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
@@ -42,6 +43,11 @@ public abstract class RemovalClient extends ClientMonitor {
|
||||
mBiometricUtils = utils;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsAction() {
|
||||
return BiometricsProtoEnums.ACTION_REMOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int start() {
|
||||
// The biometric template ids will be removed when we get confirmation from the HAL
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
|
||||
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
|
||||
@@ -90,6 +91,11 @@ public class FaceService extends BiometricServiceBase {
|
||||
super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
|
||||
restricted, owner, cookie, requireConfirmation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FaceService.this.statsModality();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,6 +132,11 @@ public class FaceService extends BiometricServiceBase {
|
||||
public boolean shouldVibrate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FaceService.this.statsModality();
|
||||
}
|
||||
};
|
||||
|
||||
enrollInternal(client, UserHandle.getCallingUserId());
|
||||
@@ -206,7 +217,12 @@ public class FaceService extends BiometricServiceBase {
|
||||
final boolean restricted = isRestricted();
|
||||
final RemovalClientImpl client = new RemovalClientImpl(getContext(), mDaemonWrapper,
|
||||
mHalDeviceId, token, new ServiceListenerImpl(receiver), faceId, 0 /* groupId */,
|
||||
userId, restricted, token.toString());
|
||||
userId, restricted, token.toString()) {
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FaceService.this.statsModality();
|
||||
}
|
||||
};
|
||||
client.setShouldNotifyUserActivity(true);
|
||||
removeInternal(client);
|
||||
}
|
||||
@@ -219,7 +235,12 @@ public class FaceService extends BiometricServiceBase {
|
||||
final boolean restricted = isRestricted();
|
||||
final EnumerateClientImpl client = new EnumerateClientImpl(getContext(), mDaemonWrapper,
|
||||
mHalDeviceId, token, new ServiceListenerImpl(receiver), userId, userId,
|
||||
restricted, getContext().getOpPackageName());
|
||||
restricted, getContext().getOpPackageName()) {
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FaceService.this.statsModality();
|
||||
}
|
||||
};
|
||||
enumerateInternal(client);
|
||||
}
|
||||
|
||||
@@ -770,6 +791,11 @@ public class FaceService extends BiometricServiceBase {
|
||||
// noop for Face.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return BiometricsProtoEnums.MODALITY_FACE;
|
||||
}
|
||||
|
||||
/** Gets the face daemon */
|
||||
private synchronized IBiometricsFace getFaceDaemon() {
|
||||
if (mDaemon == null) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
|
||||
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
|
||||
@@ -101,6 +102,11 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
}
|
||||
|
||||
private final class FingerprintAuthClient extends AuthenticationClientImpl {
|
||||
@Override
|
||||
protected boolean isFingerprint() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public FingerprintAuthClient(Context context,
|
||||
DaemonWrapper daemon, long halDeviceId, IBinder token,
|
||||
ServiceListener listener, int targetUserId, int groupId, long opId,
|
||||
@@ -109,6 +115,11 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
|
||||
restricted, owner, cookie, requireConfirmation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FingerprintService.this.statsModality();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,6 +158,11 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
public boolean shouldVibrate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FingerprintService.this.statsModality();
|
||||
}
|
||||
};
|
||||
|
||||
enrollInternal(client, userId);
|
||||
@@ -225,7 +241,12 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
final boolean restricted = isRestricted();
|
||||
final RemovalClientImpl client = new RemovalClientImpl(getContext(), mDaemonWrapper,
|
||||
mHalDeviceId, token, new ServiceListenerImpl(receiver), fingerId, groupId,
|
||||
userId, restricted, token.toString());
|
||||
userId, restricted, token.toString()) {
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FingerprintService.this.statsModality();
|
||||
}
|
||||
};
|
||||
client.setShouldNotifyUserActivity(true);
|
||||
removeInternal(client);
|
||||
}
|
||||
@@ -238,7 +259,12 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
final boolean restricted = isRestricted();
|
||||
final EnumerateClientImpl client = new EnumerateClientImpl(getContext(), mDaemonWrapper,
|
||||
mHalDeviceId, token, new ServiceListenerImpl(receiver), userId, userId,
|
||||
restricted, getContext().getOpPackageName());
|
||||
restricted, getContext().getOpPackageName()) {
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FingerprintService.this.statsModality();
|
||||
}
|
||||
};
|
||||
enumerateInternal(client);
|
||||
}
|
||||
|
||||
@@ -544,6 +570,11 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
}
|
||||
return remaining == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FingerprintService.this.statsModality();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -558,6 +589,11 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
restricted,
|
||||
owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return FingerprintService.this.statsModality();
|
||||
}
|
||||
}
|
||||
|
||||
private final FingerprintMetrics mFingerprintMetrics = new FingerprintMetrics();
|
||||
@@ -885,6 +921,11 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return BiometricsProtoEnums.MODALITY_FINGERPRINT;
|
||||
}
|
||||
|
||||
/** Gets the fingerprint daemon */
|
||||
private synchronized IBiometricsFingerprint getFingerprintDaemon() {
|
||||
if (mDaemon == null) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.biometrics.iris;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
|
||||
import com.android.server.biometrics.BiometricServiceBase;
|
||||
import com.android.server.biometrics.BiometricUtils;
|
||||
@@ -128,4 +129,9 @@ public class IrisService extends BiometricServiceBase {
|
||||
protected boolean checkAppOps(int uid, String opPackageName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int statsModality() {
|
||||
return BiometricsProtoEnums.MODALITY_IRIS;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user