diff options
author | Amith Yamasani <yamasani@google.com> | 2012-12-14 12:09:36 -0800 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2013-03-06 09:49:44 -0800 |
commit | 67df64b3a48a8157d08a98fa90135d0ac0ee621c (patch) | |
tree | d390d5c537c976a14688e24c1f9a8a213840ff29 /core/java/android/accounts | |
parent | 0ffc81c1ada65b4ef4febaacf044e9fa62309b87 (diff) | |
download | frameworks_base-67df64b3a48a8157d08a98fa90135d0ac0ee621c.zip frameworks_base-67df64b3a48a8157d08a98fa90135d0ac0ee621c.tar.gz frameworks_base-67df64b3a48a8157d08a98fa90135d0ac0ee621c.tar.bz2 |
Shared accounts and sharing of apps
API and preliminary implementation for sharing primary user accounts with a secondary user.
AbstractAccountAuthenticator has new methods to retrieve and apply a bundle of credentials
to clone an account from the primary to a restricted secondary user. The AccountManagerService
initiates the account clone when it starts up the user and detects that the user has
a shared account registered that hasn't been converted to a real account.
AccountManager also has new hidden APIs to add/remove/get shared accounts. There might be
further improvements to this API to make shared accounts hidden/visible to select apps.
AccountManagerService has a new table to store the shared account information.
Added ability in PackageManager to install and uninstall packages for a secondary user. This
is required when the primary user selects a few apps to share with a restricted user.
Remove shared accounts from secondary users when primary user removes the account.
Change-Id: I9378ed0d8c1cc66baf150a4bec0ede56f6f8b06b
Diffstat (limited to 'core/java/android/accounts')
4 files changed, 151 insertions, 0 deletions
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java index e9535ab..fa46689 100644 --- a/core/java/android/accounts/AbstractAccountAuthenticator.java +++ b/core/java/android/accounts/AbstractAccountAuthenticator.java @@ -275,6 +275,38 @@ public abstract class AbstractAccountAuthenticator { handleException(response, "getAccountRemovalAllowed", account.toString(), e); } } + + public void getAccountCredentialsForCloning(IAccountAuthenticatorResponse response, + Account account) throws RemoteException { + checkBinderPermission(); + try { + final Bundle result = + AbstractAccountAuthenticator.this.getAccountCredentialsForCloning( + new AccountAuthenticatorResponse(response), account); + if (result != null) { + response.onResult(result); + } + } catch (Exception e) { + handleException(response, "getAccountCredentialsForCloning", account.toString(), e); + } + } + + public void addAccountFromCredentials(IAccountAuthenticatorResponse response, + Account account, + Bundle accountCredentials) throws RemoteException { + checkBinderPermission(); + try { + final Bundle result = + AbstractAccountAuthenticator.this.addAccountFromCredentials( + new AccountAuthenticatorResponse(response), account, + accountCredentials); + if (result != null) { + response.onResult(result); + } + } catch (Exception e) { + handleException(response, "addAccountFromCredentials", account.toString(), e); + } + } } private void handleException(IAccountAuthenticatorResponse response, String method, @@ -471,4 +503,54 @@ public abstract class AbstractAccountAuthenticator { result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); return result; } + + /** + * @hide + * Returns a Bundle that contains whatever is required to clone the account on a different + * user. The Bundle is passed to the authenticator instance in the target user via + * {@link #addAccountFromCredentials(AccountAuthenticatorResponse, Account, Bundle)}. + * The default implementation returns null, indicating that cloning is not supported. + * @param response to send the result back to the AccountManager, will never be null + * @param account the account to clone, will never be null + * @return a Bundle result or null if the result is to be returned via the response. + * @throws NetworkErrorException + * @see {@link #addAccountFromCredentials(AccountAuthenticatorResponse, Account, Bundle)} + */ + public Bundle getAccountCredentialsForCloning(final AccountAuthenticatorResponse response, + final Account account) throws NetworkErrorException { + new Thread(new Runnable() { + public void run() { + Bundle result = new Bundle(); + result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); + response.onResult(result); + } + }).start(); + return null; + } + + /** + * @hide + * Creates an account based on credentials provided by the authenticator instance of another + * user on the device, who has chosen to share the account with this user. + * @param response to send the result back to the AccountManager, will never be null + * @param account the account to clone, will never be null + * @param accountCredentials the Bundle containing the required credentials to create the + * account. Contents of the Bundle are only meaningful to the authenticator. This Bundle is + * provided by {@link #getAccountCredentialsForCloning(AccountAuthenticatorResponse, Account)}. + * @return a Bundle result or null if the result is to be returned via the response. + * @throws NetworkErrorException + * @see {@link #getAccountCredentialsForCloning(AccountAuthenticatorResponse, Account)} + */ + public Bundle addAccountFromCredentials(final AccountAuthenticatorResponse response, + Account account, + Bundle accountCredentials) throws NetworkErrorException { + new Thread(new Runnable() { + public void run() { + Bundle result = new Bundle(); + result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); + response.onResult(result); + } + }).start(); + return null; + } } diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 6d9bb1d..6aac723 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -1123,6 +1123,57 @@ public class AccountManager { } /** + * Adds a shared account from the primary user to a secondary user. Adding the shared account + * doesn't take effect immediately. When the target user starts up, any pending shared accounts + * are attempted to be copied to the target user from the primary via calls to the + * authenticator. + * @param account the account to share + * @param user the target user + * @return + * @hide + */ + public boolean addSharedAccount(final Account account, UserHandle user) { + try { + boolean val = mService.addSharedAccountAsUser(account, user.getIdentifier()); + return val; + } catch (RemoteException re) { + // won't ever happen + throw new RuntimeException(re); + } + } + + /** + * @hide + * Removes the shared account. + * @param account the account to remove + * @param user the user to remove the account from + * @return + */ + public boolean removeSharedAccount(final Account account, UserHandle user) { + try { + boolean val = mService.removeSharedAccountAsUser(account, user.getIdentifier()); + return val; + } catch (RemoteException re) { + // won't ever happen + throw new RuntimeException(re); + } + } + + /** + * @hide + * @param user + * @return + */ + public Account[] getSharedAccounts(UserHandle user) { + try { + return mService.getSharedAccountsAsUser(user.getIdentifier()); + } catch (RemoteException re) { + // won't ever happen + throw new RuntimeException(re); + } + } + + /** * Confirms that the user knows the password for an account to make extra * sure they are the owner of the account. The user-entered password can * be supplied directly, otherwise the authenticator for this account type diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl index 8860710..58612da 100644 --- a/core/java/android/accounts/IAccountAuthenticator.aidl +++ b/core/java/android/accounts/IAccountAuthenticator.aidl @@ -70,4 +70,17 @@ oneway interface IAccountAuthenticator { * Gets whether or not the account is allowed to be removed. */ void getAccountRemovalAllowed(in IAccountAuthenticatorResponse response, in Account account); + + /** + * Returns a Bundle containing the required credentials to copy the account across users. + */ + void getAccountCredentialsForCloning(in IAccountAuthenticatorResponse response, + in Account account); + + /** + * Uses the Bundle containing credentials from another instance of the authenticator to create + * a copy of the account on this user. + */ + void addAccountFromCredentials(in IAccountAuthenticatorResponse response, in Account account, + in Bundle accountCredentials); } diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl index dbb4924..47b257d 100644 --- a/core/java/android/accounts/IAccountManager.aidl +++ b/core/java/android/accounts/IAccountManager.aidl @@ -58,4 +58,9 @@ interface IAccountManager { in Bundle options, boolean expectActivityLaunch, int userId); void getAuthTokenLabel(in IAccountManagerResponse response, String accountType, String authTokenType); + + /* Shared accounts */ + boolean addSharedAccountAsUser(in Account account, int userId); + Account[] getSharedAccountsAsUser(int userId); + boolean removeSharedAccountAsUser(in Account account, int userId); } |