Skip to content

Add checkout diagnostics for Kotlin - #643

Open
markmur wants to merge 1 commit into
swift-checkout-diagnosticsfrom
kotlin-checkout-diagnostics
Open

Add checkout diagnostics for Kotlin#643
markmur wants to merge 1 commit into
swift-checkout-diagnosticsfrom
kotlin-checkout-diagnostics

Conversation

@markmur

@markmur markmur commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

What changes are you making?

Add Kotlin parity for the checkout diagnostics and ingress-policy API introduced in the parent Swift PR.

  • Add ShopifyCheckoutKit.diagnostics.subscribe { ... } without introducing a coroutines dependency.
  • Add typed CheckoutDiagnosticEvent.MessageRejected and CheckoutMessageRejection.Reason APIs.
  • Deliver listeners on the Android main thread through the existing thread helper.
  • Use CopyOnWriteArraySet for listener snapshots and AtomicBoolean for idempotent cancellation.
  • Isolate listener exceptions and retain default debug logging when there are no subscribers.
  • Move child-frame, explicit-port-zero, and origin-allowlist decisions into CheckoutMessageIngressPolicy before protocol dispatch.
  • Remove Configuration.onMessageRejected and omit the untrusted raw message body.
  • Add Java interop coverage for subscribing and cancelling via AutoCloseable.

How message admission works

CheckoutMessageIngressPolicy is the trust boundary between the Android WebView transport and checkout protocol handling. AndroidX WebKit provides the authenticated source origin and frame metadata alongside the untrusted message body. The bridge packages those values into an IncomingCheckoutMessage and asks the policy for an Accepted or Rejected(...) decision before scheduling protocol parsing or dispatch.

The policy applies the transport-level rules in one place:

  • Reject messages sent by a child frame.
  • Build the effective origin allowlist from allowedMessageOrigins and the loaded checkout origin.
  • When origin validation is enabled, reject an explicitly specified port zero and origins that do not match the allowlist.
  • Accept the message when all enabled admission checks pass.

An accepted message continues into the protocol executor and client dispatch. A rejected message never reaches the protocol client; the bridge emits CheckoutDiagnosticEvent.MessageRejected with the authenticated origin and typed rejection reason, then stops processing it. This lets the protocol client assume it only handles admitted checkout messages without making it responsible for Android WebView-specific trust decisions.

Consumer API

No coroutine scope or Flow dependency is required:

val diagnosticSubscription =
    ShopifyCheckoutKit.diagnostics.subscribe { event ->
        when (event) {
            is CheckoutDiagnosticEvent.MessageRejected -> {
                val rejection = event.rejection
                reportRejectedMessage(rejection.origin, rejection.reason)
            }
        }
    }

// Cancel when the observing component is destroyed.
diagnosticSubscription.cancel()

Subscriptions are hot and do not replay. Subscribe before calling preload if the application needs diagnostics emitted by a background checkout WebView. Listeners are delivered on the Android main thread.

The raw rejected message body is intentionally unavailable because it is untrusted and may contain sensitive or arbitrarily large data.


Before you merge

Important

  • I've added tests to support my implementation
  • I have read and agree with the Contribution Guidelines
  • I have read and agree with the Code of Conduct
  • I've updated the relevant platform README (platforms/swift/README.md and/or platforms/android/README.md)

@markmur
markmur requested a review from a team as a code owner August 14, 2026 09:25
@github-actions github-actions Bot added the #gsd:50662 Rebase Checkout Kit on UCP label Aug 14, 2026

markmur commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@markmur markmur changed the title Add Kotlin checkout diagnostics Add checkout diagnostics for Kotlin Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Package Size

Platform Artifact Base Head Delta
Android release AAR 281.8 KiB 298.1 KiB +16.2 KiB
Android file breakdown
File Base Head Delta
classes.jar 297.7 KiB 316.2 KiB +18.5 KiB
res/layout/checkout_view_content.xml 2.6 KiB 2.6 KiB 0 B
res/layout/checkout_sheet_content.xml 2.0 KiB 2.0 KiB 0 B
res/values/values.xml 1.3 KiB 1.3 KiB 0 B
R.txt 1.2 KiB 1.2 KiB 0 B
AndroidManifest.xml 922 B 922 B 0 B
proguard.txt 798 B 798 B 0 B
res/drawable/close.xml 431 B 431 B 0 B
res/menu/checkout_menu.xml 354 B 354 B 0 B
META-INF/com/android/build/gradle/aar-metadata.properties 157 B 157 B 0 B

Measured from the PR base SHA and PR head SHA. The file breakdown shows uncompressed sizes within each package artifact, so individual files do not sum to the compressed artifact total. This comment reports package artifact sizes only; it is not a final app binary-size report.

@bitrise

bitrise Bot commented Aug 14, 2026

Copy link
Copy Markdown

Install this build

Open Tophat, select your target device, then click Install. Links open on the Mac running Tophat.

SDK Install
Kotlin Install with Tophat

Checkout Kit E2E results

Status Suite Target Platform OS version tag Device
kotlin-android kotlin android latest Google Pixel 9
Android 17.0

@markmur
markmur force-pushed the swift-checkout-diagnostics branch from 0733f3e to b19daf0 Compare August 14, 2026 09:55
@markmur
markmur force-pushed the kotlin-checkout-diagnostics branch from 8f622b8 to 56e6b20 Compare August 14, 2026 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

#gsd:50662 Rebase Checkout Kit on UCP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant