diff options
author | Fabian Henneke <FabianHenneke@users.noreply.github.com> | 2020-07-30 10:29:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-30 13:59:01 +0530 |
commit | 3afeff45d8bd5fff66e1d0fa2c15fa2527487af1 (patch) | |
tree | 7aef187653ee2b8dd4a8606cbffe708e03b7e409 | |
parent | 8481491994f51127aa04aebcd26904ad904d6a77 (diff) |
Fix two SMS Autofill crashes (#985)
SMS OTP Autofill currently crashes for two reasons:
1. Tasks.await has a precondition of not running on the UI thread.
2. Exceptions thrown from Tasks are always wrapped into
ExecutionExceptions and need to be unwrapped before they can be
identified as ResolvableApiException.
This commit addresses both issues by making waitForSms a proper
coroutine using withContext and a custom wrapper around Task<T> that
relies on suspendCoroutine and automatically unwraps exceptions.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | app/src/nonFree/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSmsActivity.kt | 33 |
2 files changed, 29 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a43462eb..f49f0cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - Allow creating nested directories directly - I keep saying this but for real: error message for wrong SSH/HTTPS password is properly fixed now - Correctly hide TOTP import button when TOTP secret/OTPAUTH URL is already present in extra content +- SMS OTP Autofill no longer crashes when invoked and correctly asks for the required permission on first use ## [1.10.1] - 2020-07-23 diff --git a/app/src/nonFree/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSmsActivity.kt b/app/src/nonFree/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSmsActivity.kt index 02394867..4413ea10 100644 --- a/app/src/nonFree/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSmsActivity.kt +++ b/app/src/nonFree/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSmsActivity.kt @@ -24,13 +24,30 @@ import com.google.android.gms.auth.api.phone.SmsRetriever import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability import com.google.android.gms.common.api.ResolvableApiException -import com.google.android.gms.tasks.Tasks +import com.google.android.gms.tasks.Task import com.zeapo.pwdstore.autofill.oreo.AutofillAction import com.zeapo.pwdstore.autofill.oreo.Credentials import com.zeapo.pwdstore.autofill.oreo.FillableForm import com.zeapo.pwdstore.databinding.ActivityOreoAutofillSmsBinding import com.zeapo.pwdstore.utils.viewBinding +import java.util.concurrent.ExecutionException +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +suspend fun <T> Task<T>.suspendableAwait() = suspendCoroutine<T> { cont -> + addOnSuccessListener { result: T -> + cont.resume(result) + } + addOnFailureListener { e -> + // Unwrap specific exceptions (e.g. ResolvableApiException) from ExecutionException. + val cause = (e as? ExecutionException)?.cause ?: e + cont.resumeWithException(cause) + } +} @RequiresApi(Build.VERSION_CODES.O) class AutofillSmsActivity : AppCompatActivity() { @@ -105,15 +122,21 @@ class AutofillSmsActivity : AppCompatActivity() { } } - private fun waitForSms() { + private suspend fun waitForSms() { val smsClient = SmsCodeRetriever.getAutofillClient(this@AutofillSmsActivity) try { - Tasks.await(smsClient.startSmsCodeRetriever()) + withContext(Dispatchers.IO) { + smsClient.startSmsCodeRetriever().suspendableAwait() + } } catch (e: ResolvableApiException) { - e.startResolutionForResult(this, 1) + withContext(Dispatchers.Main) { + e.startResolutionForResult(this@AutofillSmsActivity, 1) + } } catch (e: Exception) { e(e) - finish() + withContext(Dispatchers.Main) { + finish() + } } } |