This source file includes following definitions.
- tokenAvailable
- get
- overrideAccountManagerHelperForTests
- createAccountFromName
- getGoogleAccountNames
- getGoogleAccounts
- hasGoogleAccounts
- getAccountFromName
- hasAccountForName
- hasGoogleAccountAuthenticator
- getAuthTokenFromBackground
- getAuthTokenFromForeground
- onConnectionTypeChanged
- getAuthTokenInner
- getAuthTokenAsynchronously
- onGotAuthTokenResult
- getNewAuthToken
- getNewAuthTokenFromForeground
- invalidateAuthToken
package org.chromium.sync.signin;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorDescription;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import com.google.common.annotations.VisibleForTesting;
import org.chromium.base.ThreadUtils;
import org.chromium.net.NetworkChangeNotifier;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
public class AccountManagerHelper {
private static final String TAG = "AccountManagerHelper";
public static final String GOOGLE_ACCOUNT_TYPE = "com.google";
private static final Object sLock = new Object();
private static final int MAX_TRIES = 3;
private static AccountManagerHelper sAccountManagerHelper;
private final AccountManagerDelegate mAccountManager;
private Context mApplicationContext;
public interface GetAuthTokenCallback {
void tokenAvailable(String token);
}
private AccountManagerHelper(Context context,
AccountManagerDelegate accountManager) {
mApplicationContext = context.getApplicationContext();
mAccountManager = accountManager;
}
public static AccountManagerHelper get(Context context) {
synchronized (sLock) {
if (sAccountManagerHelper == null) {
sAccountManagerHelper = new AccountManagerHelper(context,
new SystemAccountManagerDelegate(context));
}
}
return sAccountManagerHelper;
}
@VisibleForTesting
public static void overrideAccountManagerHelperForTests(Context context,
AccountManagerDelegate accountManager) {
synchronized (sLock) {
sAccountManagerHelper = new AccountManagerHelper(context, accountManager);
}
}
public static Account createAccountFromName(String name) {
return new Account(name, GOOGLE_ACCOUNT_TYPE);
}
public List<String> getGoogleAccountNames() {
List<String> accountNames = new ArrayList<String>();
Account[] accounts = mAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE);
for (Account account : accounts) {
accountNames.add(account.name);
}
return accountNames;
}
public Account[] getGoogleAccounts() {
return mAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE);
}
public boolean hasGoogleAccounts() {
return getGoogleAccounts().length > 0;
}
public Account getAccountFromName(String accountName) {
Account[] accounts = mAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE);
for (Account account : accounts) {
if (account.name.equals(accountName)) {
return account;
}
}
return null;
}
public boolean hasAccountForName(String accountName) {
return getAccountFromName(accountName) != null;
}
public boolean hasGoogleAccountAuthenticator() {
AuthenticatorDescription[] descs = mAccountManager.getAuthenticatorTypes();
for (AuthenticatorDescription desc : descs) {
if (GOOGLE_ACCOUNT_TYPE.equals(desc.type)) return true;
}
return false;
}
@Deprecated
public String getAuthTokenFromBackground(Account account, String authTokenType) {
AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(account,
authTokenType, false, null, null);
AtomicBoolean errorEncountered = new AtomicBoolean(false);
return getAuthTokenInner(future, errorEncountered);
}
public void getAuthTokenFromForeground(Activity activity, Account account, String authTokenType,
GetAuthTokenCallback callback) {
AtomicInteger numTries = new AtomicInteger(0);
AtomicBoolean errorEncountered = new AtomicBoolean(false);
getAuthTokenAsynchronously(activity, account, authTokenType, callback, numTries,
errorEncountered, null);
}
private class ConnectionRetry implements NetworkChangeNotifier.ConnectionTypeObserver {
private final Account mAccount;
private final String mAuthTokenType;
private final GetAuthTokenCallback mCallback;
private final AtomicInteger mNumTries;
private final AtomicBoolean mErrorEncountered;
ConnectionRetry(Account account, String authTokenType, GetAuthTokenCallback callback,
AtomicInteger numTries, AtomicBoolean errorEncountered) {
mAccount = account;
mAuthTokenType = authTokenType;
mCallback = callback;
mNumTries = numTries;
mErrorEncountered = errorEncountered;
}
@Override
public void onConnectionTypeChanged(int connectionType) {
assert mNumTries.get() <= MAX_TRIES;
if (mNumTries.get() == MAX_TRIES) {
NetworkChangeNotifier.removeConnectionTypeObserver(this);
return;
}
if (NetworkChangeNotifier.isOnline()) {
NetworkChangeNotifier.removeConnectionTypeObserver(this);
getAuthTokenAsynchronously(null, mAccount, mAuthTokenType, mCallback, mNumTries,
mErrorEncountered, this);
}
}
}
private String getAuthTokenInner(AccountManagerFuture<Bundle> future,
AtomicBoolean errorEncountered) {
try {
Bundle result = future.getResult();
if (result != null) {
if (result.containsKey(AccountManager.KEY_INTENT)) {
Log.d(TAG, "Starting intent to get auth credentials");
Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
int flags = intent.getFlags();
flags |= Intent.FLAG_ACTIVITY_NEW_TASK;
intent.setFlags(flags);
mApplicationContext.startActivity(intent);
return null;
}
return result.getString(AccountManager.KEY_AUTHTOKEN);
} else {
Log.w(TAG, "Auth token - getAuthToken returned null");
}
} catch (OperationCanceledException e) {
Log.w(TAG, "Auth token - operation cancelled", e);
} catch (AuthenticatorException e) {
Log.w(TAG, "Auth token - authenticator exception", e);
} catch (IOException e) {
Log.w(TAG, "Auth token - IO exception", e);
errorEncountered.set(true);
}
return null;
}
private void getAuthTokenAsynchronously(@Nullable Activity activity, final Account account,
final String authTokenType, final GetAuthTokenCallback callback,
final AtomicInteger numTries, final AtomicBoolean errorEncountered,
final ConnectionRetry retry) {
AccountManagerFuture<Bundle> future;
if (numTries.get() == 0 && activity != null) {
future = mAccountManager.getAuthToken(
account, authTokenType, null, activity, null, null);
} else {
future = mAccountManager.getAuthToken(
account, authTokenType, false, null, null);
}
final AccountManagerFuture<Bundle> finalFuture = future;
errorEncountered.set(false);
if (ThreadUtils.runningOnUiThread()) {
new AsyncTask<Void, Void, String>() {
@Override
public String doInBackground(Void... params) {
return getAuthTokenInner(finalFuture, errorEncountered);
}
@Override
public void onPostExecute(String authToken) {
onGotAuthTokenResult(account, authTokenType, authToken, callback, numTries,
errorEncountered, retry);
}
}.execute();
} else {
String authToken = getAuthTokenInner(finalFuture, errorEncountered);
onGotAuthTokenResult(account, authTokenType, authToken, callback, numTries,
errorEncountered, retry);
}
}
private void onGotAuthTokenResult(Account account, String authTokenType, String authToken,
GetAuthTokenCallback callback, AtomicInteger numTries, AtomicBoolean errorEncountered,
ConnectionRetry retry) {
if (authToken != null || !errorEncountered.get() ||
numTries.incrementAndGet() == MAX_TRIES ||
!NetworkChangeNotifier.isInitialized()) {
callback.tokenAvailable(authToken);
return;
}
if (retry == null) {
ConnectionRetry newRetry = new ConnectionRetry(account, authTokenType, callback,
numTries, errorEncountered);
NetworkChangeNotifier.addConnectionTypeObserver(newRetry);
} else {
NetworkChangeNotifier.addConnectionTypeObserver(retry);
}
}
@Deprecated
public String getNewAuthToken(Account account, String authToken, String authTokenType) {
if (authToken != null && !authToken.isEmpty()) {
mAccountManager.invalidateAuthToken(GOOGLE_ACCOUNT_TYPE, authToken);
}
try {
return mAccountManager.blockingGetAuthToken(account, authTokenType, true);
} catch (OperationCanceledException e) {
Log.w(TAG, "Auth token - operation cancelled", e);
} catch (AuthenticatorException e) {
Log.w(TAG, "Auth token - authenticator exception", e);
} catch (IOException e) {
Log.w(TAG, "Auth token - IO exception", e);
}
return null;
}
public void getNewAuthTokenFromForeground(Account account, String authToken,
String authTokenType, GetAuthTokenCallback callback) {
if (authToken != null && !authToken.isEmpty()) {
mAccountManager.invalidateAuthToken(GOOGLE_ACCOUNT_TYPE, authToken);
}
AtomicInteger numTries = new AtomicInteger(0);
AtomicBoolean errorEncountered = new AtomicBoolean(false);
getAuthTokenAsynchronously(
null, account, authTokenType, callback, numTries, errorEncountered, null);
}
public void invalidateAuthToken(String authToken) {
mAccountManager.invalidateAuthToken(GOOGLE_ACCOUNT_TYPE, authToken);
}
}