diff options
| author | Alexandra Gherghina <alexgherghina@google.com> | 2014-06-05 10:49:14 +0100 |
|---|---|---|
| committer | Alexandra Gherghina <alexgherghina@google.com> | 2014-06-12 18:39:33 +0100 |
| commit | c1cf161af036e0f337b58ef0739a8ff2e42f01e7 (patch) | |
| tree | 5677bc04bce8515a67230d2df40c93302a8d4707 | |
| parent | e830c37a4a499c439083afc56c64fa178ea5889d (diff) | |
| download | frameworks_base-c1cf161af036e0f337b58ef0739a8ff2e42f01e7.zip frameworks_base-c1cf161af036e0f337b58ef0739a8ff2e42f01e7.tar.gz frameworks_base-c1cf161af036e0f337b58ef0739a8ff2e42f01e7.tar.bz2 | |
Modifies APIs for retrieving managed profile accounts.
This is needed for Account Settings UI.
Bug: 13656853
Change-Id: I33129e4b7b33b428a7bf670259accacb60f62d9b
4 files changed, 79 insertions, 11 deletions
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 12fcdcf..806a55b 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -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); @@ -389,6 +411,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 * is authorized to use, particularly for shared accounts. * @param packageName package name of the calling app. diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl index 86e279f..1373dc8 100644 --- a/core/java/android/accounts/IAccountManager.aidl +++ b/core/java/android/accounts/IAccountManager.aidl @@ -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); diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 914c170..afbf983 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -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. @@ -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. @@ -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 diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index b2aaf74..e152ebe 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -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>> @@ -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)) { @@ -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 |
