-
Notifications
You must be signed in to change notification settings - Fork 659
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix issue with authenticators launching activity in background #5667
Fix issue with authenticators launching activity in background #5667
Conversation
Diffuse output:
APK
DEX
|
1284244
to
e37e132
Compare
val lifecycleOwner = host.lifecycleOwner | ||
lifecycleOwner.lifecycleScope.launch { | ||
lifecycleOwner.whenResumed { | ||
performAuthentication(host, authenticatable, requestOptions) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using this in the public authenticate()
method and calling a protected method that subclasses can override. Seemed better to me than making every single authenticator implement the lifecycle observation. Thoughts?
@@ -43,6 +49,8 @@ sealed class AuthActivityStarterHost { | |||
override val statusBarColor: Int? | |||
) : AuthActivityStarterHost() { | |||
|
|||
override val lifecycleOwner: LifecycleOwner = fragment.requireActivity() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any concerns with this as the lifecycle owner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we guarantee that the activity is a lifecycle owner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because every activity is. I was just wondering if there are any downsides to using the activity lifecycle instead of the fragment lifecycle. Since we call fragment.startActivityForResult()
below, I’ll just change the lifecycleOwner
to also point to the fragment.
|
||
@RunWith(RobolectricTestRunner::class) | ||
@OptIn(ExperimentalCoroutinesApi::class) | ||
class GenericAuthenticatorTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using this to test the lifecycle observation behavior. The tests for the authenticator subclasses stay (mostly) unchanged.
e1d0d71
to
4b70ade
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding @ccen-stripe to reviewers
} | ||
|
||
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) | ||
abstract suspend fun performAuthentication( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be protected
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made this public so that I could test it in unit tests, and added the VisibleForTesting
annotation to limit its visibility outside of tests.
But now I’m thinking that I should instead call authenticate()
in these tests and just mock host.lifecycleOwner
. Will update the pull request!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request updated, so this is now protected
Instead of each authenticator awaiting the desired lifecycle state, we're now doing this in a single place in PaymentAuthenticator.
fe5ed6e
to
8f4412a
Compare
8f4412a
to
1742afc
Compare
Summary
Resolves: #5508
This pull request fixes an issue where launching a
PaymentAuthenticator
while in the background resulted in the payment being considered a failure in the SDK, even if the payment was successful. The problem seems to be limited to Android 10 and 11.Instead of launching the authentication activity right away, we now observe the lifecycle of
AuthActivityStarterHost
and only start the activity when it’s resumed.Motivation
Bugfix.
Testing
Screenshots
N/A.
Changelog
Completed payments are no longer incorrectly reported as having failed if the app is backgrounded during confirmation on Android 10 and 11.