diff options
author | Fred Quintana <fredq@google.com> | 2009-10-22 18:39:44 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2009-10-22 18:39:44 -0700 |
commit | 44dd4732184ce01b5fa0c7ed09347d27de60595b (patch) | |
tree | 0e757a9e58071fa134fe50bae50fa0b69554dd61 | |
parent | 52ab52f35b9b6be78b818f377608c18d97f137ce (diff) | |
parent | f3971747506ca9055e7b5c42a809ac12f8c26ad3 (diff) | |
download | frameworks_base-44dd4732184ce01b5fa0c7ed09347d27de60595b.zip frameworks_base-44dd4732184ce01b5fa0c7ed09347d27de60595b.tar.gz frameworks_base-44dd4732184ce01b5fa0c7ed09347d27de60595b.tar.bz2 |
am f3971747: am 0bf653b5: am f4520f3e: Merge change I9161f53d into eclair-sdk
Merge commit 'f3971747506ca9055e7b5c42a809ac12f8c26ad3' into eclair-mr2-plus-aosp
* commit 'f3971747506ca9055e7b5c42a809ac12f8c26ad3':
update account manager javadoc
5 files changed, 716 insertions, 51 deletions
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java index 456cf98..ee6d748 100644 --- a/core/java/android/accounts/AbstractAccountAuthenticator.java +++ b/core/java/android/accounts/AbstractAccountAuthenticator.java @@ -26,9 +26,78 @@ import android.content.Intent; import android.Manifest; /** - * Base class for creating AccountAuthenticators. This implements the IAccountAuthenticator - * binder interface and also provides helper libraries to simplify the creation of - * AccountAuthenticators. + * Abstract base class for creating AccountAuthenticators. + * In order to be an authenticator one must extend this class, provider implementations for the + * abstract methods and write a service that returns the result of {@link #getIBinder()} + * in the service's {@link android.app.Service#onBind(android.content.Intent)} when invoked + * with an intent with action {@link AccountManager#ACTION_AUTHENTICATOR_INTENT}. This service + * must specify the following intent filter and metadata tags in its AndroidManifest.xml file + * <pre> + * <intent-filter> + * <action android:name="android.accounts.AccountAuthenticator" /> + * </intent-filter> + * <meta-data android:name="android.accounts.AccountAuthenticator" + * android:resource="@xml/authenticator" /> + * </pre> + * The <code>android:resource</code> attribute must point to a resource that looks like: + * <pre> + * <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" + * android:accountType="typeOfAuthenticator" + * android:icon="@drawable/icon" + * android:smallIcon="@drawable/miniIcon" + * android:label="@string/label" + * android:accountPreferences="@xml/account_preferences" + * /> + * </pre> + * Replace the icons and labels with your own resources. The <code>android:accountType</code> + * attribute must be a string that uniquely identifies your authenticator and will be the same + * string that user will use when making calls on the {@link AccountManager} and it also + * corresponds to {@link Account#type} for your accounts. One user of the android:icon is the + * "Account & Sync" settings page and one user of the android:smallIcon is the Contact Application's + * tab panels. + * <p> + * The preferences attribute points to an PreferenceScreen xml hierarchy that contains + * a list of PreferenceScreens that can be invoked to manage the authenticator. An example is: + * <pre> + * <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + * <PreferenceCategory android:title="@string/title_fmt" /> + * <PreferenceScreen + * android:key="key1" + * android:title="@string/key1_action" + * android:summary="@string/key1_summary"> + * <intent + * android:action="key1.ACTION" + * android:targetPackage="key1.package" + * android:targetClass="key1.class" /> + * </PreferenceScreen> + * </PreferenceScreen> + * </pre> + * + * <p> + * The standard pattern for implementing any of the abstract methods is the following: + * <ul> + * <li> If the supplied arguments are enough for the authenticator to fully satisfy the request + * then it will do so and return a {@link Bundle} that contains the results. + * <li> If the authenticator needs information from the user to satisfy the request then it + * will create an {@link Intent} to an activity that will prompt the user for the information + * and then carry out the request. This intent must be returned in a Bundle as key + * {@link AccountManager#KEY_INTENT}. + * <p> + * The activity needs to return the final result when it is complete so the Intent should contain + * the {@link AccountAuthenticatorResponse} as {@link AccountManager#KEY_ACCOUNT_MANAGER_RESPONSE}. + * The activity must then call {@link AccountAuthenticatorResponse#onResult} or + * {@link AccountAuthenticatorResponse#onError} when it is complete. + * </ul> + * <p> + * The following descriptions of each of the abstract authenticator methods will not describe the + * possible asynchronous nature of the request handling and will instead just describe the input + * parameters and the expected result. + * <p> + * When writing an activity to satisfy these requests one must pass in the AccountManagerResponse + * and return the result via that response when the activity finishes (or whenever else the + * activity author deems it is the correct time to respond). + * The {@link AccountAuthenticatorActivity} handles this, so one may wish to extend that when + * writing activities to handle these requests. */ public abstract class AbstractAccountAuthenticator { private final Context mContext; @@ -239,19 +308,135 @@ public abstract class AbstractAccountAuthenticator { */ public abstract Bundle editProperties(AccountAuthenticatorResponse response, String accountType); + + /** + * Adds an account of the specified accountType. + * @param response to send the result back to the AccountManager, will never be null + * @param accountType the type of account to add, will never be null + * @param authTokenType the type of auth token to retrieve after adding the account, may be null + * @param requiredFeatures a String array of authenticator-specific features that the added + * account must support, may be null + * @param options a Bundle of authenticator-specific options, may be null + * @return a Bundle result or null if the result is to be returned via the response. The result + * will contain either: + * <ul> + * <li> {@link AccountManager#KEY_INTENT}, or + * <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of + * the account that was added, plus {@link AccountManager#KEY_AUTHTOKEN} if an authTokenType + * was supplied, or + * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to + * indicate an error + * </ul> + * @throws NetworkErrorException if the authenticator could not honor the request due to a + * network error + */ public abstract Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException; + + /** + * Checks that the user knows the credentials of an account. + * @param response to send the result back to the AccountManager, will never be null + * @param account the account whose credentials are to be checked, will never be null + * @param options a Bundle of authenticator-specific options, may be null + * @return a Bundle result or null if the result is to be returned via the response. The result + * will contain either: + * <ul> + * <li> {@link AccountManager#KEY_INTENT}, or + * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the check succeeded, false otherwise + * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to + * indicate an error + * </ul> + */ public abstract Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options); + + /** + * Gets the authtoken for an account. + * @param response to send the result back to the AccountManager, will never be null + * @param account the account whose credentials are to be retrieved, will never be null + * @param authTokenType the type of auth token to retrieve, will never be null + * @param loginOptions a Bundle of authenticator-specific options, may be null + * @return a Bundle result or null if the result is to be returned via the response. The result + * will contain either: + * <ul> + * <li> {@link AccountManager#KEY_INTENT}, or + * <li> {@link AccountManager#KEY_ACCOUNT_NAME}, {@link AccountManager#KEY_ACCOUNT_TYPE}, + * and {@link AccountManager#KEY_AUTHTOKEN}, or + * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to + * indicate an error + * </ul> + * @throws NetworkErrorException if the authenticator could not honor the request due to a + * network error + */ public abstract Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions) throws NetworkErrorException; + + /** + * Ask the authenticator for a localized label for the given authTokenType. + * @param authTokenType the authTokenType whose label is to be returned, will never be null + * @return the localized label of the auth token type, may be null if the type isn't known + */ public abstract String getAuthTokenLabel(String authTokenType); + + /** + * Update the locally stored credentials for an account. + * @param response to send the result back to the AccountManager, will never be null + * @param account the account whose credentials are to be updated, will never be null + * @param authTokenType the type of auth token to retrieve after updating the credentials, + * may be null + * @param loginOptions a Bundle of authenticator-specific options, may be null + * @return a Bundle result or null if the result is to be returned via the response. The result + * will contain either: + * <ul> + * <li> {@link AccountManager#KEY_INTENT}, or + * <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of + * the account that was added, plus {@link AccountManager#KEY_AUTHTOKEN} if an authTokenType + * was supplied, or + * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to + * indicate an error + * </ul> + */ public abstract Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions); + + /** + * Checks if the account supports all the specified authenticator specific features. + * @param response to send the result back to the AccountManager, will never be null + * @param account the account to check, will never be null + * @param features an array of features to check, will never be null + * @return a Bundle result or null if the result is to be returned via the response. The result + * will contain either: + * <ul> + * <li> {@link AccountManager#KEY_INTENT}, or + * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the account has all the features, + * false otherwise + * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to + * indicate an error + * </ul> + * @throws NetworkErrorException if the authenticator could not honor the request due to a + * network error + */ public abstract Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException; + + /** + * Checks if the removal of this account is allowed. + * @param response to send the result back to the AccountManager, will never be null + * @param account the account to check, will never be null + * @return a Bundle result or null if the result is to be returned via the response. The result + * will contain either: + * <ul> + * <li> {@link AccountManager#KEY_INTENT}, or + * <li> {@link AccountManager#KEY_BOOLEAN_RESULT}, true if the removal of the account is + * allowed, false otherwise + * <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to + * indicate an error + * </ul> + * @throws NetworkErrorException if the authenticator could not honor the request due to a + * network error + */ public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, Account account) throws NetworkErrorException { final Bundle result = new Bundle(); diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java index 6e1f304..3d7be48 100644 --- a/core/java/android/accounts/AccountAuthenticatorActivity.java +++ b/core/java/android/accounts/AccountAuthenticatorActivity.java @@ -22,21 +22,17 @@ import android.os.Bundle; /** * Base class for implementing an Activity that is used to help implement an - * AbstractAccountAuthenticator. If the AbstractAccountAuthenticator needs to return an Intent - * that is to be used to launch an Activity that needs to return results to satisfy an - * AbstractAccountAuthenticator request, it should store the AccountAuthenticatorResponse - * inside of the Intent as follows: - * <p> + * AbstractAccountAuthenticator. If the AbstractAccountAuthenticator needs to use an activity + * to handle the request then it can have the activity extend AccountAuthenticatorActivity. + * The AbstractAccountAuthenticator passes in the response to the intent using the following: + * <pre> * intent.putExtra(Constants.ACCOUNT_AUTHENTICATOR_RESPONSE_KEY, response); - * <p> - * The activity that it launches should extend the AccountAuthenticatorActivity. If this - * activity has a result that satisfies the original request it sets it via: - * <p> - * setAccountAuthenticatorResult(result) - * <p> + * </pre> + * The activity then sets the result that is to be handed to the response via + * {@link #setAccountAuthenticatorResult(android.os.Bundle)}. * This result will be sent as the result of the request when the activity finishes. If this - * is never set or if it is set to null then the request will be canceled when the activity - * finishes. + * is never set or if it is set to null then error {@link AccountManager#ERROR_CODE_CANCELED} + * will be called on the response. */ public class AccountAuthenticatorActivity extends Activity { private AccountAuthenticatorResponse mAccountAuthenticatorResponse = null; diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index d032449..153d95f 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -42,13 +42,34 @@ import java.util.Map; import com.google.android.collect.Maps; /** - * A class that helps with interactions with the AccountManagerService. It provides + * A class that helps with interactions with the AccountManager Service. It provides * methods to allow for account, password, and authtoken management for all accounts on the * device. One accesses the {@link AccountManager} by calling: + * <pre> * AccountManager accountManager = AccountManager.get(context); + * </pre> * * <p> - * TODO(fredq) this interface is still in flux + * The AccountManager Service provides storage for the accounts known to the system, + * provides methods to manage them, and allows the registration of authenticators to + * which operations such as addAccount and getAuthToken are delegated. + * <p> + * Many of the calls take an {@link AccountManagerCallback} and {@link Handler} as parameters. + * These calls return immediately but run asynchronously. If a callback is provided then + * {@link AccountManagerCallback#run} will be invoked wen the request completes, successfully + * or not. An {@link AccountManagerFuture} is returned by these requests and also passed into the + * callback. The result if retrieved by calling {@link AccountManagerFuture#getResult()} which + * either returns the result or throws an exception as appropriate. + * <p> + * The asynchronous request can be made blocking by not providing a callback and instead + * calling {@link AccountManagerFuture#getResult()} on the future that is returned. This will + * cause the running thread to block until the result is returned. Keep in mind that one + * should not block the main thread in this way. Instead one should either use a callback, + * thus making the call asynchronous, or make the blocking call on a separate thread. + * <p> + * If one wants to ensure that the callback is invoked from a specific handler then they should + * pass the handler to the request. This makes it easier to ensure thread-safety by running + * all of one's logic from a single handler. */ public class AccountManager { private static final String TAG = "AccountManager"; @@ -60,6 +81,7 @@ public class AccountManager { public static final int ERROR_CODE_UNSUPPORTED_OPERATION = 6; public static final int ERROR_CODE_BAD_ARGUMENTS = 7; public static final int ERROR_CODE_BAD_REQUEST = 8; + public static final String KEY_ACCOUNTS = "accounts"; public static final String KEY_AUTHENTICATOR_TYPES = "authenticator_types"; public static final String KEY_USERDATA = "userdata"; @@ -110,10 +132,26 @@ public class AccountManager { mMainHandler = handler; } + /** + * Retrieve an AccountManager instance that is associated with the context that is passed in. + * Certain calls such as {@link #addOnAccountsUpdatedListener} use this context internally, + * so the caller must take care to use a {@link Context} whose lifetime is associated with + * the listener registration. + * @param context The {@link Context} to use when necessary + * @return an {@link AccountManager} instance that is associated with context + */ public static AccountManager get(Context context) { return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE); } + /** + * Get the password that is associated with the account. Returns null if the account does + * not exist. + * <p> + * Requires that the caller has permission + * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and is running + * with the same UID as the Authenticator for the account. + */ public String getPassword(final Account account) { try { return mService.getPassword(account); @@ -123,6 +161,14 @@ public class AccountManager { } } + /** + * Get the user data named by "key" that is associated with the account. + * Returns null if the account does not exist or if it does not have a value for key. + * <p> + * Requires that the caller has permission + * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and is running + * with the same UID as the Authenticator for the account. + */ public String getUserData(final Account account, final String key) { try { return mService.getUserData(account, key); @@ -132,6 +178,14 @@ public class AccountManager { } } + /** + * Query the AccountManager Service for an array that contains a + * {@link AuthenticatorDescription} for each registered authenticator. + * @return an array that contains all the authenticators known to the AccountManager service. + * This array will be empty if there are no authenticators and will never return null. + * <p> + * No permission is required to make this call. + */ public AuthenticatorDescription[] getAuthenticatorTypes() { try { return mService.getAuthenticatorTypes(); @@ -141,6 +195,13 @@ public class AccountManager { } } + /** + * Query the AccountManager Service for all accounts. + * @return an array that contains all the accounts known to the AccountManager service. + * This array will be empty if there are no accounts and will never return null. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#GET_ACCOUNTS} + */ public Account[] getAccounts() { try { return mService.getAccounts(null); @@ -150,6 +211,15 @@ public class AccountManager { } } + /** + * Query the AccountManager for the set of accounts that have a given type. If null + * is passed as the type than all accounts are returned. + * @param type the account type by which to filter, or null to get all accounts + * @return an array that contains the accounts that match the specified type. This array + * will be empty if no accounts match. It will never return null. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#GET_ACCOUNTS} + */ public Account[] getAccountsByType(String type) { try { return mService.getAccounts(type); @@ -159,6 +229,18 @@ public class AccountManager { } } + /** + * Add an account to the AccountManager's set of known accounts. + * <p> + * Requires that the caller has permission + * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and is running + * with the same UID as the Authenticator for the account. + * @param account The account to add + * @param password The password to associate with the account. May be null. + * @param extras A bundle of key/value pairs to set as the account's userdata. May be null. + * @return true if the account was sucessfully added, false otherwise, for example, + * if the account already exists or if the account is null + */ public boolean addAccountExplicitly(Account account, String password, Bundle extras) { try { return mService.addAccount(account, password, extras); @@ -168,6 +250,29 @@ public class AccountManager { } } + /** + * Removes the given account. If this account does not exist then this call has no effect. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * + * @param account The {@link Account} to remove + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Boolean} that is true if the account is successfully removed + * or false if the authenticator refuses to remove the account. + */ public AccountManagerFuture<Boolean> removeAccount(final Account account, AccountManagerCallback<Boolean> callback, Handler handler) { return new Future2Task<Boolean>(handler, callback) { @@ -183,6 +288,14 @@ public class AccountManager { }.start(); } + /** + * Removes the given authtoken. If this authtoken does not exist for the given account type + * then this call has no effect. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * @param accountType the account type of the authtoken to invalidate + * @param authToken the authtoken to invalidate + */ public void invalidateAuthToken(final String accountType, final String authToken) { try { mService.invalidateAuthToken(accountType, authToken); @@ -192,6 +305,20 @@ public class AccountManager { } } + /** + * Gets the authtoken named by "authTokenType" for the specified account if it is cached + * by the AccountManager. If no authtoken is cached then null is returned rather than + * asking the authenticaticor to generate one. If the account or the + * authtoken do not exist then null is returned. + * <p> + * Requires that the caller has permission + * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and is running + * with the same UID as the Authenticator for the account. + * @param account the account whose authtoken is to be retrieved, must not be null + * @param authTokenType the type of authtoken to retrieve + * @return an authtoken for the given account and authTokenType, if one is cached by the + * AccountManager, null otherwise. + */ public String peekAuthToken(final Account account, final String authTokenType) { try { return mService.peekAuthToken(account, authTokenType); @@ -201,6 +328,16 @@ public class AccountManager { } } + /** + * Sets the password for the account. The password may be null. If the account does not exist + * then this call has no affect. + * <p> + * Requires that the caller has permission + * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and is running + * with the same UID as the Authenticator for the account. + * @param account the account whose password is to be set. Must not be null. + * @param password the password to set for the account. May be null. + */ public void setPassword(final Account account, final String password) { try { mService.setPassword(account, password); @@ -210,6 +347,13 @@ public class AccountManager { } } + /** + * Sets the password for account to null. If the account does not exist then this call + * has no effect. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * @param account the account whose password is to be cleared. Must not be null. + */ public void clearPassword(final Account account) { try { mService.clearPassword(account); @@ -219,6 +363,17 @@ public class AccountManager { } } + /** + * Sets account's userdata named "key" to the specified value. If the account does not + * exist then this call has no effect. + * <p> + * Requires that the caller has permission + * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and is running + * with the same UID as the Authenticator for the account. + * @param account the account whose userdata is to be set. Must not be null. + * @param key the key of the userdata to set. Must not be null. + * @param value the value to set. May be null. + */ public void setUserData(final Account account, final String key, final String value) { try { mService.setUserData(account, key, value); @@ -228,6 +383,17 @@ public class AccountManager { } } + /** + * Sets the authtoken named by "authTokenType" to the value specified by authToken. + * If the account does not exist then this call has no effect. + * <p> + * Requires that the caller has permission + * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and is running + * with the same UID as the Authenticator for the account. + * @param account the account whose authtoken is to be set. Must not be null. + * @param authTokenType the type of the authtoken to set. Must not be null. + * @param authToken the authToken to set. May be null. + */ public void setAuthToken(Account account, final String authTokenType, final String authToken) { try { mService.setAuthToken(account, authTokenType, authToken); @@ -237,6 +403,25 @@ public class AccountManager { } } + /** + * Convenience method that makes a blocking call to + * {@link #getAuthToken(Account, String, boolean, AccountManagerCallback, Handler)} + * then extracts and returns the value of {@link #KEY_AUTHTOKEN} from its result. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#USE_CREDENTIALS}. + * @param account the account whose authtoken is to be retrieved, must not be null + * @param authTokenType the type of authtoken to retrieve + * @param notifyAuthFailure if true, cause the AccountManager to put up a "sign-on" notification + * for the account if no authtoken is cached by the AccountManager and the the authenticator + * does not have valid credentials to get an authtoken. + * @return an authtoken for the given account and authTokenType, if one is cached by the + * AccountManager, null otherwise. + * @throws AuthenticatorException if the authenticator is not present, unreachable or returns + * an invalid response. + * @throws OperationCanceledException if the request is canceled for any reason + * @throws java.io.IOException if the authenticator experiences an IOException while attempting + * to communicate with its backend server. + */ public String blockingGetAuthToken(Account account, String authTokenType, boolean notifyAuthFailure) throws OperationCanceledException, IOException, AuthenticatorException { @@ -246,16 +431,47 @@ public class AccountManager { } /** - * Request the auth token for this account/authTokenType. If this succeeds then the - * auth token will then be passed to the activity. If this results in an authentication - * failure then a login intent will be returned that can be invoked to prompt the user to - * update their credentials. This login activity will return the auth token to the calling - * activity. If activity is null then the login intent will not be invoked. + * Request that an authtoken of the specified type be returned for an account. + * If the Account Manager has a cached authtoken of the requested type then it will + * service the request itself. Otherwise it will pass the request on to the authenticator. + * The authenticator can try to service this request with information it already has stored + * in the AccountManager but may need to launch an activity to prompt the + * user to enter credentials. If it is able to retrieve the authtoken it will be returned + * in the result. + * <p> + * If the authenticator needs to prompt the user for credentials it will return an intent to + * the activity that will do the prompting. If an activity is supplied then that activity + * will be used to launch the intent and the result will come from it. Otherwise a result will + * be returned that contains the intent. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#USE_CREDENTIALS}. * - * @param account the account whose auth token should be retrieved - * @param authTokenType the auth token type that should be retrieved - * @param loginOptions - * @param activity the activity to launch the login intent, if necessary, and to which + * @param account The account whose credentials are to be updated. + * @param authTokenType the auth token to retrieve as part of updating the credentials. + * May be null. + * @param loginOptions authenticator specific options for the request + * @param activity If the authenticator returns a {@link #KEY_INTENT} in the result then + * the intent will be started with this activity. If activity is null then the result will + * be returned as-is. + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Bundle} that contains: + * <ul> + * <li> {@link #KEY_ACCOUNT_NAME}, {@link #KEY_ACCOUNT_TYPE} and {@link #KEY_AUTHTOKEN} + * </ul> + * If the user presses "back" then the request will be canceled. */ public AccountManagerFuture<Bundle> getAuthToken( final Account account, final String authTokenType, final Bundle loginOptions, @@ -271,6 +487,48 @@ public class AccountManager { }.start(); } + /** + * Request that an authtoken of the specified type be returned for an account. + * If the Account Manager has a cached authtoken of the requested type then it will + * service the request itself. Otherwise it will pass the request on to the authenticator. + * The authenticator can try to service this request with information it already has stored + * in the AccountManager but may need to launch an activity to prompt the + * user to enter credentials. If it is able to retrieve the authtoken it will be returned + * in the result. + * <p> + * If the authenticator needs to prompt the user for credentials it will return an intent for + * an activity that will do the prompting. If an intent is returned and notifyAuthFailure + * is true then a notification will be created that launches this intent. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#USE_CREDENTIALS}. + * + * @param account The account whose credentials are to be updated. + * @param authTokenType the auth token to retrieve as part of updating the credentials. + * May be null. + * @param notifyAuthFailure if true and the authenticator returns a {@link #KEY_INTENT} in the + * result then a "sign-on needed" notification will be created that will launch this intent. + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Bundle} that contains either: + * <ul> + * <li> {@link #KEY_INTENT}, which is to be used to prompt the user for the credentials + * <li> {@link #KEY_ACCOUNT_NAME}, {@link #KEY_ACCOUNT_TYPE} and {@link #KEY_AUTHTOKEN} + * if the authenticator is able to retrieve the auth token + * </ul> + * If the user presses "back" then the request will be canceled. + */ public AccountManagerFuture<Bundle> getAuthToken( final Account account, final String authTokenType, final boolean notifyAuthFailure, AccountManagerCallback<Bundle> callback, Handler handler) { @@ -284,6 +542,44 @@ public class AccountManager { }.start(); } + /** + * Request that an account be added with the given accountType. This request + * is processed by the authenticator for the account type. If no authenticator is registered + * in the system then {@link AuthenticatorException} is thrown. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * + * @param accountType The type of account to add. This must not be null. + * @param authTokenType The account that is added should be able to service this auth token + * type. This may be null. + * @param requiredFeatures The account that is added should support these features. + * This array may be null or empty. + * @param addAccountOptions A bundle of authenticator-specific options that is passed on + * to the authenticator. This may be null. + * @param activity If the authenticator returns a {@link #KEY_INTENT} in the result then + * the intent will be started with this activity. If activity is null then the result will + * be returned as-is. + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Bundle} that contains either: + * <ul> + * <li> {@link #KEY_INTENT}, or + * <li> {@link #KEY_ACCOUNT_NAME}, {@link #KEY_ACCOUNT_TYPE} + * and {@link #KEY_AUTHTOKEN} (if an authTokenType was specified). + * </ul> + */ public AccountManagerFuture<Bundle> addAccount(final String accountType, final String authTokenType, final String[] requiredFeatures, final Bundle addAccountOptions, @@ -318,6 +614,42 @@ public class AccountManager { }.start(); } + /** + * Requests that the authenticator checks that the user knows the credentials for the account. + * This is typically done by returning an intent to an activity that prompts the user to + * enter the credentials. This request + * is processed by the authenticator for the account. If no matching authenticator is + * registered in the system then {@link AuthenticatorException} is thrown. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * + * @param account The account whose credentials are to be checked + * @param options authenticator specific options for the request + * @param activity If the authenticator returns a {@link #KEY_INTENT} in the result then + * the intent will be started with this activity. If activity is null then the result will + * be returned as-is. + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Bundle} that contains either: + * <ul> + * <li> {@link #KEY_INTENT}, which is to be used to prompt the user for the credentials + * <li> {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE} if the user enters the correct + * credentials + * </ul> + * If the user presses "back" then the request will be canceled. + */ public AccountManagerFuture<Bundle> confirmCredentials(final Account account, final Bundle options, final Activity activity, @@ -330,7 +662,46 @@ public class AccountManager { }.start(); } - public AccountManagerFuture<Bundle> updateCredentials(final Account account, final String authTokenType, + /** + * Requests that the authenticator update the the credentials for a user. This is typically + * done by returning an intent to an activity that will prompt the user to update the stored + * credentials for the account. This request + * is processed by the authenticator for the account. If no matching authenticator is + * registered in the system then {@link AuthenticatorException} is thrown. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * + * @param account The account whose credentials are to be updated. + * @param authTokenType the auth token to retrieve as part of updating the credentials. + * May be null. + * @param loginOptions authenticator specific options for the request + * @param activity If the authenticator returns a {@link #KEY_INTENT} in the result then + * the intent will be started with this activity. If activity is null then the result will + * be returned as-is. + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Bundle} that contains either: + * <ul> + * <li> {@link #KEY_INTENT}, which is to be used to prompt the user for the credentials + * <li> {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE} if the user enters the correct + * credentials, and optionally a {@link #KEY_AUTHTOKEN} if an authTokenType was provided. + * </ul> + * If the user presses "back" then the request will be canceled. + */ + public AccountManagerFuture<Bundle> updateCredentials(final Account account, + final String authTokenType, final Bundle loginOptions, final Activity activity, final AccountManagerCallback<Bundle> callback, final Handler handler) { @@ -342,8 +713,41 @@ public class AccountManager { }.start(); } - public AccountManagerFuture<Bundle> editProperties(final String accountType, final Activity activity, - final AccountManagerCallback<Bundle> callback, + /** + * Request that the properties for an authenticator be updated. This is typically done by + * returning an intent to an activity that will allow the user to make changes. This request + * is processed by the authenticator for the account. If no matching authenticator is + * registered in the system then {@link AuthenticatorException} is thrown. + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * + * @param accountType The account type of the authenticator whose properties are to be edited. + * @param activity If the authenticator returns a {@link #KEY_INTENT} in the result then + * the intent will be started with this activity. If activity is null then the result will + * be returned as-is. + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Bundle} that contains either: + * <ul> + * <li> {@link #KEY_INTENT}, which is to be used to prompt the user for the credentials + * <li> nothing, returned if the edit completes successfully + * </ul> + * If the user presses "back" then the request will be canceled. + */ + public AccountManagerFuture<Bundle> editProperties(final String accountType, + final Activity activity, final AccountManagerCallback<Bundle> callback, final Handler handler) { return new AmsTask(activity, handler, callback) { public void doWork() throws RemoteException { @@ -783,6 +1187,48 @@ public class AccountManager { } } + /** + * Convenience method that combines the functionality of {@link #getAccountsByTypeAndFeatures}, + * {@link #getAuthToken(Account, String, Bundle, Activity, AccountManagerCallback, Handler)}, + * and {@link #addAccount}. It first gets the list of accounts that match accountType and the + * feature set. If there are none then {@link #addAccount} is invoked with the authTokenType + * feature set, and addAccountOptions. If there is exactly one then + * {@link #getAuthToken(Account, String, Bundle, Activity, AccountManagerCallback, Handler)} is + * called with that account. If there are more than one then a chooser activity is launched + * to prompt the user to select one of them and then the authtoken is retrieved for it, + * <p> + * This call returns immediately but runs asynchronously and the result is accessed via the + * {@link AccountManagerFuture} that is returned. This future is also passed as the sole + * parameter to the {@link AccountManagerCallback}. If the caller wished to use this + * method asynchronously then they will generally pass in a callback object that will get + * invoked with the {@link AccountManagerFuture}. If they wish to use it synchronously then + * they will generally pass null for the callback and instead call + * {@link android.accounts.AccountManagerFuture#getResult()} on this method's return value, + * which will then block until the request completes. + * <p> + * Requires that the caller has permission {@link android.Manifest.permission#MANAGE_ACCOUNTS}. + * + * @param accountType the accountType to query; this must be non-null + * @param authTokenType the type of authtoken to retrieve; this must be non-null + * @param features a filter for the accounts. See {@link #getAccountsByTypeAndFeatures}. + * @param activityForPrompting The activity used to start any account management + * activities that are required to fulfill this request. This may be null. + * @param addAccountOptions authenticator-specific options used if an account needs to be added + * @param loginOptions authenticator-specific options passed to getAuthToken + * @param callback A callback to invoke when the request completes. If null then + * no callback is invoked. + * @param handler The {@link Handler} to use to invoke the callback. If null then the + * main thread's {@link Handler} is used. + * @return an {@link AccountManagerFuture} that represents the future result of the call. + * The future result is a {@link Bundle} that contains either: + * <ul> + * <li> {@link #KEY_INTENT}, if no activity is supplied yet an activity needs to launched to + * fulfill the request. + * <li> {@link #KEY_ACCOUNT_NAME}, {@link #KEY_ACCOUNT_TYPE} and {@link #KEY_AUTHTOKEN} if the + * request completes successfully. + * </ul> + * If the user presses "back" then the request will be canceled. + */ public AccountManagerFuture<Bundle> getAuthTokenByFeatures( final String accountType, final String authTokenType, final String[] features, final Activity activityForPrompting, final Bundle addAccountOptions, diff --git a/core/java/android/accounts/AccountManagerFuture.java b/core/java/android/accounts/AccountManagerFuture.java index 0a26bfa..a1ab00c 100644 --- a/core/java/android/accounts/AccountManagerFuture.java +++ b/core/java/android/accounts/AccountManagerFuture.java @@ -80,29 +80,37 @@ public interface AccountManagerFuture<V> { boolean isDone(); /** - * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws - * {@link InterruptedException} then the - * {@link AccountManagerFuture} is canceled and - * {@link android.accounts.OperationCanceledException} is thrown. - * @return the {@link android.os.Bundle} that is returned by get() - * @throws android.accounts.OperationCanceledException if get() throws the unchecked - * CancellationException - * or if the Future was interrupted. + * Accessor for the future result the {@link AccountManagerFuture} represents. This + * call will block until the result is available. In order to check if the result is + * available without blocking, one may call {@link #isDone()} and {@link #isCancelled()}. + * If the request that generated this result fails or is canceled then an exception + * will be thrown rather than the call returning normally. + * @return the actual result + * @throws android.accounts.OperationCanceledException if the request was canceled for any + * reason + * @throws android.accounts.AuthenticatorException if there was an error communicating with + * the authenticator or if the authenticator returned an invalid response + * @throws java.io.IOException if the authenticator returned an error response that indicates + * that it encountered an IOException while communicating with the authentication server */ V getResult() throws OperationCanceledException, IOException, AuthenticatorException; /** - * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws - * {@link InterruptedException} then the - * {@link AccountManagerFuture} is canceled and - * {@link android.accounts.OperationCanceledException} is thrown. + * Accessor for the future result the {@link AccountManagerFuture} represents. This + * call will block until the result is available. In order to check if the result is + * available without blocking, one may call {@link #isDone()} and {@link #isCancelled()}. + * If the request that generated this result fails or is canceled then an exception + * will be thrown rather than the call returning normally. If a timeout is specified then + * the request will automatically be canceled if it does not complete in that amount of time. * @param timeout the maximum time to wait - * @param unit the time unit of the timeout argument - * @return the {@link android.os.Bundle} that is returned by - * {@link java.util.concurrent.Future#get()} - * @throws android.accounts.OperationCanceledException if get() throws the unchecked - * {@link java.util.concurrent.CancellationException} or if the {@link AccountManagerFuture} - * was interrupted. + * @param unit the time unit of the timeout argument. This must not be null. + * @return the actual result + * @throws android.accounts.OperationCanceledException if the request was canceled for any + * reason + * @throws android.accounts.AuthenticatorException if there was an error communicating with + * the authenticator or if the authenticator returned an invalid response + * @throws java.io.IOException if the authenticator returned an error response that indicates + * that it encountered an IOException while communicating with the authentication server */ V getResult(long timeout, TimeUnit unit) throws OperationCanceledException, IOException, AuthenticatorException; diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java index 28673b4..e642700 100644 --- a/core/java/android/accounts/AuthenticatorDescription.java +++ b/core/java/android/accounts/AuthenticatorDescription.java @@ -3,15 +3,33 @@ package android.accounts; import android.os.Parcelable; import android.os.Parcel; +/** + * A {@link Parcelable} value type that contains information about an account authenticator. + */ public class AuthenticatorDescription implements Parcelable { + /** The string that uniquely identifies an authenticator */ final public String type; + + /** A resource id of a label for the authenticator that is suitable for displaying */ final public int labelId; - final public int iconId; - final public int smallIconId; + + /** A resource id of a icon for the authenticator */ + final public int iconId; + + /** A resource id of a smaller icon for the authenticator */ + final public int smallIconId; + + /** + * A resource id for a hierarchy of PreferenceScreen to be added to the settings page for the + * account. See {@link AbstractAccountAuthenticator} for an example. + */ final public int accountPreferencesId; + + /** The package name that can be used to lookup the resources from above. */ final public String packageName; - public AuthenticatorDescription(String type, String packageName, int labelId, int iconId, + /** A constructor for a full AuthenticatorDescription */ + public AuthenticatorDescription(String type, String packageName, int labelId, int iconId, int smallIconId, int prefId) { if (type == null) throw new IllegalArgumentException("type cannot be null"); if (packageName == null) throw new IllegalArgumentException("packageName cannot be null"); @@ -23,6 +41,11 @@ public class AuthenticatorDescription implements Parcelable { this.accountPreferencesId = prefId; } + /** + * A factory method for creating an AuthenticatorDescription that can be used as a key + * to identify the authenticator by its type. + */ + public static AuthenticatorDescription newKey(String type) { if (type == null) throw new IllegalArgumentException("type cannot be null"); return new AuthenticatorDescription(type); @@ -46,14 +69,17 @@ public class AuthenticatorDescription implements Parcelable { this.accountPreferencesId = source.readInt(); } + /** @inheritDoc */ public int describeContents() { return 0; } + /** Returns the hashcode of the type only. */ public int hashCode() { return type.hashCode(); } + /** Compares the type only, suitable for key comparisons. */ public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof AuthenticatorDescription)) return false; @@ -61,6 +87,7 @@ public class AuthenticatorDescription implements Parcelable { return type.equals(other.type); } + /** @inhericDoc */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(type); dest.writeString(packageName); @@ -70,12 +97,15 @@ public class AuthenticatorDescription implements Parcelable { dest.writeInt(accountPreferencesId); } + /** Used to create the object from a parcel. */ public static final Creator<AuthenticatorDescription> CREATOR = new Creator<AuthenticatorDescription>() { + /** @inheritDoc */ public AuthenticatorDescription createFromParcel(Parcel source) { return new AuthenticatorDescription(source); } + /** @inheritDoc */ public AuthenticatorDescription[] newArray(int size) { return new AuthenticatorDescription[size]; } |