Home | History | Annotate | Download | only in toolbox
      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 
     17 package com.android.volley.toolbox;
     18 
     19 import com.android.volley.AuthFailureError;
     20 
     21 import android.accounts.Account;
     22 import android.accounts.AccountManager;
     23 import android.accounts.AccountManagerFuture;
     24 import android.annotation.SuppressLint;
     25 import android.content.Context;
     26 import android.content.Intent;
     27 import android.os.Bundle;
     28 
     29 /**
     30  * An Authenticator that uses {@link AccountManager} to get auth
     31  * tokens of a specified type for a specified account.
     32  */
     33 // TODO: Update this to account for runtime permissions
     34 @SuppressLint("MissingPermission")
     35 public class AndroidAuthenticator implements Authenticator {
     36     private final AccountManager mAccountManager;
     37     private final Account mAccount;
     38     private final String mAuthTokenType;
     39     private final boolean mNotifyAuthFailure;
     40 
     41     /**
     42      * Creates a new authenticator.
     43      * @param context Context for accessing AccountManager
     44      * @param account Account to authenticate as
     45      * @param authTokenType Auth token type passed to AccountManager
     46      */
     47     public AndroidAuthenticator(Context context, Account account, String authTokenType) {
     48         this(context, account, authTokenType, false);
     49     }
     50 
     51     /**
     52      * Creates a new authenticator.
     53      * @param context Context for accessing AccountManager
     54      * @param account Account to authenticate as
     55      * @param authTokenType Auth token type passed to AccountManager
     56      * @param notifyAuthFailure Whether to raise a notification upon auth failure
     57      */
     58     public AndroidAuthenticator(Context context, Account account, String authTokenType,
     59             boolean notifyAuthFailure) {
     60         this(AccountManager.get(context), account, authTokenType, notifyAuthFailure);
     61     }
     62 
     63     // Visible for testing. Allows injection of a mock AccountManager.
     64     AndroidAuthenticator(AccountManager accountManager, Account account,
     65             String authTokenType, boolean notifyAuthFailure) {
     66         mAccountManager = accountManager;
     67         mAccount = account;
     68         mAuthTokenType = authTokenType;
     69         mNotifyAuthFailure = notifyAuthFailure;
     70     }
     71 
     72     /**
     73      * Returns the Account being used by this authenticator.
     74      */
     75     public Account getAccount() {
     76         return mAccount;
     77     }
     78 
     79     /**
     80      * Returns the Auth Token Type used by this authenticator.
     81      */
     82     public String getAuthTokenType() {
     83         return mAuthTokenType;
     84     }
     85 
     86     // TODO: Figure out what to do about notifyAuthFailure
     87     @SuppressWarnings("deprecation")
     88     @Override
     89     public String getAuthToken() throws AuthFailureError {
     90         AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(mAccount,
     91                 mAuthTokenType, mNotifyAuthFailure, null, null);
     92         Bundle result;
     93         try {
     94             result = future.getResult();
     95         } catch (Exception e) {
     96             throw new AuthFailureError("Error while retrieving auth token", e);
     97         }
     98         String authToken = null;
     99         if (future.isDone() && !future.isCancelled()) {
    100             if (result.containsKey(AccountManager.KEY_INTENT)) {
    101                 Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
    102                 throw new AuthFailureError(intent);
    103             }
    104             authToken = result.getString(AccountManager.KEY_AUTHTOKEN);
    105         }
    106         if (authToken == null) {
    107             throw new AuthFailureError("Got null auth token for type: " + mAuthTokenType);
    108         }
    109 
    110         return authToken;
    111     }
    112 
    113     @Override
    114     public void invalidateAuthToken(String authToken) {
    115         mAccountManager.invalidateAuthToken(mAccount.type, authToken);
    116     }
    117 }
    118