Loading core/java/android/hardware/fingerprint/FingerprintManager.java +20 −2 Original line number Diff line number Diff line Loading @@ -496,7 +496,10 @@ public class FingerprintManager { */ @RequiresPermission(MANAGE_FINGERPRINT) public void enroll(byte [] token, CancellationSignal cancel, int flags, EnrollmentCallback callback) { EnrollmentCallback callback, int userId) { if (userId == UserHandle.USER_CURRENT) { userId = getCurrentUserId(); } if (callback == null) { throw new IllegalArgumentException("Must supply an enrollment callback"); } Loading @@ -512,7 +515,7 @@ public class FingerprintManager { if (mService != null) try { mEnrollmentCallback = callback; mService.enroll(mToken, token, getCurrentUserId(), mServiceReceiver, flags); mService.enroll(mToken, token, userId, mServiceReceiver, flags); } catch (RemoteException e) { Log.w(TAG, "Remote exception in enroll: ", e); if (callback != null) { Loading Loading @@ -555,6 +558,21 @@ public class FingerprintManager { return result; } /** * Sets the active user. This is meant to be used to select the current profile for enrollment * to allow separate enrolled fingers for a work profile * @param userId * @hide */ @RequiresPermission(MANAGE_FINGERPRINT) public void setActiveUser(int userId) { if (mService != null) try { mService.setActiveUser(userId); } catch (RemoteException e) { Log.w(TAG, "Remote exception in setActiveUser: ", e); } } /** * Remove given fingerprint template from fingerprint hardware and/or protected storage. * @param fp the fingerprint item to remove Loading core/java/android/hardware/fingerprint/IFingerprintService.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -75,4 +75,7 @@ interface IFingerprintService { // Add a callback which gets notified when the fingerprint lockout period expired. void addLockoutResetCallback(IFingerprintServiceLockoutResetCallback callback); // Explicitly set the active user (for enrolling work profile) void setActiveUser(int uid); } services/core/java/com/android/server/fingerprint/FingerprintService.java +70 −22 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.fingerprint; import android.Manifest; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.trust.TrustManager; import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.AppOpsManager; Loading Loading @@ -103,6 +104,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private static final int MAX_FAILED_ATTEMPTS = 5; private static final int FINGERPRINT_ACQUIRED_GOOD = 0; private final String mKeyguardPackage; private int mCurrentUserId = UserHandle.USER_CURRENT; Handler mHandler = new Handler() { @Override Loading @@ -125,6 +127,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private IFingerprintDaemon mDaemon; private final PowerManager mPowerManager; private final AlarmManager mAlarmManager; private final UserManager mUserManager; private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -152,6 +155,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe mAlarmManager = mContext.getSystemService(AlarmManager.class); mContext.registerReceiver(mLockoutReceiver, new IntentFilter(ACTION_LOCKOUT_RESET), RESET_FINGERPRINT_LOCKOUT, null /* handler */); mUserManager = UserManager.get(mContext); } @Override Loading @@ -170,7 +174,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe mDaemon.init(mDaemonCallback); mHalDeviceId = mDaemon.openHal(); if (mHalDeviceId != 0) { updateActiveGroup(ActivityManager.getCurrentUser()); updateActiveGroup(ActivityManager.getCurrentUser(), null); } else { Slog.w(TAG, "Failed to open Fingerprint HAL!"); mDaemon = null; Loading Loading @@ -261,7 +265,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } void handleUserSwitching(int userId) { updateActiveGroup(userId); updateActiveGroup(userId, null); } private void removeClient(ClientMonitor client) { Loading Loading @@ -414,7 +418,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe removeClient(mEnrollClient); } void startAuthentication(IBinder token, long opId, int groupId, void startAuthentication(IBinder token, long opId, int realUserId, int groupId, IFingerprintServiceReceiver receiver, int flags, boolean restricted, String opPackageName) { IFingerprintDaemon daemon = getFingerprintDaemon(); Loading @@ -423,6 +427,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return; } stopPendingOperations(true); updateActiveGroup(groupId, opPackageName); mAuthClient = new ClientMonitor(token, receiver, groupId, restricted, opPackageName); if (inLockoutMode()) { Slog.v(TAG, "In lockout mode; disallowing authentication"); Loading Loading @@ -564,7 +569,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe checkPermission(USE_FINGERPRINT); final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); if (opPackageName.equals(mKeyguardPackage)) { if (isKeyguard(opPackageName)) { return true; // Keyguard is always allowed } if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) { Loading @@ -583,6 +588,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return true; } /** * @param clientPackage * @return true if this is keyguard package */ private boolean isKeyguard(String clientPackage) { return mKeyguardPackage.equals(clientPackage); } private void addLockoutResetMonitor(FingerprintServiceLockoutResetMonitor monitor) { if (!mLockoutMonitors.contains(monitor)) { mLockoutMonitors.add(monitor); Loading Loading @@ -927,14 +940,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe // Group ID is arbitrarily set to parent profile user ID. It just represents // the default fingerprints for the user. final int effectiveGroupId = getEffectiveUserId(groupId); final int realUserId = Binder.getCallingUid(); final boolean restricted = isRestricted(); mHandler.post(new Runnable() { @Override public void run() { MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0); startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted, opPackageName); startAuthentication(token, opId, realUserId, effectiveGroupId, receiver, flags, restricted, opPackageName); } }); } Loading @@ -952,6 +966,17 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe }); } @Override // Binder call public void setActiveUser(final int userId) { checkPermission(MANAGE_FINGERPRINT); mHandler.post(new Runnable() { @Override public void run() { updateActiveGroup(userId, null); } }); } @Override // Binder call public void remove(final IBinder token, final int fingerId, final int groupId, final IFingerprintServiceReceiver receiver) { Loading Loading @@ -1102,11 +1127,12 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe listenForUserSwitches(); } private void updateActiveGroup(int userId) { private void updateActiveGroup(int userId, String clientPackage) { IFingerprintDaemon daemon = getFingerprintDaemon(); if (daemon != null) { try { userId = getEffectiveUserId(userId); userId = getUserOrWorkProfileId(clientPackage, userId); if (userId != mCurrentUserId) { final File systemDir = Environment.getUserSystemDirectory(userId); final File fpDir = new File(systemDir, FP_DATA_DIR); if (!fpDir.exists()) { Loading @@ -1123,12 +1149,34 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } } daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes()); mCurrentUserId = userId; } } catch (RemoteException e) { Slog.e(TAG, "Failed to setActiveGroup():", e); } } } /** * @param clientPackage the package of the caller * @return the profile id */ private int getUserOrWorkProfileId(String clientPackage, int userId) { if (!isKeyguard(clientPackage) && isWorkProfile(userId)) { return userId; } return getEffectiveUserId(userId); } /** * @param userId * @return true if this is a work profile */ private boolean isWorkProfile(int userId) { UserInfo info = mUserManager.getUserInfo(userId); return info != null && info.isManagedProfile(); } private void listenForUserSwitches() { try { ActivityManagerNative.getDefault().registerUserSwitchObserver( Loading Loading
core/java/android/hardware/fingerprint/FingerprintManager.java +20 −2 Original line number Diff line number Diff line Loading @@ -496,7 +496,10 @@ public class FingerprintManager { */ @RequiresPermission(MANAGE_FINGERPRINT) public void enroll(byte [] token, CancellationSignal cancel, int flags, EnrollmentCallback callback) { EnrollmentCallback callback, int userId) { if (userId == UserHandle.USER_CURRENT) { userId = getCurrentUserId(); } if (callback == null) { throw new IllegalArgumentException("Must supply an enrollment callback"); } Loading @@ -512,7 +515,7 @@ public class FingerprintManager { if (mService != null) try { mEnrollmentCallback = callback; mService.enroll(mToken, token, getCurrentUserId(), mServiceReceiver, flags); mService.enroll(mToken, token, userId, mServiceReceiver, flags); } catch (RemoteException e) { Log.w(TAG, "Remote exception in enroll: ", e); if (callback != null) { Loading Loading @@ -555,6 +558,21 @@ public class FingerprintManager { return result; } /** * Sets the active user. This is meant to be used to select the current profile for enrollment * to allow separate enrolled fingers for a work profile * @param userId * @hide */ @RequiresPermission(MANAGE_FINGERPRINT) public void setActiveUser(int userId) { if (mService != null) try { mService.setActiveUser(userId); } catch (RemoteException e) { Log.w(TAG, "Remote exception in setActiveUser: ", e); } } /** * Remove given fingerprint template from fingerprint hardware and/or protected storage. * @param fp the fingerprint item to remove Loading
core/java/android/hardware/fingerprint/IFingerprintService.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -75,4 +75,7 @@ interface IFingerprintService { // Add a callback which gets notified when the fingerprint lockout period expired. void addLockoutResetCallback(IFingerprintServiceLockoutResetCallback callback); // Explicitly set the active user (for enrolling work profile) void setActiveUser(int uid); }
services/core/java/com/android/server/fingerprint/FingerprintService.java +70 −22 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.fingerprint; import android.Manifest; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.trust.TrustManager; import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.AppOpsManager; Loading Loading @@ -103,6 +104,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private static final int MAX_FAILED_ATTEMPTS = 5; private static final int FINGERPRINT_ACQUIRED_GOOD = 0; private final String mKeyguardPackage; private int mCurrentUserId = UserHandle.USER_CURRENT; Handler mHandler = new Handler() { @Override Loading @@ -125,6 +127,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private IFingerprintDaemon mDaemon; private final PowerManager mPowerManager; private final AlarmManager mAlarmManager; private final UserManager mUserManager; private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -152,6 +155,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe mAlarmManager = mContext.getSystemService(AlarmManager.class); mContext.registerReceiver(mLockoutReceiver, new IntentFilter(ACTION_LOCKOUT_RESET), RESET_FINGERPRINT_LOCKOUT, null /* handler */); mUserManager = UserManager.get(mContext); } @Override Loading @@ -170,7 +174,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe mDaemon.init(mDaemonCallback); mHalDeviceId = mDaemon.openHal(); if (mHalDeviceId != 0) { updateActiveGroup(ActivityManager.getCurrentUser()); updateActiveGroup(ActivityManager.getCurrentUser(), null); } else { Slog.w(TAG, "Failed to open Fingerprint HAL!"); mDaemon = null; Loading Loading @@ -261,7 +265,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } void handleUserSwitching(int userId) { updateActiveGroup(userId); updateActiveGroup(userId, null); } private void removeClient(ClientMonitor client) { Loading Loading @@ -414,7 +418,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe removeClient(mEnrollClient); } void startAuthentication(IBinder token, long opId, int groupId, void startAuthentication(IBinder token, long opId, int realUserId, int groupId, IFingerprintServiceReceiver receiver, int flags, boolean restricted, String opPackageName) { IFingerprintDaemon daemon = getFingerprintDaemon(); Loading @@ -423,6 +427,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return; } stopPendingOperations(true); updateActiveGroup(groupId, opPackageName); mAuthClient = new ClientMonitor(token, receiver, groupId, restricted, opPackageName); if (inLockoutMode()) { Slog.v(TAG, "In lockout mode; disallowing authentication"); Loading Loading @@ -564,7 +569,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe checkPermission(USE_FINGERPRINT); final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); if (opPackageName.equals(mKeyguardPackage)) { if (isKeyguard(opPackageName)) { return true; // Keyguard is always allowed } if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) { Loading @@ -583,6 +588,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return true; } /** * @param clientPackage * @return true if this is keyguard package */ private boolean isKeyguard(String clientPackage) { return mKeyguardPackage.equals(clientPackage); } private void addLockoutResetMonitor(FingerprintServiceLockoutResetMonitor monitor) { if (!mLockoutMonitors.contains(monitor)) { mLockoutMonitors.add(monitor); Loading Loading @@ -927,14 +940,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe // Group ID is arbitrarily set to parent profile user ID. It just represents // the default fingerprints for the user. final int effectiveGroupId = getEffectiveUserId(groupId); final int realUserId = Binder.getCallingUid(); final boolean restricted = isRestricted(); mHandler.post(new Runnable() { @Override public void run() { MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0); startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted, opPackageName); startAuthentication(token, opId, realUserId, effectiveGroupId, receiver, flags, restricted, opPackageName); } }); } Loading @@ -952,6 +966,17 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe }); } @Override // Binder call public void setActiveUser(final int userId) { checkPermission(MANAGE_FINGERPRINT); mHandler.post(new Runnable() { @Override public void run() { updateActiveGroup(userId, null); } }); } @Override // Binder call public void remove(final IBinder token, final int fingerId, final int groupId, final IFingerprintServiceReceiver receiver) { Loading Loading @@ -1102,11 +1127,12 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe listenForUserSwitches(); } private void updateActiveGroup(int userId) { private void updateActiveGroup(int userId, String clientPackage) { IFingerprintDaemon daemon = getFingerprintDaemon(); if (daemon != null) { try { userId = getEffectiveUserId(userId); userId = getUserOrWorkProfileId(clientPackage, userId); if (userId != mCurrentUserId) { final File systemDir = Environment.getUserSystemDirectory(userId); final File fpDir = new File(systemDir, FP_DATA_DIR); if (!fpDir.exists()) { Loading @@ -1123,12 +1149,34 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } } daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes()); mCurrentUserId = userId; } } catch (RemoteException e) { Slog.e(TAG, "Failed to setActiveGroup():", e); } } } /** * @param clientPackage the package of the caller * @return the profile id */ private int getUserOrWorkProfileId(String clientPackage, int userId) { if (!isKeyguard(clientPackage) && isWorkProfile(userId)) { return userId; } return getEffectiveUserId(userId); } /** * @param userId * @return true if this is a work profile */ private boolean isWorkProfile(int userId) { UserInfo info = mUserManager.getUserInfo(userId); return info != null && info.isManagedProfile(); } private void listenForUserSwitches() { try { ActivityManagerNative.getDefault().registerUserSwitchObserver( Loading