Skip to content

[Android] Evict preloaded checkout under memory pressure#453

Open
markmur wants to merge 1 commit into
preloading-evictionfrom
android-preload-eviction
Open

[Android] Evict preloaded checkout under memory pressure#453
markmur wants to merge 1 commit into
preloading-evictionfrom
android-preload-eviction

Conversation

@markmur

@markmur markmur commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Ports the Swift memory-pressure eviction behaviour to Android. Registers a ComponentCallbacks2 on the application context when preloading starts; on a trim-memory signal at or above TRIM_MEMORY_RUNNING_LOW the single cached preload WebView is evicted and the handle transitions to the new PreloadState.Evicted. A presented checkout is spared — eviction is a no-op while isPresented is true, mirroring the Swift guard.

Eviction fires through the cache's own registered callback, so there's no public entry point; tests drive it via the internal cache. See the two new cases in PreloadObservabilityTest for the idle-evict and presented-spared paths.

Why ship this

  • Process survival: a paused checkout WebView is prime reclaimable memory. If we ignore onTrimMemory, Android's low-memory killer reclaims at process granularity and can take the whole host app — voluntarily handing back one WebView is the far cheaper trade. This is the change's main justification.
  • Platform contract: ComponentCallbacks2 exists precisely for caches like this. An SDK that holds a heavyweight WebView and ignores trim signals is a memory hog consumers have to work around.
  • Bounded and low-risk: the cache is single-slot and TTL-bounded, and eviction is isPresented-guarded, so it can only ever reclaim one idle entry and never a live checkout.
  • Completes the lifecycle: [Android] Add preload state observability #451 exposed PreloadState; Evicted closes it so a preload can't silently vanish under pressure with no corresponding state for consumers to observe.

markmur commented Jul 13, 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.

@github-actions github-actions Bot added the #gsd:50662 Rebase Checkout Kit on UCP label Jul 13, 2026
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

React Native — Coverage Report

Lines Statements Branches Functions
Coverage: 92%
91.85% (327/356) 87.98% (183/208) 100% (86/86)

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

Package Size

Platform Artifact Base Head Delta
Android release AAR 257.6 KiB 264.5 KiB +6.9 KiB
Android file breakdown
File Base Head Delta
classes.jar 273.5 KiB 281.3 KiB +7.8 KiB
res/layout/checkout_view_content.xml 2.2 KiB 2.2 KiB 0 B
res/layout/checkout_sheet_content.xml 2.0 KiB 2.0 KiB 0 B
res/values/values.xml 1.2 KiB 1.2 KiB 0 B
R.txt 1.1 KiB 1.1 KiB 0 B
proguard.txt 798 B 798 B 0 B
AndroidManifest.xml 578 B 578 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.

