Review triggers were lost when the user left the screen immediately - #2200
Merged
mpretty-cyro merged 1 commit intoAug 31, 2026
Conversation
mpretty-cyro
marked this pull request as ready for review
August 31, 2026 06:11
Change the theme and press back straight away and no review prompt ever appears -- not just in a test, for anyone. The same is true of the accent colour. The defect is the channel's capacity, not the call sites. `Channel<Event>()` is rendezvous, so `send` does not complete when it is called: it suspends until the collector receives. The emission therefore had to outlive the screen that triggered it, and a theme change is precisely the interaction a user follows with "back" within milliseconds -- the ViewModel is cleared, its scope is cancelled, and the event is gone. All four emit sites were lifecycle-scoped: path visited on `lifecycleScope`, donate and both appearance setters on `viewModelScope`. Three of them survived on user behaviour rather than on structure -- visiting Path leaves you on Path, and tapping Donate opens a link and leaves Settings alive -- so they looked correct while carrying the same race. Repairing only the appearance screen would have left them racing and looked like a fix. So the fix is at the manager: the channel is UNLIMITED and `onEvent` is no longer suspending, handing off via `trySend`. No caller needs a coroutine, and no future caller can reintroduce this by choosing the wrong scope. The four call sites lose their launches. `trySend` cannot fail on an unlimited channel short of the manager being closed, but the failure is logged rather than discarded: a silently dropped event would look exactly like the bug being fixed. Both appearance setters are covered -- setNewAccent had the identical shape and the same defect, untested until now.
mpretty-cyro
force-pushed
the
fix/review-events-survive-navigation
branch
from
August 31, 2026 06:21
6fbe394 to
462fe77
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A review trigger emitted from a screen the user immediately leaves never arrives, so the prompt never shows.
What happens
Change the theme in Appearance and press back, and no review prompt appears — not late, never. Found by
Review prompt Appearance triggerin the Appium suite, which had never passed.Why
InAppReviewManager's event channel was a rendezvous channel (capacity 0). On a rendezvous channelsenddoes not complete when it is called — it suspends until the collector receives. Every call site wrapped it in the screen's own scope:So the emission had to outlive the screen that triggered it. Changing a theme is the one interaction a user reliably follows with "back" within milliseconds, which is why Theme lost it and Path and Donate did not — all four were equally exposed; three survived on user behaviour rather than on structure. A fast enough Donate tap has the same defect.
The change
The channel becomes
UNLIMITEDandonEventbecomes non-suspending (trySend), so no caller needs a coroutine and the four call sites reduce to a plain call. FixingAppearanceSettingsViewModelalone would have left Donate and Path racing and looked fixed, because those two are hard to lose by hand.A dropped
trySendis logged rather than swallowed. On an unlimited channel it is unreachable short of the manager being closed, but silence there would look exactly like the bug this replaces.setNewAccentis covered by the same change; it had the identical shape and no coverage.Verification
Two new tests in
InAppReviewManagerEventDeliveryTest. The first fires an event before the collector has started — the precise moment a rendezvous channel had nowhere to put it — and waits withfirst { it }rather than sampling, so a lost event fails by timing out instead of by reading a stalefalse.Mutated by setting the capacity back to
RENDEZVOUSwhile keepingtrySend: both tests fail. That isolates the buffer as the thing doing the work rather than the non-suspending signature.End to end: all six
Review prompt *Appium specs pass against this build, includingAppearance trigger, which was previously unreachable rather than flaky.Note
Touches
InAppReviewManagerTest.kt, whichqa/review-prompt-app-updated-extraalso adds a class to — the two conflict on that file and want stacking or a merge order.