feat(device): support API 37 in DeviceSpec#3332
Conversation
API 37 (Android 17) publishes only as `android-37.0` / `google_apis_ps16k` — no plain `android-37` / `google_apis` package. DeviceSpec.Android derives the minor-versioned platform id and the ps16k package segment from osVersion. avdmanager rejects `google_apis_ps16k` as a `--tag` (it is the sdkmanager package-path segment, not the SystemImage TagId). Rather than special-case the tag, drop `--tag`/`--abi` from createAndroidDevice and let avdmanager infer both from the fully-qualified `--package` — the path already pins tag and ABI. This matches the maestro-device AvdManager flow. Refs: - https://android-developers.googleblog.com/2025/12/android-16-qpr2-is-released.html (minor-SDK scheme) - https://developer.android.com/guide/practices/page-sizes (16 KB page-size variant)
Rename imagePackageTag → imageDir and expand the comment to spell out that the 3rd path segment is the on-disk system-images directory, not the image's SystemImage.TagId. They coincide for single-tag images (≤36) but diverge for API 37's multi-tag 16KB image (dir "google_apis_ps16k" vs tag "google_apis"), which is why a fully-qualified --package is the sole source of truth and --tag/--abi are never passed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7bba319 to
204be92
Compare
| // permanent minor-SDK scheme since Android 16 QPR2) and only the 16 KB ("…_ps16k") dir ships. | ||
| // https://android-developers.googleblog.com/2025/12/android-16-qpr2-is-released.html | ||
| // https://developer.android.com/guide/practices/page-sizes | ||
| private val imagePlatform: String get() = if (osVersion >= 37) "$os.0" else os |
There was a problem hiding this comment.
Is it premature to start thinking about the 36.1 or 37.1 images?
| // https://android-developers.googleblog.com/2025/12/android-16-qpr2-is-released.html | ||
| // https://developer.android.com/guide/practices/page-sizes | ||
| private val imagePlatform: String get() = if (osVersion >= 37) "$os.0" else os | ||
| private val imageDir: String get() = if (osVersion >= 37) "google_apis_ps16k" else "google_apis" |
There was a problem hiding this comment.
I think I'm little worried about this one. This is a time maybe we should ask what is it exactly that's start device is supposed to do, if its launching available device.
Hardcoding system images might not be the right call here. The reason we only have google_apis_ps16k for android 37 is that its not stable yet.
This would mean if they add google apis tomorrow we might need to revert it back or we should have a way to launch device with any other image as well.
Its true for even APIs today, there are system images like:
system-images;android-35;google_apis_playstore_tablet;arm64-v8a
So, maybe a better solution is to have a provisioned way for user to launch any system image available locally.
amanjeetsingh150
left a comment
There was a problem hiding this comment.
There are other things that we want to ensure before we commit to this PR. Supporting API 37 has a broader definition for core things like:
- Ensuring it starts locally
- Running current E2E to ensure core is able to run without issues
- Cloud support to bump sdk versions.
I don't think right now with this PR we're in state to fully commit the API 37 support.
So, I'm curious what is exactly that's user is asking here and if there are other ways to get them unblock?
4074cc8 to
36cfba7
Compare
|
The user is me. I want to get timely support in place, given all the work we did to make it easy, and now that Google have released their final beta. I've tested this branch locally and can launch devices on macOS. I'm travelling so don't have Windows/Linux available. I've push changes to enable e2e and kicked off a run for API 37 here: https://github.com/mobile-dev-inc/Maestro/actions/runs/26881770783 🤞 |
Why
API 37 (Android 17) publishes its system images differently from API ≤36, and
maestro start-device --platform android --device-os android-37failed because of it. Two things changed upstream:android-37.0, notandroid-37(Google's permanent minor-SDK scheme since Android 16 QPR2).google_apis_ps16k, not plaingoogle_apis. This is also the first multi-tag image: itsSystemImage.TagIdisgoogle_apis,page_size_16kb,ai_glasses_compatible.What
1. Build the correct package path (
DeviceSpec.Android.emulatorImage)Derive the platform (
android-37.0) and directory (google_apis_ps16k) fromosVersionfor API ≥37; ≤36 is unchanged.2. Stop passing
--tag/--abitoavdmanager(DeviceService.createAndroidDevice,DeviceCreateUtil)The old code passed
deviceSpec.tagasavdmanager --tag. That worked for ≤36 only because the package-path directory happened to equal the tag id (bothgoogle_apis). For API 37 they diverge: the directory isgoogle_apis_ps16kbut the tag id is stillgoogle_apis, so--tag google_apis_ps16kis rejected:A fully-qualified
--packagealready pins the tag and ABI, andavdmanagerauto-derives both from it — so--tag/--abiare redundant in this flow and can only match-or-fail. We now pass only--package(matching how themaestro-deviceworker already creates AVDs) and delete the now-deadDeviceSpec.Android.tagproperty.Testing
DeviceSpecTestasserts the API 37 package path resolves tosystem-images;android-37.0;google_apis_ps16k;arm64-v8a.maestro start-device --platform android --device-os android-37end-to-end: AVD created with the correcttag.id=google_apis/abi=arm64-v8a(avdmanager-derived), emulator booted to Android 17 / 16 KB page size.