Merge "Update Account Discovery API."
This commit is contained in:
committed by
Android (Google) Code Review
commit
de9c63b8ae
@@ -2909,7 +2909,7 @@ package android.accounts {
|
||||
public class AccountManager {
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, 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<java.lang.Integer, java.lang.Integer>);
|
||||
method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
|
||||
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<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, 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<android.accounts.Account, java.lang.Integer> 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<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
|
||||
method public java.util.Map<java.lang.String, java.lang.Integer> 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<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
|
||||
method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
|
||||
method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, 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<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, 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
|
||||
|
||||
@@ -3028,7 +3028,7 @@ package android.accounts {
|
||||
public class AccountManager {
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, 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<java.lang.Integer, java.lang.Integer>);
|
||||
method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
|
||||
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<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback<android.os.Bundle>, 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<android.accounts.Account, java.lang.Integer> 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<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
|
||||
method public java.util.Map<java.lang.String, java.lang.Integer> 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<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
|
||||
method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
|
||||
method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, 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<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, 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
|
||||
|
||||
@@ -2909,7 +2909,7 @@ package android.accounts {
|
||||
public class AccountManager {
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, 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<java.lang.Integer, java.lang.Integer>);
|
||||
method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
|
||||
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<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, 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<android.accounts.Account, java.lang.Integer> 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<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
|
||||
method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
|
||||
method public java.util.Map<java.lang.String, java.lang.Integer> 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<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
|
||||
method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
|
||||
method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, 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<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, 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
|
||||
|
||||
@@ -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 {
|
||||
*
|
||||
* <p>
|
||||
* <b>NOTE:</b> 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.
|
||||
* <p>
|
||||
* <b>NOTE:</b> 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.
|
||||
* <p>
|
||||
* 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<Integer, Integer> visibility) {
|
||||
Map<String, Integer> 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.
|
||||
* <p>
|
||||
* 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<Integer, Integer> getUidsAndVisibilityForAccount(Account account) {
|
||||
public Map<String, Integer> getPackagesAndVisibilityForAccount(Account account) {
|
||||
try {
|
||||
if (account == null)
|
||||
throw new IllegalArgumentException("account is null");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Integer, Integer> result = (Map<Integer, Integer>) mService
|
||||
.getUidsAndVisibilityForAccount(account);
|
||||
Map<String, Integer> result = (Map<String, Integer>) 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}.
|
||||
* <p>
|
||||
* See {@link #getAccountVisibility} for possible values.
|
||||
* <p>
|
||||
* 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:
|
||||
* <ul>
|
||||
* <li>{@link #VISIBILITY_UNDEFINED}</li>
|
||||
* <li>{@link #VISIBILITY_VISIBLE}</li>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -108,15 +108,12 @@ interface IAccountManager {
|
||||
void isCredentialsUpdateSuggested(in IAccountManagerResponse response, in Account account,
|
||||
String statusToken);
|
||||
|
||||
/* Returns Map<Integer, Integer> from UID to visibility with all values stored for given account*/
|
||||
Map getUidsAndVisibilityForAccount(in Account account);
|
||||
|
||||
/* Returns Map<String, Integer> 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 <Account, Integer>*/
|
||||
Map getAccountsAndVisibilityForPackage(in String packageName, in String accountType);
|
||||
|
||||
|
||||
@@ -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<Integer, Integer>) uidToVisibility);
|
||||
(Map<String, Integer>) 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<Integer, Integer> getUidsAndVisibilityForAccount(Account account) {
|
||||
public Map<String, Integer> 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<Integer, Integer> getUidsAndVisibilityForAccount(Account account,
|
||||
private Map<String, Integer> 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<String> 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<String> 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<String> getRequestingPackageNames(String accountType, UserAccounts accouns) {
|
||||
LinkedHashSet<String> getRequestingPackageNames(String accountType, UserAccounts accounts) {
|
||||
// TODO return packages registered to get notifications.
|
||||
return new LinkedHashSet<String>();
|
||||
}
|
||||
|
||||
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<Integer, Integer> uidToVisibility) {
|
||||
Bundle extras, int callingUid, Map<String, Integer> packageToVisibility) {
|
||||
Bundle.setDefusable(extras, true);
|
||||
if (account == null) {
|
||||
return false;
|
||||
@@ -1513,9 +1565,9 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
|
||||
if (uidToVisibility != null) {
|
||||
for (Entry<Integer, Integer> entry : uidToVisibility.entrySet()) {
|
||||
setAccountVisibility(account, entry.getKey() /* uid */,
|
||||
if (packageToVisibility != null) {
|
||||
for (Entry<String, Integer> 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<String> 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<UserInfo> 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<Account, Integer> 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) {
|
||||
|
||||
@@ -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<Integer, Integer> findAllVisibilityValuesForAccount(Account account) {
|
||||
Map<String, Integer> findAllVisibilityValuesForAccount(Account account) {
|
||||
SQLiteDatabase db = mDeDatabase.getReadableDatabase();
|
||||
Map<Integer, Integer> result = new HashMap<>();
|
||||
Map<String, Integer> 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) {
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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<Integer, Integer> vis = mAccountsDb.findAllVisibilityValuesForAccount(account);
|
||||
Map<String, Integer> 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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user