Index: sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java |
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 8c3efc9055aaf48d523040e2767f40f6d48a1358..f28f21d7c94b612ad581555cfabc6ec99ace2fe3 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 { |