Loading core/java/android/accounts/AccountManager.java +45 −1 Original line number Diff line number Diff line Loading @@ -359,7 +359,29 @@ public class AccountManager { */ public AuthenticatorDescription[] getAuthenticatorTypes() { try { return mService.getAuthenticatorTypes(); return mService.getAuthenticatorTypes(UserHandle.getCallingUserId()); } catch (RemoteException e) { // will never happen throw new RuntimeException(e); } } /** * @hide * Lists the currently registered authenticators for a given user id. * * <p>It is safe to call this method from the main thread. * * <p>The caller has to be in the same user or have the permission * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}. * * @return An array of {@link AuthenticatorDescription} for every * authenticator known to the AccountManager service. Empty (never * null) if no authenticators are known. */ public AuthenticatorDescription[] getAuthenticatorTypesAsUser(int userId) { try { return mService.getAuthenticatorTypes(userId); } catch (RemoteException e) { // will never happen throw new RuntimeException(e); Loading Loading @@ -387,6 +409,28 @@ public class AccountManager { } } /** * @hide * Lists all accounts of any type registered on the device for a given * user id. Equivalent to getAccountsByType(null). * * <p>It is safe to call this method from the main thread. * * <p>This method requires the caller to hold the permission * {@link android.Manifest.permission#GET_ACCOUNTS}. * * @return An array of {@link Account}, one for each account. Empty * (never null) if no accounts have been added. */ public Account[] getAccountsAsUser(int userId) { try { return mService.getAccountsAsUser(null, userId); } catch (RemoteException e) { // won't ever happen throw new RuntimeException(e); } } /** * @hide * For use by internal activities. Returns the list of accounts that the calling package Loading core/java/android/accounts/IAccountManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import android.os.Bundle; interface IAccountManager { String getPassword(in Account account); String getUserData(in Account account, String key); AuthenticatorDescription[] getAuthenticatorTypes(); AuthenticatorDescription[] getAuthenticatorTypes(int userId); Account[] getAccounts(String accountType); Account[] getAccountsForPackage(String packageName, int uid); Account[] getAccountsByTypeForPackage(String type, String packageName); Loading core/java/android/os/UserHandle.java +17 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package android.os; import android.util.SparseArray; import java.io.PrintWriter; import java.util.HashMap; /** * Representation of a user on the device. Loading Loading @@ -66,6 +69,8 @@ public final class UserHandle implements Parcelable { final int mHandle; private static final SparseArray<UserHandle> userHandles = new SparseArray<UserHandle>(); /** * Checks to see if the user id is the same for the two uids, i.e., they belong to the same * user. Loading Loading @@ -124,6 +129,18 @@ public final class UserHandle implements Parcelable { return getUserId(Binder.getCallingUid()); } /** @hide */ public static final UserHandle getCallingUserHandle() { int userId = getUserId(Binder.getCallingUid()); UserHandle userHandle = userHandles.get(userId); // Intentionally not synchronized to save time if (userHandle == null) { userHandle = new UserHandle(userId); userHandles.put(userId, userHandle); } return userHandle; } /** * Returns the uid that is composed from the userId and the appId. * @hide Loading services/core/java/com/android/server/accounts/AccountManagerService.java +16 −9 Original line number Diff line number Diff line Loading @@ -537,13 +537,16 @@ public class AccountManagerService } @Override public AuthenticatorDescription[] getAuthenticatorTypes() { public AuthenticatorDescription[] getAuthenticatorTypes(int userId) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "getAuthenticatorTypes: " + "for user id " + userId + "caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); } final int userId = UserHandle.getCallingUserId(); // Only allow the system process to read accounts of other users enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId() + " trying get authenticator types for " + userId); final long identityToken = clearCallingIdentity(); try { Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> Loading @@ -562,6 +565,16 @@ public class AccountManagerService } } private void enforceCrossUserPermission(int userId, String errorMessage) { if (userId != UserHandle.getCallingUserId() && Binder.getCallingUid() != Process.myUid() && mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException(errorMessage); } } @Override public boolean addAccountExplicitly(Account account, String password, Bundle extras) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Loading Loading @@ -1567,14 +1580,8 @@ public class AccountManagerService final Account account, final Bundle options, final boolean expectActivityLaunch, int userId) { // Only allow the system process to read accounts of other users if (userId != UserHandle.getCallingUserId() && Binder.getCallingUid() != Process.myUid() && mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("User " + UserHandle.getCallingUserId() enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId() + " trying to confirm account credentials for " + userId); } if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "confirmCredentials: " + account Loading Loading
core/java/android/accounts/AccountManager.java +45 −1 Original line number Diff line number Diff line Loading @@ -359,7 +359,29 @@ public class AccountManager { */ public AuthenticatorDescription[] getAuthenticatorTypes() { try { return mService.getAuthenticatorTypes(); return mService.getAuthenticatorTypes(UserHandle.getCallingUserId()); } catch (RemoteException e) { // will never happen throw new RuntimeException(e); } } /** * @hide * Lists the currently registered authenticators for a given user id. * * <p>It is safe to call this method from the main thread. * * <p>The caller has to be in the same user or have the permission * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}. * * @return An array of {@link AuthenticatorDescription} for every * authenticator known to the AccountManager service. Empty (never * null) if no authenticators are known. */ public AuthenticatorDescription[] getAuthenticatorTypesAsUser(int userId) { try { return mService.getAuthenticatorTypes(userId); } catch (RemoteException e) { // will never happen throw new RuntimeException(e); Loading Loading @@ -387,6 +409,28 @@ public class AccountManager { } } /** * @hide * Lists all accounts of any type registered on the device for a given * user id. Equivalent to getAccountsByType(null). * * <p>It is safe to call this method from the main thread. * * <p>This method requires the caller to hold the permission * {@link android.Manifest.permission#GET_ACCOUNTS}. * * @return An array of {@link Account}, one for each account. Empty * (never null) if no accounts have been added. */ public Account[] getAccountsAsUser(int userId) { try { return mService.getAccountsAsUser(null, userId); } catch (RemoteException e) { // won't ever happen throw new RuntimeException(e); } } /** * @hide * For use by internal activities. Returns the list of accounts that the calling package Loading
core/java/android/accounts/IAccountManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import android.os.Bundle; interface IAccountManager { String getPassword(in Account account); String getUserData(in Account account, String key); AuthenticatorDescription[] getAuthenticatorTypes(); AuthenticatorDescription[] getAuthenticatorTypes(int userId); Account[] getAccounts(String accountType); Account[] getAccountsForPackage(String packageName, int uid); Account[] getAccountsByTypeForPackage(String type, String packageName); Loading
core/java/android/os/UserHandle.java +17 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package android.os; import android.util.SparseArray; import java.io.PrintWriter; import java.util.HashMap; /** * Representation of a user on the device. Loading Loading @@ -66,6 +69,8 @@ public final class UserHandle implements Parcelable { final int mHandle; private static final SparseArray<UserHandle> userHandles = new SparseArray<UserHandle>(); /** * Checks to see if the user id is the same for the two uids, i.e., they belong to the same * user. Loading Loading @@ -124,6 +129,18 @@ public final class UserHandle implements Parcelable { return getUserId(Binder.getCallingUid()); } /** @hide */ public static final UserHandle getCallingUserHandle() { int userId = getUserId(Binder.getCallingUid()); UserHandle userHandle = userHandles.get(userId); // Intentionally not synchronized to save time if (userHandle == null) { userHandle = new UserHandle(userId); userHandles.put(userId, userHandle); } return userHandle; } /** * Returns the uid that is composed from the userId and the appId. * @hide Loading
services/core/java/com/android/server/accounts/AccountManagerService.java +16 −9 Original line number Diff line number Diff line Loading @@ -537,13 +537,16 @@ public class AccountManagerService } @Override public AuthenticatorDescription[] getAuthenticatorTypes() { public AuthenticatorDescription[] getAuthenticatorTypes(int userId) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "getAuthenticatorTypes: " + "for user id " + userId + "caller's uid " + Binder.getCallingUid() + ", pid " + Binder.getCallingPid()); } final int userId = UserHandle.getCallingUserId(); // Only allow the system process to read accounts of other users enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId() + " trying get authenticator types for " + userId); final long identityToken = clearCallingIdentity(); try { Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> Loading @@ -562,6 +565,16 @@ public class AccountManagerService } } private void enforceCrossUserPermission(int userId, String errorMessage) { if (userId != UserHandle.getCallingUserId() && Binder.getCallingUid() != Process.myUid() && mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException(errorMessage); } } @Override public boolean addAccountExplicitly(Account account, String password, Bundle extras) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Loading Loading @@ -1567,14 +1580,8 @@ public class AccountManagerService final Account account, final Bundle options, final boolean expectActivityLaunch, int userId) { // Only allow the system process to read accounts of other users if (userId != UserHandle.getCallingUserId() && Binder.getCallingUid() != Process.myUid() && mContext.checkCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("User " + UserHandle.getCallingUserId() enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId() + " trying to confirm account credentials for " + userId); } if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "confirmCredentials: " + account Loading