Loading cmds/statsd/src/atoms.proto +71 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,9 @@ message Atom { VibratorStateChanged vibrator_state_changed = 84; DeferredJobStatsReported deferred_job_stats_reported = 85; ThermalThrottlingStateChanged thermal_throttling = 86; FingerprintAcquired fingerprint_acquired = 87; FingerprintAuthenticated fingerprint_authenticated = 88; FingerprintErrorOccurred fingerprint_error_occurred = 89; } // Pulled events will start at field 10000. Loading Loading @@ -169,6 +172,7 @@ message Atom { CategorySize category_size = 10028; android.service.procstats.ProcessStatsSectionProto proc_stats = 10029; BatteryVoltage battery_voltage = 10030; NumFingerprints num_fingerprints = 10031; } // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above Loading Loading @@ -1832,6 +1836,60 @@ message GenericAtom { optional android.os.statsd.EventType event_id = 2; } /** * Logs when a fingerprint acquire event occurs. * * Logged from: * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java */ message FingerprintAcquired { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // If this acquire is for a crypto fingerprint. // e.g. Secure purchases, unlock password storage. optional bool is_crypto = 2; } /** * Logs when a fingerprint authentication event occurs. * * Logged from: * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java */ message FingerprintAuthenticated { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // If this authentication is for a crypto fingerprint. // e.g. Secure purchases, unlock password storage. optional bool is_crypto = 2; // Whether or not this authentication was successful. optional bool is_authenticated = 3; } /** * Logs when a fingerprint error occurs. * * Logged from: * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java */ message FingerprintErrorOccurred { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // If this error is for a crypto fingerprint. // e.g. Secure purchases, unlock password storage. optional bool is_crypto = 2; enum Error { UNKNOWN = 0; LOCKOUT = 1; PERMANENT_LOCKOUT = 2; } // The type of error. optional Error error = 3; } ////////////////////////////////////////////////////////////////////// // Pulled atoms below this line // ////////////////////////////////////////////////////////////////////// Loading Loading @@ -2408,3 +2466,16 @@ message CategorySize { // Uses System.currentTimeMillis(), which is wall clock time. optional int64 cache_time_millis = 3; } /** * Pulls the number of fingerprints for each user. * * Pulled from StatsCompanionService, which queries FingerprintManager. */ message NumFingerprints { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // Number of fingerprints registered to that user. optional int32 num_fingerprints = 2; } cmds/statsd/src/external/StatsPullerManager.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,12 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}}, // Number of fingerprints registered to each user. {android::util::NUM_FINGERPRINTS, {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS)}}, }; StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) { Loading services/core/java/com/android/server/biometrics/BiometricService.java +4 −1 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ public abstract class BiometricService extends SystemService implements IHwBinde private ClientMonitor mPendingClient; private PerformanceStats mPerformanceStats; protected int mCurrentUserId = UserHandle.USER_NULL; // Tracks if the current authentication makes use of CryptoObjects. protected boolean mIsCrypto; // Normal authentications are tracked by mPerformanceMap. protected HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>(); // Transactions that make use of CryptoObjects are tracked by mCryptoPerformaceMap. Loading Loading @@ -715,6 +717,7 @@ public abstract class BiometricService extends SystemService implements IHwBinde pmap.put(mCurrentUserId, stats); } mPerformanceStats = stats; mIsCrypto = (opId != 0); startAuthentication(client, opPackageName); }); Loading Loading @@ -847,7 +850,7 @@ public abstract class BiometricService extends SystemService implements IHwBinde return mKeyguardPackage.equals(clientPackage); } private int getLockoutMode() { protected int getLockoutMode() { final int currentUser = ActivityManager.getCurrentUser(); final int failedAttempts = mFailedAttempts.get(currentUser, 0); if (failedAttempts >= getFailedAttemptsLockoutPermanent()) { Loading services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java +23 −0 Original line number Diff line number Diff line Loading @@ -50,12 +50,14 @@ import android.os.SELinux; import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; import android.util.StatsLog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.util.DumpUtils; import com.android.server.SystemServerInitThreadPool; import com.android.server.biometrics.AuthenticationClient; import com.android.server.biometrics.BiometricService; import com.android.server.biometrics.BiometricUtils; import com.android.server.biometrics.ClientMonitor; Loading Loading @@ -590,6 +592,11 @@ public class FingerprintService extends BiometricService { public void onAcquired(final long deviceId, final int acquiredInfo, final int vendorCode) { mHandler.post(() -> { FingerprintService.super.handleAcquired(deviceId, acquiredInfo, vendorCode); if (getLockoutMode() == AuthenticationClient.LOCKOUT_NONE && getCurrentClient() instanceof AuthenticationClient) { // Ignore enrollment acquisitions or acquisitions when we are locked out. StatsLog.write(StatsLog.FINGERPRINT_ACQUIRED, mCurrentUserId, mIsCrypto); } }); } Loading @@ -599,6 +606,22 @@ public class FingerprintService extends BiometricService { mHandler.post(() -> { Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId); FingerprintService.super.handleAuthenticated(fp, token); // Send authentication to statsd. final boolean authenticated = fingerId != 0; StatsLog.write(StatsLog.FINGERPRINT_AUTHENTICATED, mCurrentUserId, mIsCrypto, authenticated); if (!authenticated) { // If we failed to authenticate because of a lockout, inform statsd. final int lockoutMode = getLockoutMode(); if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) { StatsLog.write(StatsLog.FINGERPRINT_ERROR_OCCURRED, mCurrentUserId, mIsCrypto, StatsLog.FINGERPRINT_ERROR_OCCURRED__ERROR__LOCKOUT); } else if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) { StatsLog.write(StatsLog.FINGERPRINT_ERROR_OCCURRED, mCurrentUserId, mIsCrypto, StatsLog.FINGERPRINT_ERROR_OCCURRED__ERROR__PERMANENT_LOCKOUT); } } }); } Loading services/core/java/com/android/server/stats/StatsCompanionService.java +27 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.IntentSender; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.hardware.fingerprint.FingerprintManager; import android.net.NetworkStats; import android.net.wifi.IWifiManager; import android.net.wifi.WifiActivityEnergyInfo; Loading Loading @@ -1171,6 +1172,28 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } private void pullNumFingerprints(int tagId, List<StatsLogEventWrapper> pulledData) { FingerprintManager fingerprintManager = mContext.getSystemService(FingerprintManager.class); if (fingerprintManager == null) { return; } UserManager userManager = mContext.getSystemService(UserManager.class); if (userManager == null) { return; } final long token = Binder.clearCallingIdentity(); long elapsedNanos = SystemClock.elapsedRealtimeNanos(); for (UserInfo user : userManager.getUsers()) { final int userId = user.getUserHandle().getIdentifier(); final int numFingerprints = fingerprintManager.getEnrolledFingerprints(userId).size(); StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2 /* fields */); e.writeInt(userId); e.writeInt(numFingerprints); pulledData.add(e); } Binder.restoreCallingIdentity(token); } /** * Pulls various data. */ Loading Loading @@ -1277,6 +1300,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullCategorySize(tagId, ret); break; } case StatsLog.NUM_FINGERPRINTS: { pullNumFingerprints(tagId, ret); break; } default: Slog.w(TAG, "No such tagId data as " + tagId); return null; Loading Loading
cmds/statsd/src/atoms.proto +71 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,9 @@ message Atom { VibratorStateChanged vibrator_state_changed = 84; DeferredJobStatsReported deferred_job_stats_reported = 85; ThermalThrottlingStateChanged thermal_throttling = 86; FingerprintAcquired fingerprint_acquired = 87; FingerprintAuthenticated fingerprint_authenticated = 88; FingerprintErrorOccurred fingerprint_error_occurred = 89; } // Pulled events will start at field 10000. Loading Loading @@ -169,6 +172,7 @@ message Atom { CategorySize category_size = 10028; android.service.procstats.ProcessStatsSectionProto proc_stats = 10029; BatteryVoltage battery_voltage = 10030; NumFingerprints num_fingerprints = 10031; } // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above Loading Loading @@ -1832,6 +1836,60 @@ message GenericAtom { optional android.os.statsd.EventType event_id = 2; } /** * Logs when a fingerprint acquire event occurs. * * Logged from: * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java */ message FingerprintAcquired { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // If this acquire is for a crypto fingerprint. // e.g. Secure purchases, unlock password storage. optional bool is_crypto = 2; } /** * Logs when a fingerprint authentication event occurs. * * Logged from: * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java */ message FingerprintAuthenticated { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // If this authentication is for a crypto fingerprint. // e.g. Secure purchases, unlock password storage. optional bool is_crypto = 2; // Whether or not this authentication was successful. optional bool is_authenticated = 3; } /** * Logs when a fingerprint error occurs. * * Logged from: * frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java */ message FingerprintErrorOccurred { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // If this error is for a crypto fingerprint. // e.g. Secure purchases, unlock password storage. optional bool is_crypto = 2; enum Error { UNKNOWN = 0; LOCKOUT = 1; PERMANENT_LOCKOUT = 2; } // The type of error. optional Error error = 3; } ////////////////////////////////////////////////////////////////////// // Pulled atoms below this line // ////////////////////////////////////////////////////////////////////// Loading Loading @@ -2408,3 +2466,16 @@ message CategorySize { // Uses System.currentTimeMillis(), which is wall clock time. optional int64 cache_time_millis = 3; } /** * Pulls the number of fingerprints for each user. * * Pulled from StatsCompanionService, which queries FingerprintManager. */ message NumFingerprints { // The associated user. Eg: 0 for owners, 10+ for others. // Defined in android/os/UserHandle.java optional int32 user = 1; // Number of fingerprints registered to that user. optional int32 num_fingerprints = 2; }
cmds/statsd/src/external/StatsPullerManager.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,12 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}}, // Number of fingerprints registered to each user. {android::util::NUM_FINGERPRINTS, {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS)}}, }; StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) { Loading
services/core/java/com/android/server/biometrics/BiometricService.java +4 −1 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ public abstract class BiometricService extends SystemService implements IHwBinde private ClientMonitor mPendingClient; private PerformanceStats mPerformanceStats; protected int mCurrentUserId = UserHandle.USER_NULL; // Tracks if the current authentication makes use of CryptoObjects. protected boolean mIsCrypto; // Normal authentications are tracked by mPerformanceMap. protected HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>(); // Transactions that make use of CryptoObjects are tracked by mCryptoPerformaceMap. Loading Loading @@ -715,6 +717,7 @@ public abstract class BiometricService extends SystemService implements IHwBinde pmap.put(mCurrentUserId, stats); } mPerformanceStats = stats; mIsCrypto = (opId != 0); startAuthentication(client, opPackageName); }); Loading Loading @@ -847,7 +850,7 @@ public abstract class BiometricService extends SystemService implements IHwBinde return mKeyguardPackage.equals(clientPackage); } private int getLockoutMode() { protected int getLockoutMode() { final int currentUser = ActivityManager.getCurrentUser(); final int failedAttempts = mFailedAttempts.get(currentUser, 0); if (failedAttempts >= getFailedAttemptsLockoutPermanent()) { Loading
services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java +23 −0 Original line number Diff line number Diff line Loading @@ -50,12 +50,14 @@ import android.os.SELinux; import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; import android.util.StatsLog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.util.DumpUtils; import com.android.server.SystemServerInitThreadPool; import com.android.server.biometrics.AuthenticationClient; import com.android.server.biometrics.BiometricService; import com.android.server.biometrics.BiometricUtils; import com.android.server.biometrics.ClientMonitor; Loading Loading @@ -590,6 +592,11 @@ public class FingerprintService extends BiometricService { public void onAcquired(final long deviceId, final int acquiredInfo, final int vendorCode) { mHandler.post(() -> { FingerprintService.super.handleAcquired(deviceId, acquiredInfo, vendorCode); if (getLockoutMode() == AuthenticationClient.LOCKOUT_NONE && getCurrentClient() instanceof AuthenticationClient) { // Ignore enrollment acquisitions or acquisitions when we are locked out. StatsLog.write(StatsLog.FINGERPRINT_ACQUIRED, mCurrentUserId, mIsCrypto); } }); } Loading @@ -599,6 +606,22 @@ public class FingerprintService extends BiometricService { mHandler.post(() -> { Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId); FingerprintService.super.handleAuthenticated(fp, token); // Send authentication to statsd. final boolean authenticated = fingerId != 0; StatsLog.write(StatsLog.FINGERPRINT_AUTHENTICATED, mCurrentUserId, mIsCrypto, authenticated); if (!authenticated) { // If we failed to authenticate because of a lockout, inform statsd. final int lockoutMode = getLockoutMode(); if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) { StatsLog.write(StatsLog.FINGERPRINT_ERROR_OCCURRED, mCurrentUserId, mIsCrypto, StatsLog.FINGERPRINT_ERROR_OCCURRED__ERROR__LOCKOUT); } else if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) { StatsLog.write(StatsLog.FINGERPRINT_ERROR_OCCURRED, mCurrentUserId, mIsCrypto, StatsLog.FINGERPRINT_ERROR_OCCURRED__ERROR__PERMANENT_LOCKOUT); } } }); } Loading
services/core/java/com/android/server/stats/StatsCompanionService.java +27 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.IntentSender; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.hardware.fingerprint.FingerprintManager; import android.net.NetworkStats; import android.net.wifi.IWifiManager; import android.net.wifi.WifiActivityEnergyInfo; Loading Loading @@ -1171,6 +1172,28 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } private void pullNumFingerprints(int tagId, List<StatsLogEventWrapper> pulledData) { FingerprintManager fingerprintManager = mContext.getSystemService(FingerprintManager.class); if (fingerprintManager == null) { return; } UserManager userManager = mContext.getSystemService(UserManager.class); if (userManager == null) { return; } final long token = Binder.clearCallingIdentity(); long elapsedNanos = SystemClock.elapsedRealtimeNanos(); for (UserInfo user : userManager.getUsers()) { final int userId = user.getUserHandle().getIdentifier(); final int numFingerprints = fingerprintManager.getEnrolledFingerprints(userId).size(); StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2 /* fields */); e.writeInt(userId); e.writeInt(numFingerprints); pulledData.add(e); } Binder.restoreCallingIdentity(token); } /** * Pulls various data. */ Loading Loading @@ -1277,6 +1300,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullCategorySize(tagId, ret); break; } case StatsLog.NUM_FINGERPRINTS: { pullNumFingerprints(tagId, ret); break; } default: Slog.w(TAG, "No such tagId data as " + tagId); return null; Loading