perf(ios): skip the simulator accessibility write when this host's preferences already allow it

Merged
TH
6d ago
+137-3

Summary

#4276 made every iOS simulator open run simctl spawn … defaults write com.apple.Accessibility ApplicationAccessibilityEnabled -bool YES before the launch, which costs about 0.85–1.05 s (a simctl spawn read costs the same, ~0.9 s). The maintainer review on #4276 flagged it.

The launch guard now reads the simulator's preferences file from this host (<set>/<udid>/data/Library/Preferences/com.apple.Accessibility.plist, parsed with the existing parseApplePlist, ~0.3 ms warm) and writes only when the key is explicitly off. It skips the write when the key is on, 1, or absent (a never-used simulator has no key and its apps expose a full tree). A missing or unreadable file, or a scoped tool provider (Limrun), still writes. Teardown repair stays unconditional.

Race accepted: after XCTest teardown the file lags the guest by under 200 ms (measured: +0 ms disk 1 / guest 0; +200 ms both 0). Our own teardown repairs the key; only a foreign teardown within that window is missed.

3 files. Design reviewed with Codex.

Validation

  • Tested SHA: dbf6f508726424a703fa1cd2cedb97dc98a93d5b; pnpm check:affected --run --head dbf6f508726424a703fa1cd2cedb97dc98a93d5b passed. Timing runs below were taken at 2909056; later commits only add tests and move the host path lookup inside the guard's try.
  • New ios-simulator-accessibility.test.ts: skip on on/1/absent; write on off/0/malformed/missing; re-read on every launch.
  • Live, fresh iPhone 17 simulator (iOS 26.2), isolated state and lease dirs, key = 1, 5× open --relaunch: main 3188/2407/3458/2566/2703 ms, this PR 2898/1320/1134/1181/1185 ms (first run includes runner startup).
  • Live, key forced to NO on disk: open --relaunch wrote it back to 1 before launch.
  • Live, absent key (fresh iPhone 17 simulator, iOS 26.2; plutil -p showed the preferences file without ApplicationAccessibilityEnabled): open --relaunch left the key absent (no write), AXe read 155 nodes, and the first snapshot -i had 29 nodes. A key=1 run on the same simulator gave 155 and 29.