@markmur
markmur force-pushed the android-preload-observability branch from 89e6e70 to 284f325 Compare July 13, 2026 22:10
@markmur
markmur force-pushed the android-preload-eviction branch from 5bd9b5f to 4a8ed16 Compare July 13, 2026 22:10
@markmur
markmur force-pushed the android-preload-eviction branch from 4a8ed16 to b789d74 Compare July 15, 2026 12:06
@markmur
markmur force-pushed the android-preload-observability branch 2 times, most recently from bd21ffc to eeb5755 Compare July 15, 2026 12:50
@markmur
markmur force-pushed the android-preload-eviction branch from b789d74 to 2a9e701 Compare July 15, 2026 12:50
@markmur
markmur force-pushed the android-preload-observability branch from eeb5755 to 95c911b Compare July 15, 2026 13:08
@markmur
markmur force-pushed the android-preload-eviction branch 2 times, most recently from d81c123 to ccdc8c9 Compare July 15, 2026 13:09
@markmur
markmur force-pushed the android-preload-observability branch from 95c911b to a0d96f6 Compare July 15, 2026 13:09
@markmur
markmur changed the base branch from android-preload-observability to graphite-base/453 July 15, 2026 14:42
@markmur
markmur force-pushed the graphite-base/453 branch from a0d96f6 to 9d501ce Compare July 15, 2026 14:42
@markmur
markmur force-pushed the android-preload-eviction branch from ccdc8c9 to 13b1118 Compare July 15, 2026 14:42
@markmur
markmur changed the base branch from graphite-base/453 to preloading-eviction July 15, 2026 14:42
@markmur
markmur force-pushed the preloading-eviction branch from 9d501ce to 5fb8321 Compare July 15, 2026 15:00
@markmur
markmur force-pushed the android-preload-eviction branch 2 times, most recently from c4933ef to 5bc3ee0 Compare July 15, 2026 15:11
@markmur
markmur force-pushed the preloading-eviction branch 2 times, most recently from 4950275 to 39056a1 Compare July 15, 2026 16:01
@markmur
markmur force-pushed the android-preload-eviction branch from 5bc3ee0 to 16414d6 Compare July 15, 2026 16:01
@markmur
markmur force-pushed the android-preload-eviction branch 2 times, most recently from 5e97725 to 846c8f0 Compare July 16, 2026 14:18
@markmur
markmur force-pushed the preloading-eviction branch from ea93142 to 6312803 Compare July 16, 2026 14:18
@markmur
markmur force-pushed the android-preload-eviction branch from 846c8f0 to 9ccc261 Compare July 16, 2026 15:09
@markmur
markmur force-pushed the preloading-eviction branch from 6312803 to d45eadc Compare July 16, 2026 15:09
@markmur
markmur force-pushed the android-preload-eviction branch from 9ccc261 to 324b331 Compare July 16, 2026 15:20
@markmur
markmur force-pushed the preloading-eviction branch from d45eadc to 23fda26 Compare July 16, 2026 15:20
@markmur
markmur force-pushed the android-preload-eviction branch from 324b331 to f01da17 Compare July 16, 2026 15:48
@markmur
markmur force-pushed the preloading-eviction branch from 23fda26 to d4fff69 Compare July 16, 2026 15:48
@markmur
markmur force-pushed the android-preload-eviction branch from f01da17 to 6020bf3 Compare July 16, 2026 19:16
@markmur
markmur force-pushed the preloading-eviction branch 2 times, most recently from 37982e2 to e3a3ccf Compare July 16, 2026 19:41
@markmur
markmur force-pushed the android-preload-eviction branch from 6020bf3 to 9d2685c Compare July 16, 2026 19:41
@bitrise

bitrise Bot commented Jul 16, 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
tests/shared/launch-smoke.yaml kotlin android latest Google Pixel 9
Android 17.0

@markmur
markmur force-pushed the android-preload-eviction branch from 9d2685c to bd1c71c Compare July 16, 2026 20:09
@markmur
markmur force-pushed the preloading-eviction branch from e3a3ccf to 6f38ed6 Compare July 16, 2026 20:09
fun evict() {
val cached = entry
if (cached == null || cached.view.isPresented) return
terminate(PreloadState.Evicted)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

terminate seems to not be defined

memoryCallbacksRegistered = true
context.registerComponentCallbacks(object : ComponentCallbacks2 {
override fun onTrimMemory(level: Int) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we do MEMORY_RUNNING_CRITICAL too

 @Suppress("DEPRECATION")
  private fun isRunningLowOnMemory(level: Int): Boolean =
      level in ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW..
          ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL

  override fun onTrimMemory(level: Int) {
      if (isRunningLowOnMemory(level)) {
          evict(PreloadState.Evicted)
      }
  }

if (memoryCallbacksRegistered) return
memoryCallbacksRegistered = true
context.registerComponentCallbacks(object : ComponentCallbacks2 {
override fun onTrimMemory(level: Int) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth a comment that these levels aren't reported in API level 34+

It looks like we just get notified of things TRIM_MEMORY_BACKGROUND and TRIM_MEMORY_UI_HIDDEN from that API level on

so the eviction wouldn't work on newer devices

@markmur
markmur force-pushed the preloading-eviction branch from 6f38ed6 to 200b47f Compare July 17, 2026 10:25
@markmur
markmur force-pushed the android-preload-eviction branch from bd1c71c to 6957945 Compare July 17, 2026 10:25
@markmur
markmur force-pushed the preloading-eviction branch from 200b47f to d812e9a Compare July 17, 2026 12:48
@markmur
markmur force-pushed the android-preload-eviction branch 4 times, most recently from 0f6be84 to 2f73ea1 Compare July 17, 2026 14:44
@markmur
markmur force-pushed the preloading-eviction branch from b5368a2 to ab0b2d8 Compare July 17, 2026 14:53
@markmur
markmur force-pushed the android-preload-eviction branch 2 times, most recently from 3d625ba to b879a39 Compare July 17, 2026 15:35
Assisted-By: devx/42793469-bf64-49c6-b1db-f4d6c628a330
@markmur
markmur force-pushed the preloading-eviction branch from ab0b2d8 to c79c41f Compare July 17, 2026 16:19
@markmur
markmur force-pushed the android-preload-eviction branch from b879a39 to 6e05554 Compare July 17, 2026 16:19
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.

2 participants