Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b68be013 authored by Sandra Kwan's avatar Sandra Kwan Committed by Android (Google) Code Review
Browse files

Merge "AccountManager: add startAddAccount API."

parents b8f71add 78812287
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2732,6 +2732,7 @@ package android.accounts {
    method public abstract java.lang.String getAuthTokenLabel(java.lang.String);
    method public final android.os.IBinder getIBinder();
    method public abstract android.os.Bundle hasFeatures(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String[]) throws android.accounts.NetworkErrorException;
    method public android.os.Bundle startAddAccountSession(android.accounts.AccountAuthenticatorResponse, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle) throws android.accounts.NetworkErrorException;
    method public abstract android.os.Bundle updateCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
    field public static final java.lang.String KEY_CUSTOM_TOKEN_EXPIRY = "android.accounts.expiry";
  }
@@ -2796,6 +2797,7 @@ package android.accounts {
    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);
    method public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(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 android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
    field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator";
    field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
@@ -2812,6 +2814,8 @@ package android.accounts {
    field public static final java.lang.String KEY_ACCOUNT_AUTHENTICATOR_RESPONSE = "accountAuthenticatorResponse";
    field public static final java.lang.String KEY_ACCOUNT_MANAGER_RESPONSE = "accountManagerResponse";
    field public static final java.lang.String KEY_ACCOUNT_NAME = "authAccount";
    field public static final java.lang.String KEY_ACCOUNT_SESSION_BUNDLE = "accountSessionBundle";
    field public static final java.lang.String KEY_ACCOUNT_STATUS_TOKEN = "accountStatusToken";
    field public static final java.lang.String KEY_ACCOUNT_TYPE = "accountType";
    field public static final java.lang.String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
    field public static final java.lang.String KEY_AUTHENTICATOR_TYPES = "authenticator_types";
+4 −0
Original line number Diff line number Diff line
@@ -2831,6 +2831,7 @@ package android.accounts {
    method public abstract java.lang.String getAuthTokenLabel(java.lang.String);
    method public final android.os.IBinder getIBinder();
    method public abstract android.os.Bundle hasFeatures(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String[]) throws android.accounts.NetworkErrorException;
    method public android.os.Bundle startAddAccountSession(android.accounts.AccountAuthenticatorResponse, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle) throws android.accounts.NetworkErrorException;
    method public abstract android.os.Bundle updateCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
    field public static final java.lang.String KEY_CUSTOM_TOKEN_EXPIRY = "android.accounts.expiry";
  }
@@ -2895,6 +2896,7 @@ package android.accounts {
    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);
    method public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(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 android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
    field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator";
    field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
@@ -2911,6 +2913,8 @@ package android.accounts {
    field public static final java.lang.String KEY_ACCOUNT_AUTHENTICATOR_RESPONSE = "accountAuthenticatorResponse";
    field public static final java.lang.String KEY_ACCOUNT_MANAGER_RESPONSE = "accountManagerResponse";
    field public static final java.lang.String KEY_ACCOUNT_NAME = "authAccount";
    field public static final java.lang.String KEY_ACCOUNT_SESSION_BUNDLE = "accountSessionBundle";
    field public static final java.lang.String KEY_ACCOUNT_STATUS_TOKEN = "accountStatusToken";
    field public static final java.lang.String KEY_ACCOUNT_TYPE = "accountType";
    field public static final java.lang.String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
    field public static final java.lang.String KEY_AUTHENTICATOR_TYPES = "authenticator_types";
+97 −0
Original line number Diff line number Diff line
@@ -116,6 +116,25 @@ public abstract class AbstractAccountAuthenticator {
     */
    public static final String KEY_CUSTOM_TOKEN_EXPIRY = "android.accounts.expiry";

    /**
     * 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.
     */
    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.
     */
    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.
     */
    private static final String KEY_OPTIONS = "android.accounts.AbstractAccountAuthenticator.KEY_OPTIONS";

    private final Context mContext;

    public AbstractAccountAuthenticator(Context context) {
@@ -336,6 +355,36 @@ public abstract class AbstractAccountAuthenticator {
                handleException(response, "addAccountFromCredentials", account.toString(), e);
            }
        }

        @Override
        public void startAddAccountSession(IAccountAuthenticatorResponse response,
                String accountType, String authTokenType, String[] features, Bundle options)
                throws RemoteException {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG,
                        "startAddAccountSession: accountType " + accountType
                        + ", authTokenType " + authTokenType
                        + ", features " + (features == null ? "[]" : Arrays.toString(features)));
            }
            checkBinderPermission();
            try {
                final Bundle result = AbstractAccountAuthenticator.this.startAddAccountSession(
                        new AccountAuthenticatorResponse(response), accountType, authTokenType,
                        features, options);
                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                    if (result != null) {
                        result.keySet(); // force it to be unparcelled
                    }
                    Log.v(TAG, "startAddAccountSession: result "
                            + AccountManager.sanitizeResult(result));
                }
                if (result != null) {
                    response.onResult(result);
                }
            } catch (Exception e) {
                handleException(response, "startAddAccountSession", accountType, e);
            }
        }
    }

    private void handleException(IAccountAuthenticatorResponse response, String method,
@@ -603,4 +652,52 @@ public abstract class AbstractAccountAuthenticator {
        }).start();
        return null;
    }

    /**
     * Starts the add account session to authenticate user to 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 authenticate with, will never
     *            be null
     * @param authTokenType the type of auth token to retrieve after
     *            authenticating with the account, may be null
     * @param requiredFeatures a String array of authenticator-specific features
     *            that the account authenticated with 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_SESSION_BUNDLE} for adding
     *         the account to device later, and if account is authenticated,
     *         optional {@link AccountManager#KEY_PASSWORD} and
     *         {@link AccountManager#KEY_ACCOUNT_STATUS_TOKEN} for checking the
     *         status of the account, 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 startAddAccountSession(final AccountAuthenticatorResponse response,
            final String accountType, final String authTokenType, final String[] requiredFeatures,
            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.putStringArray(KEY_REQUIRED_FEATURES, requiredFeatures);
                sessionBundle.putBundle(KEY_OPTIONS, options);
                Bundle result = new Bundle();
                result.putBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, sessionBundle);
                response.onResult(result);
            }

        }).start();
        return null;
    }
}
+94 −0
Original line number Diff line number Diff line
@@ -240,6 +240,20 @@ public class AccountManager {
     */
    public static final String KEY_NOTIFY_ON_FAILURE = "notifyOnAuthFailure";

    /**
     * Bundle key used for a {@link Bundle} in result from
     * {@link #startAddAccountSession} and friends which returns session data
     * for installing an account later.
     */
    public static final String KEY_ACCOUNT_SESSION_BUNDLE = "accountSessionBundle";

    /**
     * Bundle key used for the {@link String} account status token in result
     * from {@link #startAddAccountSession} and friends which returns
     * information about a particular account.
     */
    public static final String KEY_ACCOUNT_STATUS_TOKEN = "accountStatusToken";

    public static final String ACTION_AUTHENTICATOR_INTENT =
            "android.accounts.AccountAuthenticator";
    public static final String AUTHENTICATOR_META_DATA_NAME =
