ReviewOS

also looking at this

craft-native/craft

fix(mobile): preserve native editing, navigation, and durable media requests

#369
Merged chris wants to merge codex/native-vertical-scroll-tab-swipes into main
36 files +864 -185
packages/android/src/emulator.tsmodified+11-1
Changes to packages/android/src/emulator.ts
@@ -36,6 +36,7 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr
3636 if (options.acceleration === 'software' && process.arch !== 'x64')
3737 throw new Error('Android software emulation requires an x86_64 host and system image')
3838 const bootTimeoutMs = options.bootTimeoutMs ?? 600_000
39 const requiresPlayStore = options.image.split(';')[2] === 'google_apis_playstore'
3940 const maximumBootTimeoutMs = options.acceleration === 'software' ? 1_200_000 : 600_000
4041 if (!Number.isSafeInteger(bootTimeoutMs) || bootTimeoutMs < 1000 || bootTimeoutMs > maximumBootTimeoutMs)
4142 throw new Error(`Android bootTimeoutMs must be an integer between 1000 and ${maximumBootTimeoutMs} milliseconds`)
@@ -159,6 +160,11 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr
159160 // boot_completed can precede SettingsProvider and System UI readiness.
160161 const settings = await run([adb, '-s', serial, 'shell', 'settings', 'get', 'global', 'animator_duration_scale'], undefined, probeTimeout(), true)
161162 const packages = await run([adb, '-s', serial, 'shell', 'pm', 'path', 'android'], undefined, probeTimeout(), true)
163 // A stock Play image can expose the framework package and HOME while
164 // first-boot provisioning is still registering its bundled apps.
165 const playStore = requiresPlayStore
166 ? await run([adb, '-s', serial, 'shell', 'pm', 'path', 'com.android.vending'], undefined, probeTimeout(), true)
167 : undefined
162168 const systemUi = await run([adb, '-s', serial, 'shell', 'pidof', 'com.android.systemui'], undefined, probeTimeout(), true)
163169 // Native acceptance must be able to observe platform crashes before
164170 // launching any app. boot_completed/System UI can precede logd's ADB
@@ -171,9 +177,13 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr
171177 // modifying device setup or relaxing native acceptance.
172178 const home = await run([adb, '-s', serial, 'shell', 'cmd', 'package', 'resolve-activity', '--brief', '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.HOME'], undefined, probeTimeout(), true)
173179 const homeActivity = home.stdout.trim().split(/\r?\n/).at(-1) ?? ''
180 const temporaryHome = homeActivity.startsWith('com.android.sdksetup/')
181 || /^com\.android\.settings\/(?:\.|com\.android\.settings\.)FallbackHome$/.test(homeActivity)
182 || /^android\/.*(?:Resolver|Chooser)Activity$/.test(homeActivity)
174183 booted = settings.code === 0 && packages.code === 0 && systemUi.code === 0 && events.code === 0
175184 && /^package:\/\S+/m.test(packages.stdout) && /^\d+(?:\s+\d+)*$/.test(systemUi.stdout.trim())
176 && home.code === 0 && /^[\w.]+\/[\w.$]+$/.test(homeActivity) && !homeActivity.startsWith('com.android.sdksetup/')
185 && (!requiresPlayStore || (playStore?.code === 0 && /^package:\/\S+/m.test(playStore.stdout)))
186 && home.code === 0 && /^[\w.]+\/[\w.$]+$/.test(homeActivity) && !temporaryHome
177187 }
178188 }
179189 const checkedAt = Date.now()