Fingerprint: get auth id for non-current user.
Previously, getAuthenticatorId() simply returns the authenticator id corresponding to the currently active user in FingerprintService. However, this can cause bugs when, for example, KeyStore calls the method before storing a fingerprint-bound key for a non-current user. In such cases, the authenticator id of the calling user is desired, which is not necessarily the same as the "current user" in FingerprintService. This CL ensures the FingerprintService always returns the authenticator id of the calling user. Bug: 33459191 Test: manual Change-Id: Ia9d6b869d16bd37f45358ba839cd12901ebc1076 Merged-In: I35c5a3a7082cffb8941eeaa219c8e20948ad41a9
This commit is contained in:
@ -710,7 +710,7 @@ public class FingerprintManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the authenticator token for binding keys to the lifecycle
|
* 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
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@ -74,6 +74,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A service to manage multiple clients that want to access the fingerprint HAL API.
|
* 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 =
|
private final ArrayList<FingerprintServiceLockoutResetMonitor> mLockoutMonitors =
|
||||||
new ArrayList<>();
|
new ArrayList<>();
|
||||||
|
private final Map<Integer, Long> mAuthenticatorIds =
|
||||||
|
Collections.synchronizedMap(new HashMap<>());
|
||||||
private final AppOpsManager mAppOps;
|
private final AppOpsManager mAppOps;
|
||||||
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
|
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
|
||||||
private static final int MAX_FAILED_ATTEMPTS = 5;
|
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 final UserManager mUserManager;
|
||||||
private ClientMonitor mCurrentClient;
|
private ClientMonitor mCurrentClient;
|
||||||
private ClientMonitor mPendingClient;
|
private ClientMonitor mPendingClient;
|
||||||
private long mCurrentAuthenticatorId;
|
|
||||||
private PerformanceStats mPerformanceStats;
|
private PerformanceStats mPerformanceStats;
|
||||||
|
|
||||||
// Normal fingerprint authentications are tracked by mPerformanceMap.
|
// Normal fingerprint authentications are tracked by mPerformanceMap.
|
||||||
@ -209,6 +211,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
mDaemon.init(mDaemonCallback);
|
mDaemon.init(mDaemonCallback);
|
||||||
mHalDeviceId = mDaemon.openHal();
|
mHalDeviceId = mDaemon.openHal();
|
||||||
if (mHalDeviceId != 0) {
|
if (mHalDeviceId != 0) {
|
||||||
|
loadAuthenticatorIds();
|
||||||
updateActiveGroup(ActivityManager.getCurrentUser(), null);
|
updateActiveGroup(ActivityManager.getCurrentUser(), null);
|
||||||
} else {
|
} else {
|
||||||
Slog.w(TAG, "Failed to open Fingerprint HAL!");
|
Slog.w(TAG, "Failed to open Fingerprint HAL!");
|
||||||
@ -226,6 +229,26 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
return mDaemon;
|
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) {
|
protected void handleEnumerate(long deviceId, int[] fingerIds, int[] groupIds) {
|
||||||
if (fingerIds.length != groupIds.length) {
|
if (fingerIds.length != groupIds.length) {
|
||||||
Slog.w(TAG, "fingerIds and groupIds differ in length: f[]="
|
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) {
|
boolean isCurrentUserOrProfile(int userId) {
|
||||||
UserManager um = UserManager.get(mContext);
|
UserManager um = UserManager.get(mContext);
|
||||||
|
if (um == null) {
|
||||||
// Allow current user or profiles of the current user...
|
Slog.e(TAG, "Unable to acquire UserManager");
|
||||||
for (int profileId : um.getEnabledProfileIds(userId)) {
|
return false;
|
||||||
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) {
|
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());
|
daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes());
|
||||||
mCurrentUserId = userId;
|
mCurrentUserId = userId;
|
||||||
}
|
}
|
||||||
mCurrentAuthenticatorId = daemon.getAuthenticatorId();
|
mAuthenticatorIds.put(userId, daemon.getAuthenticatorId());
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.e(TAG, "Failed to setActiveGroup():", 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
|
* @return true if this is a work profile
|
||||||
*/
|
*/
|
||||||
private boolean isWorkProfile(int userId) {
|
private boolean isWorkProfile(int userId) {
|
||||||
UserInfo info = mUserManager.getUserInfo(userId);
|
UserInfo userInfo = null;
|
||||||
return info != null && info.isManagedProfile();
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
userInfo = mUserManager.getUserInfo(userId);
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
return userInfo != null && userInfo.isManagedProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void listenForUserSwitches() {
|
private void listenForUserSwitches() {
|
||||||
@ -1085,12 +1123,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/**
|
||||||
* @param opPackageName the name of the calling package
|
* @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) {
|
public long getAuthenticatorId(String opPackageName) {
|
||||||
return mCurrentAuthenticatorId;
|
final int userId = getUserOrWorkProfileId(opPackageName, UserHandle.getCallingUserId());
|
||||||
|
Long authenticatorId = mAuthenticatorIds.get(userId);
|
||||||
|
return authenticatorId != null ? authenticatorId : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user