Skip to content

[local_auth] Convert Android to new Pigeon suspend support - #12894

Merged
auto-submit[bot] merged 4 commits into
flutter:mainfrom
stuartmorgan-g:kotlin-local-auth-part-3-async
Oct 13, 2026
Merged

auto-submit[bot] merged 4 commits into
flutter:mainfrom
stuartmorgan-g:kotlin-local-auth-part-3-async

Conversation

@stuartmorgan-g

@stuartmorgan-g stuartmorgan-g commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Switches the async authenticate method from the old callback system to Pigeon's new suspend support. Because the underlying SDK doesn't have a suspend-style method currently, the plugin bridges the existing intrenal callback to a suspend coroutine.

This will simplify later conversion to JNI-backed Pigeon, and also simplifies unit tests.

Part of flutter/flutter#192417

Pre-Review Checklist

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2

Switches the async authenticat method from the old callback system to
Pigeon's new `suspend` support. Because the underlying SDK doesn't have
a `suspend`-style method currently, the plugin bridges the existing
intrenal callback to a `suspend` coroutine.

This will simplify later conversion to JNI-backed Pigeon, and also
simplifies unit tests.

Part of flutter/flutter#192417

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the internal platform API of the Android local authentication plugin from callbacks to Kotlin coroutines (suspend functions), updating the Pigeon-generated messages and modifying the corresponding unit tests to run within runTest. A review comment identifies a potential issue in createAuthCompletionHandler where the suspended authenticate coroutine could hang indefinitely if stopAuthentication() is called, and suggests using a local AtomicBoolean to guarantee the continuation is resumed exactly once.

