also looking at this
fix(native): retain keyed controls and correct map and tab chrome
#368
32 files
+449
-100
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.
| @@ -5,7 +5,7 @@ import { join } from 'node:path' | ||
| 5 | 5 | import { createAndroidEmulator } from '../../../android/src/emulator' |
| 6 | 6 | import type { AndroidEmulatorOptions } from '../../../android/src/emulator' |
| 7 | 7 | |
| 8 | function fixture(hardware: boolean, delayedSettings = false, delayedEvents = false): { root: string, options: AndroidEmulatorOptions } { | |
| 8 | function fixture(hardware: boolean, delayedSettings = false, delayedEvents = false, delayedHome = false): { root: string, options: AndroidEmulatorOptions } { | |
| 9 | 9 | const root = mkdtempSync(join(tmpdir(), 'craft emulator fixture ')) |
| 10 | 10 | const sdk = join(root, 'managed sdk') |
| 11 | 11 | for (const directory of ['bin', 'platform-tools', 'emulator']) mkdirSync(join(sdk, directory), { recursive: true }) |
| @@ -30,6 +30,13 @@ else | ||
| 30 | 30 | printf '1\\n' ;; |
| 31 | 31 | *'pm path android') printf 'package:/system/framework/framework-res.apk\\n' ;; |
| 32 | 32 | *'pidof com.android.systemui') printf '1234\\n' ;; |
| 33 | *'cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.HOME') | |
| 34 | if [ '${delayedHome ? 'yes' : 'no'}' = yes ] && [ ! -f "$ANDROID_HOME/home-ready" ]; then | |
| 35 | touch "$ANDROID_HOME/home-ready" | |
| 36 | printf 'com.android.sdksetup/.DefaultActivity\\n' | |
| 37 | else | |
| 38 | printf 'com.android.launcher3/.Launcher\\n' | |
| 39 | fi ;; | |
| 33 | 40 | *'logcat -b events -d -t 1') |
| 34 | 41 | if [ '${delayedEvents ? 'yes' : 'no'}' = yes ] && [ ! -f "$ANDROID_HOME/events-ready" ]; then |
| 35 | 42 | touch "$ANDROID_HOME/events-ready" |
| @@ -113,6 +120,21 @@ test('boot and System UI do not admit a device before its event log is readable' | ||
| 113 | 120 | finally { await session?.dispose(); rmSync(root, { recursive: true, force: true }) } |
| 114 | 121 | }, 10_000) |
| 115 | 122 | |
| 123 | test('boot completion waits for the automatic SDK setup activity to release HOME', async () => { | |
| 124 | const { root, options } = fixture(true, false, false, true) | |
| 125 | let session: Awaited<ReturnType<typeof createAndroidEmulator>> | undefined | |
| 126 | try { | |
| 127 | session = await createAndroidEmulator(options) | |
| 128 | const trace = readFileSync(join(options.artifactsDirectory, 'device-commands.jsonl'), 'utf8').trim().split('\n').map(line => JSON.parse(line)) | |
| 129 | const home = trace.filter(entry => entry.args.includes('resolve-activity')) | |
| 130 | expect(home.map(entry => entry.stdout.trim())).toEqual(['com.android.sdksetup/.DefaultActivity', 'com.android.launcher3/.Launcher']) | |
| 131 | const identity = JSON.parse(readFileSync(join(options.artifactsDirectory, 'android-emulator.json'), 'utf8')) | |
| 132 | expect(Date.parse(home[1].finishedAt)).toBeLessThanOrEqual(Date.parse(identity.bootedAt)) | |
| 133 | expect(identity.bootTimeoutMs).toBe(600_000) | |
| 134 | } | |
| 135 | finally { await session?.dispose(); rmSync(root, { recursive: true, force: true }) } | |
| 136 | }, 10_000) | |
| 137 | ||
| 116 | 138 | test('the SDK process fixture records hardware mode and reaps only its owned process', async () => { |
| 117 | 139 | const { root, options } = fixture(true) |
| 118 | 140 | options.bootTimeoutMs = 42_000 |