diff options
| -rw-r--r-- | core/java/android/hardware/fingerprint/FingerprintManager.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/fingerprint/FingerprintService.java | 64 |
2 files changed, 53 insertions, 13 deletions
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index f17fd55bd22a..c5ae1f54aed6 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -710,7 +710,7 @@ public class FingerprintManager { /** * Retrieves the authenticator token for binding keys to the lifecycle - * of the current set of fingerprints. Used only by internal clients. + * of the calling user's fingerprints. Used only by internal clients. * * @hide */ diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index 6c11794b189d..e6408238e4c2 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -74,6 +74,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; /** * A service to manage multiple clients that want to access the fingerprint HAL API. @@ -101,6 +102,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private final ArrayList<FingerprintServiceLockoutResetMonitor> mLockoutMonitors = new ArrayList<>(); + private final Map<Integer, Long> mAuthenticatorIds = + Collections.synchronizedMap(new HashMap<>()); private final AppOpsManager mAppOps; private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000; private static final int MAX_FAILED_ATTEMPTS = 5; @@ -117,7 +120,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private final UserManager mUserManager; private ClientMonitor mCurrentClient; private ClientMonitor mPendingClient; - private long mCurrentAuthenticatorId; private PerformanceStats mPerformanceStats; // Normal fingerprint authentications are tracked by mPerformanceMap. @@ -209,6 +211,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe mDaemon.init(mDaemonCallback); mHalDeviceId = mDaemon.openHal(); if (mHalDeviceId != 0) { + loadAuthenticatorIds(); updateActiveGroup(ActivityManager.getCurrentUser(), null); } else { Slog.w(TAG, "Failed to open Fingerprint HAL!"); @@ -226,6 +229,26 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return mDaemon; } + /** Populates existing authenticator ids. To be used only during the start of the service. */ + private void loadAuthenticatorIds() { + // This operation can be expensive, so keep track of the elapsed time. Might need to move to + // background if it takes too long. + long t = System.currentTimeMillis(); + + mAuthenticatorIds.clear(); + for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) { + int userId = getUserOrWorkProfileId(null, user.id); + if (!mAuthenticatorIds.containsKey(userId)) { + updateActiveGroup(userId, null); + } + } + + t = System.currentTimeMillis() - t; + if (t > 1000) { + Slog.w(TAG, "loadAuthenticatorIds() taking too long: " + t + "ms"); + } + } + protected void handleEnumerate(long deviceId, int[] fingerIds, int[] groupIds) { if (fingerIds.length != groupIds.length) { Slog.w(TAG, "fingerIds and groupIds differ in length: f[]=" @@ -443,14 +466,23 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe boolean isCurrentUserOrProfile(int userId) { UserManager um = UserManager.get(mContext); + if (um == null) { + Slog.e(TAG, "Unable to acquire UserManager"); + return false; + } - // Allow current user or profiles of the current user... - for (int profileId : um.getEnabledProfileIds(userId)) { - if (profileId == userId) { - return true; + final long token = Binder.clearCallingIdentity(); + try { + // Allow current user or profiles of the current user... + for (int profileId : um.getEnabledProfileIds(mCurrentUserId)) { + if (profileId == userId) { + return true; + } } + return false; + } finally { + Binder.restoreCallingIdentity(token); } - return false; } private boolean isForegroundActivity(int uid, int pid) { @@ -1035,7 +1067,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes()); mCurrentUserId = userId; } - mCurrentAuthenticatorId = daemon.getAuthenticatorId(); + mAuthenticatorIds.put(userId, daemon.getAuthenticatorId()); } catch (RemoteException e) { Slog.e(TAG, "Failed to setActiveGroup():", e); } @@ -1058,8 +1090,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe * @return true if this is a work profile */ private boolean isWorkProfile(int userId) { - UserInfo info = mUserManager.getUserInfo(userId); - return info != null && info.isManagedProfile(); + UserInfo userInfo = null; + final long token = Binder.clearCallingIdentity(); + try { + userInfo = mUserManager.getUserInfo(userId); + } finally { + Binder.restoreCallingIdentity(token); + } + return userInfo != null && userInfo.isManagedProfile(); } private void listenForUserSwitches() { @@ -1085,12 +1123,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } } - /*** + /** * @param opPackageName the name of the calling package - * @return authenticator id for the current user + * @return authenticator id for the calling user */ public long getAuthenticatorId(String opPackageName) { - return mCurrentAuthenticatorId; + final int userId = getUserOrWorkProfileId(opPackageName, UserHandle.getCallingUserId()); + Long authenticatorId = mAuthenticatorIds.get(userId); + return authenticatorId != null ? authenticatorId : 0; } } |