package com.newsrob.auth;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AuthenticatorDescription;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import com.newsrob.NewsRob;
import com.newsrob.PL;
public class AccountManagementUtilsImplementation implements IAccountManagementUtils {
static final String GOOGLE_ACCOUNT_TYPE = "com.google";
private static final String[] GOOGLE_ACCOUNT = new String[] { "google" }; // hosted_or_google
private static final String AUTH_TOKEN_TYPE_READER = "reader";
private static final String TAG = "NewsRob Auth";
public List<String> getAccounts(Context context) {
Account[] accounts = getAccounts(context, getAccountManager(context));
List<String> accountNames = new ArrayList<String>(accounts.length);
for (Account account : accounts)
accountNames.add(account.name);
return accountNames;
}
AccountManager getAccountManager(Context context) {
return AccountManager.get(context);
}
public String blockingGetAuthToken(Context ctx, String googleAccount) throws OperationCanceledException,
AuthenticatorException, IOException {
PL.log("AMU.blockingGetAuthToken for " + googleAccount + ".", ctx);
AccountManager am = getAccountManager(ctx);
Account selectedAccount = findAccountByGoogleAccountId(ctx, am, googleAccount);
String token = am.blockingGetAuthToken(selectedAccount, AUTH_TOKEN_TYPE_READER, true);
PL.log("AMU.blockingGetAuthToken for " + googleAccount + "(2) returns " + token + ".", ctx);
return token;
}
public void getAuthToken(final Activity waitingActivity, Handler handler, final IAuthenticationCallback callback,
String googleAccount) {
PL.log("AMU.getAuthToken for " + googleAccount + ".", waitingActivity);
AccountManager accountManager = AccountManager.get(waitingActivity);
// find the selected account
Account selectedAccount = findAccountByGoogleAccountId(waitingActivity, accountManager, googleAccount);
if (selectedAccount == null)
throw new RuntimeException("No account found for " + googleAccount + ".");
final Account selAccount = selectedAccount;
// do the authentication
// hosted
// google_or_hosted
// legacy
// prefer_hosted
// google_prefer_hosted
// legacy_hosted
// require_google
// google_or_legacy_hosted
// "google", "legacy_hosted"
// google/google works -> mariano.kamp, androidnewsreader
// legacy_hosted_or_google
if (false)
accountManager.getAuthTokenByFeatures(GOOGLE_ACCOUNT_TYPE, "reader", GOOGLE_ACCOUNT, waitingActivity,
new Bundle(), null, new AccountManagerCallback<Bundle>() {
public void run(android.accounts.AccountManagerFuture<Bundle> f) {
try {
Bundle b = f.getResult();
for (String key : b.keySet())
System.out.println("key " + key + " value " + b.getByte(key));
String authToken = f.getResult().getString(AccountManager.KEY_AUTHTOKEN);
if (authToken == null)
throw new RuntimeException("AuthToken was null.");
callback.onAuthTokenReceived(selAccount.name, authToken);
} catch (Exception e) {
e.printStackTrace();
if (e instanceof OperationCanceledException)
e = new Exception("Operation canceled by user.");
callback.onError(e);
}
}
}, handler);
if (true)
accountManager.getAuthToken(selectedAccount, AUTH_TOKEN_TYPE_READER, null, waitingActivity,
new AccountManagerCallback<Bundle>() {
public void run(android.accounts.AccountManagerFuture<Bundle> f) {
try {
String authToken = f.getResult().getString(AccountManager.KEY_AUTHTOKEN);
if (authToken == null)
throw new RuntimeException("AuthToken was null.");
PL.log("AMU.getAuthToken for " + selAccount.name + "received token="
+ authToken.substring(0, 4) + "(2).", waitingActivity);
callback.onAuthTokenReceived(selAccount.name, authToken);
} catch (Exception e) {
e.printStackTrace();
if (e instanceof OperationCanceledException)
e = new Exception("Operation canceled by user.");
callback.onError(e);
}
}
}, handler);
}
public boolean supportsGoogleAuth(Context context) {
for (AuthenticatorDescription ad : getAccountManager(context).getAuthenticatorTypes()) {
if (GOOGLE_ACCOUNT_TYPE.equals(ad.type))
return true;
}
return false;
}
@Override
public void invalidateAuthToken(Context context, String authToken) {
Log.d(TAG, "Token invalidated.");
PL.log("AMU.invalidateAuthToken", context);
getAccountManager(context).invalidateAuthToken(GOOGLE_ACCOUNT_TYPE, authToken);
}
public void addAccount(Activity owningActivity) {
Log.d(TAG, "addAccount() called.");
try {
getAccountManager(owningActivity).addAccount(GOOGLE_ACCOUNT_TYPE, null, null, null, owningActivity, null,
null);
// Intent i = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
// i.putExtra("EXTRA_AUTHORITIES", GOOGLE_ACCOUNT);
// owningActivity.startActivity(i);
// b =
// getAccountManager(owningActivity).addAccount(GOOGLE_ACCOUNT_TYPE,
// AUTH_TOKEN_TYPE_READER,
// GOOGLE_ACCOUNT, null, owningActivity, null, null).getResult();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
Account findAccountByGoogleAccountId(Context context, AccountManager accountManager, String googleAccount) {
Account[] accounts = getAccounts(context, accountManager);
Account foundAccount = null;
for (Account account : accounts) {
if (account.name != null && account.name.equals(googleAccount)) {
foundAccount = account;
// break
}
}
return foundAccount;
}
private Account[] getAccounts(Context context, AccountManager accountManager) {
Account[] accounts = null;
try {
accounts = accountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE);
// accountManager.getAccountsByTypeAndFeatures(GOOGLE_ACCOUNT_TYPE,
// GOOGLE_ACCOUNT, null, null)
// .getResult();
if (false && NewsRob.isDebuggingEnabled(context))
for (Account account : accounts) {
System.out.println("Account======" + account.name);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return accounts;
}
}