USB: Input-Only Microphone Should Not Mute Built-in Speakers, Technical Analysis & Proposed Fix
When any USB-C audio device is connected to Quest 3 — even an input-only microphone with no speaker/DAC capability — Meta Horizon OS routes ALL audio (both input AND output) to the USB-C port and mutes the built-in headset speakers. This contradicts standard Android AOSP behavior and blocks legitimate professional use cases. The Problem Many professional VR applications need external microphone input (for speech recognition, recording, or communication) while maintaining audio output through the built-in speakers. Examples include therapeutic VR, education, accessibility, content creation, live streaming, and enterprise training. We purchased a USB-C gooseneck microphone that is input-only (no speaker, no DAC, isSink=false). On standard Android devices, connecting this mic only affects audio input — speakers continue working. On Quest 3, the built-in speakers are immediately muted, even though the USB device has zero output capability. What We've Tried (Everything Fails) 1. usb_audio_automatic_routing_disabled=1 (ADB): Does not selectively disable routing — prevents the USB device from registering with AudioService entirely (UsbAlsaManager.selectAlsaDevice() returns early), so setPreferredDevice() cannot find the mic at all. 2. AudioManager.setCommunicationDevice(builtInSpeaker) (API 31+): Only affects USAGE_VOICE_COMMUNICATION streams, not media/game audio. Unity uses FMOD → AAudio (native C layer), which routes through USAGE_GAME — unaffected. 3. AudioTrack.setPreferredDevice(builtInSpeaker): Would require intercepting the engine's internal audio output at the native layer — not feasible, and Quest 3's audio HAL may override it anyway. 4. "External Microphone" toggle (Settings > Advanced, v64+): Enables USB mic recognition only. Does NOT provide split input/output routing. 5. Input-only USB mic (isSource=true, isSink=false): Expected AOSP-compliant behavior (only input rerouted). Built-in speakers are still muted. Root Cause Analysis — AOSP vs. Meta Horizon OS In upstream AOSP, UsbAlsaManager.java checks actual device capabilities via USB Audio Class descriptors: // AOSP: frameworks/base/services/usb/java/com/android/server/usb/UsbAlsaManager.java private void selectAlsaDevice(UsbAlsaDevice alsaDevice) { UsbDescriptorParser parser = alsaDevice.getParser(); if (parser.hasOutput()) { // Only register OUTPUT if USB device has playback capability alsaDevice.startOutput(); } if (parser.hasInput()) { // Only register INPUT if USB device has capture capability alsaDevice.startInput(); } } The AOSP AudioPolicyManager then only reroutes streams matching registered capabilities. An input-only device never triggers checkOutputsForDevice(), so speakers remain active. Meta's Horizon OS overrides this separation. The most likely cause: // Probable Meta override (simplified): void AudioPolicyManager::onNewUsbDevice(audio_devices_t device) { // Does not check if device has output capability setDeviceConnectionState(AUDIO_DEVICE_OUT_SPEAKER, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE); setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE); } Proposed Fix Check the USB device's Audio Class descriptors before modifying output routing: void AudioPolicyManager::onNewUsbDevice(const sp<UsbAlsaDevice>& device) { if (device->hasCapture()) { setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE); } if (device->hasPlayback()) { // Route output to USB ONLY if device has output capability setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE); } // If !hasPlayback(): leave built-in speaker routing UNCHANGED } This is a single conditional check in the audio policy layer. It requires zero UI changes and simply aligns Quest 3 with upstream AOSP behavior. Additional Solutions (If a Broader Fix is Planned) - User-facing setting: Add "Audio Output" under Settings > Sound with options "Headset Speakers" / "USB-C" / "Automatic", independent of input routing. - Developer API: Allow applications to call setPreferredDevice() with routing respected for all audio usages (not just USAGE_VOICE_COMMUNICATION). Impact The Quest 3 hardware is fully capable — speakers and USB operate on independent audio paths. This is purely a software routing policy that could be resolved with a minimal code change. The fix would unblock every developer building applications that need external audio input while maintaining speaker output. Happy to provide dumpsys audio output or USB device descriptors to help diagnose the exact policy override. Related: A similar request was posted on the archived forum: "Request for Enhanced Audio Routing Controls with External Microphones on Meta Quest" (jrb-vr, October 2024) — which received no response.36Views0likes1CommentNPCs with Avatar/Style2Meta material are invisible on Meta Quest
I've rigged, animated, and imported avatars into my Unity project and scene as prefabs. I've created new materials for them with the same shader as my player avatar utilizes when he loads in - Avatar/Style2Meta. When playing the project on my laptop, I can see my Avatar NPCs with those materials fine. As soon as I build and run the project on my Meta Quest 2, they become invisible. I really like the shader, so I wanna keep it and not compromise for using two different materials for player and NPC avatars. Why does it happen only when playing on the headset, and how do I fix it?46Views0likes2CommentsQuest 3: 6GHz WiFi disabled when Country Code is AT (Austria)
Device: Meta Quest 3 OS Version: [v83.1032] Region: Austria (AT) Severity: High (Feature possibly broken for entire country) Summary The Quest 3 disables its 6GHz (WiFi 6E) radio specifically when the OS detects the Country Code AT. The hardware is fully functional and connects successfully to 6GHz networks when the device is in a temporary 00 (World) regulatory state. However, as soon as the OS detects an AT beacon and updates the Country Code, the 6GHz network immediately disappears from scan results and the connection drops. This indicates that the internal Regulatory Database (regdb) or wpa_supplicant configuration for Austria is outdated or incorrectly flagged as "6GHz Disabled," despite Austria fully adopting EU decision (EU) 2021/1067 allowing LPI use in the 5945–6425 MHz band. Technical Evidence & Reproduction: Working State (Country Code: 00): After a factory reset or specific reboot conditions, adb shell cmd wifi get-country-code returns 00. In this state, the Quest successfully detects and connects to my 6GHz AP (Asus RT-AXE7800) on PSC Channel 37 (6135 MHz) and Channel 85 (6375 MHz). Throughput is stable; wpa_supplicant logs show successful SAE authentication. Broken State (Country Code: AT): Once the device parses 802.11d beacons from neighboring routers, adb shell cmd wifi get-country-code updates to AT. Immediate Failure: The currently connected 6GHz session drops. Scanning Failure: adb shell cmd wifi start-scan followed by list-scan-results returns zero 6GHz networks. The radio effectively shuts down or filters out all 6GHz beacons. Router Configuration Used (Verified compliant with ETSI EN 303 687): Model: Asus RT-AXE7800 (but also observed same behavior for TP Link Wifi 6E Router) 6GHz (WiFi 6E) Mode: LPI (Low Power Indoor) Security: WPA3-SAE Channel: 37 (6135 MHz) - Note: This is a PSC channel and well within the Austrian 6425 MHz limit. Bandwidth: 80 MHz, 160MHz Result: Works on iPhones and Windows laptops in Austria. Fails on Quest 3 only when AT is active. Logcat Trace Analysis: The issue is reproducible by observing the transition from the default regulatory domain (00) to the local domain (AT). State 1: Country Code 00 (Working) The device connects successfully to 6GHz. wpa_supplicant confirms SAE authentication and association. SupplicantStaIfaceHalAidlImpl: connectToNetwork "MySSID"SAE wpa_supplicant: wlan0: Trying to associate with SSID 'MySSID' wpa_supplicant: wlan0: Associated with 08:bf:b8:xx:xx:xx The Trigger Event (Detected in logs): The system processes 802.11d beacons and updates the kernel regulatory domain. info/wificond: Regulatory domain changed to country: AT on wiphy_index: 0 State 2: Country Code AT (Broken) Immediately following the regulatory update, the 6GHz network becomes invisible to the scanner, despite using a valid PSC Channel (37) and LPI mode. The connection is dropped and cannot be re-established. WifiClientModeImpl: Network not found event received: network: "MySSID" wpa_supplicant: assoc key_mgmt 0x0 [Defaults to Open because Beacon is ignored by driver] Root Cause Conclusion: The regulatory table for AT (Austria) on Quest 3 appears to have a regression that either: A) Incorrectly blacklists the 6GHz band entirely, OR B) Enforces "Standard Power" signal requirements on "Low Power Indoor" (LPI) connections, causing valid LPI beacons to be discarded. Conclusion: The Quest 3 OS is falsely enforcing a 6GHz blackout for the AT ISO code. Austria is an LPI-approved region. Please update the OS regulatory tables to allow 6GHz (5945–6425 MHz) operation when the Country Code is set to Austria.105Views0likes3CommentsQuest System Keyboard Input Box is gone on the new GameActivity entry point Unity 6
Hello, We are encountering a significant issue with system keyboard on Meta Quest builds using Unity 6. The Problem Forced Entry Point: Unity 6 now defaults to the GameActivity application entry point. When we attempt to use the older Activity entry point (required for the previous keyboard system), the application crashes on startup, forcing us to use GameActivity. Missing Input Box: The GameActivity entry point uses the GameActivity Jetpack library, which has removed the on-screen input box that traditionally appears above the system keyboard. For mobile apps, this is a clean design, but in Meta Quest VR, this causes a major UX problem. The UX Issue on Meta Quest Since the Quest system keyboard is visually separate and detached from the in-game UI, users lose all visual confirmation of what they are typing. The visible input box on the system keyboard is necessary in VR to show the user the text they are actively entering. The Constraint Migrating our entire project to a custom virtual keyboard is not feasible due to the complexity of supporting multiple languages and character sets. Our Question Is there an official or known way to restore the input box feature on the system keyboard, as it existed with the old "Activity" entry point, while still using the required GameActivity in Unity 6? Any guidance on modifying the GameActivity bridge or another low-level fix would be greatly appreciated. Thank you!187Views0likes3CommentsDistanceGrabUseInteractable?
Hi, This is definitely a pretty basic question relating to the Meta Interaction SDK for Unity. I've managed to get a HandGrabUseInteractable linked to a HandGrabinteractable via a SecondaryInteractionFilter. However, I also have a DistanceHandGrabInteractable on that object, linked to its own HandGrabUseInteractable linked to the same delegate as the first. When I grab the object without distance grab, my script calls BeginUse, EndUse, and ComputeUseStrength properly. When I grab with distance, it does not, as far as I can tell - I am working on Mac and the simulator was not working with this scenario at all, so I have to port the APK to my quest each time I want to test. That takes away a bit of my debugging capabilities. I thought perhaps this was an issue with having multiple HandGrabUseInteractables, but when I removed the duplicate and made the object only have DistanceHandGrabInteractable and one HandGrabUseInteractable, it still did not work. I also wondered if perhaps HandGrabUseInteractable only supports the HandGrabInteractable, and not other HandGrabInteractables? But peeking at the package code and reading the SecondaryInteractionFilter docs seemed to suggest either HandGrabInteractable or DistanceHandGrabInteractable should work, so long as all references are piped correctly. What am I doing wrong? How can I link my DistanceHandGrabInteractable to a HandGrabUseInteractable? Will I need to make my own DistanceGrabUseInteractable script, perhaps using the existing HandGrabUseInteractable as a base? Thanks for the help20Views0likes0CommentsHow do I access the meta quest device name or id
Hi! Hopefully someone has solved this problem - I'm looking to log some information to a cloud database and I need to access and log the device Id. The ID I'm looking for isn't accessed via "SystemInfo.deviceUniqueIdentifier", nor is it SystemInfo.deviceModel, deviceName, or deviceType. The ID I'm looking for is the same ID that shows up in the Meta Horizon Managed Services devices list. It's a 14 digit device Id like "1WMHH6666V0335". I'm looking to access this Id in Unity. Can someone tell me what property I'm looking for? I think this might be the SERIAL number. Thanks for your time!46Views0likes1CommentVoice and Haptics SDKs not 16kb aligned
I develop AR applications designed to run on both the Quest3 as well as Android/iOS devices in Unity. It would appear as though a couple of the aar/so files in the meta voice SDK and Haptics SDK are not 16kb aligned and cause issues when trying to deploy to the google play store (using the all-in-one package updated to latest at the time of this post, v81). Since both targets (Quest3 and Android) share build settings, it complicates deploying an APK that has these meta libraries in it. The files with issues are: mailto:com.meta.xr.sdk.voice@1613052ece81\Lib\Telemetry\Plugins\SDKTelemetry.aar mailto:com.meta.xr.sdk.voice@1613052ece81\Lib\Wit.ai\Lib\third-party\UnityOpus\Plugins\UnityOpus\Plugins\Androidunityopus.aar mailto:com.meta.xr.sdk.haptics@cd1f215a823c\Plugins\libs\Android\ARM64\libhaptics_sdk.so I did notice in the changelogs for v81 that several libraries were updated for 16kb alignment, it seems as though a few may have been missed. One big thing to note is that the two aar files DO NOT trigger the 16kb warning within the unity editor at build time, so the issue will only be caught once you upload it to the google play store for deployment.53Views1like1CommentIssues with Gaussian Splatting integration in Meta Spatial SDK (v0.9.2) – Standalone Quest 3
Hi everyone, I am an architect and urban planner, developing VR/MR projects in my spare time. I’m currently working on a native Quest 3 application to view Gaussian Splats for highly detailed virtual project tours. My Goal: Render native Gaussian Splatting (3DGS) on Quest 3 (Standalone). Synchronize the splat position with the real world for a seamless transition from Mixed Reality (MR) to Virtual Reality (VR) with a skybox. Targeting a minimum of 150k splats with stable performance. Previous Attempts: I initially used Unity with the Aras/Ninja implementations. While it works perfectly via Oculus Link (PCVR), it’s not viable for my needs because: PC Builds don't support the specific MR features I need for this project. The Android build (standalone) performance is extremely poor, even with optimized settings and a small 50k splat PLY file (unusable frame rates). Current Issue with Meta Spatial SDK: I’ve switched to the Meta Spatial SDK (Packages v0.9.2) to leverage the new native splat support mentioned here: Spatial SDK Splats Documentation. Despite following the documentation step-by-step: The splats do not appear in the scene. I am getting several reference errors (MissingReference/NullReference) that I can't seem to resolve. My Question: Has anyone successfully created a native Quest 3 APK using the Spatial SDK to run Gaussian Splats (~150k splats)? If so, could you share the correct workflow or point out common pitfalls with this specific SDK version? Any help or documentation beyond the official guide would be greatly appreciated!427Views2likes12CommentsAccessibility Feature Request: Conversation Focus Mode for Ray-Ban Meta Display Glasses
Hi everyone! I’m a Ray-Ban Meta display glasses user who is hard of hearing and wears hearing aids daily. I’d love to see a conversation focus mode added that prioritizes voices directly in front of the wearer and reduces background noise. In busy environments, this would make a big difference for hearing-aid users and others who rely on clearer speech in real time. If this type of accessibility feature is ever developed, I would absolutely love the ability to have it added to my glasses and would be happy to provide feedback or participate in any beta or user-testing opportunities. I’ve also submitted this through support channels, but wanted to share here in case the team is gathering feedback.125Views1like0CommentsCannot control the volume of voice calls on v85
Hello team, I am developing an application related to WebRTC, and I need to control the voice call volume on Meta Quest 3 (increase, decrease, or mute completely). Everything was fine at first, but after I updated the OS to v85.0, when I turned the volume down to zero using the physical button, the sound on YouTube was muted, but the voice call audio was still present. I was very surprised that even Facebook Messenger behaves the same way. Is this a bug in the OS, or is it a new OS behavior? I couldn't find any related information in the release notes. Please help me. Thank you very much.15Views0likes0Comments