Home | History | Annotate | Download | only in shadows
      1 package com.xtremelabs.robolectric.shadows;
      2 
      3 import android.accounts.Account;
      4 import android.accounts.AccountManager;
      5 import android.accounts.AccountManagerCallback;
      6 import android.accounts.AccountManagerFuture;
      7 import android.accounts.AuthenticatorException;
      8 import android.accounts.OperationCanceledException;
      9 import android.app.Activity;
     10 import android.content.Context;
     11 import android.os.Bundle;
     12 import android.os.Handler;
     13 
     14 import com.xtremelabs.robolectric.Robolectric;
     15 import com.xtremelabs.robolectric.internal.Implementation;
     16 import com.xtremelabs.robolectric.internal.Implements;
     17 import com.xtremelabs.robolectric.internal.RealObject;
     18 
     19 import java.io.IOException;
     20 import java.util.*;
     21 import java.util.concurrent.TimeUnit;
     22 
     23 import static com.xtremelabs.robolectric.Robolectric.newInstanceOf;
     24 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
     25 
     26 /**
     27  * Shadows the {@code android.accounts.AccountManager} class.
     28  */
     29 @SuppressWarnings({"UnusedDeclaration"})
     30 @Implements(AccountManager.class)
     31 public class ShadowAccountManager {
     32 
     33     public static final String AUTH_TOKEN_VALUE = "authToken";
     34 
     35     private static AccountManager singleton;
     36 
     37     private Account[] accounts;
     38     private HashMap<Account, HashMap<String, String>> cachedAuthTokenValues =
     39             new HashMap<Account, HashMap<String, String>>();
     40 
     41     @Implementation
     42     public static AccountManager get(Context context) {
     43         if (singleton == null) {
     44             singleton = Robolectric.newInstanceOf(AccountManager.class);
     45         }
     46         return singleton;
     47     }
     48 
     49     @Implementation
     50     public AccountManagerFuture<Bundle> getAuthToken(Account account, String authTokenType, Bundle options, Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
     51         //TODO: Add complete activity to perform the account intent dance.
     52         final Account finalAccount = account;
     53         return new AccountManagerFuture<Bundle>() {
     54 
     55             private boolean isFutureCancelled;
     56             private boolean isFutureDone;
     57 
     58             @Override
     59             public boolean cancel(boolean mayInterruptIfRunning) {
     60                 if (isFutureDone) {
     61                     return false;
     62                 }
     63                 isFutureCancelled = true;
     64                 return isCancelled();
     65             }
     66 
     67             @Override
     68             public Bundle getResult(long timeout, TimeUnit unit) throws OperationCanceledException,
     69                     AuthenticatorException, IOException {
     70                 Bundle result = new Bundle();
     71                 if (!isCancelled()) {
     72                     addBundleResults(result, finalAccount);
     73                     isFutureDone = true;
     74                 }
     75                 return result;
     76             }
     77 
     78             @Override
     79             public Bundle getResult() throws OperationCanceledException,
     80                     AuthenticatorException, IOException {
     81                 Bundle result = new Bundle();
     82                 if (!isCancelled()) {
     83                     addBundleResults(result, finalAccount);
     84                     isFutureDone = true;
     85                 }
     86                 return result;
     87             }
     88 
     89             @Override
     90             public boolean isCancelled() {
     91                 return isFutureCancelled;
     92             }
     93 
     94             @Override
     95             public boolean isDone() {
     96                 return isFutureDone || isFutureCancelled;
     97             }
     98 
     99             private void addBundleResults(Bundle bundle, final Account account) {
    100                 bundle.putString(AccountManager.KEY_AUTHTOKEN, AUTH_TOKEN_VALUE);
    101                 bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
    102                 bundle.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
    103             }
    104         };
    105     }
    106 
    107     @Implementation
    108     public AccountManagerFuture<Bundle> getAuthTokenByFeatures(String accountType, String authTokenType, String[] features, Activity activity, Bundle addAccountOptions, Bundle getAuthTokenOptions, AccountManagerCallback<Bundle> callback, Handler handler) {
    109         //TODO: Add complete activity to perform the account intent dance.
    110         final String finalAccountType = accountType;
    111         return new AccountManagerFuture<Bundle>() {
    112 
    113             private boolean isFutureCancelled;
    114             private boolean isFutureDone;
    115 
    116             @Override
    117             public boolean cancel(boolean mayInterruptIfRunning) {
    118                 if (isFutureDone) {
    119                     return false;
    120                 }
    121                 isFutureCancelled = true;
    122                 return isCancelled();
    123             }
    124 
    125             @Override
    126             public Bundle getResult(long timeout, TimeUnit unit) throws OperationCanceledException,
    127                     AuthenticatorException, IOException {
    128                 Bundle result = new Bundle();
    129                 if (!isCancelled()) {
    130                     addBundleResults(result, finalAccountType);
    131                     isFutureDone = true;
    132                 }
    133                 return result;
    134             }
    135 
    136             @Override
    137             public Bundle getResult() throws OperationCanceledException,
    138                     AuthenticatorException, IOException {
    139                 Bundle result = new Bundle();
    140                 if (!isCancelled()) {
    141                     addBundleResults(result, finalAccountType);
    142                     isFutureDone = true;
    143                 }
    144                 return result;
    145             }
    146 
    147             @Override
    148             public boolean isCancelled() {
    149                 return isFutureCancelled;
    150             }
    151 
    152             @Override
    153             public boolean isDone() {
    154                 return isFutureDone || isFutureCancelled;
    155             }
    156 
    157             private void addBundleResults(Bundle bundle, final String accountType) {
    158                 bundle.putString(AccountManager.KEY_AUTHTOKEN, AUTH_TOKEN_VALUE);
    159                 bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
    160                 bundle.putString(AccountManager.KEY_ACCOUNT_NAME, "accountName");
    161             }
    162         };
    163     }
    164 
    165     @Implementation
    166     public void invalidateAuthToken(String accountType, String authToken) {}
    167 
    168     @Implementation
    169     public Account[] getAccounts() {
    170         return getAccountsByType(null);
    171     }
    172 
    173     @Implementation
    174     public Account[] getAccountsByType(String accountType) {
    175         if (accountType == null) {
    176             return accounts;
    177         }
    178 
    179         ArrayList<Account> accountList = new ArrayList<Account>();
    180         if (accounts != null) {
    181             for (Account account : accounts) {
    182                 if (accountType.equals(account.type)) {
    183                     accountList.add(account);
    184                 }
    185             }
    186         }
    187         return accountList.toArray(new Account[accountList.size()]);
    188     }
    189 
    190     @Implementation
    191     public String peekAuthToken(Account account, String authTokenType) {
    192         HashMap<String, String> tokens = cachedAuthTokenValues.get(account);
    193         return (tokens != null) ? tokens.get(authTokenType) : null;
    194     }
    195 
    196     public void setCachedAuthToken(Account account, String authTokenType, String authTokenValue) {
    197         if (!cachedAuthTokenValues.containsKey(account)) {
    198             cachedAuthTokenValues.put(account, new HashMap<String, String>());
    199         }
    200         cachedAuthTokenValues.get(account).put(authTokenType, authTokenValue);
    201     }
    202 
    203     public void setAccounts(Account[] accounts) {
    204         this.accounts = accounts;
    205     }
    206 }
    207