diff --git a/app/src/main/java/com/getcode/util/AccountAuthenticator.kt b/app/src/main/java/com/getcode/util/AccountAuthenticator.kt index 7f8e49a17..4327adac6 100644 --- a/app/src/main/java/com/getcode/util/AccountAuthenticator.kt +++ b/app/src/main/java/com/getcode/util/AccountAuthenticator.kt @@ -3,6 +3,7 @@ package com.getcode.util import android.accounts.* import android.content.Context import android.os.Bundle +import androidx.core.os.bundleOf import com.getcode.utils.trace @@ -66,13 +67,21 @@ class AccountAuthenticator( return Bundle() } - override fun getAuthTokenLabel(arg0: String): String? = null + override fun getAuthTokenLabel(arg0: String): String? { + return "entropy" + } @Throws(NetworkErrorException::class) override fun hasFeatures( arg0: AccountAuthenticatorResponse, arg1: Account, arg2: Array - ): Bundle? = null + ): Bundle { + // This call is used to query whether the Authenticator supports + // specific features. We don't expect to get called, so we always + // return false (no) for any queries. + val result = bundleOf(AccountManager.KEY_BOOLEAN_RESULT to false) + return result + } @Throws(NetworkErrorException::class) override fun updateCredentials( diff --git a/app/src/main/java/com/getcode/util/AccountUtils.kt b/app/src/main/java/com/getcode/util/AccountUtils.kt index 7a624e9eb..d3621c846 100644 --- a/app/src/main/java/com/getcode/util/AccountUtils.kt +++ b/app/src/main/java/com/getcode/util/AccountUtils.kt @@ -3,11 +3,10 @@ package com.getcode.util import android.accounts.Account import android.accounts.AccountManager import android.accounts.AuthenticatorException -import android.app.Activity import android.content.Context -import android.os.Bundle import android.os.Handler import android.os.HandlerThread +import androidx.core.os.bundleOf import com.getcode.BuildConfig import com.getcode.utils.TraceType import com.getcode.utils.trace @@ -23,14 +22,20 @@ import kotlin.coroutines.resume object AccountUtils { - private const val acctType = BuildConfig.APPLICATION_ID - - fun addAccount(context: Context, name: String, password: String, token: String) { - val am: AccountManager = AccountManager.get(context) - val a = Account(name, acctType) - - am.addAccountExplicitly(a, password, Bundle()) - am.setAuthToken(a, acctType, token) + private const val ACCOUNT_TYPE = BuildConfig.APPLICATION_ID + + fun addAccount( + context: Context, + name: String, + password: String, + token: String + ) { + val accountManager: AccountManager = AccountManager.get(context) + val account = Account(name, ACCOUNT_TYPE) + + val data = bundleOf(AccountManager.KEY_AUTH_TOKEN_LABEL to "entropy") + accountManager.addAccountExplicitly(account, password, data) + accountManager.setAuthToken(account, ACCOUNT_TYPE, token) } suspend fun removeAccounts(context: Context): @NonNull Single { @@ -63,34 +68,29 @@ object AccountUtils { private suspend fun getAccountNoActivity( context: Context - ) : Pair? = suspendCancellableCoroutine { cont -> + ): Pair? = suspendCancellableCoroutine { cont -> trace("getAuthToken", type = TraceType.Silent) val am: AccountManager = AccountManager.get(context) - val accountthing = am.accounts.getOrNull(0) - if (accountthing == null) { + val account = am.accounts.getOrNull(0) + if (account == null) { trace("no associated account found", type = TraceType.Error) cont.resume(null to null) return@suspendCancellableCoroutine } val start = Clock.System.now() am.getAuthToken( - accountthing, acctType, null, false, + account, ACCOUNT_TYPE, null, false, { future -> try { val bundle = future?.result val authToken = bundle?.getString(AccountManager.KEY_AUTHTOKEN) - val accountName = bundle?.getString(AccountManager.KEY_ACCOUNT_NAME) - val account: Account? = getAccount(context, accountName) val end = Clock.System.now() trace("auth token fetch took ${end.toEpochMilliseconds() - start.toEpochMilliseconds()} ms") - cont.resume(authToken.orEmpty() to account) - - if (null == account && authToken != null) { - addAccount(context, accountName.orEmpty(), "", authToken) - } + cont.resume(authToken.orEmpty() to account) } catch (e: AuthenticatorException) { + e.printStackTrace() trace(message = "failed to read account", error = e, type = TraceType.Error) cont.resume(null to null) } @@ -98,19 +98,18 @@ object AccountUtils { ) } - suspend fun getToken(context: Context): String? { - return getAccountNoActivity(context)?.first - } - - private fun getAccount(context: Context?, accountName: String?): Account? { val accountManager = AccountManager.get(context) - val accounts = accountManager.getAccountsByType(acctType) - for (account in accounts) { - if (account.name.equals(accountName, ignoreCase = true)) { - return account + val account = accountManager.accounts.firstOrNull() + if (account != null) { + val token = runCatching { accountManager.peekAuthToken(account, ACCOUNT_TYPE) } + .getOrNull()?.takeIf { it.isNotEmpty() } + + if (token != null) { + return token } } - return null + + return getAccountNoActivity(context)?.first } } \ No newline at end of file