Merge "Modifies APIs for retrieving managed profile accounts."

This commit is contained in:
Alexandra Gherghina
2014-06-13 09:51:33 +00:00
committed by Android (Google) Code Review
4 changed files with 79 additions and 11 deletions

View File

@@ -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);
@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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