hz-android-2d-porting
Guides porting existing Android 2D apps to Meta VR and Horizon OS — input adaptation, panel layout, and design requirements. Use…
Build and sideload Android apps for Meta Portal devices (Portal, Portal+, Portal Mini, Portal Go, Portal TV) using metavr. Use when targeting Portal hardware — covers ADB enablement, the no-GMS constraint, manifest/launcher intent-filter requirements, icon density quirks
Claude Code
$ npx -y skills add meta-quest/agentic-tools --skill portal --agent claude-code
Codex
$ npx skills add meta-quest/agentic-tools --skill portal -a codex -y
Cursor
$ npx skills add meta-quest/agentic-tools --skill portal -a cursor -y
Gemini CLI
$ npx skills add meta-quest/agentic-tools --skill portal -a gemini-cli -y
GitHub Copilot
$ npx skills add meta-quest/agentic-tools --skill portal -a github-copilot -y
OpenCode
$ npx skills add meta-quest/agentic-tools --skill portal -a opencode -y
Windsurf
$ npx skills add meta-quest/agentic-tools --skill portal -a windsurf -y
name: portal license: Apache-2.0 description: Build and sideload Android apps for Meta Portal devices (Portal, Portal+, Portal Mini, Portal Go, Portal TV) using metavr. Use when targeting Portal hardware — covers ADB enablement, the no-GMS constraint, manifest/launcher intent-filter requirements, icon density quirks (PNG-only, mipmap-xxxhdpi), the Smart Camera SDK, and the gradle + `metavr adb` build/deploy/debug loop. Auto-load when the user mentions "Portal" device, targets `minSdkVersion` 28-29 for a tabletop/TV form factor, or works with the `com.facebook.portal` package. allowed-tools: Read, Bash(metavr:*), Bash(npx:*), Bash(android:*), Bash(./gradlew:*)
This skill is for building Android apps that target Meta's Portal device family. Portal devices are discontinued (sales stopped end of 2022), but ADB is now enabled, so owners can sideload their own apps.
The hardware: Snapdragon-based Android tablets and TV sticks running a modified AOSP **without** Google Mobile Services. Several models, all touch or TV. `minSdkVersion` 28 (Android 9) or 29 (Android 10) depending on device.
This skill pairs with **metavr** (Meta VR CLI) — install it first. Use `metavr adb` in place of raw `adb` everywhere. See `resources/metavr.md` for the one-line install (via `npx`), the MCP-into-your-editor setup, and the Portal-relevant command surface. The full `metavr-cli` skill ships in the same repo and can also be loaded for deeper reference.
If you only remember a few things, remember these. Each is a class of bug Portal apps hit constantly.
1. **No Google Mobile Services.** No Play Services, no Firebase, no FCM, no Play Billing, no Google Sign-In, no Google Maps SDK, no AdMob, no ML Kit. Apps with hard GMS deps will crash on launch. Pick non-GMS alternatives — see `resources/app-requirements.md`. 2. **`minSdkVersion ≤ 28` is required** (Portal hardware tops out at API 29). For **new apps**, `targetSdkVersion 29` is the safest default. For **porting existing apps**, `targetSdkVersion` higher than 29 usually works fine — verified empirically with `targetSdk = 36`. Don't waste time downgrading the target SDK of an existing app unless you observe a concrete runtime issue. 3. **Launcher intent-filter is required.** Touch devices need `MAIN + LAUNCHER`; Portal TV needs `MAIN + LEANBACK_LAUNCHER`. The `DEFAULT` category is **not** required (verified empirically on Portal — apps with only `MAIN + LAUNCHER` appear on the home tile grid). Without one of these, the app installs but never appears on the home screen. 4. **App icon must include a PNG in `mipmap-xxxhdpi/`** as a fallback. Declare `android:icon` (touch) or `android:banner` (TV) on the launcher activity. You can also ship adaptive icons (`mipmap-anydpi-v26/`) and other density PNGs alongside — Portal's launcher correctly falls back to the `mipmap-xxxhdpi` PNG when the adaptive XML can't be rendered. Apps with **only** adaptive icons (no PNG fallback) will not have a visible icon on Portal. 5. **No contacts API. No account/credentials API.** `READ_CONTACTS` is denied. The account provider returns nothing. 5a. **Basic mic capture works; the far-field / beamformed mic array does not.** Standard `RECORD_AUDIO` opens an `AudioRecord` stream and delivers real audio from `handset-mic` (the single-channel mic). The far-field beamformed array used by "Hey Portal" wake-word is gated by a Meta-signed native permission (`com.facebook.alohasdk.permission.RECORD_AUDIO_PRIVILEGED`) and is not available to sideloaded apps. So basic voice features work; sideloaded wake-word detection and high-quality room-distance pickup do not. See `resources/app-requirements.md` § Microphone capture for details. 6. **Touch UI for tabletop, not phone form factor.** Portal sits on a counter or stand. Users interact from 50–100 cm. Hit targets ≥ 64 dp (96 dp for primary actions), body text ≥ 16 sp (18 sp on Portal+), landscape-first. Full Portal design system (typography, spacing, palette, WCAG ratios, TalkBack rules) is in `resources/design-guidelines.md`; for Jetpack Compose apps, `resources/compose-theme.md` is a copy-paste theme starter that bakes these rules into `Color.kt` / `Theme.kt` / `Type.kt`. 7. **Reserve the top ~64 dp** (only if your top content sits within 64 dp of the canvas edge). Portal has a persistent system overlay strip at the top: **back / home buttons (top-left)** and **Wi-Fi / status (top-right)**. It floats *above* app content with no automatic safe-area inset. Apps whose top UI hugs the edge (edge-to-edge toolbars, sticky headers, full-bleed modals) will tuck under it. Apps whose top content naturally sits ≥80 dp below the canvas edge don't need any change. The overlay pills are **white**, so apps with a **light background** in the top region need an additional dark scrim even after inset — see `resources/app-requirements.md` § Top system overlay.
| Device | `minSdkVersion` | Connection | |---|---|---| | Portal (1st and 2nd gen) | 28 / 29 | USB-C (back) | | Portal Mini | 29 | USB-C (back) | | Portal+ (1st and 2nd gen) | 28 / 29 | USB-C (back) | | Portal Go | 29 | USB-C (under rubber cover on back) | | Portal TV | 29 | USB-C |
Set `minSdkVersion 28` if you want to cover everything. If you don't need to support 1st-gen Portal / Portal+, you can target 29.
**Toolchain first — don't hand-hunt for it.** Building needs two host-machine pieces: a **JDK** (Gradle/AGP run on it) and the **Android SDK**. Install the SDK with Google's [`android` CLI](https://developer.android.com/tools) — don't go scavenging the filesystem for an SDK. For the JDK, point `JAVA_HOME` at **Android Studio's bundled JBR** if Android Studio is installed, otherwise install **Temurin 17**. The `android` CLI installs the **SDK only — it does not provide a JDK.** Full walkthrough: `resources/android-sdk-setup.md`.
# 1) Get a JDK 17 (one-time, host machine — Gradle / AGP run on it;
Guides porting existing Android 2D apps to Meta VR and Horizon OS — input adaptation, panel layout, and design requirements. Use…
Upgrades Meta VR apps to newer Horizon OS SDK versions — migration guides, deprecated API replacements, changelog. Use when…
Guides design of comfortable, intuitive VR/MR experiences for Meta VR and Horizon OS — comfort guidelines, interaction patterns,…
Builds WebXR experiences for Meta VR and Horizon OS using the Immersive Web SDK (IWSDK) — ECS architecture, Three.js integration,…
Build multi-window Meta Horizon OS experiences with the MetaVrx Layout SDK in Jetpack Compose or React Native. Covers framework…
Builds app UI for Meta VR and Horizon OS with the MetaVrx UI Set, a Jetpack Compose component library and design system. Covers…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.