hz-android-2d-porting agentic skill. The skill analyzes your existing Android project, proposes the changes needed for Meta Quest, and helps you build and test the result.AndroidManifest.xml with the required Horizon OS tags and metadata:| Area | Manifest declaration | Why it matters |
|---|---|---|
Supported devices | <meta-data android:name="com.oculus.supportedDevices" android:value="quest2|questpro|quest3|quest3s" /> | Declares supported Quest devices |
Default window size | android:defaultWidth="1024dp" android:defaultHeight="640dp" inside <layout> | Initial size of your resizable app window |
Minimum window size | android:minWidth="360dp" android:minHeight="225dp" inside <layout> | Smallest size at which your app remains usable |
Orientation and display | android:screenOrientation and window metadata | Handles window resizing and immersive display |
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="com.oculus.supportedDevices"
android:value="quest2|questpro|quest3|quest3s" />
<activity
android:name=".MainActivity"
android:exported="true">
<layout
android:defaultWidth="1024dp"
android:defaultHeight="640dp"
android:minWidth="360dp"
android:minHeight="225dp" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
| Approach | Best for |
|---|---|
Product flavors | Apps that want to completely remove unsupported code and dependencies from the Horizon OS build at compile time. |
Runtime detection | Apps or libraries that need a single build artifact for Horizon OS and other Android platforms. |
app/src/quest/, app/src/mobile/) has its own manifest and dependencies merged with main at compile time.mobileImplementation for Google Play Billing and questImplementation for Horizon Billing. The Meta Horizon Android Studio Plugin
can generate this structure for you.// app/build.gradle.kts
dependencies {
"mobileImplementation"(libs.gms.billing)
"questImplementation"(libs.horizon.billing.compatibility)
}
app/src/main/ and flavor-specific code in app/src/quest/ and app/src/mobile/. For example, keep BillingUser.kt in main and provide quest/java/Billing.kt using Horizon Billing and mobile/java/Billing.kt using Google Play Billing with the same interface.quest/AndroidManifest.xml, mobile-only permissions in mobile/AndroidManifest.xml, and shared declarations in main/AndroidManifest.xml.PackageManager.hasSystemFeature() method to check for the Horizon OS or standalone VR system feature. This procedure does not add a dependency to your app.import android.content.Context
private const val FEATURE_HORIZON_OS = "horizonos.software.horizon_os"
private const val FEATURE_STANDALONE_VR = "oculus.hardware.standalone_vr"
fun isRunningOnHorizonOs(context: Context): Boolean {
val packageManager = context.packageManager
return packageManager.hasSystemFeature(FEATURE_HORIZON_OS) ||
packageManager.hasSystemFeature(FEATURE_STANDALONE_VR)
}
| GMS dependency | Replacement |
|---|---|
gms.auth (Sign-In) | |
gms.location | |
gms.ads.identifier (Ad ID) | |
billingclient.api | |
Android Notifications |
| Firebase library | Replacement |
|---|---|
App Check Play Integrity provider | |
App Check SafetyNet provider | |
App Indexing | |
Dynamic Links | |
Cloud Messaging | |
ML Vision | None |
ML Custom Model | None |
INSTALL_PACKAGES or headset-meaningless ones like CALL_PHONE. A build that requests a prohibited permission fails store upload. Other permissions are allowed after review; you explain the use case at submission.AndroidManifest.xml before you build. The Meta Horizon Android Studio Plugin
underlines unsupported libraries and permissions as you type.metavr ssim download metavr ssim start metavr app install path/to/app.apk metavr app launch your.package.name
questDebug or mobileDebug, and allow Gradle to sync again.questImplementation or mobileImplementation instead of implementation.