diff options
author | Alexandra Gherghina <alexgherghina@google.com> | 2014-07-03 11:40:08 +0100 |
---|---|---|
committer | Alexandra Gherghina <alexgherghina@google.com> | 2014-07-17 17:08:49 +0000 |
commit | 999d394adee533c55fce38bd632ffd4f1af91362 (patch) | |
tree | d53e3c50e09778874f11407d92be5d376b1c9fe7 /services | |
parent | 3f4f2fbcd0557e32464e393cb9acc28c2328614e (diff) | |
download | frameworks_base-999d394adee533c55fce38bd632ffd4f1af91362.zip frameworks_base-999d394adee533c55fce38bd632ffd4f1af91362.tar.gz frameworks_base-999d394adee533c55fce38bd632ffd4f1af91362.tar.bz2 |
Ads per-user APIs to manage accounts through the AccountManager
Bug: 16056552
Bug: 14642886
Change-Id: I17ff6c2515285e63c84cecf2f861d10666c393c5
Diffstat (limited to 'services')
-rw-r--r-- | services/core/java/com/android/server/accounts/AccountManagerService.java | 188 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 8 |
2 files changed, 179 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index e152ebe..36d67ee 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -871,15 +871,82 @@ public class AccountManagerService checkManageAccountsPermission(); UserHandle user = Binder.getCallingUserHandle(); UserAccounts accounts = getUserAccountsForCaller(); - if (!canUserModifyAccounts(Binder.getCallingUid(), account.type)) { + int userId = Binder.getCallingUserHandle().getIdentifier(); + if (!canUserModifyAccounts(userId)) { try { + // TODO: This should be ERROR_CODE_USER_RESTRICTED instead. See http://b/16322768 response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "User cannot modify accounts"); } catch (RemoteException re) { } return; } + if (!canUserModifyAccountsForType(userId, account.type)) { + try { + response.onError(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE, + "User cannot modify accounts of this type (policy)."); + } catch (RemoteException re) { + } + return; + } + + long identityToken = clearCallingIdentity(); + + cancelNotification(getSigninRequiredNotificationId(accounts, account), user); + synchronized (accounts.credentialsPermissionNotificationIds) { + for (Pair<Pair<Account, String>, Integer> pair: + accounts.credentialsPermissionNotificationIds.keySet()) { + if (account.equals(pair.first.first)) { + int id = accounts.credentialsPermissionNotificationIds.get(pair); + cancelNotification(id, user); + } + } + } + + try { + new RemoveAccountSession(accounts, response, account).bind(); + } finally { + restoreCallingIdentity(identityToken); + } + } + + @Override + public void removeAccountAsUser(IAccountManagerResponse response, Account account, + int userId) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "removeAccount: " + account + + ", response " + response + + ", caller's uid " + Binder.getCallingUid() + + ", pid " + Binder.getCallingPid() + + ", for user id " + userId); + } + if (response == null) throw new IllegalArgumentException("response is null"); + if (account == null) throw new IllegalArgumentException("account is null"); + + // Only allow the system process to modify accounts of other users + enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId() + + " trying to remove account for " + userId); + checkManageAccountsPermission(); + UserAccounts accounts = getUserAccounts(userId); + if (!canUserModifyAccounts(userId)) { + try { + response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, + "User cannot modify accounts"); + } catch (RemoteException re) { + } + return; + } + if (!canUserModifyAccountsForType(userId, account.type)) { + try { + response.onError(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE, + "User cannot modify accounts of this type (policy)."); + } catch (RemoteException re) { + } + return; + } + + UserHandle user = new UserHandle(userId); long identityToken = clearCallingIdentity(); cancelNotification(getSigninRequiredNotificationId(accounts, account), user); @@ -1526,20 +1593,23 @@ public class AccountManagerService checkManageAccountsPermission(); // Is user disallowed from modifying accounts? - if (!canUserModifyAccounts(Binder.getCallingUid(), accountType)) { + int userId = Binder.getCallingUserHandle().getIdentifier(); + if (!canUserModifyAccounts(userId)) { try { response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, "User is not allowed to add an account!"); } catch (RemoteException re) { } - Intent cantAddAccount = new Intent(mContext, CantAddAccountActivity.class); - cantAddAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - long identityToken = clearCallingIdentity(); + showCantAddAccount(AccountManager.ERROR_CODE_USER_RESTRICTED); + return; + } + if (!canUserModifyAccountsForType(userId, accountType)) { try { - mContext.startActivityAsUser(cantAddAccount, UserHandle.CURRENT); - } finally { - restoreCallingIdentity(identityToken); + response.onError(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE, + "User cannot modify accounts of this type (policy)."); + } catch (RemoteException re) { } + showCantAddAccount(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE); return; } @@ -1576,6 +1646,92 @@ public class AccountManagerService } @Override + public void addAccountAsUser(final IAccountManagerResponse response, final String accountType, + final String authTokenType, final String[] requiredFeatures, + final boolean expectActivityLaunch, final Bundle optionsIn, int userId) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "addAccount: accountType " + accountType + + ", response " + response + + ", authTokenType " + authTokenType + + ", requiredFeatures " + stringArrayToString(requiredFeatures) + + ", expectActivityLaunch " + expectActivityLaunch + + ", caller's uid " + Binder.getCallingUid() + + ", pid " + Binder.getCallingPid() + + ", for user id " + userId); + } + if (response == null) throw new IllegalArgumentException("response is null"); + if (accountType == null) throw new IllegalArgumentException("accountType is null"); + checkManageAccountsPermission(); + + // Only allow the system process to add accounts of other users + enforceCrossUserPermission(userId, "User " + UserHandle.getCallingUserId() + + " trying to add account for " + userId); + + // Is user disallowed from modifying accounts? + if (!canUserModifyAccounts(userId)) { + try { + response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, + "User is not allowed to add an account!"); + } catch (RemoteException re) { + } + showCantAddAccount(AccountManager.ERROR_CODE_USER_RESTRICTED); + return; + } + if (!canUserModifyAccountsForType(userId, accountType)) { + try { + response.onError(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE, + "User cannot modify accounts of this type (policy)."); + } catch (RemoteException re) { + } + showCantAddAccount(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE); + return; + } + + UserAccounts accounts = getUserAccounts(userId); + final int pid = Binder.getCallingPid(); + final int uid = Binder.getCallingUid(); + final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; + options.putInt(AccountManager.KEY_CALLER_UID, uid); + options.putInt(AccountManager.KEY_CALLER_PID, pid); + + long identityToken = clearCallingIdentity(); + try { + new Session(accounts, response, accountType, expectActivityLaunch, + true /* stripAuthTokenFromResult */) { + @Override + public void run() throws RemoteException { + mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, + options); + } + + @Override + protected String toDebugString(long now) { + return super.toDebugString(now) + ", addAccount" + + ", accountType " + accountType + + ", requiredFeatures " + + (requiredFeatures != null + ? TextUtils.join(",", requiredFeatures) + : null); + } + }.bind(); + } finally { + restoreCallingIdentity(identityToken); + } + } + + private void showCantAddAccount(int errorCode) { + Intent cantAddAccount = new Intent(mContext, CantAddAccountActivity.class); + cantAddAccount.putExtra(CantAddAccountActivity.EXTRA_ERROR_CODE, errorCode); + cantAddAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + long identityToken = clearCallingIdentity(); + try { + mContext.startActivity(cantAddAccount); + } finally { + restoreCallingIdentity(identityToken); + } + } + + @Override public void confirmCredentialsAsUser(IAccountManagerResponse response, final Account account, final Bundle options, final boolean expectActivityLaunch, int userId) { @@ -2766,18 +2922,18 @@ public class AccountManagerService Manifest.permission.USE_CREDENTIALS); } - private boolean canUserModifyAccounts(int callingUid, String accountType) { - if (callingUid != Process.myUid()) { - if (getUserManager().getUserRestrictions( - new UserHandle(UserHandle.getUserId(callingUid))) - .getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { - return false; - } + private boolean canUserModifyAccounts(int userId) { + if (getUserManager().getUserRestrictions(new UserHandle(userId)) + .getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS)) { + return false; } + return true; + } + private boolean canUserModifyAccountsForType(int userId, String accountType) { DevicePolicyManager dpm = (DevicePolicyManager) mContext .getSystemService(Context.DEVICE_POLICY_SERVICE); - String[] typesArray = dpm.getAccountTypesWithManagementDisabled(); + String[] typesArray = dpm.getAccountTypesWithManagementDisabledAsUser(userId); for (String forbiddenType : typesArray) { if (forbiddenType.equals(accountType)) { return false; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 9e4d90d..e40c812 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3888,11 +3888,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public String[] getAccountTypesWithManagementDisabled() { + return getAccountTypesWithManagementDisabledAsUser(UserHandle.getCallingUserId()); + } + + @Override + public String[] getAccountTypesWithManagementDisabledAsUser(int userId) { + enforceCrossUserPermission(userId); if (!mHasFeature) { return null; } synchronized (this) { - DevicePolicyData policy = getUserData(UserHandle.getCallingUserId()); + DevicePolicyData policy = getUserData(userId); final int N = policy.mAdminList.size(); HashSet<String> resultSet = new HashSet<String>(); for (int i = 0; i < N; i++) { |