@@ -2590,4 +2604,84 @@ public class AccountManager {
            }
        }
    }

    /**
     * Asks the user to authenticate with an account of a specified type. The
     * authenticator for this account type processes this request with the
     * appropriate user interface. If the user does elect to authenticate with a
     * new account, a bundle of session data for installing the account later is
     * returned with optional account password and account status token.
     * <p>
     * This method may be called from any thread, but the returned
     * {@link AccountManagerFuture} must not be used on the main thread.
     * <p>
     * <p>
     * <b>NOTE:</b> The account will not be installed to the device by calling
     * this api alone.
     *
     * @param accountType The type of account to add; must not be null
     * @param authTokenType The type of auth token (see {@link #getAuthToken})
     *            this account will need to be able to generate, null for none
     * @param requiredFeatures The features (see {@link #hasFeatures}) this
     *            account must have, null for none
     * @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
     *            create an account; 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 activity was specified and user was authenticated
     *         with an account:
     *         <ul>
     *         <li>{@link #KEY_ACCOUNT_SESSION_BUNDLE} - encrypted Bundle for
     *         adding the the to the 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 only
     *         {@link #KEY_INTENT} with the {@link Intent} needed to launch the
     *         actual account creation process. If authenticator doesn't support
     *         this method, the returned Bundle contains only
     *         {@link #KEY_ACCOUNT_SESSION_BUNDLE} with encrypted
     *         {@code options} needed to add account later. If an error
     *         occurred, {@link AccountManagerFuture#getResult()} throws:
     *         <ul>
     *         <li>{@link AuthenticatorException} if no authenticator was
     *         registered for this account type or the authenticator failed to
     *         respond
     *         <li>{@link OperationCanceledException} if the operation was
     *         canceled for any reason, including the user canceling the
     *         creation process or adding accounts (of this type) has been
     *         disabled by policy
     *         <li>{@link IOException} if the authenticator experienced an I/O
     *         problem creating a new account, usually because of network
     *         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) {
        if (accountType == null) throw new IllegalArgumentException("accountType is null");
        final Bundle optionsIn = new Bundle();
        if (options != null) {
            optionsIn.putAll(options);
        }
        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());

        return new AmsTask(activity, handler, callback) {
            @Override
            public void doWork() throws RemoteException {
                mService.startAddAccountSession(mResponse, accountType, authTokenType,
                        requiredFeatures, activity != null, optionsIn);
            }
        }.start();
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -83,4 +83,11 @@ oneway interface IAccountAuthenticator {
     */
    void addAccountFromCredentials(in IAccountAuthenticatorResponse response, in Account account,
            in Bundle accountCredentials);

    /**
     * Starts the add account session by prompting the user for account information
     * and return a Bundle containing data to finish the session later.
     */
    void startAddAccountSession(in IAccountAuthenticatorResponse response, String accountType,
        String authTokenType, in String[] requiredFeatures, in Bundle options);
}
Loading