diff --git a/api/current.txt b/api/current.txt index 39097e77971d3..eca3c27d56b67 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2909,7 +2909,7 @@ package android.accounts { public class AccountManager { method public android.accounts.AccountManagerFuture addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle); - method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map); + method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]); method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException; @@ -2918,7 +2918,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public static android.accounts.AccountManager get(android.content.Context); - method public int getAccountVisibility(android.accounts.Account, int); + method public int getAccountVisibility(android.accounts.Account, java.lang.String); method public android.accounts.Account[] getAccounts(); method public java.util.Map getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String); method public android.accounts.Account[] getAccountsByType(java.lang.String); @@ -2929,9 +2929,9 @@ package android.accounts { method public android.accounts.AccountManagerFuture getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes(); + method public java.util.Map getPackagesAndVisibilityForAccount(android.accounts.Account); method public java.lang.String getPassword(android.accounts.Account); method public java.lang.String getPreviousName(android.accounts.Account); - method public java.util.Map getUidsAndVisibilityForAccount(android.accounts.Account); method public java.lang.String getUserData(android.accounts.Account, java.lang.String); method public android.accounts.AccountManagerFuture hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback, android.os.Handler); method public void invalidateAuthToken(java.lang.String, java.lang.String); @@ -2945,7 +2945,7 @@ package android.accounts { method public boolean removeAccountExplicitly(android.accounts.Account); method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener); method public android.accounts.AccountManagerFuture renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback, android.os.Handler); - method public boolean setAccountVisibility(android.accounts.Account, int, int); + method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int); method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String); method public void setPassword(android.accounts.Account, java.lang.String); method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String); @@ -2985,8 +2985,8 @@ package android.accounts { field public static final java.lang.String KEY_PASSWORD = "password"; field public static final java.lang.String KEY_USERDATA = "userdata"; field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; - field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd - field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe + field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible"; + field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible"; field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3 field public static final int VISIBILITY_UNDEFINED = 0; // 0x0 field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4 diff --git a/api/system-current.txt b/api/system-current.txt index 781600fd1776a..55b32f6c3b936 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3028,7 +3028,7 @@ package android.accounts { public class AccountManager { method public android.accounts.AccountManagerFuture addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle); - method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map); + method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]); method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException; @@ -3038,7 +3038,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback, android.os.Handler); method public static android.accounts.AccountManager get(android.content.Context); - method public int getAccountVisibility(android.accounts.Account, int); + method public int getAccountVisibility(android.accounts.Account, java.lang.String); method public android.accounts.Account[] getAccounts(); method public java.util.Map getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String); method public android.accounts.Account[] getAccountsByType(java.lang.String); @@ -3049,9 +3049,9 @@ package android.accounts { method public android.accounts.AccountManagerFuture getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes(); + method public java.util.Map getPackagesAndVisibilityForAccount(android.accounts.Account); method public java.lang.String getPassword(android.accounts.Account); method public java.lang.String getPreviousName(android.accounts.Account); - method public java.util.Map getUidsAndVisibilityForAccount(android.accounts.Account); method public java.lang.String getUserData(android.accounts.Account, java.lang.String); method public android.accounts.AccountManagerFuture hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback, android.os.Handler); method public void invalidateAuthToken(java.lang.String, java.lang.String); @@ -3065,7 +3065,7 @@ package android.accounts { method public boolean removeAccountExplicitly(android.accounts.Account); method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener); method public android.accounts.AccountManagerFuture renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback, android.os.Handler); - method public boolean setAccountVisibility(android.accounts.Account, int, int); + method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int); method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String); method public void setPassword(android.accounts.Account, java.lang.String); method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String); @@ -3105,8 +3105,8 @@ package android.accounts { field public static final java.lang.String KEY_PASSWORD = "password"; field public static final java.lang.String KEY_USERDATA = "userdata"; field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; - field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd - field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe + field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible"; + field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible"; field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3 field public static final int VISIBILITY_UNDEFINED = 0; // 0x0 field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4 diff --git a/api/test-current.txt b/api/test-current.txt index f07420a6a95b0..bc7a0015485b5 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -2909,7 +2909,7 @@ package android.accounts { public class AccountManager { method public android.accounts.AccountManagerFuture addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle); - method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map); + method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean); method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]); method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException; @@ -2918,7 +2918,7 @@ package android.accounts { method public android.accounts.AccountManagerFuture editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback, android.os.Handler); method public static android.accounts.AccountManager get(android.content.Context); - method public int getAccountVisibility(android.accounts.Account, int); + method public int getAccountVisibility(android.accounts.Account, java.lang.String); method public android.accounts.Account[] getAccounts(); method public java.util.Map getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String); method public android.accounts.Account[] getAccountsByType(java.lang.String); @@ -2929,9 +2929,9 @@ package android.accounts { method public android.accounts.AccountManagerFuture getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AccountManagerFuture getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback, android.os.Handler); method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes(); + method public java.util.Map getPackagesAndVisibilityForAccount(android.accounts.Account); method public java.lang.String getPassword(android.accounts.Account); method public java.lang.String getPreviousName(android.accounts.Account); - method public java.util.Map getUidsAndVisibilityForAccount(android.accounts.Account); method public java.lang.String getUserData(android.accounts.Account, java.lang.String); method public android.accounts.AccountManagerFuture hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback, android.os.Handler); method public void invalidateAuthToken(java.lang.String, java.lang.String); @@ -2945,7 +2945,7 @@ package android.accounts { method public boolean removeAccountExplicitly(android.accounts.Account); method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener); method public android.accounts.AccountManagerFuture renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback, android.os.Handler); - method public boolean setAccountVisibility(android.accounts.Account, int, int); + method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int); method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String); method public void setPassword(android.accounts.Account, java.lang.String); method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String); @@ -2985,8 +2985,8 @@ package android.accounts { field public static final java.lang.String KEY_PASSWORD = "password"; field public static final java.lang.String KEY_USERDATA = "userdata"; field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED"; - field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd - field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe + field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible"; + field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible"; field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3 field public static final int VISIBILITY_UNDEFINED = 0; // 0x0 field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4 diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index def0ff9878995..02636819781a9 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -338,21 +338,24 @@ public class AccountManager { "android.accounts.LOGIN_ACCOUNTS_CHANGED"; /** - * Uid key to set default visibility for applications targeting API level + * Key to set default visibility for applications targeting API level * {@link android.os.Build.VERSION_CODES#O} or above and don't have the same signature as * authenticator See {@link #getAccountVisibility}. If the value was not set by authenticator - * USER_MANAGED_NOT_VISIBLE is used. + * {@link #VISIBILITY_USER_MANAGED_NOT_VISIBLE} is used. */ - public static final int UID_KEY_DEFAULT_VISIBILITY = -2; + public static final String PACKAGE_NAME_KEY_LEGACY_VISIBLE = + "android.accounts.key_legacy_visible"; /** - * Uid key to set visibility for applications targeting API level below - * {@link android.os.Build.VERSION_CODES#O} with GET_ACCOUNS permission, or applications with - * any targeting API level with the same signature as authenticator. See - * {@link #getAccountVisibility}. If the value was not set by authenticator USER_MANAGED_VISIBLE - * is used. + * Key to set visibility for applications targeting API level below + * {@link android.os.Build.VERSION_CODES#O} with + * {@link android.Manifest.permission#GET_ACCOUNTS} permission, or applications with any + * targeting API level with the same signature as authenticator. See + * {@link #getAccountVisibility}. If the value was not set by authenticator + * {@link #VISIBILITY_USER_MANAGED_VISIBLE} is used. */ - public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; + public static final String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = + "android.accounts.key_legacy_not_visible"; /** * @hide @@ -565,12 +568,14 @@ public class AccountManager { } /** - * Returns the accounts visible to the specified package, in an environment where some apps - * are not authorized to view all accounts. This method can only be called by system apps. + * Returns the accounts visible to the specified package, in an environment where some apps are + * not authorized to view all accounts. This method can only be called by system apps and + * authenticators managing the type + * * @param type The type of accounts to return, null to retrieve all accounts * @param packageName The package name of the app for which the accounts are to be returned - * @return An array of {@link Account}, one per matching account. Empty - * (never null) if no accounts of the specified type have been added. + * @return An array of {@link Account}, one per matching account. Empty (never null) if no + * accounts of the specified type have been added. */ @NonNull public Account[] getAccountsByTypeForPackage(String type, String packageName) { @@ -609,7 +614,8 @@ public class AccountManager { * *

* NOTE: If targeting your app to work on API level - * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, GET_ACCOUNTS permission is + * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, + * {@link android.Manifest.permission#GET_ACCOUNTS} permission is * needed for those platforms, irrespective of uid or signature match. See docs for this * function in API level {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}. * @@ -750,7 +756,8 @@ public class AccountManager { * accounts managed by AbstractAccountAuthenticators whose signature matches the client. *

* NOTE: If targeting your app to work on API level - * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, GET_ACCOUNTS permission is + * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, + * {@link android.Manifest.permission#GET_ACCOUNTS} permission is * needed for those platforms, irrespective of uid or signature match. See docs for this * function in API level {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}. * @@ -822,9 +829,8 @@ public class AccountManager { } /** - * Adds an account directly to the AccountManager. Additionally this makes the Account visible - * to desired UIDs of applications on the device, and sends directed broadcasts to these - * individual applications. + * Adds an account directly to the AccountManager. Additionally it specifies Account visiblity + * for given list of packages. *

* Normally used by sign-up wizards associated with authenticators, not directly by * applications. @@ -841,14 +847,14 @@ public class AccountManager { * @param account The {@link Account} to add * @param password The password to associate with the account, null for none * @param extras String values to use for the account's userdata, null for none - * @param visibility Map from uid to visibility values which will be set before account is - * added. See getAccountVisibility for possilbe values. + * @param visibility Map from packageName to visibility values which will be set before account + * is added. See {@link #getAccountVisibility} for possible values. * * @return True if the account was successfully added, false if the account already exists, the * account is null, or another error occurs. */ public boolean addAccountExplicitly(Account account, String password, Bundle extras, - Map visibility) { + Map visibility) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -860,20 +866,22 @@ public class AccountManager { } /** - * Returns UIDs of applications for which visibility of given account was explicitly set. + * Returns package names and visibility which were explicitly set for given account. *

* This method requires the caller to have a signature match with the authenticator that owns * the specified account. * * @param account The account for which visibility data should be returned. * - * @return Map from uid to visibility for given account. + * @return Map from package names to visibility for given account. */ - public Map getUidsAndVisibilityForAccount(Account account) { + public Map getPackagesAndVisibilityForAccount(Account account) { try { + if (account == null) + throw new IllegalArgumentException("account is null"); @SuppressWarnings("unchecked") - Map result = (Map) mService - .getUidsAndVisibilityForAccount(account); + Map result = (Map) mService + .getPackagesAndVisibilityForAccount(account); return result; } catch (RemoteException re) { throw re.rethrowFromSystemServer(); @@ -907,30 +915,34 @@ public class AccountManager { } /** - * Set visibility value of given account to certain UID. + * Set visibility value of given account to certain packageName. + * Package name must match installed application, or be equal to + * {@link #PACKAGE_NAME_KEY_LEGACY_VISIBLE} or {@link #PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE}. *

* See {@link #getAccountVisibility} for possible values. *

* This method requires the caller to have a signature match with the authenticator that owns * the specified account. * - * @param account Account to make visible. - * @param uid The UID of the application to modify account visibility. + * @param account Account to update visibility + * @param packageName Package name of the application to modify account visibility. * @param visibility - new visibility value. * * @return True if visibility value was succesfully updated. */ - public boolean setAccountVisibility(Account account, int uid, + public boolean setAccountVisibility(Account account, String packageName, @AccountVisibility int visibility) { + if (account == null) + throw new IllegalArgumentException("account is null"); try { - return mService.setAccountVisibility(account, uid, visibility); + return mService.setAccountVisibility(account, packageName, visibility); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** - * Gets visibility of certain account for given UID. Possible returned values are: + * Get visibility of certain account for given application. Possible returned values are: *

    *
  • {@link #VISIBILITY_UNDEFINED}
  • *
  • {@link #VISIBILITY_VISIBLE}
  • @@ -944,13 +956,15 @@ public class AccountManager { * the specified account. * * @param account Account to get visibility. - * @param uid The UID of the application to get account visibility. + * @param packageName Package name of the application to get account visibility * - * @return int Visibility for given account and uid. + * @return int Visibility for given account and package. */ - public @AccountVisibility int getAccountVisibility(Account account, int uid) { + public @AccountVisibility int getAccountVisibility(Account account, String packageName) { + if (account == null) + throw new IllegalArgumentException("account is null"); try { - return mService.getAccountVisibility(account, uid); + return mService.getAccountVisibility(account, packageName); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java index 95fdfef7a5c3a..35011b5f3ec3e 100644 --- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java +++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java @@ -437,7 +437,7 @@ public class ChooseTypeAndAccountActivity extends Activity } if (oldVisibility != null && oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE) { - AccountManager.get(this).setAccountVisibility(account, mCallingUid, + AccountManager.get(this).setAccountVisibility(account, mCallingPackage, AccountManager.VISIBILITY_USER_MANAGED_VISIBLE); } Bundle bundle = new Bundle(); diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl index 63a0919aec5d8..e0fdac146f68a 100644 --- a/core/java/android/accounts/IAccountManager.aidl +++ b/core/java/android/accounts/IAccountManager.aidl @@ -108,15 +108,12 @@ interface IAccountManager { void isCredentialsUpdateSuggested(in IAccountManagerResponse response, in Account account, String statusToken); - /* Returns Map from UID to visibility with all values stored for given account*/ - Map getUidsAndVisibilityForAccount(in Account account); - + /* Returns Map from package name to visibility with all values stored for given account */ + Map getPackagesAndVisibilityForAccount(in Account account); boolean addAccountExplicitlyWithVisibility(in Account account, String password, in Bundle extras, in Map visibility); - - boolean setAccountVisibility(in Account a, int uid, int newVisibility); - int getAccountVisibility(in Account a, int uid); - + boolean setAccountVisibility(in Account a, in String packageName, int newVisibility); + int getAccountVisibility(in Account a, in String packageName); /* Type may be null returns Map */ Map getAccountsAndVisibilityForPackage(in String packageName, in String accountType); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index bfa3f04edc689..fdd7cb1392045 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -287,16 +287,17 @@ public class AccountManagerService * and then rebuild the cache. All under the cache lock. But that change is too * large at this point. */ + final String removedPackageName = intent.getData().toString(); Runnable purgingRunnable = new Runnable() { @Override public void run() { purgeOldGrantsAll(); // Notify authenticator about removed app? + removeVisibilityValuesForPackage(removedPackageName); } }; mHandler.post(purgingRunnable); } - } }, intentFilter); @@ -429,7 +430,7 @@ public class AccountManagerService @Override public boolean addAccountExplicitlyWithVisibility(Account account, String password, - Bundle extras, Map uidToVisibility) { + Bundle extras, Map packageToVisibility) { Bundle.setDefusable(extras, true); final int callingUid = Binder.getCallingUid(); @@ -455,7 +456,7 @@ public class AccountManagerService try { UserAccounts accounts = getUserAccounts(userId); return addAccountInternal(accounts, account, password, extras, callingUid, - (Map) uidToVisibility); + (Map) packageToVisibility); } finally { restoreCallingIdentity(identityToken); } @@ -505,7 +506,7 @@ public class AccountManagerService if (accountsOfType != null) { for (Account account : accountsOfType) { result.put(account, - resolveAccountVisibility(account, uid, packageName, accounts)); + resolveAccountVisibility(account, packageName, accounts)); } } } @@ -514,7 +515,7 @@ public class AccountManagerService } @Override - public Map getUidsAndVisibilityForAccount(Account account) { + public Map getPackagesAndVisibilityForAccount(Account account) { if (account == null) throw new IllegalArgumentException("account is null"); int callingUid = Binder.getCallingUid(); int userId = UserHandle.getUserId(callingUid); @@ -525,18 +526,18 @@ public class AccountManagerService String.format("uid %s cannot get secrets for account %s", callingUid, account); throw new SecurityException(msg); } - return getUidsAndVisibilityForAccount(account, accounts); + return getPackagesAndVisibilityForAccount(account, accounts); } /** - * Returns all UIDs and visibility values, which were set for given account + * Returns all package names and visibility values, which were set for given account. * - * @param account account + * @param account Account to get visibility values. * @param accounts UserAccount that currently hosts the account and application * - * @return Map from uid to visibility. + * @return Map from package names to visibility. */ - private Map getUidsAndVisibilityForAccount(Account account, + private Map getPackagesAndVisibilityForAccount(Account account, UserAccounts accounts) { final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { @@ -548,7 +549,7 @@ public class AccountManagerService } @Override - public int getAccountVisibility(Account a, int uid) { + public int getAccountVisibility(Account a, String packageName) { if (a == null) throw new IllegalArgumentException("account is null"); int callingUid = Binder.getCallingUid(); if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid)) @@ -559,23 +560,24 @@ public class AccountManagerService a.type); throw new SecurityException(msg); } - return getAccountVisibility(a, uid, getUserAccounts(UserHandle.getUserId(callingUid))); + return getAccountVisibility(a, packageName, + getUserAccounts(UserHandle.getUserId(callingUid))); } /** - * Method gets visibility for given account and UID from the database + * Method returns visibility for given account and package name. * - * @param account The account to check visibility of - * @param uid UID to check visibility of + * @param account The account to check visibility. + * @param packageName Package name to check visibility. * @param accounts UserAccount that currently hosts the account and application * * @return Visibility value, AccountManager.VISIBILITY_UNDEFINED if no value was stored. * */ - private int getAccountVisibility(Account account, int uid, UserAccounts accounts) { + private int getAccountVisibility(Account account, String packageName, UserAccounts accounts) { final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { - Integer visibility = accounts.accountsDb.findAccountVisibility(account, uid); + Integer visibility = accounts.accountsDb.findAccountVisibility(account, packageName); return visibility != null ? visibility : AccountManager.VISIBILITY_UNDEFINED; } finally { StrictMode.setThreadPolicy(oldPolicy); @@ -586,19 +588,29 @@ public class AccountManagerService * Method which handles default values for Account visibility. * * @param account The account to check visibility. - * @param uid UID to check visibility. - * @param packageName Package name to check visibility - the method assumes that it has the same - * uid as specified in the parameter. + * @param packageName Package name to check visibility * @param accounts UserAccount that currently hosts the account and application * * @return Visibility value, the method never returns AccountManager.VISIBILITY_UNDEFINED * */ - private Integer resolveAccountVisibility(Account account, int uid, String packageName, + private Integer resolveAccountVisibility(Account account, @NonNull String packageName, UserAccounts accounts) { - if (packageName == null) { - packageName = getPackageNameForUid(uid); + Preconditions.checkNotNull(packageName, "packageName cannot be null"); + + int uid = -1; + try { + long identityToken = clearCallingIdentity(); + try { + uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId); + } finally { + restoreCallingIdentity(identityToken); + } + } catch (NameNotFoundException e) { + Log.d(TAG, "Package not found " + e.getMessage()); + return AccountManager.VISIBILITY_NOT_VISIBLE; } + // System visibility can not be restricted. if (UserHandle.isSameApp(uid, Process.SYSTEM_UID)) { return AccountManager.VISIBILITY_VISIBLE; @@ -612,8 +624,13 @@ public class AccountManagerService return AccountManager.VISIBILITY_VISIBLE; // Authenticator can always see the account } + if (isSpecialPackageKey(packageName)) { + Log.d(TAG, "Package name is forbidden: " + packageName); + return AccountManager.VISIBILITY_NOT_VISIBLE; + } + // Return stored value if it was set. - int visibility = getAccountVisibility(account, uid, accounts); + int visibility = getAccountVisibility(account, packageName, accounts); if (AccountManager.VISIBILITY_UNDEFINED != visibility) { return visibility; @@ -622,10 +639,9 @@ public class AccountManagerService if (isPermittedForPackage(packageName, accounts.userId, Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) { return AccountManager.VISIBILITY_VISIBLE; - } // Profile owner gets visibility by default. - if(isProfileOwner(uid)) { + if (isProfileOwner(uid)) { return AccountManager.VISIBILITY_VISIBLE; } // Apps with READ_CONTACTS permission get visibility by default even post O. @@ -638,13 +654,13 @@ public class AccountManagerService // Use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature // match. visibility = getAccountVisibility(account, - AccountManager.UID_KEY_DEFAULT_LEGACY_VISIBILITY, accounts); + AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE, accounts); if (AccountManager.VISIBILITY_UNDEFINED == visibility) { visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE; } } else { - visibility = getAccountVisibility(account, AccountManager.UID_KEY_DEFAULT_VISIBILITY, - accounts); + visibility = getAccountVisibility(account, + AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, accounts); if (AccountManager.VISIBILITY_UNDEFINED == visibility) { visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE; } @@ -655,7 +671,7 @@ public class AccountManagerService /** * Checks targetSdk for a package; * - * @param packageName Package Name + * @param packageName Package name * * @return True if package's target SDK is below {@link android.os.Build.VERSION_CODES#O}, or * undefined @@ -682,7 +698,7 @@ public class AccountManagerService } @Override - public boolean setAccountVisibility(Account a, int uid, int newVisibility) { + public boolean setAccountVisibility(Account a, String packageName, int newVisibility) { if (a == null) throw new IllegalArgumentException("account is null"); int callingUid = Binder.getCallingUid(); if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid)) @@ -693,38 +709,42 @@ public class AccountManagerService a.type); throw new SecurityException(msg); } - return setAccountVisibility(a, uid, newVisibility, true /* notify */, + return setAccountVisibility(a, packageName, newVisibility, true /* notify */, getUserAccounts(UserHandle.getUserId(callingUid))); } /** - * Gives a certain UID, represented a application, access to an account. This method - * is called indirectly by the Authenticator. + * Updates visibility for given account name and package. * - * @param account Account to update visibility - * @param uid to add visibility of the Account - * @param newVisibility new visibility + * @param account Account to update visibility. + * @param packageName Package name for which visibility is updated. + * @param newVisibility New visibility calue * @param notify if the flag is set applications will get notification about visibility change * @param accounts UserAccount that currently hosts the account and application * * @return True if account visibility was changed. */ - private boolean setAccountVisibility(Account account, int uid, int newVisibility, + private boolean setAccountVisibility(Account account, String packageName, int newVisibility, boolean notify, UserAccounts accounts) { synchronized (accounts.cacheLock) { LinkedHashSet interestedPackages; if (notify) { - if (uid < 0) { + if (isSpecialPackageKey(packageName)) { interestedPackages = getRequestingPackageNames(account.type, accounts); } else { - interestedPackages = new LinkedHashSet<>(); - String[] subPackages = mPackageManager.getPackagesForUid(uid); - if (subPackages != null) { - Collections.addAll(interestedPackages, subPackages); + if (!packageExistsForUser(packageName, accounts.userId)) { + return false; // package is not installed. } + interestedPackages = new LinkedHashSet<>(); + interestedPackages.add(packageName); } } else { // Notifications will not be send. + if (!isSpecialPackageKey(packageName) && + !packageExistsForUser(packageName, accounts.userId)) { + // package is not installed and not meta value. + return false; + } interestedPackages = new LinkedHashSet<>(); } Integer[] interestedPackagesVisibility = new Integer[interestedPackages.size()]; @@ -734,14 +754,15 @@ public class AccountManagerService return false; } int index = 0; - for (String packageName : interestedPackages) { + for (String interestedPackage : interestedPackages) { interestedPackagesVisibility[index++] = - resolveAccountVisibility(account, uid, packageName, accounts); + resolveAccountVisibility(account, interestedPackage, accounts); } final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); try { - if (!accounts.accountsDb.setAccountVisibility(accountId, uid, newVisibility)) { + if (!accounts.accountsDb.setAccountVisibility(accountId, packageName, + newVisibility)) { return false; } } finally { @@ -749,10 +770,10 @@ public class AccountManagerService } index = 0; - for (String packageName : interestedPackages) { - int visibility = resolveAccountVisibility(account, uid, packageName, accounts); + for (String interestedPackage : interestedPackages) { + int visibility = resolveAccountVisibility(account, interestedPackage, accounts); if (visibility != interestedPackagesVisibility[index++]) { - sendNotification(packageName, account, accounts.userId); + sendNotification(interestedPackage, account, accounts.userId); } } if (notify) { @@ -777,23 +798,40 @@ public class AccountManagerService LinkedHashSet interestedPackages = getRequestingPackageNames(account.type, accounts); for (String packageName : interestedPackages) { - try { - final int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId); - int visibility = resolveAccountVisibility(account, uid, packageName, accounts); - if (visibility != AccountManager.VISIBILITY_NOT_VISIBLE) { - sendNotification(packageName, account, accounts.userId); - } - } catch (NameNotFoundException e) { - // ignore + int visibility = resolveAccountVisibility(account, packageName, accounts); + if (visibility != AccountManager.VISIBILITY_NOT_VISIBLE) { + sendNotification(packageName, account, accounts.userId); } } } - LinkedHashSet getRequestingPackageNames(String accountType, UserAccounts accouns) { + LinkedHashSet getRequestingPackageNames(String accountType, UserAccounts accounts) { // TODO return packages registered to get notifications. return new LinkedHashSet(); } + private boolean packageExistsForUser(String packageName, int userId) { + try { + long identityToken = clearCallingIdentity(); + try { + mPackageManager.getPackageUidAsUser(packageName, userId); + return true; // package exist + } finally { + restoreCallingIdentity(identityToken); + } + } catch (NameNotFoundException e) { + return false; + } + } + + /** + * Returns true if packageName is one of special values. + */ + private boolean isSpecialPackageKey(String packageName) { + return (AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE.equals(packageName) + || AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE.equals(packageName)); + } + private void sendAccountsChangedBroadcast(int userId) { Log.i(TAG, "the accounts changed, sending broadcast of " + ACCOUNTS_CHANGED_INTENT.getAction()); @@ -1075,6 +1113,20 @@ public class AccountManagerService } } + private void removeVisibilityValuesForPackage(String packageName) { + synchronized (mUsers) { + for (int i = 0; i < mUsers.size(); i++) { + UserAccounts accounts = mUsers.valueAt(i); + try { + int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId); + } catch (NameNotFoundException e) { + // package does not exist - remove visibility values + accounts.accountsDb.deleteAccountVisibilityForPackage(packageName); + } + } + } + } + private void onUserRemoved(Intent intent) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId < 1) return; @@ -1472,7 +1524,7 @@ public class AccountManagerService } private boolean addAccountInternal(UserAccounts accounts, Account account, String password, - Bundle extras, int callingUid, Map uidToVisibility) { + Bundle extras, int callingUid, Map packageToVisibility) { Bundle.setDefusable(extras, true); if (account == null) { return false; @@ -1513,9 +1565,9 @@ public class AccountManagerService } } - if (uidToVisibility != null) { - for (Entry entry : uidToVisibility.entrySet()) { - setAccountVisibility(account, entry.getKey() /* uid */, + if (packageToVisibility != null) { + for (Entry entry : packageToVisibility.entrySet()) { + setAccountVisibility(account, entry.getKey() /* package */, entry.getValue() /* visibility */, false /* notify */, accounts); } } @@ -1569,6 +1621,7 @@ public class AccountManagerService public void hasFeatures(IAccountManagerResponse response, Account account, String[] features, String opPackageName) { int callingUid = Binder.getCallingUid(); + mAppOpsManager.checkPackage(callingUid, opPackageName); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "hasFeatures: " + account + ", response " + response @@ -1982,14 +2035,7 @@ public class AccountManagerService int[] visibilityForInterestedPackages = new int[interestedPackages.size()]; int index = 0; for (String packageName : interestedPackages) { - int visibility = AccountManager.VISIBILITY_NOT_VISIBLE; - try { - final int uid = mPackageManager.getPackageUidAsUser(packageName, - UserHandle.getUserId(callingUid)); - visibility = resolveAccountVisibility(account, uid, packageName, accounts); - } catch (NameNotFoundException e) { - // ignore - } + int visibility = resolveAccountVisibility(account, packageName, accounts); visibilityForInterestedPackages[index++] = visibility; } accounts.accountsDb.beginTransaction(); @@ -3663,7 +3709,7 @@ public class AccountManagerService // In addition to the permissions required to get an auth token we also allow // the account to be accessed by apps for which user or authenticator granted visibility. - int visibility = resolveAccountVisibility(account, uid, packageName, + int visibility = resolveAccountVisibility(account, packageName, getUserAccounts(UserHandle.getUserId(uid))); return (visibility == AccountManager.VISIBILITY_VISIBLE || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE); @@ -3870,6 +3916,7 @@ public class AccountManagerService @NonNull public Account[] getAccounts(int userId, String opPackageName) { int callingUid = Binder.getCallingUid(); + mAppOpsManager.checkPackage(callingUid, opPackageName); List visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId, opPackageName); if (visibleAccountTypes.isEmpty()) { @@ -3890,7 +3937,7 @@ public class AccountManagerService } /** - * Returns accounts for all running users. + * Returns accounts for all running users, ignores visibility values. * * @hide */ @@ -3906,7 +3953,11 @@ public class AccountManagerService return getAccounts(runningUserIds); } - /** {@hide} */ + /** + * Returns accounts for all users, ignores visibility values. + * + * @hide + */ @NonNull public AccountAndUser[] getAllAccounts() { final List users = getUserManager().getUsers(true); @@ -3924,10 +3975,12 @@ public class AccountManagerService UserAccounts userAccounts = getUserAccounts(userId); if (userAccounts == null) continue; synchronized (userAccounts.cacheLock) { - Account[] accounts = getAccountsFromCacheLocked(userAccounts, null, + Account[] accounts = getAccountsFromCacheLocked( + userAccounts, + null /* type */, Binder.getCallingUid(), - null, - false /* incl managed not visible*/); + null /* packageName */, + false /* include managed not visible*/); for (int a = 0; a < accounts.length; a++) { runningAccounts.add(new AccountAndUser(accounts[a], userId)); } @@ -3941,9 +3994,10 @@ public class AccountManagerService @Override @NonNull public Account[] getAccountsAsUser(String type, int userId, String opPackageName) { - // Need calling package - return getAccountsAsUser(type, userId, null /* callingPackage */, -1, opPackageName, - false /* includeUserManagedNotVisible */); + int callingUid = Binder.getCallingUid(); + mAppOpsManager.checkPackage(callingUid, opPackageName); + return getAccountsAsUser(type, userId, opPackageName /* callingPackage */, -1, + opPackageName, false /* includeUserManagedNotVisible */); } @NonNull @@ -4112,6 +4166,7 @@ public class AccountManagerService public Account[] getAccountsForPackage(String packageName, int uid, String opPackageName) { int callingUid = Binder.getCallingUid(); if (!UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)) { + // Don't do opPackageName check - caller is system. throw new SecurityException("getAccountsForPackage() called from unauthorized uid " + callingUid + " with uid=" + uid); } @@ -4125,6 +4180,7 @@ public class AccountManagerService String opPackageName) { int callingUid = Binder.getCallingUid(); int userId = UserHandle.getCallingUserId(); + mAppOpsManager.checkPackage(callingUid, opPackageName); int packageUid = -1; try { packageUid = mPackageManager.getPackageUidAsUser(packageName, userId); @@ -4148,6 +4204,7 @@ public class AccountManagerService String[] features, String opPackageName) { int callingUid = Binder.getCallingUid(); + mAppOpsManager.checkPackage(callingUid, opPackageName); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "getAccounts: accountType " + type + ", response " + response @@ -4738,7 +4795,7 @@ public class AccountManagerService userAccounts.accountsDb.dumpDeAccountsTable(fout); } else { Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */, - Process.SYSTEM_UID, null, false); + Process.SYSTEM_UID, null /* packageName */, false); fout.println("Accounts: " + accounts.length); for (Account account : accounts) { fout.println(" " + account); @@ -4954,7 +5011,7 @@ public class AccountManagerService // Method checks visibility for applications targeing API level below {@link // android.os.Build.VERSION_CODES#O}, - // returns true if the the app has GET_ACCOUNTS or GET_ACCOUNTS_PRIVELEGED permission. + // returns true if the the app has GET_ACCOUNTS or GET_ACCOUNTS_PRIVILEGED permission. private boolean checkGetAccountsPermission(String packageName, int userId) { return isPermittedForPackage(packageName, userId, Manifest.permission.GET_ACCOUNTS, Manifest.permission.GET_ACCOUNTS_PRIVILEGED); @@ -5307,8 +5364,7 @@ public class AccountManagerService // filter based on visibility. Map firstPass = new HashMap<>(); for (Account account : unfiltered) { - int visibility = - resolveAccountVisibility(account, callingUid, callingPackage, accounts); + int visibility = resolveAccountVisibility(account, callingPackage, accounts); if ((visibility == AccountManager.VISIBILITY_VISIBLE || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE) || (includeManagedNotVisible @@ -5403,6 +5459,9 @@ public class AccountManagerService */ protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType, int callingUid, String callingPackage, boolean includeManagedNotVisible) { + if (callingPackage == null) { + callingPackage = getPackageNameForUid(callingUid); + } if (accountType != null) { final Account[] accounts = userAccounts.accountCache.get(accountType); if (accounts == null) { diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java index 85e4b5ffbdc33..537002648ed9e 100644 --- a/services/core/java/com/android/server/accounts/AccountsDb.java +++ b/services/core/java/com/android/server/accounts/AccountsDb.java @@ -54,7 +54,7 @@ class AccountsDb implements AutoCloseable { private static final String DATABASE_NAME = "accounts.db"; private static final int PRE_N_DATABASE_VERSION = 9; private static final int CE_DATABASE_VERSION = 10; - private static final int DE_DATABASE_VERSION = 2; // Added visibility support in O. + private static final int DE_DATABASE_VERSION = 3; // Added visibility support in O static final String TABLE_ACCOUNTS = "accounts"; @@ -75,7 +75,7 @@ class AccountsDb implements AutoCloseable { private static final String TABLE_VISIBILITY = "visibility"; private static final String VISIBILITY_ACCOUNTS_ID = "accounts_id"; - private static final String VISIBILITY_UID = "_uid"; + private static final String VISIBILITY_PACKAGE = "_package"; private static final String VISIBILITY_VALUE = "value"; private static final String TABLE_GRANTS = "grants"; @@ -252,7 +252,7 @@ class AccountsDb implements AutoCloseable { createAccountsDeletionTrigger(db); db.execSQL("DROP TABLE IF EXISTS " + TABLE_GRANTS); db.execSQL("DROP TABLE IF EXISTS " + TABLE_DEBUG); - oldVersion ++; + oldVersion++; } if (oldVersion != newVersion) { @@ -559,9 +559,9 @@ class AccountsDb implements AutoCloseable { private void createAccountsVisibilityTable(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE_VISIBILITY + " ( " + VISIBILITY_ACCOUNTS_ID + " INTEGER NOT NULL, " - + VISIBILITY_UID + " TEXT NOT NULL, " + + VISIBILITY_PACKAGE + " TEXT NOT NULL, " + VISIBILITY_VALUE + " INTEGER, " - + "PRIMARY KEY(" + VISIBILITY_ACCOUNTS_ID + "," + VISIBILITY_UID + "))"); + + "PRIMARY KEY(" + VISIBILITY_ACCOUNTS_ID + "," + VISIBILITY_PACKAGE + "))"); } static void createDebugTable(SQLiteDatabase db) { @@ -591,9 +591,18 @@ class AccountsDb implements AutoCloseable { Log.i(TAG, "upgrade from version " + oldVersion + " to version " + newVersion); if (oldVersion == 1) { - createAccountsVisibilityTable(db); - createAccountsDeletionVisibilityCleanupTrigger(db); - ++oldVersion; + createAccountsVisibilityTable(db); + createAccountsDeletionVisibilityCleanupTrigger(db); + oldVersion = 3; // skip version 2 which had uid based table + } + + if (oldVersion == 2) { + // Remove uid based table and replace it with packageName based + db.execSQL("DROP TRIGGER IF EXISTS " + TABLE_ACCOUNTS + "DeleteVisibility"); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_ACCOUNTS); + createAccountsVisibilityTable(db); + createAccountsDeletionVisibilityCleanupTrigger(db); + oldVersion++; } if (oldVersion != newVersion) { @@ -890,20 +899,20 @@ class AccountsDb implements AutoCloseable { new String[] {Integer.toString(uid)}) > 0; } - boolean setAccountVisibility(long accountId, int uid, int visibility) { + boolean setAccountVisibility(long accountId, String packageName, int visibility) { SQLiteDatabase db = mDeDatabase.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(VISIBILITY_ACCOUNTS_ID, String.valueOf(accountId)); - values.put(VISIBILITY_UID, String.valueOf(uid)); + values.put(VISIBILITY_PACKAGE, packageName); values.put(VISIBILITY_VALUE, String.valueOf(visibility)); return (db.replace(TABLE_VISIBILITY, VISIBILITY_VALUE, values) != -1); } - Integer findAccountVisibility(Account account, int uid) { + Integer findAccountVisibility(Account account, String packageName) { SQLiteDatabase db = mDeDatabase.getWritableDatabase(); final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE}, - SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_UID + "=? ", - new String[] {account.name, account.type, String.valueOf(uid)}, null, null, null); + SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_PACKAGE + "=? ", + new String[] {account.name, account.type, packageName}, null, null, null); try { while (cursor.moveToNext()) { return cursor.getInt(0); @@ -914,11 +923,11 @@ class AccountsDb implements AutoCloseable { return null; } - Integer findAccountVisibility(long accountId, int uid) { + Integer findAccountVisibility(long accountId, String packageName) { SQLiteDatabase db = mDeDatabase.getWritableDatabase(); final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE}, - VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_UID + "=? ", - new String[] {String.valueOf(accountId), String.valueOf(uid)}, null, null, null); + VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_PACKAGE + "=? ", + new String[] {String.valueOf(accountId), packageName}, null, null, null); try { while (cursor.moveToNext()) { return cursor.getInt(0); @@ -944,18 +953,18 @@ class AccountsDb implements AutoCloseable { } /** - * Returns a map from uid to visibility value. + * Returns a map from packageNames to visibility. */ - Map findAllVisibilityValuesForAccount(Account account) { + Map findAllVisibilityValuesForAccount(Account account) { SQLiteDatabase db = mDeDatabase.getReadableDatabase(); - Map result = new HashMap<>(); + Map result = new HashMap<>(); final Cursor cursor = - db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_UID, VISIBILITY_VALUE}, - SELECTION_ACCOUNTS_ID_BY_ACCOUNT, - new String[] {account.name, account.type}, null, null, null); + db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_PACKAGE, VISIBILITY_VALUE}, + SELECTION_ACCOUNTS_ID_BY_ACCOUNT, new String[] {account.name, account.type}, + null, null, null); try { while (cursor.moveToNext()) { - result.put(cursor.getInt(0), cursor.getInt(1)); + result.put(cursor.getString(0), cursor.getInt(1)); } } finally { cursor.close(); @@ -963,10 +972,10 @@ class AccountsDb implements AutoCloseable { return result; } - boolean deleteAccountVisibilityForUid(int uid) { + boolean deleteAccountVisibilityForPackage(String packageName) { SQLiteDatabase db = mDeDatabase.getWritableDatabase(); - return db.delete(TABLE_VISIBILITY, VISIBILITY_UID + "=? ", - new String[] {Integer.toString(uid)}) > 0; + return db.delete(TABLE_VISIBILITY, VISIBILITY_PACKAGE + "=? ", + new String[] {packageName}) > 0; } long insertOrReplaceMetaAuthTypeAndUid(String authenticatorType, int uid) { diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index 213fb27b8a7b9..e433b60e1c94a 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -190,6 +190,8 @@ public class AccountManagerServiceTest extends AndroidTestCase { mAms.addAccountExplicitly(a31, "p31", null); mAms.addAccountExplicitly(a32, "p32", null); + String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE}; + when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list); Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName()); Arrays.sort(accounts, new AccountSorter()); assertEquals(6, accounts.length); @@ -306,6 +308,8 @@ public class AccountManagerServiceTest extends AndroidTestCase { @SmallTest public void testRemovedAccountSync() throws Exception { + String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE}; + when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list); unlockSystemUser(); Account a1 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); Account a2 = new Account("account2", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2); @@ -347,6 +351,8 @@ public class AccountManagerServiceTest extends AndroidTestCase { // Start testing unlockSystemUser(); + String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE}; + when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list); Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName()); assertEquals("1 account should be migrated", 1, accounts.length); assertEquals(PreNTestDatabaseHelper.ACCOUNT_NAME, accounts[0].name); @@ -1048,7 +1054,6 @@ public class AccountManagerServiceTest extends AndroidTestCase { // Assert finishSessionAsUser added calling uid and pid into the sessionBundle assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_UID)); assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_PID)); - // Assert App bundle data overrides sessionBundle data assertEquals(sessionBundle.getString( AccountManager.KEY_ANDROID_PACKAGE_NAME), "APCT.package"); @@ -1387,6 +1392,9 @@ public class AccountManagerServiceTest extends AndroidTestCase { @SmallTest public void testRemoveAccountAsUserRemovalAllowed() throws Exception { + String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE}; + when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list); + unlockSystemUser(); mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p1", null); Account[] addedAccounts = diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java index 2e045ff433411..2cb8af4e97e7d 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java @@ -355,49 +355,49 @@ public class AccountsDbTest { @Test public void testVisibilityFindSetDelete() { long accId = 10; - int uid1 = 100500; - int uid2 = 100501; + String packageName1 = "com.example.one"; + String packageName2 = "com.example.two"; Account account = new Account("name", "example.com"); - assertNull(mAccountsDb.findAccountVisibility(account, uid1)); + assertNull(mAccountsDb.findAccountVisibility(account, packageName1)); mAccountsDb.insertDeAccount(account, accId); - assertNull(mAccountsDb.findAccountVisibility(account, uid1)); - assertNull(mAccountsDb.findAccountVisibility(accId, uid1)); + assertNull(mAccountsDb.findAccountVisibility(account, packageName1)); + assertNull(mAccountsDb.findAccountVisibility(accId, packageName1)); - mAccountsDb.setAccountVisibility(accId, uid1, 1); - assertEquals(mAccountsDb.findAccountVisibility(account, uid1), Integer.valueOf(1)); - assertEquals(mAccountsDb.findAccountVisibility(accId, uid1), Integer.valueOf(1)); + mAccountsDb.setAccountVisibility(accId, packageName1, 1); + assertEquals(mAccountsDb.findAccountVisibility(account, packageName1), Integer.valueOf(1)); + assertEquals(mAccountsDb.findAccountVisibility(accId, packageName1), Integer.valueOf(1)); - mAccountsDb.setAccountVisibility(accId, uid2, 2); - assertEquals(mAccountsDb.findAccountVisibility(accId, uid2), Integer.valueOf(2)); + mAccountsDb.setAccountVisibility(accId, packageName2, 2); + assertEquals(mAccountsDb.findAccountVisibility(accId, packageName2), Integer.valueOf(2)); - mAccountsDb.setAccountVisibility(accId, uid2, 3); - assertEquals(mAccountsDb.findAccountVisibility(accId, uid2), Integer.valueOf(3)); + mAccountsDb.setAccountVisibility(accId, packageName2, 3); + assertEquals(mAccountsDb.findAccountVisibility(accId, packageName2), Integer.valueOf(3)); - Map vis = mAccountsDb.findAllVisibilityValuesForAccount(account); + Map vis = mAccountsDb.findAllVisibilityValuesForAccount(account); assertEquals(vis.size(), 2); - assertEquals(vis.get(uid1), Integer.valueOf(1)); - assertEquals(vis.get(uid2), Integer.valueOf(3)); + assertEquals(vis.get(packageName1), Integer.valueOf(1)); + assertEquals(vis.get(packageName2), Integer.valueOf(3)); - assertTrue(mAccountsDb.deleteAccountVisibilityForUid(uid1)); - assertNull(mAccountsDb.findAccountVisibility(accId, uid1)); - assertFalse(mAccountsDb.deleteAccountVisibilityForUid(uid1)); // Already deleted. + assertTrue(mAccountsDb.deleteAccountVisibilityForPackage(packageName1)); + assertNull(mAccountsDb.findAccountVisibility(accId, packageName1)); + assertFalse(mAccountsDb.deleteAccountVisibilityForPackage(packageName1)); // 2nd attempt. } @Test public void testVisibilityCleanupTrigger() { long accId = 10; - int uid1 = 100500; + String packageName1 = "com.example.one"; Account account = new Account("name", "example.com"); - assertNull(mAccountsDb.findAccountVisibility(account, uid1)); + assertNull(mAccountsDb.findAccountVisibility(account, packageName1)); mAccountsDb.insertDeAccount(account, accId); - assertNull(mAccountsDb.findAccountVisibility(account, uid1)); + assertNull(mAccountsDb.findAccountVisibility(account, packageName1)); - mAccountsDb.setAccountVisibility(accId, uid1, 1); - assertEquals(mAccountsDb.findAccountVisibility(accId, uid1), Integer.valueOf(1)); + mAccountsDb.setAccountVisibility(accId, packageName1, 1); + assertEquals(mAccountsDb.findAccountVisibility(accId, packageName1), Integer.valueOf(1)); assertTrue(mAccountsDb.deleteDeAccount(accId)); // Trigger should remove visibility. - assertNull(mAccountsDb.findAccountVisibility(account, uid1)); + assertNull(mAccountsDb.findAccountVisibility(account, packageName1)); } }