summaryrefslogtreecommitdiffstats
path: root/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java')
-rw-r--r--sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java419
1 files changed, 14 insertions, 405 deletions
diff --git a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
index 8c3efc9..f28f21d 100644
--- a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
+++ b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
@@ -8,23 +8,11 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
import android.accounts.Account;
import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorDescription;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
import android.os.AsyncTask;
-import android.os.Bundle;
import android.os.Handler;
-import android.text.TextUtils;
import org.chromium.base.Callback;
import org.chromium.base.Log;
@@ -32,24 +20,13 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.sync.signin.AccountManagerDelegate;
import org.chromium.sync.signin.AccountManagerHelper;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.annotation.Nullable;
/**
* The MockAccountManager helps out if you want to mock out all calls to the Android AccountManager.
@@ -84,8 +61,6 @@ public class MockAccountManager implements AccountManagerDelegate {
private final Set<AccountHolder> mAccounts;
- private final List<AccountAuthTokenPreparation> mAccountPermissionPreparations;
-
private final Handler mMainHandler;
private final SingleThreadedExecutor mExecutor;
@@ -104,7 +79,6 @@ public class MockAccountManager implements AccountManagerDelegate {
mExecutor = new SingleThreadedExecutor();
mGetAccountsTaskCounter = new ZeroCounter();
mAccounts = new HashSet<AccountHolder>();
- mAccountPermissionPreparations = new LinkedList<AccountAuthTokenPreparation>();
if (accounts != null) {
for (Account account : accounts) {
mAccounts.add(AccountHolder.create().account(account).alwaysAccept(true).build());
@@ -119,7 +93,7 @@ public class MockAccountManager implements AccountManagerDelegate {
}
@Override
- public Account[] getAccountsByType(@Nullable String type) {
+ public Account[] getAccountsByType(String type) {
if (!AccountManagerHelper.GOOGLE_ACCOUNT_TYPE.equals(type)) {
throw new IllegalArgumentException("Invalid account type: " + type);
}
@@ -128,7 +102,7 @@ public class MockAccountManager implements AccountManagerDelegate {
} else {
ArrayList<Account> validAccounts = new ArrayList<Account>();
for (AccountHolder ah : mAccounts) {
- if (TextUtils.equals(ah.getAccount().type, type)) {
+ if (type.equals(ah.getAccount().type)) {
validAccounts.add(ah.getAccount());
}
}
@@ -208,72 +182,28 @@ public class MockAccountManager implements AccountManagerDelegate {
}
@Override
- public AccountManagerFuture<Bundle> getAuthToken(Account account, String authTokenType,
- boolean notifyAuthFailure, AccountManagerCallback<Bundle> callback, Handler handler) {
- return getAuthTokenFuture(account, authTokenType, null, callback, handler);
- }
-
- private AccountManagerFuture<Bundle> getAuthTokenFuture(Account account, String authTokenType,
- Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
- final AccountHolder ah = getAccountHolder(account);
- if (ah.hasBeenAccepted(authTokenType)) {
- final String authToken = internalGenerateAndStoreAuthToken(ah, authTokenType);
- return runTask(mExecutor,
- new AccountManagerAuthTokenTask(activity, handler, callback,
- account, authTokenType,
- new Callable<Bundle>() {
- @Override
- public Bundle call() throws Exception {
- return getAuthTokenBundle(ah.getAccount(), authToken);
- }
- }));
- } else {
- Log.d(TAG, "getAuthTokenFuture: Account " + ah.getAccount()
- + " is asking for permission for " + authTokenType);
- final Intent intent = newGrantCredentialsPermissionIntent(
- activity != null, account, authTokenType);
- return runTask(mExecutor,
- new AccountManagerAuthTokenTask(activity, handler, callback,
- account, authTokenType,
- new Callable<Bundle>() {
- @Override
- public Bundle call() throws Exception {
- Bundle result = new Bundle();
- result.putParcelable(AccountManager.KEY_INTENT, intent);
- return result;
- }
- }));
- }
- }
-
- private static Bundle getAuthTokenBundle(Account account, String authToken) {
- Bundle result = new Bundle();
- result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
- result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
- result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
- return result;
- }
-
- private String internalGenerateAndStoreAuthToken(AccountHolder ah, String authTokenType) {
+ public String getAuthToken(Account account, String authTokenScope) {
+ AccountHolder ah = getAccountHolder(account);
+ assert ah.hasBeenAccepted(authTokenScope);
synchronized (mAccounts) {
// Some tests register auth tokens with value null, and those should be preserved.
- if (!ah.hasAuthTokenRegistered(authTokenType)
- && ah.getAuthToken(authTokenType) == null) {
+ if (!ah.hasAuthTokenRegistered(authTokenScope)
+ && ah.getAuthToken(authTokenScope) == null) {
// No authtoken registered. Need to create one.
String authToken = UUID.randomUUID().toString();
- Log.d(TAG, "Created new auth token for " + ah.getAccount()
- + ": autTokenType = " + authTokenType + ", authToken = " + authToken);
- ah = ah.withAuthToken(authTokenType, authToken);
+ Log.d(TAG, "Created new auth token for " + ah.getAccount() + ": authTokenScope = "
+ + authTokenScope + ", authToken = " + authToken);
+ ah = ah.withAuthToken(authTokenScope, authToken);
mAccounts.add(ah);
}
}
- return ah.getAuthToken(authTokenType);
+ return ah.getAuthToken(authTokenScope);
}
@Override
- public void invalidateAuthToken(String accountType, String authToken) {
- if (!AccountManagerHelper.GOOGLE_ACCOUNT_TYPE.equals(accountType)) {
- throw new IllegalArgumentException("Invalid account type: " + accountType);
+ public void invalidateAuthToken(String accountScope, String authToken) {
+ if (!AccountManagerHelper.GOOGLE_ACCOUNT_TYPE.equals(accountScope)) {
+ throw new IllegalArgumentException("Invalid account type: " + accountScope);
}
if (authToken == null) {
throw new IllegalArgumentException("AuthToken can not be null");
@@ -313,74 +243,6 @@ public class MockAccountManager implements AccountManagerDelegate {
});
}
- public void notifyFeaturesFetched(Account account, Set<String> features) {
- getAccountHolder(account).didFetchFeatures(features);
- }
-
- public void prepareAllowAppPermission(Account account, String authTokenType) {
- addPreparedAppPermission(new AccountAuthTokenPreparation(account, authTokenType, true));
- }
-
- public void prepareDenyAppPermission(Account account, String authTokenType) {
- addPreparedAppPermission(new AccountAuthTokenPreparation(account, authTokenType, false));
- }
-
- private void addPreparedAppPermission(AccountAuthTokenPreparation accountAuthTokenPreparation) {
- Log.d(TAG, "Adding " + accountAuthTokenPreparation);
- mAccountPermissionPreparations.add(accountAuthTokenPreparation);
- }
-
- private AccountAuthTokenPreparation getPreparedPermission(Account account,
- String authTokenType) {
- for (AccountAuthTokenPreparation accountPrep : mAccountPermissionPreparations) {
- if (accountPrep.getAccount().equals(account)
- && accountPrep.getAuthTokenType().equals(authTokenType)) {
- return accountPrep;
- }
- }
- return null;
- }
-
- private void applyPreparedPermission(AccountAuthTokenPreparation prep) {
- if (prep != null) {
- Log.d(TAG, "Applying " + prep);
- mAccountPermissionPreparations.remove(prep);
- mAccounts.add(getAccountHolder(prep.getAccount()).withHasBeenAccepted(
- prep.getAuthTokenType(), prep.isAllowed()));
- }
- }
-
- private Intent newGrantCredentialsPermissionIntent(boolean hasActivity, Account account,
- String authTokenType) {
- ComponentName component = new ComponentName(mTestContext,
- MockGrantCredentialsPermissionActivity.class.getCanonicalName());
-
- // Make sure we can start the activity.
- ActivityInfo ai = null;
- try {
- ai = mContext.getPackageManager().getActivityInfo(component, 0);
- } catch (PackageManager.NameNotFoundException e) {
- throw new IllegalStateException(
- "Unable to find " + component.getClassName());
- }
- if (ai.applicationInfo != mContext.getApplicationInfo() && !ai.exported) {
- throw new IllegalStateException(
- "Unable to start " + ai.name + ". "
- + "The accounts you added to MockAccountManager may not be "
- + "configured correctly.");
- }
-
- Intent intent = new Intent();
- intent.setComponent(component);
- intent.putExtra(MockGrantCredentialsPermissionActivity.ACCOUNT, account);
- intent.putExtra(MockGrantCredentialsPermissionActivity.AUTH_TOKEN_TYPE, authTokenType);
- if (!hasActivity) {
- // No activity provided, so we help the caller by adding the new task flag
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
- return intent;
- }
-
private AccountHolder getAccountHolder(Account account) {
if (account == null) {
throw new IllegalArgumentException("Account can not be null");
@@ -393,216 +255,6 @@ public class MockAccountManager implements AccountManagerDelegate {
throw new IllegalArgumentException("Can not find AccountHolder for account " + account);
}
- private static <T> AccountManagerFuture<T> runTask(Executor executorService,
- AccountManagerTask<T> accountManagerBundleTask) {
- executorService.execute(accountManagerBundleTask);
- return accountManagerBundleTask;
- }
-
- private class AccountManagerTask<T> extends FutureTask<T> implements AccountManagerFuture<T> {
-
- protected final Handler mHandler;
-
- protected final AccountManagerCallback<T> mCallback;
-
- protected final Callable<T> mCallable;
-
- public AccountManagerTask(Handler handler,
- AccountManagerCallback<T> callback, Callable<T> callable) {
- super(new Callable<T>() {
- @Override
- public T call() throws Exception {
- throw new IllegalStateException("this should never be called, "
- + "but call must be overridden.");
- }
- });
- mHandler = handler;
- mCallback = callback;
- mCallable = callable;
- }
-
- private T internalGetResult(long timeout, TimeUnit unit)
- throws OperationCanceledException, IOException, AuthenticatorException {
- try {
- if (timeout == -1) {
- return get();
- } else {
- return get(timeout, unit);
- }
- } catch (CancellationException e) {
- throw new OperationCanceledException();
- } catch (TimeoutException e) {
- // Fall through and cancel.
- } catch (InterruptedException e) {
- // Fall through and cancel.
- } catch (ExecutionException e) {
- final Throwable cause = e.getCause();
- if (cause instanceof IOException) {
- throw (IOException) cause;
- } else if (cause instanceof UnsupportedOperationException) {
- throw new AuthenticatorException(cause);
- } else if (cause instanceof AuthenticatorException) {
- throw (AuthenticatorException) cause;
- } else if (cause instanceof RuntimeException) {
- throw (RuntimeException) cause;
- } else if (cause instanceof Error) {
- throw (Error) cause;
- } else {
- throw new IllegalStateException(cause);
- }
- } finally {
- cancel(true /* Interrupt if running. */);
- }
- throw new OperationCanceledException();
- }
-
- @Override
- public T getResult()
- throws OperationCanceledException, IOException, AuthenticatorException {
- return internalGetResult(-1, null);
- }
-
- @Override
- public T getResult(long timeout, TimeUnit unit)
- throws OperationCanceledException, IOException, AuthenticatorException {
- return internalGetResult(timeout, unit);
- }
-
- @Override
- public void run() {
- try {
- set(mCallable.call());
- } catch (Exception e) {
- setException(e);
- }
- }
-
- @Override
- protected void done() {
- if (mCallback != null) {
- postToHandler(getHandler(), mCallback, this);
- }
- }
-
- private Handler getHandler() {
- return mHandler == null ? mMainHandler : mHandler;
- }
-
- }
-
- private static <T> void postToHandler(Handler handler, final AccountManagerCallback<T> callback,
- final AccountManagerFuture<T> future) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- callback.run(future);
- }
- });
- }
-
- private class AccountManagerAuthTokenTask extends AccountManagerTask<Bundle> {
-
- private final Activity mActivity;
-
- private final AccountAuthTokenPreparation mAccountAuthTokenPreparation;
-
- private final Account mAccount;
-
- private final String mAuthTokenType;
-
- public AccountManagerAuthTokenTask(Activity activity, Handler handler,
- AccountManagerCallback<Bundle> callback,
- Account account, String authTokenType,
- Callable<Bundle> callable) {
- super(handler, callback, callable);
- mActivity = activity;
- mAccountAuthTokenPreparation = getPreparedPermission(account, authTokenType);
- mAccount = account;
- mAuthTokenType = authTokenType;
- }
-
- @Override
- public void run() {
- try {
- Bundle bundle = mCallable.call();
- Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
- if (intent != null) {
- // Start the intent activity and wait for it to finish.
- if (mActivity != null) {
- waitForActivity(mActivity, intent);
- } else {
- waitForActivity(mContext, intent);
- }
- if (mAccountAuthTokenPreparation == null) {
- throw new IllegalStateException("No account preparation ready for "
- + mAccount + ", authTokenType = " + mAuthTokenType
- + ". Add a call to either prepareGrantAppPermission(...) or "
- + "prepareRevokeAppPermission(...) in your test before asking for "
- + "an auth token");
- } else {
- // We have shown the Allow/Deny activity, and it has gone away. We can now
- // apply the pre-stored permission.
- applyPreparedPermission(mAccountAuthTokenPreparation);
- generateResult(getAccountHolder(mAccount), mAuthTokenType);
- }
- } else {
- set(bundle);
- }
- } catch (Exception e) {
- setException(e);
- }
- }
-
- private void generateResult(AccountHolder accountHolder, String authTokenType)
- throws OperationCanceledException {
- if (accountHolder.hasBeenAccepted(authTokenType)) {
- String authToken = internalGenerateAndStoreAuthToken(accountHolder, authTokenType);
- // Return a valid auth token.
- set(getAuthTokenBundle(accountHolder.getAccount(), authToken));
- } else {
- // Throw same exception as when user clicks "Deny".
- throw new OperationCanceledException("User denied request");
- }
- }
- }
-
- /**
- * This method starts {@link MockGrantCredentialsPermissionActivity} and waits for it
- * to be started before it returns.
- *
- * @param context the context to start the intent in
- * @param intent the intent to use to start MockGrantCredentialsPermissionActivity
- */
- @SuppressWarnings("WaitNotInLoop")
- private void waitForActivity(Context context, Intent intent) {
- final Object mutex = new Object();
- BroadcastReceiver receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- synchronized (mutex) {
- mutex.notifyAll();
- }
- }
- };
- if (!MockGrantCredentialsPermissionActivity.class.getCanonicalName()
- .equals(intent.getComponent().getClassName())) {
- throw new IllegalArgumentException("Can only wait for "
- + "MockGrantCredentialsPermissionActivity");
- }
- mContext.registerReceiver(receiver, new IntentFilter(MUTEX_WAIT_ACTION));
- context.startActivity(intent);
- try {
- Log.d(TAG, "Waiting for broadcast of " + MUTEX_WAIT_ACTION);
- synchronized (mutex) {
- mutex.wait(WAIT_TIME_FOR_GRANT_BROADCAST_MS);
- }
- } catch (InterruptedException e) {
- throw new IllegalStateException("Got unexpected InterruptedException");
- }
- Log.d(TAG, "Got broadcast of " + MUTEX_WAIT_ACTION);
- mContext.unregisterReceiver(receiver);
- }
-
private void postAsyncAccountChangedEvent() {
// Mimic that this does not happen on the main thread.
new AsyncTask<Void, Void, Void>() {
@@ -615,49 +267,6 @@ public class MockAccountManager implements AccountManagerDelegate {
}
/**
- * Internal class for storage of prepared account auth token permissions.
- *
- * This is used internally by {@link MockAccountManager} to mock the same behavior as clicking
- * Allow/Deny in the Android {@link GrantCredentialsPermissionActivity}.
- */
- private static class AccountAuthTokenPreparation {
-
- private final Account mAccount;
-
- private final String mAuthTokenType;
-
- private final boolean mAllowed;
-
- private AccountAuthTokenPreparation(Account account, String authTokenType,
- boolean allowed) {
- mAccount = account;
- mAuthTokenType = authTokenType;
- mAllowed = allowed;
- }
-
- public Account getAccount() {
- return mAccount;
- }
-
- public String getAuthTokenType() {
- return mAuthTokenType;
- }
-
- public boolean isAllowed() {
- return mAllowed;
- }
-
- @Override
- public String toString() {
- return "AccountAuthTokenPreparation{"
- + "mAccount=" + mAccount
- + ", mAuthTokenType='" + mAuthTokenType + '\''
- + ", mAllowed=" + mAllowed
- + '}';
- }
- }
-
- /**
* Simple concurrency helper class for waiting until a resource count becomes zero.
*/
private static class ZeroCounter {