AndroidAuthenticator.java revision 6c9de79451d6f9410c006e4b17d3d07fae12b273
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.volley.toolbox;
18
19import com.android.volley.AuthFailureError;
20
21import android.accounts.Account;
22import android.accounts.AccountManager;
23import android.accounts.AccountManagerFuture;
24import android.content.Context;
25import android.content.Intent;
26import android.os.Bundle;
27
28/**
29 * An Authenticator that uses {@link AccountManager} to get auth
30 * tokens of a specified type for a specified account.
31 */
32public class AndroidAuthenticator implements Authenticator {
33    private final AccountManager mAccountManager;
34    private final Account mAccount;
35    private final String mAuthTokenType;
36    private final boolean mNotifyAuthFailure;
37
38    /**
39     * Creates a new authenticator.
40     * @param context Context for accessing AccountManager
41     * @param account Account to authenticate as
42     * @param authTokenType Auth token type passed to AccountManager
43     */
44    public AndroidAuthenticator(Context context, Account account, String authTokenType) {
45        this(context, account, authTokenType, false);
46    }
47
48    /**
49     * Creates a new authenticator.
50     * @param context Context for accessing AccountManager
51     * @param account Account to authenticate as
52     * @param authTokenType Auth token type passed to AccountManager
53     * @param notifyAuthFailure Whether to raise a notification upon auth failure
54     */
55    public AndroidAuthenticator(Context context, Account account, String authTokenType,
56            boolean notifyAuthFailure) {
57        this(AccountManager.get(context), account, authTokenType, notifyAuthFailure);
58    }
59
60    // Visible for testing. Allows injection of a mock AccountManager.
61    AndroidAuthenticator(AccountManager accountManager, Account account,
62            String authTokenType, boolean notifyAuthFailure) {
63        mAccountManager = accountManager;
64        mAccount = account;
65        mAuthTokenType = authTokenType;
66        mNotifyAuthFailure = notifyAuthFailure;
67    }
68
69    /**
70     * Returns the Account being used by this authenticator.
71     */
72    public Account getAccount() {
73        return mAccount;
74    }
75
76    // TODO: Figure out what to do about notifyAuthFailure
77    @SuppressWarnings("deprecation")
78    @Override
79    public String getAuthToken() throws AuthFailureError {
80        AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(mAccount,
81                mAuthTokenType, mNotifyAuthFailure, null, null);
82        Bundle result;
83        try {
84            result = future.getResult();
85        } catch (Exception e) {
86            throw new AuthFailureError("Error while retrieving auth token", e);
87        }
88        String authToken = null;
89        if (future.isDone() && !future.isCancelled()) {
90            if (result.containsKey(AccountManager.KEY_INTENT)) {
91                Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
92                throw new AuthFailureError(intent);
93            }
94            authToken = result.getString(AccountManager.KEY_AUTHTOKEN);
95        }
96        if (authToken == null) {
97            throw new AuthFailureError("Got null auth token for type: " + mAuthTokenType);
98        }
99
100        return authToken;
101    }
102
103    @Override
104    public void invalidateAuthToken(String authToken) {
105        mAccountManager.invalidateAuthToken(mAccount.type, authToken);
106    }
107}
108