ReviewOS

also looking at this

craft-native/craft

feat(maps): add key-free native Android maps and shared map controls

#363
Merged chris wants to merge codex/wildloop-native-map-providers into main
28 files +1857 -481

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

.github/workflows/ci.ymlmodified+1-1
Changes to .github/workflows/ci.yml
@@ -21,7 +21,7 @@ jobs:
2121 android-software-emulator:
2222 name: Android software emulator
2323 runs-on: ubuntu-latest
24 timeout-minutes: 25
24 timeout-minutes: 35
2525 steps:
2626 - uses: actions/checkout@v6
2727 - name: Install the managed Android toolchain
packages/android/src/emulator.tsmodified+8-3
Changes to packages/android/src/emulator.ts
@@ -12,6 +12,8 @@ export interface AndroidEmulatorOptions {
1212 temporaryDirectory?: string
1313 port?: number
1414 acceptLicenses?: boolean
15 /** Readiness budget in milliseconds, from 1 second to 30 minutes; defaults to 10 minutes. */
16 bootTimeoutMs?: number
1517 env?: Record<string, string | undefined>
1618}
1719
@@ -33,6 +35,9 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr
3335 throw new Error('The Android system image must match the host architecture')
3436 if (options.acceleration === 'software' && process.arch !== 'x64')
3537 throw new Error('Android software emulation requires an x86_64 host and system image')
38 const bootTimeoutMs = options.bootTimeoutMs ?? 600_000
39 if (!Number.isSafeInteger(bootTimeoutMs) || bootTimeoutMs < 1000 || bootTimeoutMs > 1_800_000)
40 throw new Error('Android bootTimeoutMs must be between 1000 and 1800000 milliseconds')
3641 const port = options.port ?? 5558
3742 if (!Number.isInteger(port) || port < 5554 || port > 5682 || port % 2 !== 0) throw new Error('Android console ports must be even and between 5554 and 5682')
3843 const sdk = resolve(options.sdkRoot)
@@ -103,9 +108,9 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr
103108 created = true
104109 log = openSync(join(artifacts, 'emulator.log'), 'w')
105110 child = Bun.spawn([executable, '-avd', name, '-port', String(port), '-no-window', '-no-snapshot', '-no-audio', '-no-boot-anim', '-gpu', 'software', '-memory', '2048', '-cores', '2', '-accel', options.acceleration === 'software' ? 'off' : 'on'], { env, stdout: log, stderr: log })
106 const identity = { image: options.image, acceleration: options.acceleration, accelerationProbeExitCode: acceleration.code, serial, avdDirectory: env.ANDROID_AVD_HOME, emulatorPid: child.pid }
111 const identity = { image: options.image, acceleration: options.acceleration, bootTimeoutMs, accelerationProbeExitCode: acceleration.code, serial, avdDirectory: env.ANDROID_AVD_HOME, emulatorPid: child.pid }
107112 await Bun.write(join(artifacts, 'android-emulator.json'), JSON.stringify(identity, null, 2) + '\n')
108 const deadline = Date.now() + 600_000
113 const deadline = Date.now() + bootTimeoutMs
109114 while (Date.now() < deadline && child.exitCode === null) {
110115 let booted = false
111116 // Nonzero ADB exits are expected while services initialize. Filesystem,
@@ -128,7 +133,7 @@ export async function createAndroidEmulator(options: AndroidEmulatorOptions): Pr
128133 }
129134 await Bun.sleep(2000)
130135 }
131 throw new Error(`The owned Android emulator did not boot; inspect ${artifacts}`)
136 throw new Error(`The owned Android emulator did not boot within ${bootTimeoutMs}ms; inspect ${artifacts}`)
132137 }
133138 catch (error) {
134139 if (child) {
scripts/verify-android-emulator.tsmodified+3-0
Changes to scripts/verify-android-emulator.ts
@@ -26,7 +26,10 @@ try {
2626 session = await createAndroidEmulator({
2727 sdkRoot: join(owned, 'sdk'), sdkmanager, avdmanager,
2828 image: 'system-images;android-35;google_apis_playstore;x86_64',
29 // The stock Play image performs real first-boot dex optimization under TCG.
30 // Keep every readiness and package assertion; give this software run an explicit bound.
2931 acceleration: 'software', artifactsDirectory: artifacts,
32 bootTimeoutMs: 20 * 60_000,
3033 temporaryDirectory: owned, acceptLicenses: true,
3134 env: { JAVA_HOME: javaHome },
3235 })