AccountManager: add startUpdateCredentials API.
Adding startUpdateCredentials API to AccountManager and AbstractAccountAuthenticator. Change-Id: Id9a1ff86764f2fde01fd8482594e4ae34e1f3bd1
This commit is contained in:
@@ -119,21 +119,26 @@ public abstract class AbstractAccountAuthenticator {
|
||||
/**
|
||||
* Bundle key used for the {@link String} account type in session bundle.
|
||||
* This is used in the default implementation of
|
||||
* {@link #startAddAccountSession}. TODO: and startUpdateCredentialsSession.
|
||||
* {@link #startAddAccountSession} and {@link startUpdateCredentialsSession}.
|
||||
*/
|
||||
private static final String KEY_AUTH_TOKEN_TYPE = "android.accounts.KEY_AUTH_TOKEN_TYPE";
|
||||
/**
|
||||
* Bundle key used for the {@link String} array of required features in
|
||||
* session bundle. This is used in the default implementation of
|
||||
* {@link #startAddAccountSession}. TODO: and startUpdateCredentialsSession.
|
||||
* {@link #startAddAccountSession} and {@link startUpdateCredentialsSession}.
|
||||
*/
|
||||
private static final String KEY_REQUIRED_FEATURES = "android.accounts.AbstractAccountAuthenticator.KEY_REQUIRED_FEATURES";
|
||||
/**
|
||||
* Bundle key used for the {@link Bundle} options in session bundle. This is
|
||||
* used in default implementation of {@link #startAddAccountSession}. TODO:
|
||||
* and startUpdateCredentialsSession.
|
||||
* used in default implementation of {@link #startAddAccountSession} and
|
||||
* {@link startUpdateCredentialsSession}.
|
||||
*/
|
||||
private static final String KEY_OPTIONS = "android.accounts.AbstractAccountAuthenticator.KEY_OPTIONS";
|
||||
/**
|
||||
* Bundle key used for the {@link Account} account in session bundle. This is used
|
||||
* used in default implementation of {@link startUpdateCredentialsSession}.
|
||||
*/
|
||||
private static final String KEY_ACCOUNT = "android.accounts.AbstractAccountAuthenticator.KEY_ACCOUNT";
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
@@ -385,6 +390,43 @@ public abstract class AbstractAccountAuthenticator {
|
||||
handleException(response, "startAddAccountSession", accountType, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUpdateCredentialsSession(
|
||||
IAccountAuthenticatorResponse response,
|
||||
Account account,
|
||||
String authTokenType,
|
||||
Bundle loginOptions) throws RemoteException {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "startUpdateCredentialsSession: "
|
||||
+ account
|
||||
+ ", authTokenType "
|
||||
+ authTokenType);
|
||||
}
|
||||
checkBinderPermission();
|
||||
try {
|
||||
final Bundle result = AbstractAccountAuthenticator.this
|
||||
.startUpdateCredentialsSession(
|
||||
new AccountAuthenticatorResponse(response),
|
||||
account,
|
||||
authTokenType,
|
||||
loginOptions);
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
// Result may be null.
|
||||
if (result != null) {
|
||||
result.keySet(); // force it to be unparcelled
|
||||
}
|
||||
Log.v(TAG, "startUpdateCredentialsSession: result "
|
||||
+ AccountManager.sanitizeResult(result));
|
||||
}
|
||||
if (result != null) {
|
||||
response.onResult(result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
handleException(response, "startUpdateCredentialsSession",
|
||||
account.toString() + "," + authTokenType, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleException(IAccountAuthenticatorResponse response, String method,
|
||||
@@ -700,4 +742,49 @@ public abstract class AbstractAccountAuthenticator {
|
||||
}).start();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks user to re-authenticate for an account but defers updating the locally stored
|
||||
* credentials.
|
||||
*
|
||||
* @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 (TODO)
|
||||
* @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_SESSION_BUNDLE} for updating the
|
||||
* locally stored credentials later, and if account is
|
||||
* re-authenticated, {@link AccountManager#KEY_PASSWORD} and
|
||||
* {@link AccountManager#KEY_ACCOUNT_STATUS_TOKEN} for checking the
|
||||
* status of the account later, 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 Bundle startUpdateCredentialsSession(final AccountAuthenticatorResponse response,
|
||||
final Account account, final String authTokenType, final Bundle options)
|
||||
throws NetworkErrorException {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Bundle sessionBundle = new Bundle();
|
||||
sessionBundle.putString(KEY_AUTH_TOKEN_TYPE, authTokenType);
|
||||
sessionBundle.putParcelable(KEY_ACCOUNT, account);
|
||||
sessionBundle.putBundle(KEY_OPTIONS, options);
|
||||
Bundle result = new Bundle();
|
||||
result.putBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, sessionBundle);
|
||||
response.onResult(result);
|
||||
}
|
||||
|
||||
}).start();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2666,9 +2666,14 @@ public class AccountManager {
|
||||
* trouble
|
||||
* </ul>
|
||||
*/
|
||||
public AccountManagerFuture<Bundle> startAddAccountSession(final String accountType,
|
||||
final String authTokenType, final String[] requiredFeatures, final Bundle options,
|
||||
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
|
||||
public AccountManagerFuture<Bundle> startAddAccountSession(
|
||||
final String accountType,
|
||||
final String authTokenType,
|
||||
final String[] requiredFeatures,
|
||||
final Bundle options,
|
||||
final Activity activity,
|
||||
AccountManagerCallback<Bundle> callback,
|
||||
Handler handler) {
|
||||
if (accountType == null) throw new IllegalArgumentException("accountType is null");
|
||||
final Bundle optionsIn = new Bundle();
|
||||
if (options != null) {
|
||||
@@ -2679,8 +2684,89 @@ public class AccountManager {
|
||||
return new AmsTask(activity, handler, callback) {
|
||||
@Override
|
||||
public void doWork() throws RemoteException {
|
||||
mService.startAddAccountSession(mResponse, accountType, authTokenType,
|
||||
requiredFeatures, activity != null, optionsIn);
|
||||
mService.startAddAccountSession(
|
||||
mResponse,
|
||||
accountType,
|
||||
authTokenType,
|
||||
requiredFeatures,
|
||||
activity != null,
|
||||
optionsIn);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the user to enter a new password for an account but not updating the
|
||||
* saved credentials for the account until finishSession is
|
||||
* called.
|
||||
* <p>
|
||||
* This method may be called from any thread, but the returned
|
||||
* {@link AccountManagerFuture} must not be used on the main thread.
|
||||
* <p>
|
||||
* <b>NOTE:</b> The saved credentials for the account alone will not be
|
||||
* updated by calling this API alone .
|
||||
*
|
||||
* @param account The account to update credentials for
|
||||
* @param authTokenType The credentials entered must allow an auth token of
|
||||
* this type to be created (but no actual auth token is
|
||||
* returned); may be null
|
||||
* @param options Authenticator-specific options for the request; may be
|
||||
* null or empty
|
||||
* @param activity The {@link Activity} context to use for launching a new
|
||||
* authenticator-defined sub-Activity to prompt the user to enter
|
||||
* a password; used only to call startActivity(); if null, the
|
||||
* prompt will not be launched directly, but the necessary
|
||||
* {@link Intent} will be returned to the caller instead
|
||||
* @param callback Callback to invoke when the request completes, null for
|
||||
* no callback
|
||||
* @param handler {@link Handler} identifying the callback thread, null for
|
||||
* the main thread
|
||||
* @return An {@link AccountManagerFuture} which resolves to a Bundle with
|
||||
* these fields if an activity was supplied and user was
|
||||
* successfully re-authenticated to the account (TODO: default impl
|
||||
* only returns escorw?):
|
||||
* <ul>
|
||||
* <li>{@link #KEY_ACCOUNT_SESSION_BUNDLE} - encrypted Bundle for
|
||||
* updating the local credentials on device later.
|
||||
* <li>{@link #KEY_PASSWORD} - optional, the password or password hash of the
|
||||
* account
|
||||
* <li>{@link #KEY_ACCOUNT_STATUS_TOKEN} - optional, token to check status of
|
||||
* the account
|
||||
* </ul>
|
||||
* If no activity was specified, the returned Bundle contains
|
||||
* {@link #KEY_INTENT} with the {@link Intent} needed to launch the
|
||||
* password prompt. If an error occurred,
|
||||
* {@link AccountManagerFuture#getResult()} throws:
|
||||
* <ul>
|
||||
* <li>{@link AuthenticatorException} if the authenticator failed to
|
||||
* respond
|
||||
* <li>{@link OperationCanceledException} if the operation was
|
||||
* canceled for any reason, including the user canceling the
|
||||
* password prompt
|
||||
* <li>{@link IOException} if the authenticator experienced an I/O
|
||||
* problem verifying the password, usually because of network
|
||||
* trouble
|
||||
* </ul>
|
||||
*/
|
||||
public AccountManagerFuture<Bundle> startUpdateCredentialsSession(
|
||||
final Account account,
|
||||
final String authTokenType,
|
||||
final Bundle options,
|
||||
final Activity activity,
|
||||
final AccountManagerCallback<Bundle> callback,
|
||||
final Handler handler) {
|
||||
if (account == null) {
|
||||
throw new IllegalArgumentException("account is null");
|
||||
}
|
||||
return new AmsTask(activity, handler, callback) {
|
||||
@Override
|
||||
public void doWork() throws RemoteException {
|
||||
mService.startUpdateCredentialsSession(
|
||||
mResponse,
|
||||
account,
|
||||
authTokenType,
|
||||
activity != null,
|
||||
options);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
@@ -90,4 +90,10 @@ oneway interface IAccountAuthenticator {
|
||||
*/
|
||||
void startAddAccountSession(in IAccountAuthenticatorResponse response, String accountType,
|
||||
String authTokenType, in String[] requiredFeatures, in Bundle options);
|
||||
|
||||
/**
|
||||
* Prompts the user for a new password but does not write it to the IAccountManager.
|
||||
*/
|
||||
void startUpdateCredentialsSession(in IAccountAuthenticatorResponse response, in Account account,
|
||||
String authTokenType, in Bundle options);
|
||||
}
|
||||
|
||||
@@ -88,4 +88,7 @@ interface IAccountManager {
|
||||
String authTokenType, in String[] requiredFeatures, boolean expectActivityLaunch,
|
||||
in Bundle options);
|
||||
|
||||
/* Update credentials in two steps. */
|
||||
void startUpdateCredentialsSession(in IAccountManagerResponse response, in Account account,
|
||||
String authTokenType, boolean expectActivityLaunch, in Bundle options);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user