also looking at this
fix(mobile): preserve native editing, navigation, and durable media requests
#369
36 files
+864
-185
| @@ -36,6 +36,7 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr | ||
| 36 | 36 | if (options.acceleration === 'software' && process.arch !== 'x64') |
| 37 | 37 | throw new Error('Android software emulation requires an x86_64 host and system image') |
| 38 | 38 | const bootTimeoutMs = options.bootTimeoutMs ?? 600_000 |
| 39 | const requiresPlayStore = options.image.split(';')[2] === 'google_apis_playstore' | |
| 39 | 40 | const maximumBootTimeoutMs = options.acceleration === 'software' ? 1_200_000 : 600_000 |
| 40 | 41 | if (!Number.isSafeInteger(bootTimeoutMs) || bootTimeoutMs < 1000 || bootTimeoutMs > maximumBootTimeoutMs) |
| 41 | 42 | 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 | ||
| 159 | 160 | // boot_completed can precede SettingsProvider and System UI readiness. |
| 160 | 161 | const settings = await run([adb, '-s', serial, 'shell', 'settings', 'get', 'global', 'animator_duration_scale'], undefined, probeTimeout(), true) |
| 161 | 162 | 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 | |
| 162 | 168 | const systemUi = await run([adb, '-s', serial, 'shell', 'pidof', 'com.android.systemui'], undefined, probeTimeout(), true) |
| 163 | 169 | // Native acceptance must be able to observe platform crashes before |
| 164 | 170 | // launching any app. boot_completed/System UI can precede logd's ADB |
| @@ -171,9 +177,13 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr | ||
| 171 | 177 | // modifying device setup or relaxing native acceptance. |
| 172 | 178 | 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) |
| 173 | 179 | 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) | |
| 174 | 183 | booted = settings.code === 0 && packages.code === 0 && systemUi.code === 0 && events.code === 0 |
| 175 | 184 | && /^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 | |
| 177 | 187 | } |
| 178 | 188 | } |
| 179 | 189 | const checkedAt = Date.now() |