Merge "Add logging for Biometrics"

This commit is contained in:
Kevin Chyn
2019-02-01 02:00:14 +00:00
committed by Android (Google) Code Review
11 changed files with 383 additions and 18 deletions

View File

@@ -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"

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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());

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;
}
}