Convert GoogleAccountManager to Kotlin

pull/1216/head
Alex Baker 5 years ago
parent 65e0e0b997
commit b4df28ae3b

@ -53,7 +53,7 @@ class GtasksLoginActivity : InjectingAppCompatActivity() {
private fun chooseAccount() {
val chooseAccountIntent = AccountManager.newChooseAccountIntent(
null, null, arrayOf("com.google"), false, null, null, null, null)
null, null, arrayOf("com.google"), null, null, null, null)
startActivityForResult(chooseAccountIntent, RC_CHOOSE_ACCOUNT)
}

@ -40,7 +40,7 @@ public class DriveLoginActivity extends InjectingAppCompatActivity {
Intent chooseAccountIntent =
android.accounts.AccountManager.newChooseAccountIntent(
null, null, new String[] {"com.google"}, false, null, null, null, null);
null, null, new String[] {"com.google"}, null, null, null, null);
startActivityForResult(chooseAccountIntent, RC_CHOOSE_ACCOUNT);
}

@ -1,140 +0,0 @@
package org.tasks.gtasks;
import static com.google.common.collect.Iterables.tryFind;
import static com.google.common.collect.Lists.transform;
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
import static java.util.Arrays.asList;
import static org.tasks.Strings.isNullOrEmpty;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.tasks.TasksScopes;
import dagger.hilt.android.qualifiers.ApplicationContext;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.play.AuthResultHandler;
import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
public class GoogleAccountManager {
private final PermissionChecker permissionChecker;
private final android.accounts.AccountManager accountManager;
private final Preferences preferences;
@Inject
public GoogleAccountManager(
@ApplicationContext Context context, PermissionChecker permissionChecker, Preferences preferences) {
this.permissionChecker = permissionChecker;
accountManager = android.accounts.AccountManager.get(context);
this.preferences = preferences;
}
public List<String> getAccounts() {
return transform(getAccountList(), account -> account.name);
}
private List<Account> getAccountList() {
return permissionChecker.canAccessAccounts()
? asList(accountManager.getAccountsByType("com.google"))
: Collections.emptyList();
}
public Account getAccount(String name) {
if (isNullOrEmpty(name)) {
return null;
}
return tryFind(getAccountList(), account -> name.equalsIgnoreCase(account.name)).orNull();
}
public boolean canAccessAccount(String name) {
return getAccount(name) != null;
}
public String getAccessToken(String name, String scope) {
assertNotMainThread();
Account account = getAccount(name);
if (account == null) {
Timber.e("Cannot find account %s", name);
return null;
}
boolean alreadyNotified = preferences.alreadyNotified(name, scope);
try {
String token =
accountManager.blockingGetAuthToken(account, "oauth2:" + scope, !alreadyNotified);
preferences.setAlreadyNotified(name, scope, isNullOrEmpty(token));
return token;
} catch (AuthenticatorException | IOException | OperationCanceledException e) {
Timber.e(e);
return null;
}
}
public void getTasksAuthToken(
final Activity activity, final String accountName, final AuthResultHandler handler) {
getToken(TasksScopes.TASKS, activity, accountName, handler);
}
public void getDriveAuthToken(
final Activity activity, final String accountName, final AuthResultHandler handler) {
getToken(DriveScopes.DRIVE_FILE, activity, accountName, handler);
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@SuppressLint("CheckResult")
private void getToken(
String scope, Activity activity, String accountName, AuthResultHandler handler) {
final Account account = getAccount(accountName);
Single.fromCallable(
() -> {
if (account == null) {
throw new RuntimeException(
activity.getString(R.string.gtasks_error_accountNotFound, accountName));
}
assertNotMainThread();
return accountManager
.getAuthToken(account, "oauth2:" + scope, new Bundle(), activity, null, null)
.getResult();
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
bundle -> {
preferences.setAlreadyNotified(accountName, scope, false);
Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
if (intent != null) {
activity.startActivity(intent);
} else {
handler.authenticationSuccessful(accountName);
}
},
e -> {
Timber.e(e);
handler.authenticationFailed(e.getMessage());
});
}
public void invalidateToken(String token) {
accountManager.invalidateAuthToken("com.google", token);
}
}

@ -0,0 +1,123 @@
package org.tasks.gtasks
import android.accounts.Account
import android.accounts.AccountManager
import android.accounts.AuthenticatorException
import android.accounts.OperationCanceledException
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.google.api.services.drive.DriveScopes
import com.google.api.services.tasks.TasksScopes
import com.google.common.collect.Lists
import com.todoroo.andlib.utility.AndroidUtilities
import dagger.hilt.android.qualifiers.ApplicationContext
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.play.AuthResultHandler
import org.tasks.preferences.PermissionChecker
import org.tasks.preferences.Preferences
import timber.log.Timber
import java.io.IOException
import javax.inject.Inject
class GoogleAccountManager @Inject constructor(
@ApplicationContext context: Context?,
private val permissionChecker: PermissionChecker,
private val preferences: Preferences
) {
private val accountManager: AccountManager = AccountManager.get(context)
val accounts: List<String>
get() = Lists.transform(accountList) { account: Account? -> account!!.name }
private val accountList: List<Account>
get() = if (permissionChecker.canAccessAccounts()) {
accountManager.getAccountsByType("com.google").toList()
} else {
emptyList()
}
fun getAccount(name: String): Account? = if (isNullOrEmpty(name)) {
null
} else {
accountList.find { name.equals(it.name, ignoreCase = true) }
}
fun canAccessAccount(name: String): Boolean {
return getAccount(name) != null
}
fun getAccessToken(name: String, scope: String): String? {
AndroidUtilities.assertNotMainThread()
val account = getAccount(name)
if (account == null) {
Timber.e("Cannot find account %s", name)
return null
}
val alreadyNotified = preferences.alreadyNotified(name, scope)
return try {
val token = accountManager.blockingGetAuthToken(account, "oauth2:$scope", !alreadyNotified)
preferences.setAlreadyNotified(name, scope, isNullOrEmpty(token))
token
} catch (e: AuthenticatorException) {
Timber.e(e)
null
} catch (e: IOException) {
Timber.e(e)
null
} catch (e: OperationCanceledException) {
Timber.e(e)
null
}
}
fun getTasksAuthToken(activity: Activity, accountName: String, handler: AuthResultHandler) {
getToken(TasksScopes.TASKS, activity, accountName, handler)
}
fun getDriveAuthToken(activity: Activity, accountName: String, handler: AuthResultHandler) {
getToken(DriveScopes.DRIVE_FILE, activity, accountName, handler)
}
@SuppressLint("CheckResult")
private fun getToken(
scope: String, activity: Activity, accountName: String, handler: AuthResultHandler) {
val account = getAccount(accountName)
Single.fromCallable {
if (account == null) {
throw RuntimeException(
activity.getString(R.string.gtasks_error_accountNotFound, accountName))
}
AndroidUtilities.assertNotMainThread()
accountManager
.getAuthToken(account, "oauth2:$scope", Bundle(), activity, null, null)
.result
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ bundle: Bundle ->
preferences.setAlreadyNotified(accountName, scope, false)
val intent = bundle[AccountManager.KEY_INTENT] as Intent?
if (intent != null) {
activity.startActivity(intent)
} else {
handler.authenticationSuccessful(accountName)
}
}
) { e: Throwable ->
Timber.e(e)
handler.authenticationFailed(e.message)
}
}
fun invalidateToken(token: String?) {
accountManager.invalidateAuthToken("com.google", token)
}
}
Loading…
Cancel
Save