mirror of https://github.com/tasks/tasks
Convert GoogleAccountManager to Kotlin
parent
65e0e0b997
commit
b4df28ae3b
@ -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…
Reference in New Issue