feat(android): resolve show*/trigger() host via explicit Context#128
Closed
ethanpschoen wants to merge 12 commits into
Closed
Conversation
Expose headless bootstrap/config/profile/consent endpoints via HeadlessApiClient, wire Ketch/KetchSdk surface APIs, refresh index HTML init, and add unit plus integration test coverage.
Remove tap-outside dismiss plumbing and index HTML touch handlers from this branch; those belong in run-sample-skills. Branch is off main only (no native storage commits).
Drop Index.kt, KetchWebView.kt, Events.kt, and WebView flow changes from the headless branch. Keep HeadlessApiClient, models, KetchSdk/Ketch REST methods, data center wiring, and integration tests.
…/feat/headless-sdk
ketch_samples/android is only provisioned on the production CDN (global.ketchcdn.com / KetchDataCenter.US), not the dev/UAT CDN (dev.ketchcdn.com). testGetBootstrapConfiguration and testHeadlessColdStartConsentRoundTrip 404 on org-specific endpoints (/config/ketch_samples/android/boot.json) against UAT, while testGetLocationReturnsGeoIP incidentally passes since /ip carries no org/property path segment. Every other reference to this org/property in the repo (sample apps, WebView-based integration tests, SDK doc comments) already targets the production CDN. Introduced in 30c83c7 with no stated rationale for UAT; verified via git blame and a live re-run against the real CDN (32/34 -> 34/34).
Mirrors the showConsent/showPreferences warm/cold WebView dispatch
pattern to fire ketch-tag's onFunction rule trigger
(ketch('trigger', 'custom', '<name>', options)). Cold boots defer
the trigger command until the tag finishes loading, since a custom
function has no boot URL param the way consent/preferences do.
- KetchWebView.trigger() / Ketch.trigger() with functionName validation
- Unit tests for functionName validation
- Integration test covering warm/cold dispatch and invalid-name rejection
- Demo button wired into both sample apps
…17712 D) Add an optional context param to showConsent/showPreferences/ showPreferencesTab/trigger that deterministically supplies the FragmentActivity host, falling back to the tracked/seeded host when omitted. Fixes the case where Ketch is constructed from a non-Activity context (e.g. a ViewModel holding applicationContext) and show*/trigger is called before any Activity has resumed, which previously failed with "No active Activity to host the Ketch experience". - findFragmentActivity(): walks the ContextWrapper chain to a FragmentActivity; falls back to the existing tracker/seed chain for a pure-Compose ComponentActivity or when no context is passed. - explicitHost is cleared on full dismiss so it can't outlive the call that set it. - Also fixes ZTriggerFunctionTest.warmWebView_dispatchesTriggerWithoutError, which left the consent banner open (isShowingExperience still true) before calling trigger(), causing the pre-existing no-host guard to block dispatch. Dismisses via the tag's primary button first, matching the retained-warm-WebView pattern used in ZWebViewRetentionTest.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6f338c5. Configure here.
…/feat/explicit-context-host-resolution
Base automatically changed from
ethanpschoen/feat/onfunction-trigger
to
justin/feat/cross-activity-lifecycle
July 15, 2026 01:00
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.

Description of this change
Why is this change being made?
How was this tested? How can the reviewer verify your testing?
Added integration tests, ran sample app
Related issues
KD-17712
Checklist
Note
Medium Risk
Changes core UI host resolution for consent/preferences/trigger; behavior is additive (optional param) but wrong context could attach dialogs to the wrong Activity.
Overview
Adds an optional
contextargument toshowConsent,showPreferences,showPreferencesTab, andtriggerso integrators can supply the hostingFragmentActivitywhen the SDK was created fromapplicationContextand no Activity has been tracked yet (avoiding "No active Activity").findFragmentActivity()walksContextWrapperchains;explicitHostoverrides the lifecycle tracker and is cleared on dismiss.Integration tests:
ZExplicitContextShowTestcovers no-arg failure vs explicitcontextsuccess;ZTriggerFunctionTestdismisses the banner via the primary button (warm WebView) and waits foronHasShownExperiencebeforetrigger().Reviewed by Cursor Bugbot for commit 6f338c5. Configure here.