[Android] 4.0.0-alpha.4
Pre-releaseBreaking changes
New preload failure cases
PreloadState.FailureReason includes two new cases. Exhaustive when expressions must handle them:
when (val reason = state.reason) {
is PreloadState.FailureReason.HttpError ->
recordHttpFailure(reason.statusCode)
PreloadState.FailureReason.NavigationFailed ->
recordNavigationFailure()
+ PreloadState.FailureReason.WebContentProcessTerminated ->
+ discardPreload()
+ PreloadState.FailureReason.ProtocolError ->
+ discardPreload()
}WebContentProcessTerminatedindicates that Android terminated or crashed the preloaded WebView renderer.ProtocolErrorindicates that checkout sent a terminal protocol error while preloading.
These failures apply only to the preload. A subsequent checkout presentation can still load normally.
Colors constructor signature changed
Colors now includes headerBorderColor. This changes its generated constructor, component functions, and copy method.
Code that constructs Colors positionally must supply the new argument:
val colors = Colors(
webViewBackground,
headerBackground,
headerFont,
progressIndicator,
closeIcon,
closeIconTint,
dragHandleColor,
+ headerBorderColor,
)Prefer named arguments or the customization builder to reduce migration work when alpha color options change:
-val colors = Colors(
- background,
- header,
- headerText,
- progress,
- null,
- null,
- handle,
- border,
-)
+val appearance = CheckoutAppearance.Storefront().customize {
+ webViewBackground = background
+ headerBackground = header
+ headerFont = headerText
+ progressIndicator = progress
+ dragHandleColor = handle
+ headerBorderColor = border
+}Additive changes
Incoming message origin validation
Checkout messages can now be restricted to explicitly trusted origins:
ShopifyCheckoutKit.configure {
+ it.allowedMessageOrigins = setOf(
+ "https://checkout.example.com",
+ "https://*.example.com",
+ )
}The checkout URL origin and shop.app are always trusted. An empty set preserves the previous behavior and accepts messages from every origin.
Rejected messages can be observed with onMessageRejected:
ShopifyCheckoutKit.configure {
+ it.onMessageRejected = { rejection ->
+ reportRejectedOrigin(
+ rejection.origin,
+ rejection.reason,
+ )
+ }
}The RejectedMessage payload is untrusted and should only be used for diagnostics.
Customize the checkout header border
The new headerBorderColor option controls the border displayed when checkout content scrolls beneath the native header:
ShopifyCheckoutKit.configure {
it.appearance = CheckoutAppearance.Storefront().customize {
headerBackground = Color.ResourceId(R.color.checkout_header)
headerFont = Color.ResourceId(R.color.checkout_header_text)
+ headerBorderColor = Color.ResourceId(R.color.checkout_header_border)
}
}Behavior changes
Renderer termination is consistently reported
Checkout now handles both WebView renderer crashes and system termination as terminal failures:
override fun onCheckoutFailed(error: CheckoutException) {
when (error.code) {
CheckoutErrorCode.WEB_CONTENT_PROCESS_TERMINATED -> showRetry()
else -> handleCheckoutFailure(error)
}
}Checkout Kit does not automatically recreate the WebView. The app must remove the failed presentation, destroy it, and create a new ShopifyCheckout for an explicit retry.
For an unconsumed background preload, the SDK reports:
PreloadState.Failed(
PreloadState.FailureReason.WebContentProcessTerminated
)It does not invoke the presentation lifecycle failure callback.
Checkout URLs must use HTTPS
Checkout creation and main-frame navigation now reject non-HTTPS checkout URLs:
-val checkout = ShopifyCheckout.create(context, checkoutUrl, listener)
+require(checkoutUrl.startsWith("https://"))
+val checkout = ShopifyCheckout.create(context, checkoutUrl, listener)Invalid URLs produce a CheckoutException with CheckoutErrorCode.SDK_ERROR. Initialization failures are delivered through the configured failure callback, and the returned checkout view remains inert.
Terminal protocol errors invalidate preloads
When a background preload receives a terminal ec.error message, it now transitions to:
PreloadState.Failed(
PreloadState.FailureReason.ProtocolError
)The error remains scoped to preload state and does not invoke the presentation failure callback.
Header border appears while scrolling
The checkout sheet now displays a subtle header border after checkout content scrolls beneath the native header. The border fades in and out as the WebView scroll position changes.
The drag handle also falls back to headerFont when no explicit dragHandleColor is provided.
What's Changed
- add multipass deprecation warning by @kiftio in #564
- Document checkout lifecycle errors by @kiftio in #538
- Encrypt Android demo customer access tokens by @kiftio in #547
- feat: incoming message origin validation for android by @michaeljsXu in #475
- Handle WebView process termination by @kiftio in #539
- chore(deps): bump com.android.application from 9.2.1 to 9.3.1 in /platforms/android by @dependabot[bot] in #522
- chore(deps): bump com.android.library from 9.2.1 to 9.3.1 in /platforms/android by @dependabot[bot] in #521
- fix: drag handle when using customize should follow headerFont by @kieran-osgood-shopify in #594
- [Android] Setup sample formatting and basic lint by @kiftio in #585
- [Android][lint] Fix android sample package name by @kiftio in #587
- Readme discrepancies by @markmur in #526
- [ReactNative] Adds title to the provider configuration for runtime changes by @kieran-osgood-shopify in #485
- Add sample app test seams and run them in CI by @kieran-osgood-shopify in #553
- Elevate sheet header with border by @markmur in #616
- Release Android 4.0.0-alpha.4 by @tiagocandido in #623
Full Changelog: android/4.0.0-alpha.3...android/4.0.0-alpha.4