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 tarrinneal@gmail.com [pigeon]add support for sealed classes
in native interop (flutter/packages#13175)
2026-10-15 tarrinneal@gmail.com [pigeon] Replace full JNI bindings with
stubs for API classes that aren't needed (flutter/packages#13173)
2026-10-14 ksanaullah383.khan@gmail.com [material_ui] Fix
self-comparison and assert bugs in semantics_tester
(flutter/packages#12722)
2026-10-14 magder@google.com [camera_avfoundation] Replace the
deprecated 'videoOrientation' with 'videoRotationAngle' on iOS 17+
(flutter/packages#13247)
2026-10-14 zengyan@88.com [material_ui] Fix GridTile crash when the
incoming constraints are unbounded (flutter/packages#12586)
2026-10-14 magder@google.com [in_app_purchase_storekit] Remove unused
and deprecated "SKDownload" hosted content (flutter/packages#13222)
2026-10-14 55765052+MohanadAbdallah-mv@users.noreply.github.com
[material_ui] Add supportingTextPadding to InputDecorator
(flutter/packages#12769)
2026-10-14 37883572+edwin-hollen@users.noreply.github.com
[vector_graphics_codec] Add support for encoding and decoding paint blur
commands (flutter/packages#13148)
2026-10-14 ketulm8@gmail.com [go_router] Fix redirect zone async error
handling (flutter/packages#12836)
2026-10-14 fluttergithubbot@gmail.com Sync release-go_router-18.1.0 to
main (flutter/packages#13260)
2026-10-14 fluttergithubbot@gmail.com Sync release-cupertino_ui-1.1.3 to
main (flutter/packages#13258)
2026-10-14 lsaudon@gmail.com [material_ui] add enableInlinePrediction
parameter to TextFormField (flutter/packages#12793)
2026-10-14 fluttergithubbot@gmail.com Sync release-material_ui-1.7.0 to
main (flutter/packages#13259)
2026-10-14 sokolovskyi.konstantin@gmail.com [material_ui] Add the
Material shapes. (flutter/packages#12771)
2026-10-14 64028623+Ahtsham0715@users.noreply.github.com [material_ui]
Add tertiary tap callbacks to InkResponse and InkWell
(flutter/packages#12676)
2026-10-14 engine-flutter-autoroll@skia.org Roll Flutter from
4249ccb to 426be96 (44 revisions) (flutter/packages#13256)
2026-10-14 47866232+chunhtai@users.noreply.github.com [material_ui]
fixes expanded state in the a11y_assessment home page dropdown
(flutter/packages#13219)
2026-10-14 zhongliu88889@gmail.com [VPAT] Fix semantics in
a11y_assessments drawer, radio, and rail demos (flutter/packages#13159)
2026-10-14 5684363+tenninebt@users.noreply.github.com
[google_maps_flutter] Add onPointOfInterestTap (flutter/packages#11872)
2026-10-14 Gornivv@gmail.com [go_router] Fix shell route key collisions
and dynamic branch updates (flutter/packages#12549)
2026-10-14 engine-flutter-autoroll@skia.org Manual roll Flutter from
d03768e to 4249ccb (158 revisions) (flutter/packages#13220)
2026-10-14 okorohelijah@google.com [image_picker_ios] Require Flutter
3.47 / iOS 15 and drop deprecated kUTType code paths
(flutter/packages#13224)
2026-10-13 louisehsu@google.com [in_app_purchase_storekit] Fixes
Storekit 2 flaky tests (flutter/packages#13213)
2026-10-13 stuartmorgan@google.com [local_auth] Convert Android to new
Pigeon suspend support (flutter/packages#12894)
2026-10-13 50643541+Mairramer@users.noreply.github.com [material_ui] Add
enabled parameter to DropdownButtonFormField (flutter/packages#12610)
2026-10-13 molchanovia.dev@gmail.com [go_router] Link ShellRoute docs to
StatefulShellRoute (flutter/packages#13120)
2026-10-13 jmccandless@google.com FadeForwards page transition
performance (flutter/packages#13161)
2026-10-13 101952451+eszter-varga@users.noreply.github.com
[in_app_purchase_android] Guard async billing callbacks against
duplicate listener responses (flutter/packages#12640)
2026-10-13 victor.orozco@cloudsufi.com [google_sign_in] Remove the
Objective-C exception catcher (flutter/packages#13156)
2026-10-13 magder@google.com [camera_avfoundation] Remove availability
checks below the package minimum iOS 13 (flutter/packages#13214)
2026-10-13 magder@google.com [google_maps_flutter_ios] Remove iOS 14
availability check from example UI tests (flutter/packages#13218)
2026-10-13 stuartmorgan@google.com [google_sign_in] Convert
implementation to Kotlin (flutter/packages#13005)
2026-10-13 victor.orozco@cloudsufi.com [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 flutter-ecosystem@google.com 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 tarrinneal@gmail.com [pigeon]add support for sealed classes
in native interop (flutter/packages#13175)
2026-10-15 tarrinneal@gmail.com [pigeon] Replace full JNI bindings with
stubs for API classes that aren't needed (flutter/packages#13173)
2026-10-14 ksanaullah383.khan@gmail.com [material_ui] Fix
self-comparison and assert bugs in semantics_tester
(flutter/packages#12722)
2026-10-14 magder@google.com [camera_avfoundation] Replace the
deprecated 'videoOrientation' with 'videoRotationAngle' on iOS 17+
(flutter/packages#13247)
2026-10-14 zengyan@88.com [material_ui] Fix GridTile crash when the
incoming constraints are unbounded (flutter/packages#12586)
2026-10-14 magder@google.com [in_app_purchase_storekit] Remove unused
and deprecated "SKDownload" hosted content (flutter/packages#13222)
2026-10-14 55765052+MohanadAbdallah-mv@users.noreply.github.com
[material_ui] Add supportingTextPadding to InputDecorator
(flutter/packages#12769)
2026-10-14 37883572+edwin-hollen@users.noreply.github.com
[vector_graphics_codec] Add support for encoding and decoding paint blur
commands (flutter/packages#13148)
2026-10-14 ketulm8@gmail.com [go_router] Fix redirect zone async error
handling (flutter/packages#12836)
2026-10-14 fluttergithubbot@gmail.com Sync release-go_router-18.1.0 to
main (flutter/packages#13260)
2026-10-14 fluttergithubbot@gmail.com Sync release-cupertino_ui-1.1.3 to
main (flutter/packages#13258)
2026-10-14 lsaudon@gmail.com [material_ui] add enableInlinePrediction
parameter to TextFormField (flutter/packages#12793)
2026-10-14 fluttergithubbot@gmail.com Sync release-material_ui-1.7.0 to
main (flutter/packages#13259)
2026-10-14 sokolovskyi.konstantin@gmail.com [material_ui] Add the
Material shapes. (flutter/packages#12771)
2026-10-14 64028623+Ahtsham0715@users.noreply.github.com [material_ui]
Add tertiary tap callbacks to InkResponse and InkWell
(flutter/packages#12676)
2026-10-14 engine-flutter-autoroll@skia.org Roll Flutter from
4249ccb to 426be96 (44 revisions) (flutter/packages#13256)
2026-10-14 47866232+chunhtai@users.noreply.github.com [material_ui]
fixes expanded state in the a11y_assessment home page dropdown
(flutter/packages#13219)
2026-10-14 zhongliu88889@gmail.com [VPAT] Fix semantics in
a11y_assessments drawer, radio, and rail demos (flutter/packages#13159)
2026-10-14 5684363+tenninebt@users.noreply.github.com
[google_maps_flutter] Add onPointOfInterestTap (flutter/packages#11872)
2026-10-14 Gornivv@gmail.com [go_router] Fix shell route key collisions
and dynamic branch updates (flutter/packages#12549)
2026-10-14 engine-flutter-autoroll@skia.org Manual roll Flutter from
d03768e to 4249ccb (158 revisions) (flutter/packages#13220)
2026-10-14 okorohelijah@google.com [image_picker_ios] Require Flutter
3.47 / iOS 15 and drop deprecated kUTType code paths
(flutter/packages#13224)
2026-10-13 louisehsu@google.com [in_app_purchase_storekit] Fixes
Storekit 2 flaky tests (flutter/packages#13213)
2026-10-13 stuartmorgan@google.com [local_auth] Convert Android to new
Pigeon suspend support (flutter/packages#12894)
2026-10-13 50643541+Mairramer@users.noreply.github.com [material_ui] Add
enabled parameter to DropdownButtonFormField (flutter/packages#12610)
2026-10-13 molchanovia.dev@gmail.com [go_router] Link ShellRoute docs to
StatefulShellRoute (flutter/packages#13120)
2026-10-13 jmccandless@google.com FadeForwards page transition
performance (flutter/packages#13161)
2026-10-13 101952451+eszter-varga@users.noreply.github.com
[in_app_purchase_android] Guard async billing callbacks against
duplicate listener responses (flutter/packages#12640)
2026-10-13 victor.orozco@cloudsufi.com [google_sign_in] Remove the
Objective-C exception catcher (flutter/packages#13156)
2026-10-13 magder@google.com [camera_avfoundation] Remove availability
checks below the package minimum iOS 13 (flutter/packages#13214)
2026-10-13 magder@google.com [google_maps_flutter_ios] Remove iOS 14
availability check from example UI tests (flutter/packages#13218)
2026-10-13 stuartmorgan@google.com [google_sign_in] Convert
implementation to Kotlin (flutter/packages#13005)
2026-10-13 victor.orozco@cloudsufi.com [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 flutter-ecosystem@google.com 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