Repository navigation
[in_app_purchase_android] Guard async billing callbacks against duplicate listener responses - #12640
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces a replyOnce helper method in MethodCallHandlerImpl.java to prevent crashes caused by duplicate listener responses from the Play Billing library. The helper wraps asynchronous callbacks using an AtomicBoolean to ensure they are executed only once, dropping subsequent duplicate invocations. Corresponding regression tests have been added to MethodCallHandlerTest.java to verify this behavior, and the package version has been updated to 0.5.3 in pubspec.yaml and CHANGELOG.md. There are no review comments, so no additional feedback is provided.
8a171d5 to
d8aaa08
Compare
…cate listener responses The Play Billing library can invoke the response listener of a single async call more than once (internal watchdog/timeout path); the second pigeon completion threw IllegalStateException 'Reply already submitted' on the main thread and killed the process. startConnection already had its own alreadyFinished guard; this extends the same single-shot protection to the other 9 async methods via a replyOnce AtomicBoolean wrapper. Claude-Session: https://claude.ai/code/session_012juAFafaPDBSvR7pcqTLMd
d8aaa08 to
2d177ab
Compare
|
[from triage] gentle ping - @gmackall are you still reviewing this PR? Thanks! |
|
We're hitting this in production as well (in_app_purchase_android 0.5.0 / Play Billing 8.0.0), on Seen on Honor LLY-NX1 (Android 16), with the app resuming from background. I also ran the Android unit tests on this branch (2d177ab) with Flutter 3.47.5:
Would be great to see this land. Thanks @eszter-varga! |
# Conflicts: # packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md
|
We hit this in production too, on In every 9.1.0 event, the crashing (second) reply comes from Billing's watchdog: Here is what the 9.1.0 bytecode shows. The |
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: ...
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: ...
The Play Billing library can invoke the response listener of a single async
call more than once (observed in production via its internal watchdog/timeout
path,
zzaf.run → zzan.run, with the real response also arriving). A pigeonreply may only be submitted once; the second completion throws
IllegalStateException: Reply already submittedon the main thread and killsthe process.
startConnectionalready guards against a doubleonBillingSetupFinishedwith its
alreadyFinishedflag; this PR extends the same protection to theother 9 async methods via a
replyOnce(methodName, callback)wrapper — anAtomicBoolean.getAndSet(true)single-shot around the pigeon callback. Thefirst completion wins; duplicates are dropped with a
Log.d. Call sites bindthe pigeon parameter as
rawCallbackand rebindcallbackto the wrapper, sothe method bodies are otherwise unchanged and every completion path
(null-client error, null-activity error, listener response, RuntimeException
catch) is single-shot. Listener side effects (
updateCachedProducts) stillrun on dropped duplicates, so if an error response lands first and the real
one second, the product cache still receives real data for a later
launchBillingFlow.Two JUnit regression tests fire a captured listener twice with distinct
results and assert exactly one pigeon completion holding the first result.
Developed with AI assistance; tested and verified by the submitter.
Fixes flutter/flutter#191832
Related: flutter/flutter#103432, flutter/flutter#134967
Pre-Review Checklist
[shared_preferences]///).Note: this PR and #12639 both bump the package to 0.5.3; whichever lands
second will be rebased and re-bumped.
Footnotes
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