Home | History | Annotate | Download | only in accounts

Lines Matching refs:ACCOUNT

21 import android.accounts.Account;
137 * A system service that provides account, password, and authtoken management for all
206 private final HashMap<Pair<Pair<Account, String>, Integer>, NotificationId>
208 private final HashMap<Account, NotificationId> signinRequiredNotificationIds
213 final HashMap<String, Account[]> accountCache = new LinkedHashMap<>();
215 private final Map<Account, Map<String, String>> userDataCache = new HashMap<>();
217 private final Map<Account, Map<String, String>> authTokenCache = new HashMap<>();
221 private final Map<Account, Map<String, Integer>> visibilityCache = new HashMap<>();
225 * type == null is used to get notifications about all account types
232 * Caches the previous names associated with an account. Previous names
233 * should be cached because we expect that when an Account is renamed,
241 private final HashMap<Account, AtomicReference<String>> previousNameCache =
242 new HashMap<Account, AtomicReference<String>>();
265 private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[]{};
337 // Need to cancel account request notifications if the update/install can access the account
352 // Cancel account request notification if an app op was preventing the account access
376 // Cancel account request notification if a permission was preventing the account access
379 Account[] accounts = null;
401 for (Account account : accounts) {
403 account, uid, packageName, true);
424 Account[] accounts = getAccountsAsUser(null, UserHandle.getUserId(uid), "android");
425 for (Account account : accounts) {
426 cancelAccountAccessRequestNotificationIfNeeded(account, uid, checkAccess);
432 Account[] accounts = getAccountsAsUser(null, UserHandle.getUserId(uid), "android");
433 for (Account account : accounts) {
434 cancelAccountAccessRequestNotificationIfNeeded(account, uid, packageName, checkAccess);
438 private void cancelAccountAccessRequestNotificationIfNeeded(Account account, int uid,
443 cancelAccountAccessRequestNotificationIfNeeded(account, uid,
449 private void cancelAccountAccessRequestNotificationIfNeeded(Account account,
451 if (!checkAccess || hasAccountAccess(account, packageName,
453 cancelNotification(getCredentialPermissionNotificationId(account,
460 public boolean addAccountExplicitlyWithVisibility(Account account, String password,
466 Log.v(TAG, "addAccountExplicitly: " + account + ", caller's uid " + callingUid
469 Preconditions.checkNotNull(account, "account cannot be null");
470 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
472 callingUid, account.type);
481 // fails if the account already exists
485 return addAccountInternal(accounts, account, password, extras, callingUid,
493 public Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
524 private Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
531 Map<Account, Integer> result = new LinkedHashMap<>();
535 final Account[] accountsOfType = accounts.accountCache.get(accountType);
537 for (Account account : accountsOfType) {
538 result.put(account,
539 resolveAccountVisibility(account, packageName, accounts));
549 public Map<String, Integer> getPackagesAndVisibilityForAccount(Account account) {
550 Preconditions.checkNotNull(account, "account cannot be null");
553 if (!isAccountManagedByCaller(account.type, callingUid, userId)
556 String.format("uid %s cannot get secrets for account %s", callingUid, account);
565 return getPackagesAndVisibilityForAccountLocked(account, accounts);
575 * Returns Map with all package names and visibility values for given account.
578 * @param account Account to get visibility values.
579 * @param accounts UserAccount that currently hosts the account and application
583 private @NonNull Map<String, Integer> getPackagesAndVisibilityForAccountLocked(Account account,
585 Map<String, Integer> accountVisibility = accounts.visibilityCache.get(account);
589 accounts.visibilityCache.put(account, accountVisibility);
595 public int getAccountVisibility(Account account, String packageName) {
596 Preconditions.checkNotNull(account, "account cannot be null");
600 if (!isAccountManagedByCaller(account.type, callingUid, userId)
605 account.type);
612 int visibility = getAccountVisibilityFromCache(account, packageName, accounts);
620 int visibility = getAccountVisibilityFromCache(account, packageName, accounts);
627 return resolveAccountVisibility(account, packageName, accounts);
634 * Method returns visibility for given account and package name.
636 * @param account The account to check visibility.
638 * @param accounts UserAccount that currently hosts the account and application
643 private int getAccountVisibilityFromCache(Account account, String packageName,
647 getPackagesAndVisibilityForAccountLocked(account, accounts);
654 * Method which handles default values for Account visibility.
656 * @param account The account to check visibility.
658 * @param accounts UserAccount that currently hosts the account and application
663 private Integer resolveAccountVisibility(Account account, @NonNull String packageName,
685 checkPackageSignature(account.type, uid, accounts.userId);
689 return AccountManager.VISIBILITY_VISIBLE; // Authenticator can always see the account
693 int visibility = getAccountVisibilityFromCache(account, packageName, accounts);
711 && accountTypeManagesContacts(account.type, accounts.userId))
715 visibility = getAccountVisibilityFromCache(account,
721 visibility = getAccountVisibilityFromCache(account,
760 public boolean setAccountVisibility(Account account, String packageName, int newVisibility) {
761 account, "account cannot be null");
765 if (!isAccountManagedByCaller(account.type, callingUid, userId)
770 account.type);
776 return setAccountVisibility(account, packageName, newVisibility, true /* notify */,
789 * Updates visibility for given account name and package.
791 * @param account Account to update visibility.
795 * @param accounts UserAccount that currently hosts the account and application
797 * @return True if account visibility was changed.
799 private boolean setAccountVisibility(Account account, String packageName, int newVisibility,
808 getRequestingPackages(account, accounts);
809 accountRemovedReceivers = getAccountRemovedReceivers(account, accounts);
816 resolveAccountVisibility(account, packageName, accounts));
818 if (shouldNotifyPackageOnAccountRemoval(account, packageName, accounts)) {
823 // Notifications will not be send - only used during add account.
833 if (!updateAccountVisibilityLocked(account, packageName, newVisibility, accounts)) {
842 resolveAccountVisibility(account, packageName, accounts);
848 sendAccountRemovedBroadcast(account, packageNameToNotify, accounts.userId);
857 // Update account visibility in cache and database.
858 private boolean updateAccountVisibilityLocked(Account account, String packageName,
860 final long accountId = accounts.accountsDb.findDeAccountId(account);
875 getPackagesAndVisibilityForAccountLocked(account, accounts);
950 // Send notification to all packages which can potentially see the account
951 private void sendNotificationAccountUpdated(Account account, UserAccounts accounts) {
952 Map<String, Integer> packagesToVisibility = getRequestingPackages(account, accounts);
964 * Sends a direct intent to a package, notifying it of account visibility change.
966 * @param packageName to send Account to
967 * @param accounts UserAccount that currently hosts the account
977 // to notifications about any account type, or type of provided account
978 // account type or all types.
979 private Map<String, Integer> getRequestingPackages(Account account, UserAccounts accounts) {
982 for (String type : new String[] {account.type, null}) {
991 result.put(packageName, resolveAccountVisibility(account, packageName, accounts));
996 // Returns a list of packages listening to ACTION_ACCOUNT_REMOVED able to see the account.
997 private List<String> getAccountRemovedReceivers(Account account, UserAccounts accounts) {
1008 int visibility = resolveAccountVisibility(account, packageName, accounts);
1017 // Returns true if given package is listening to ACTION_ACCOUNT_REMOVED and can see the account.
1018 private boolean shouldNotifyPackageOnAccountRemoval(Account account,
1020 int visibility = resolveAccountVisibility(account, packageName, accounts);
1062 private void sendAccountRemovedBroadcast(Account account, String packageName, int userId) {
1066 intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
1067 intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
1077 // The account manager only throws security exceptions, so let's
1080 Slog.wtf(TAG, "Account Manager Crash", e);
1164 // updating). So purge its data from the account databases.
1179 final Map<Long, Account> accountsMap = accountsDb.findAllDeAccounts();
1184 for (Entry<Long, Account> accountEntry : accountsMap.entrySet()) {
1186 final Account account = accountEntry.getValue();
1187 if (obsoleteAuthType.contains(account.type)) {
1188 Slog.w(TAG, "deleting account " + account.name + " because type "
1189 + account.type
1192 getRequestingPackages(account, accounts);
1194 getAccountRemovedReceivers(account, accounts);
1199 // currently locked the account will be removed later by
1213 accounts.userDataCache.remove(account);
1214 accounts.authTokenCache.remove(account);
1215 accounts.accountTokenCaches.remove(account);
1216 accounts.visibilityCache.remove(account);
1225 sendAccountRemovedBroadcast(account, packageName, accounts.userId);
1228 ArrayList<String> accountNames = accountNamesByType.get(account.type);
1231 accountNamesByType.put(account.type, accountNames);
1233 accountNames.add(account.name);
1239 final Account[] accountsForType = new Account[accountNames.size()];
1241 accountsForType[i] = new Account(accountNames.get(i), accountType,
1327 List<Account> accountsToRemove = accounts.accountsDb.findCeAccountsNotInDe();
1334 for (Account account : accountsToRemove) {
1335 removeAccountInternal(accounts, account, Process.SYSTEM_UID);
1380 for (Account account : accounts.visibilityCache.keySet()) {
1382 getPackagesAndVisibilityForAccountLocked(account, accounts);
1426 // Check if there's a shared account that needs to be created as an account
1427 Account[] sharedAccounts = getSharedAccountsAsUser(userId);
1429 Account[] accounts = getAccountsAsUser(null, userId, mContext.getOpPackageName());
1437 for (Account sa : sharedAccounts) {
1439 // Account doesn't exist. Copy it now.
1450 public String getPassword(Account account) {
1453 Log.v(TAG, "getPassword: " + account
1457 if (account == null) throw new IllegalArgumentException("account is null");
1459 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
1463 account.type);
1469 return readPasswordInternal(accounts, account);
1475 private String readPasswordInternal(UserAccounts accounts, Account account) {
1476 if (account == null) {
1487 .findAccountPasswordByNameAndType(account.name, account.type);
1493 public String getPreviousName(Account account) {
1495 Log.v(TAG, "getPreviousName: " + account
1499 Preconditions.checkNotNull(account, "account cannot be null");
1504 return readPreviousNameInternal(accounts, account);
1510 private String readPreviousNameInternal(UserAccounts accounts, Account account) {
1511 if (account == null) {
1516 AtomicReference<String> previousNameRef = accounts.previousNameCache.get(account);
1518 String previousName = accounts.accountsDb.findDeAccountPreviousName(account);
1520 accounts.previousNameCache.put(account, previousNameRef);
1530 public String getUserData(Account account, String key) {
1533 String msg = String.format("getUserData( account: %s, key: %s, callerUid: %s, pid: %s",
1534 account, key, callingUid, Binder.getCallingPid());
1537 Preconditions.checkNotNull(account, "account cannot be null");
1540 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
1544 account.type);
1554 if (!accountExistsCache(accounts, account)) {
1557 return readUserDataInternal(accounts, account, key);
1617 public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
1618 return addAccountExplicitlyWithVisibility(account, password, extras, null);
1622 public void copyAccountToUser(final IAccountManagerResponse response, final Account account,
1644 Slog.d(TAG, "Copying account " + account.name
1648 new Session(fromAccounts, response, account.type, false,
1649 false /* stripAuthTokenFromResult */, account.name,
1654 + ", " + account.type;
1659 mAuthenticator.getAccountCredentialsForCloning(this, account);
1668 completeCloningAccount(response, result, account, toAccounts, userFrom);
1680 public boolean accountAuthenticated(final Account account) {
1684 "accountAuthenticated( account: %s, callerUid: %s)",
1685 account,
1689 Preconditions.checkNotNull(account, "account cannot be null");
1691 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
1695 account.type);
1700 !canUserModifyAccountsForType(userId, account.type, callingUid)) {
1707 return updateLastAuthenticatedTime(account);
1713 private boolean updateLastAuthenticatedTime(Account account) {
1717 return accounts.accountsDb.updateAccountLastAuthenticatedTime(account);
1723 final Bundle accountCredentials, final Account account, final UserAccounts targetUser,
1728 new Session(targetUser, response, account.type, false,
1729 false /* stripAuthTokenFromResult */, account.name,
1734 + ", " + account.type;
1739 // Confirm that the owner's account still exists before this step.
1740 for (Account acc : getAccounts(parentUserId, mContext.getOpPackageName())) {
1741 if (acc.equals(account)) {
1743 this, account, accountCredentials);
1754 // account to avoid retries?
1764 // TODO: Should we remove the shadow account so that it doesn't keep trying?
1773 private boolean addAccountInternal(UserAccounts accounts, Account account, String password,
1776 if (account == null) {
1780 Log.w(TAG, "Account " + account + " cannot be added - user " + accounts.userId
1788 if (accounts.accountsDb.findCeAccountId(account) >= 0) {
1789 Log.w(TAG, "insertAccountIntoDatabase: " + account
1790 + ", skipping since the account already exists");
1793 long accountId = accounts.accountsDb.insertCeAccount(account, password);
1795 Log.w(TAG, "insertAccountIntoDatabase: " + account
1800 if (accounts.accountsDb.insertDeAccount(account, accountId) < 0) {
1801 Log.w(TAG, "insertAccountIntoDatabase: " + account
1809 Log.w(TAG, "insertAccountIntoDatabase: " + account
1818 setAccountVisibility(account, entry.getKey() /* package */,
1829 insertAccountIntoCacheLocked(accounts, account);
1836 addAccountToLinkedRestrictedUsers(account, accounts.userId);
1839 sendNotificationAccountUpdated(account, accounts);
1853 account to all linked restricted users as shared accounts. If the user is currently
1854 * running, then clone the account too.
1855 * @param account the account to share with limited users
1858 private void addAccountToLinkedRestrictedUsers(Account account, int parentUserId) {
1862 addSharedAccountAsUser(account, user.id);
1865 MESSAGE_COPY_SHARED_ACCOUNT, parentUserId, user.id, account));
1873 Account account, String[] features, String opPackageName) {
1877 Log.v(TAG, "hasFeatures: " + account
1883 Preconditions.checkArgument(account != null, "account cannot be null");
1887 checkReadAccountsPermitted(callingUid, account.type, userId,
1893 new TestFeaturesSession(accounts, response, account, features).bind();
1901 private final Account mAccount;
1904 Account account, String[] features) {
1905 super(accounts, response, account.type, false /* expectActivityLaunch */,
1906 true /* stripAuthTokenFromResult */, account.name,
1909 mAccount = account;
1958 IAccountManagerResponse response, Account accountToRename, String newName) {
1965 if (accountToRename == null) throw new IllegalArgumentException("account is null");
1977 Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName);
1993 private Account renameAccountInternal(
1994 UserAccounts accounts, Account accountToRename, String newName) {
1995 Account resultAccount = null;
2000 * now stale account name data.
2009 for (Pair<Pair<Account, String>, Integer> pair:
2022 Account renamedAccount = new Account(newName, accountToRename.type);
2025 Log.e(TAG, "renameAccount failed - account with new name already exists");
2039 Log.e(TAG, "renameAccount failed - old account does not exist");
2047 * data associated with the account in the user profile.
2052 * old account to preserve the user data associated with
2053 * the account.
2061 * account.
2074 * Owner or system user account was renamed, rename the account for
2075 * those users with which the account was shared.
2102 public void removeAccount(IAccountManagerResponse response, Account account,
2106 account,
2112 public void removeAccountAsUser(IAccountManagerResponse response, Account account,
2116 Log.v(TAG, "removeAccount: " + account
2122 Preconditions.checkArgument(account != null, "account cannot be null");
2129 "User %s tying remove account for %s" ,
2139 if (!isAccountManagedByCaller(account.type, callingUid, user.getIdentifier())
2145 account.type);
2156 if (!canUserModifyAccountsForType(userId, account.type, callingUid)) {
2166 cancelNotification(getSigninRequiredNotificationId(accounts, account), user);
2168 for (Pair<Pair<Account, String>, Integer> pair:
2170 if (account.equals(pair.first.first)) {
2176 final long accountId = accounts.accountsDb.findDeAccountId(account);
2184 new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
2191 public boolean removeAccountExplicitly(Account account) {
2194 Log.v(TAG, "removeAccountExplicitly: " + account
2199 if (account == null) {
2204 Log.e(TAG, "account is null");
2206 } else if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
2210 account.type);
2214 final long accountId = accounts.accountsDb.findDeAccountId(account);
2223 return removeAccountInternal(accounts, account, callingUid);
2230 final Account mAccount;
2232 Account account, boolean expectActivityLaunch) {
2233 super(accounts, response, account.type, expectActivityLaunch,
2234 true /* stripAuthTokenFromResult */, account.name,
2236 mAccount = account;
2242 + ", account " + mAccount;
2277 protected void removeAccountInternal(Account account) {
2278 removeAccountInternal(getUserAccountsForCaller(), account, getCallingUid());
2281 private boolean removeAccountInternal(UserAccounts accounts, Account account, int callingUid) {
2285 Slog.i(TAG, "Removing account " + account + " while user "+ accounts.userId
2290 Map<String, Integer> packagesToVisibility = getRequestingPackages(account,
2293 getAccountRemovedReceivers(account, accounts);
2299 accountId = accounts.accountsDb.findDeAccountId(account);
2304 // DE account could be removed while CE was locked
2306 long ceAccountId = accounts.accountsDb.findCeAccountId(account);
2316 removeAccountFromCacheLocked(accounts, account);
2329 sendAccountRemovedBroadcast(account, packageName, accounts.userId);
2341 // Remove from any restricted profiles that are sharing this account.
2345 removeSharedAccountAsUser(account, user.id, callingUid);
2355 for (Pair<Pair<Account, String>, Integer> key
2357 if (account.equals(key.first.first)
2361 account, uid, false));
2384 List<Pair<Account, String>> deletedTokens;
2394 for (Pair<Account, String> tokenInfo : deletedTokens) {
2395 Account act = tokenInfo.first;
2408 private List<Pair<Account, String>> invalidateAuthTokenLocked(UserAccounts accounts, String accountType,
2411 List<Pair<Account, String>> results = new ArrayList<>();
2420 results.add(Pair.create(new Account(accountName, accountType), authTokenType));
2430 Account account,
2437 if (account == null || tokenType == null || callerPkg == null || callerSigDigest == null) {
2440 cancelNotification(getSigninRequiredNotificationId(accounts, account),
2444 account, token, tokenType, callerPkg, callerSigDigest, expiryMillis);
2448 private boolean saveAuthTokenToDatabase(UserAccounts accounts, Account account, String type,
2450 if (account == null || type == null) {
2453 cancelNotification(getSigninRequiredNotificationId(accounts, account),
2459 long accountId = accounts.accountsDb.findDeAccountId(account);
2474 writeAuthTokenIntoCacheLocked(accounts, account, type, authToken);
2482 public String peekAuthToken(Account account, String authTokenType) {
2485 Log.v(TAG, "peekAuthToken: " + account
2490 Preconditions.checkNotNull(account, "account cannot be null");
2493 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
2497 account.type);
2508 return readAuthTokenInternal(accounts, account, authTokenType);
2515 public void setAuthToken(Account account, String authTokenType, String authToken) {
2518 Log.v(TAG, "setAuthToken: " + account
2523 Preconditions.checkNotNull(account, "account cannot be null");
2526 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
2530 account.type);
2536 saveAuthTokenToDatabase(accounts, account, authTokenType, authToken);
2543 public void setPassword(Account account, String password) {
2546 Log.v(TAG, "setAuthToken: " + account
2550 Preconditions.checkNotNull(account, "account cannot be null");
2552 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
2556 account.type);
2562 setPasswordInternal(accounts, account, password, callingUid);
2568 private void setPasswordInternal(UserAccounts accounts, Account account, String password,
2570 if (account == null) {
2578 final long accountId = accounts.accountsDb.findDeAccountId(account);
2582 accounts.authTokenCache.remove(account);
2583 accounts.accountTokenCaches.remove(account);
2585 // If there is an account whose password will be updated and the database
2600 sendNotificationAccountUpdated(account, accounts);
2609 public void clearPassword(Account account) {
2612 Log.v(TAG, "clearPassword: " + account
2616 Preconditions.checkNotNull(account, "account cannot be null");
2618 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
2622 account.type);
2628 setPasswordInternal(accounts, account, null, callingUid);
2635 public void setUserData(Account account, String key, String value) {
2638 Log.v(TAG, "setUserData: " + account
2644 if (account == null) throw new IllegalArgumentException("account is null");
2646 if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
2650 account.type);
2656 if (!accountExistsCache(accounts, account)) {
2659 setUserdataInternal(accounts, account, key, value);
2665 private boolean accountExistsCache(UserAccounts accounts, Account account) {
2667 if (accounts.accountCache.containsKey(account.type)) {
2668 for (Account acc : accounts.accountCache.get(account.type)) {
2669 if (acc.name.equals(account.name)) {
2678 private void setUserdataInternal(UserAccounts accounts, Account account, String key,
2683 long accountId = accounts.accountsDb.findDeAccountId(account);
2701 writeUserDataIntoCacheLocked(accounts, account, key, value);
2778 final Account account,
2785 Log.v(TAG, "getAuthToken: " + account
2795 if (account == null) {
2796 Slog.w(TAG, "getAuthToken called with null account");
2797 response.onError(AccountManager.ERROR_CODE_BAD_ARGUMENTS, "account is null");
2816 AuthenticatorDescription.newKey(account.type), accounts.userId);
2827 customTokens || permissionIsGranted(account, authTokenType, callerUid, userId);
2862 String authToken = readAuthTokenInternal(accounts, account, authTokenType);
2866 result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
2867 result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
2881 account,
2891 result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
2892 result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
2901 account.type,
2904 account.name,
2910 + ", " + account
2923 mAuthenticator.getAuthToken(this, account, authTokenType, loginOptions);
2933 account,
2953 Account resultAccount = new Account(name, type);
2967 account,
2993 account,
3025 private void createNoCredentialsPermissionNotification(Account account, Intent intent,
3033 account.name);
3044 new Notification.Builder(contextForUser, SystemNotificationChannels.ACCOUNT)
3055 account, authTokenType, uid), n, packageName, user.getIdentifier());
3058 private Intent newGrantCredentialsPermissionIntent(Account account, String packageName,
3070 intent.addCategory(getCredentialPermissionNotificationId(account,
3072 intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT, account);
3080 private NotificationId getCredentialPermissionNotificationId(Account account,
3085 final Pair<Pair<Account, String>, Integer> key =
3086 new Pair<Pair<Account, String>, Integer>(
3087 new Pair<Account, String>(account, authTokenType), uid);
3091 + ":" + account.hashCode() + ":" + authTokenType.hashCode();
3100 private NotificationId getSigninRequiredNotificationId(UserAccounts accounts, Account account) {
3103 nId = accounts.signinRequiredNotificationIds.get(account);
3106 + ":" + account.hashCode();
3109 accounts.signinRequiredNotificationIds.put(account, nId);
3138 "User is not allowed to add an account!");
3210 "User %s trying to add account for %s" ,
3219 "User is not allowed to add an account!");
3299 "User is not allowed to add an account!");
3443 Log.w(TAG, "Account type in session bundle doesn't match request.");
3487 // Account type is added to it before encryption.
3504 "User is not allowed to add an account!");
3512 // First decrypt session bundle to get account type for checking permission.
3524 // Account type cannot be null. This should not happen if session bundle was created
3536 // such as AccountManager.KEY_ANDROID_PACKAGE_NAME required by the add account flow or
3542 // Add info that may be used by add account or update credentials flow.
3624 * Called when we don't know precisely who is preventing us from adding an account.
3636 final Accountaccount,
3643 Log.v(TAG, "confirmCredentials: " + account
3653 "User %s trying to confirm account credentials for %s" ,
3658 if (account == null) throw new IllegalArgumentException("account is null");
3662 new Session(accounts, response, account.type, expectActivityLaunch,
3663 true /* stripAuthTokenFromResult */, account.name,
3667 mAuthenticator.confirmCredentials(this, account, options);
3672 + ", " + account;
3681 public void updateCredentials(IAccountManagerResponse response, final Account account,
3686 Log.v(TAG, "updateCredentials: " + account
3694 if (account == null) throw new IllegalArgumentException("account is null");
3699 new Session(accounts, response, account.type, expectActivityLaunch,
3700 true /* stripAuthTokenFromResult */, account.name,
3704 mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
3710 + ", " + account
3723 final Account account,
3730 "startUpdateCredentialsSession: " + account + ", response " + response
3738 if (account == null) {
3739 throw new IllegalArgumentException("account is null");
3756 account.type,
3758 account.name,
3764 mAuthenticator.startUpdateCredentialsSession(this, account, authTokenType,
3774 + ", " + account
3787 final Account account,
3791 "isCredentialsUpdateSuggested: " + account + ", response " + response
3798 if (account == null) {
3799 throw new IllegalArgumentException("account is null");
3809 new Session(accounts, response, account.type, false /* expectActivityLaunch */,
3810 false /* stripAuthTokenFromResult */, account.name,
3815 + ", " + account;
3820 mAuthenticator.isCredentialsUpdateSuggested(this, account, statusToken);
3886 "uid %s cannot edit authenticator properites for account type: %s",
3913 public boolean hasAccountAccess(@NonNull Account account, @NonNull String packageName,
3918 Preconditions.checkNotNull(account, "account cannot be null");
3928 return hasAccountAccess(account, packageName, uid);
3964 private boolean hasAccountAccess(@NonNull Account account, @Nullable String packageName,
3974 // is trusted by the authenticator, hence it is fine to access the account.
3975 if (permissionIsGranted(account, null, uid, UserHandle.getUserId(uid))) {
3979 // the account to be accessed by apps for which user or authenticator granted visibility.
3981 int visibility = resolveAccountVisibility(account, packageName,
3988 public IntentSender createRequestAccountAccessIntentSenderAsUser(@NonNull Account account,
3994 Preconditions.checkNotNull(account, "account cannot be null");
4010 Intent intent = newRequestAccountAccessIntent(account, packageName, uid, null);
4023 private Intent newRequestAccountAccessIntent(Account account, String packageName,
4025 return newGrantCredentialsPermissionIntent(account, packageName, uid,
4043 cancelNotification(getCredentialPermissionNotificationId(account,
4056 public boolean someUserHasAccount(@NonNull final Account account) {
4064 if (allAccounts[i].account.equals(account)) {
4076 private volatile Account[] mAccountsOfType = null;
4077 private volatile ArrayList<Account> mAccountsWithFeatures = null;
4104 // check whether each account matches the requested features
4155 Account[] accounts = new Account[mAccountsWithFeatures.size()];
4187 public Account[] getAccounts(int userId, String opPackageName) {
4247 Account[] accounts = getAccountsFromCache(
4253 for (Account account : accounts) {
4254 runningAccounts.add(new AccountAndUser(account, userId));
4264 public Account[] getAccountsAsUser(String type, int userId, String opPackageName) {
4272 private Account[] getAccountsAsUserForPackage(
4287 + " trying to get account for " + userId);
4296 // If the original calling app was using account choosing activity
4334 private Account[] getAccountsInternal(
4340 ArrayList<Account> visibleAccounts = new ArrayList<>();
4342 Account[] accountsForType = getAccountsFromCache(
4349 Account[] result = new Account[visibleAccounts.size()];
4360 Account[] accounts = getAccountsAsUser(null, parentUserId, opPackageName);
4361 for (Account account : accounts) {
4362 addSharedAccountAsUser(account, userId);
4366 private boolean addSharedAccountAsUser(Account account, int userId) {
4369 accounts.accountsDb.deleteSharedAccount(account);
4370 long accountId = accounts.accountsDb.insertSharedAccount(account);
4372 Log.w(TAG, "insertAccountIntoDatabase: " + account
4382 public boolean renameSharedAccountAsUser(Account account, String newName, int userId) {
4385 long sharedTableAccountId = accounts.accountsDb.findSharedAccountId(account);
4386 int r = accounts.accountsDb.renameSharedAccount(account, newName);
4391 // Recursively rename the account.
4392 renameAccountInternal(accounts, account, newName);
4398 Account account, int userId) {
4399 return removeSharedAccountAsUser(account, userId, getCallingUid());
4402 private boolean removeSharedAccountAsUser(Account account, int userId, int callingUid) {
4405 long sharedTableAccountId = accounts.accountsDb.findSharedAccountId(account);
4406 boolean deleted = accounts.accountsDb.deleteSharedAccount(account);
4410 removeAccountInternal(accounts, account, callingUid);
4416 public Account[] getSharedAccountsAsUser(int userId) {
4420 List<Account> accountList = accounts.accountsDb.getSharedAccounts();
4421 Account[] accountArray = new Account[accountList.size()];
4429 public Account[] getAccounts(String type, String opPackageName) {
4435 public Account[] getAccountsForPackage(String packageName, int uid, String opPackageName) {
4448 public Account[] getAccountsByTypeForPackage(String type, String packageName,
4472 private boolean needToStartChooseAccountActivity(Account[] accounts, String callingPackage) {
4475 Account account = accounts[0];
4477 int visibility = resolveAccountVisibility(account, callingPackage, userAccounts);
4483 IAccountManagerResponse response, Account[] accounts, String callingPackage) {
4495 Account[] accounts,
4509 // No qualified account exists, return an empty Bundle.
4538 Account[] accountsWithManagedNotVisible = getAccountsFromCache(
4552 Account[] accounts = new Account[parcelables.length];
4554 accounts[i] = (Account) parcelables[i];
4616 Account[] accounts = getAccountsFromCache(userAccounts, type, callingUid,
4645 for (Account account : getAccounts(userId, mContext.getOpPackageName())) {
4646 if (Objects.equals(account.getAccessId(), token)) {
4647 // An app just accessed the account. At this point it knows about
4648 // it and there is not need to hide this account from the app.
4649 // Do we need to update account visibility here?
4650 if (!hasAccountAccess(account, null, uid)) {
4651 updateAppPermission(account, AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE,
4907 updateLastAuthenticatedTime(new Account(mAccountName, mAccountType));
4914 new Account(mAccountName, mAccountType));
4936 Account account = new Account(accountName, accountType);
4937 cancelNotification(getSigninRequiredNotificationId(mAccounts, account),
5069 copyAccountToUser(/*no response*/ null, (Account) msg.obj, msg.arg1, msg.arg2);
5201 // This is a checkin request. *Only* upload the account types and the count of
5207 Account[] accounts = getAccountsFromCache(userAccounts, null /* type */,
5210 for (Account account : accounts) {
5211 fout.println(" " + account);
5241 Map<Account, Map<String, Integer>> allVisibilityValues =
5243 fout.println("Account visibility:");
5244 for (Account account : allVisibilityValues.keySet()) {
5245 fout.println(" " + account.name);
5246 Map<String, Integer> visibilities = allVisibilityValues.get(account);
5255 private void doNotification(UserAccounts accounts, Account account, CharSequence message,
5266 createNoCredentialsPermissionNotification(account, intent, packageName, userId);
5269 final NotificationId id = getSigninRequiredNotificationId(accounts, account);
5275 new Notification.Builder(contextForUser, SystemNotificationChannels.ACCOUNT)
5280 .setContentTitle(String.format(notificationTitleFormat, account.name))
5404 Account account, String authTokenType, int callerUid, int userId) {
5407 Log.v(TAG, "Access to " + account + " granted calling uid is system");
5414 Log.v(TAG, "Access to " + account + " granted calling uid "
5419 if (account != null && isAccountManagedByCaller(account.type, callerUid, userId)) {
5421 Log.v(TAG, "Access to " + account + " granted calling uid "
5422 + callerUid + " manages the account");
5426 if (account != null && hasExplicitlyGrantedPermission(account, authTokenType, callerUid)) {
5428 Log.v(TAG, "Access to " + account + " granted calling uid "
5435 Log.v(TAG, "Access to " + account + " not granted for uid " + callerUid);
5463 // Heuristic to check that account type may be associated with some contacts data and
5464 // therefore READ_CONTACTS permission grants the access to account by default.
5566 for (Account account : getUserAccountsForCaller().accountCache.get(accountType)) {
5567 if (account.name.equals(accountName)) {
5593 private boolean hasExplicitlyGrantedPermission(Account account, String authTokenType,
5604 .findMatchingGrantsCount(callerUid, authTokenType, account);
5607 account);
5614 Log.d(TAG, "no credentials permission for usage of " + account + ", "
5707 public void updateAppPermission(Account account, String authTokenType, int uid, boolean value)
5716 grantAppPermission(account, authTokenType, uid);
5718 revokeAppPermission(account, authTokenType, uid);
5723 * Allow callers with the given uid permission to get credentials for account/authTokenType.
5729 void grantAppPermission(Account account, String authTokenType, int uid) {
5730 if (account == null || authTokenType == null) {
5737 long accountId = accounts.accountsDb.findDeAccountId(account);
5742 getCredentialPermissionNotificationId(account, authTokenType, uid),
5745 cancelAccountAccessRequestNotificationIfNeeded(account, uid, true);
5752 mHandler.post(() -> listener.onAppPermissionChanged(account, uid));
5758 * account/authTokenType.
5764 private void revokeAppPermission(Account account, String authTokenType, int uid) {
5765 if (account == null || authTokenType == null) {
5774 long accountId = accounts.accountsDb.findDeAccountId(account);
5785 getCredentialPermissionNotificationId(account, authTokenType, uid),
5793 mHandler.post(() -> listener.onAppPermissionChanged(account, uid));
5797 private void removeAccountFromCacheLocked(UserAccounts accounts, Account account) {
5798 final Account[] oldAccountsForType = accounts.accountCache.get(account.type);
5800 ArrayList<Account> newAccountsList = new ArrayList<>();
5801 for (Account curAccount : oldAccountsForType) {
5802 if (!curAccount.equals(account)) {
5807 accounts.accountCache.remove(account.type);
5809 Account[] newAccountsForType = new Account[newAccountsList.size()];
5811 accounts.accountCache.put(account.type, newAccountsForType);
5814 accounts.userDataCache.remove(account);
5815 accounts.authTokenCache.remove(account);
5816 accounts.previousNameCache.remove(account);
5817 accounts.visibilityCache.remove(account);
5821 * This assumes that the caller has already checked that the account is not already present.
5822 * IMPORTANT: The account being inserted will begin to be tracked for access in remote
5823 * processes and if you will return this account to apps you should return the result.
5824 * @return The inserted account which is a new instance that is being tracked.
5826 private Account insertAccountIntoCacheLocked(UserAccounts accounts, Account account) {
5827 Account[] accountsForType = accounts.accountCache.get(account.type);
5829 Account[] newAccountsForType = new Account[oldLength + 1];
5833 String token = account.getAccessId() != null ? account.getAccessId()
5835 newAccountsForType[oldLength] = new Account(account, token);
5836 accounts.accountCache.put(account.type, newAccountsForType);
5841 private Account[] filterAccounts(UserAccounts accounts, Account[] unfiltered, int callingUid,
5847 Map<Account, Integer> firstPass = new LinkedHashMap<>();
5848 for (Account account : unfiltered) {
5849 int visibility = resolveAccountVisibility(account, visibilityFilterPackage, accounts);
5855 firstPass.put(account, visibility);
5858 Map<Account, Integer> secondPass =
5861 Account[] filtered = new Account[secondPass.size()];
5867 private Map<Account, Integer> filterSharedAccounts(UserAccounts userAccounts,
5868 @NonNull Map<Account, Integer> unfiltered, int callingUid,
5892 Account[] sharedAccounts = getSharedAccountsAsUser(userAccounts.userId);
5918 Map<Account, Integer> filtered = new LinkedHashMap<>();
5919 for (Map.Entry<Account, Integer> entry : unfiltered.entrySet()) {
5920 Account account = entry.getKey();
5921 if (account.type.equals(requiredAccountType)) {
5922 filtered.put(account, entry.getValue());
5925 for (Account shared : sharedAccounts) {
5926 if (shared.equals(account)) {
5932 filtered.put(account, entry.getValue());
5950 protected Account[] getAccountsFromCache(UserAccounts userAccounts, String accountType,
5955 Account[] accounts;
5967 Account[] accountsArray;
5969 for (Account[] accounts : userAccounts.accountCache.values()) {
5975 accountsArray = new Account[totalLength];
5977 for (Account[] accountsOfType : userAccounts.accountCache.values()) {
5990 Account account, String key, String value) {
5991 Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
5993 userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
5994 accounts.userDataCache.put(account, userDataForAccount);
6005 Account account,
6011 account, tokenType, callingPackage, pkgSigDigest);
6017 Account account, String key, String value) {
6018 Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
6020 authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account);
6021 accounts.authTokenCache.put(account, authTokensForAccount);
6030 protected String readAuthTokenInternal(UserAccounts accounts, Account account,
6032 // Fast path - check if account is already cached
6034 Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
6042 Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
6044 // need to populate the cache for this account
6045 authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account);
6046 accounts.authTokenCache.put(account, authTokensForAccount);
6053 private String readUserDataInternal(UserAccounts accounts, Account account, String key) {
6057 userDataForAccount = accounts.userDataCache.get(account);
6063 userDataForAccount = accounts.userDataCache.get(account);
6065 // need to populate the cache for this account
6066 userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
6067 accounts.userDataCache.put(account, userDataForAccount);
6116 public void requestAccountAccess(@NonNull Account account, @NonNull String packageName,
6118 if (account == null) {
6119 Slog.w(TAG, "account cannot be null");
6136 resolveAccountVisibility(account, packageName, getUserAccounts(userId));
6138 Slog.w(TAG, "requestAccountAccess: account is hidden");
6142 if (AccountManagerService.this.hasAccountAccess(account, packageName,
6158 Intent intent = newRequestAccountAccessIntent(account, packageName, uid, callback);
6164 doNotification(userAccounts, account, null, intent, packageName, userId);
6174 public boolean hasAccountAccess(@NonNull Account account, @IntRange(from = 0) int uid) {
6175 return AccountManagerService.this.hasAccountAccess(account, null, uid);