Comment on lines 110 to 118
internal fun createAuthCompletionHandler(
callback: (Result<AuthResult>) -> Unit
continuation: Continuation<AuthResult>
): (AuthResult) -> Unit {
return { authResult -> onAuthenticationCompleted(callback, authResult) }
return { authResult ->
if (authInProgress.compareAndSet(true, false)) {
continuation.resume(authResult)
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If stopAuthentication() is called, it sets authInProgress to false and cancels the authentication. This asynchronously triggers onAuthenticationError in AuthenticationHelper, which invokes this completion handler.\n\nHowever, because authInProgress has already been set to false by stopAuthentication(), the check authInProgress.compareAndSet(true, false) will fail, and continuation.resume(authResult) will never be called. This causes the suspended authenticate coroutine to hang indefinitely, leaking resources and preventing the Dart Future from completing.\n\nUsing a local AtomicBoolean to ensure the continuation is resumed exactly once, while safely attempting to clear the global authInProgress state, resolves this hang and avoids potential race conditions with subsequent authentication attempts.

  internal fun createAuthCompletionHandler(
      continuation: Continuation<AuthResult>
  ): (AuthResult) -> Unit {
    val resumed = AtomicBoolean(false)
    return { authResult ->
      if (resumed.compareAndSet(false, true)) {
        authInProgress.compareAndSet(true, false)
        continuation.resume(authResult)
      }
    }
  }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was bothering me when I was touching the code as well, so I had checked the history and it's pretty much always worked this way so I let it go. But it does seem like it if works it's because it happens not to actually be async, which doesn't seem like a good thing to rely on. I updated the PR to remove the authInProgress.set(false) line from cancel, so that it will be set to false by the callback actually triggering instead. (I verified locally with a synthetic timed cancel that this works as expected.)

@stuartmorgan-g

Copy link
Copy Markdown
Contributor Author

The test changes here were Gemini-authored, but (with the caveat that I'm not familiar with the specific test utilities involved here) looked good to me, and had the simplifications of directly using returned values that I was expecting from the refactor.

@mboetger mboetger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I didn't get to this before your last day - happy to take over from here if you want. Just let me know.

@stuartmorgan

Copy link
Copy Markdown
Contributor

@mboetger You'll need to do a CLA override on this; the automagic group stuff has updated such that my old @google.com address fails the CLA now. We've run into this before, and I always just put something like "Author was employed at Google at time the PR was opened".

@mboetger

Copy link
Copy Markdown
Contributor

@mboetger You'll need to do a CLA override on this; the automagic group stuff has updated such that my old @google.com address fails the CLA now. We've run into this before, and I always just put something like "Author was employed at Google at time the PR was opened".

Done.

@mboetger mboetger added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 13, 2026
@auto-submit
auto-submit Bot merged commit ca5b2e5 into flutter:main Oct 13, 2026
13 checks passed
opensource-fork-sync Bot pushed a commit to cla7aye15I4nd/opensource-flutter__flutter that referenced this pull request Oct 15, 2026
Roll Packages from a1ed23c to da40eaf (33 revisions)

flutter/packages@a1ed23c...da40eaf

2026-10-15 [email protected] [pigeon]add support for sealed classes
in native interop (flutter/packages#13175)
2026-10-15 [email protected] [pigeon] Replace full JNI bindings with
stubs for API classes that aren't needed (flutter/packages#13173)
2026-10-14 [email protected] [material_ui] Fix
self-comparison and assert bugs in semantics_tester
(flutter/packages#12722)
2026-10-14 [email protected] [camera_avfoundation] Replace the
deprecated 'videoOrientation' with 'videoRotationAngle' on iOS 17+
(flutter/packages#13247)
2026-10-14 [email protected] [material_ui] Fix GridTile crash when the
incoming constraints are unbounded (flutter/packages#12586)
2026-10-14 [email protected] [in_app_purchase_storekit] Remove unused
and deprecated "SKDownload" hosted content (flutter/packages#13222)
2026-10-14 [email protected]
[material_ui] Add supportingTextPadding to InputDecorator
(flutter/packages#12769)
2026-10-14 [email protected]
[vector_graphics_codec] Add support for encoding and decoding paint blur
commands (flutter/packages#13148)
2026-10-14 [email protected] [go_router] Fix redirect zone async error
handling (flutter/packages#12836)
2026-10-14 [email protected] Sync release-go_router-18.1.0 to
main (flutter/packages#13260)
2026-10-14 [email protected] Sync release-cupertino_ui-1.1.3 to
main (flutter/packages#13258)
2026-10-14 [email protected] [material_ui] add enableInlinePrediction
parameter to TextFormField (flutter/packages#12793)
2026-10-14 [email protected] Sync release-material_ui-1.7.0 to
main (flutter/packages#13259)
2026-10-14 [email protected] [material_ui] Add the
Material shapes. (flutter/packages#12771)
2026-10-14 [email protected] [material_ui]
Add tertiary tap callbacks to InkResponse and InkWell
(flutter/packages#12676)
2026-10-14 [email protected] Roll Flutter from
4249ccb to 426be96 (44 revisions) (flutter/packages#13256)
2026-10-14 [email protected] [material_ui]
fixes expanded state in the a11y_assessment home page dropdown
(flutter/packages#13219)
2026-10-14 [email protected] [VPAT] Fix semantics in
a11y_assessments drawer, radio, and rail demos (flutter/packages#13159)
2026-10-14 [email protected]
[google_maps_flutter] Add onPointOfInterestTap (flutter/packages#11872)
2026-10-14 [email protected] [go_router] Fix shell route key collisions
and dynamic branch updates (flutter/packages#12549)
2026-10-14 [email protected] Manual roll Flutter from
d03768e to 4249ccb (158 revisions) (flutter/packages#13220)
2026-10-14 [email protected] [image_picker_ios] Require Flutter
3.47 / iOS 15 and drop deprecated kUTType code paths
(flutter/packages#13224)
2026-10-13 [email protected] [in_app_purchase_storekit] Fixes
Storekit 2 flaky tests (flutter/packages#13213)
2026-10-13 [email protected] [local_auth] Convert Android to new
Pigeon suspend support (flutter/packages#12894)
2026-10-13 [email protected] [material_ui] Add
enabled parameter to DropdownButtonFormField (flutter/packages#12610)
2026-10-13 [email protected] [go_router] Link ShellRoute docs to
StatefulShellRoute (flutter/packages#13120)
2026-10-13 [email protected] FadeForwards page transition
performance (flutter/packages#13161)
2026-10-13 [email protected]
[in_app_purchase_android] Guard async billing callbacks against
duplicate listener responses (flutter/packages#12640)
2026-10-13 [email protected] [google_sign_in] Remove the
Objective-C exception catcher (flutter/packages#13156)
2026-10-13 [email protected] [camera_avfoundation] Remove availability
checks below the package minimum iOS 13 (flutter/packages#13214)
2026-10-13 [email protected] [google_maps_flutter_ios] Remove iOS 14
availability check from example UI tests (flutter/packages#13218)
2026-10-13 [email protected] [google_sign_in] Convert
implementation to Kotlin (flutter/packages#13005)
2026-10-13 [email protected] [image_picker_ios] PR 2/5 Add a
PHImageManager image-data seam and migrate plugin native tests to Swift
Testing (flutter/packages#13079)

If this roll has caused a breakage, revert this CL and set the roller
to dry run mode using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
...
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
Roll Packages from a1ed23c to da40eaf (33 revisions)

flutter/packages@a1ed23c...da40eaf

2026-10-15 [email protected] [pigeon]add support for sealed classes
in native interop (flutter/packages#13175)
2026-10-15 [email protected] [pigeon] Replace full JNI bindings with
stubs for API classes that aren't needed (flutter/packages#13173)
2026-10-14 [email protected] [material_ui] Fix
self-comparison and assert bugs in semantics_tester
(flutter/packages#12722)
2026-10-14 [email protected] [camera_avfoundation] Replace the
deprecated 'videoOrientation' with 'videoRotationAngle' on iOS 17+
(flutter/packages#13247)
2026-10-14 [email protected] [material_ui] Fix GridTile crash when the
incoming constraints are unbounded (flutter/packages#12586)
2026-10-14 [email protected] [in_app_purchase_storekit] Remove unused
and deprecated "SKDownload" hosted content (flutter/packages#13222)
2026-10-14 [email protected]
[material_ui] Add supportingTextPadding to InputDecorator
(flutter/packages#12769)
2026-10-14 [email protected]
[vector_graphics_codec] Add support for encoding and decoding paint blur
commands (flutter/packages#13148)
2026-10-14 [email protected] [go_router] Fix redirect zone async error
handling (flutter/packages#12836)
2026-10-14 [email protected] Sync release-go_router-18.1.0 to
main (flutter/packages#13260)
2026-10-14 [email protected] Sync release-cupertino_ui-1.1.3 to
main (flutter/packages#13258)
2026-10-14 [email protected] [material_ui] add enableInlinePrediction
parameter to TextFormField (flutter/packages#12793)
2026-10-14 [email protected] Sync release-material_ui-1.7.0 to
main (flutter/packages#13259)
2026-10-14 [email protected] [material_ui] Add the
Material shapes. (flutter/packages#12771)
2026-10-14 [email protected] [material_ui]
Add tertiary tap callbacks to InkResponse and InkWell
(flutter/packages#12676)
2026-10-14 [email protected] Roll Flutter from
4249ccb to 426be96 (44 revisions) (flutter/packages#13256)
2026-10-14 [email protected] [material_ui]
fixes expanded state in the a11y_assessment home page dropdown
(flutter/packages#13219)
2026-10-14 [email protected] [VPAT] Fix semantics in
a11y_assessments drawer, radio, and rail demos (flutter/packages#13159)
2026-10-14 [email protected]
[google_maps_flutter] Add onPointOfInterestTap (flutter/packages#11872)
2026-10-14 [email protected] [go_router] Fix shell route key collisions
and dynamic branch updates (flutter/packages#12549)
2026-10-14 [email protected] Manual roll Flutter from
d03768e to 4249ccb (158 revisions) (flutter/packages#13220)
2026-10-14 [email protected] [image_picker_ios] Require Flutter
3.47 / iOS 15 and drop deprecated kUTType code paths
(flutter/packages#13224)
2026-10-13 [email protected] [in_app_purchase_storekit] Fixes
Storekit 2 flaky tests (flutter/packages#13213)
2026-10-13 [email protected] [local_auth] Convert Android to new
Pigeon suspend support (flutter/packages#12894)
2026-10-13 [email protected] [material_ui] Add
enabled parameter to DropdownButtonFormField (flutter/packages#12610)
2026-10-13 [email protected] [go_router] Link ShellRoute docs to
StatefulShellRoute (flutter/packages#13120)
2026-10-13 [email protected] FadeForwards page transition
performance (flutter/packages#13161)
2026-10-13 [email protected]
[in_app_purchase_android] Guard async billing callbacks against
duplicate listener responses (flutter/packages#12640)
2026-10-13 [email protected] [google_sign_in] Remove the
Objective-C exception catcher (flutter/packages#13156)
2026-10-13 [email protected] [camera_avfoundation] Remove availability
checks below the package minimum iOS 13 (flutter/packages#13214)
2026-10-13 [email protected] [google_maps_flutter_ios] Remove iOS 14
availability check from example UI tests (flutter/packages#13218)
2026-10-13 [email protected] [google_sign_in] Convert
implementation to Kotlin (flutter/packages#13005)
2026-10-13 [email protected] [image_picker_ios] PR 2/5 Add a
PHImageManager image-data seam and migrate plugin native tests to Swift
Testing (flutter/packages#13079)

If this roll has caused a breakage, revert this CL and set the roller
to dry run mode using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD p: local_auth platform-android

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants