Native headphone controls inside Android system UI — no vendor app, driven by per-device manifests. Supports Apple, Soundcore, Samsung and others – add yours to the list!.
Orchestra is an LSPosed module. It makes the stock Android Bluetooth "About device" page render native controls — ANC / noise-control modes, feature switches, and battery by impersonating the device-settings integration for your ROM's vendor own headphonees (example: Pixel + Pixel Buds). There is no vendor app in the loop: Orchestra talks to the headphones directly over their native control protocol (RFCOMM,L2CAP, etc.), and every device is described by a small JSON manifest so addinga model is data, not code.
The same controls that Pixel Buds get natively (segmented ANC control, feature toggles, per-bud battery) appear for your headphones, in the system Settings UI, themed with Material You.
- Rooted device.
- LSPosed (or a compatible Xposed framework) compatble with API <=100
- A supported headphone (see below) — or write a manifest for your own.
Orchestra needs LSPosed because it writes a privileged Bluetooth metadata tag and hooks the system UI. It does not require a separate KSU/Magisk module.
Orchestra impersonates the Pixel device-settings integration, so platform support is defined along three axes — the OS, the ROM, and the LSposed framework. The headphones themselves are not hardcoded: which devices are supported is defined entirely by manifests (see Supported headphones below).
| Axis | Supported | Notes |
|---|---|---|
| Android version | Android 16–17 (API 36–37). minSdk 31 (Android 12). |
About-device controls and the volume-panel Noise-Control tile both verified on Android 17 (the tile requires a supported headphone as the active audio output). After updating the app you must restart System UI for the new hooks to load. |
| ROM | PixelOS (Google's Pixel build) — the only verified target. | Injection bindings ship for pixelos only. The manifest schema has an embedded per-ROM platforms slot so other root + LSPosed-capable ROMs (e.g. LineageOS) can be added later — none are implemented/verified yet. Non-Pixel OEM skins (One UI, MIUI/HyperOS, ColorOS…) are not supported. |
| Xposed framework | LSPosed and the newer "Vector" framework (legacy Xposed bridge, verified at API 101). xposedminversion 82. |
Uses the legacy Xposed API today. A dual legacy + modern libxposed engine (covering <100 and ≥101 API levels) is on the roadmap. Root required (LSPosed needs it); no separate KSU/Magisk module. |
- Download the latest APK from releases
- In LSPosed, enable Orchestra and set its scope to: System UI + Settings + Orchestra (itself), then restart System UI (or reboot).
- Open the Orchestra app → Devices tab → toggle a paired Soundcore device on ("hook" it).
- Open Settings → Connected devices → <your headphones> → gear (About device) once. The native control page now shows Orchestra's controls.
The app's Status tab tells you at a glance whether the module is active (and at what LSPosed API level), whether Bluetooth is on, and how many devices are hooked.
Which headphones are supported is defined by manifests, not by the app. Each device is a JSON
manifest in the catalog repo — orchestra-manifests —
and the app discovers them at runtime: it matches your paired devices against the catalog index,
highlights the eligible ones, and downloads their manifest when you hook one. Adding a model is writing
a manifest, not changing the app (see Developing a manifest below).
Currently shipped + hardware-verified:
| Device | Model | Controls verified |
|---|---|---|
| Soundcore Space One Pro | A3062 | 4-mode ANC (Noise Cancelling / Off / Adaptive / Transparency) + Dolby Audio, Surrounding sounds, Side tone, Multipoint, Low-battery prompt switches |
| Soundcore Liberty 4 Pro | A3957 | 3-mode ANC (Noise Cancelling / Off / Transparency) + native TWS battery (L / Case / R) |
| Shokz OpenSwim Pro | S180 | Equalizer (Standard / Vocal / Swimming), Multipoint, MP3↔Bluetooth mode, MP3 shuffle, universal-button & volume-long-press actions (MP3 transport + volume are in-app). Bone-conduction; shokz_v1 framing over RFCOMM. State is write-only/optimistic. |
| AirPods Pro 2 | A3048 | 4-mode Noise Control (Off / ANC / Transparency / Adaptive), Conversational Awareness toggle, live per-bud + case battery on the native header, ear detection (in-app), background auto-pause on ear removal, CA volume-duck (gradual fade), Adaptive Audio strength (in-app 0–100 slider, active while Noise Control = Adaptive), Rename (in-app, sets the local Bluetooth alias) |
Each manifest also catalogues further
controls that ship disabled until their command bytes are hardware-confirmed (_verified: false).
A control shipped _verified: false must be opted in per device in the app's Devices tab
before its About-page toggle appears; verified controls inject automatically. The live, authoritative
device list is the catalog index in the manifests repo.
Orchestra impersonates Android's device-settings framework (the same settingslib mechanism Pixel
Buds use):
- An LSPosed hook in Settings writes the privileged
BluetoothDevicemetadata key 25, pointing the system at Orchestra's config provider service. - Provider services (
ConfigProviderService/SettingProviderService) return the About-page layout and serve/handle each control, with optimistic UI and a persistent control socket. - A transport-abstraction registry (
ControlEngine) selects the per-device engine — by a channel'sprotocol.framingwhen set, else its transport:RfcommEngineframes the Soundcore protocol (soundcore_v1) over RFCOMM;ShokzEnginereplays the Shokzshokz_v1binary-TLV frames over the same RFCOMM/SPP socket;AacpEnginespeaks Apple's Accessory Protocol over an L2CAP socket (PSM 4097) for AirPods.ble_gattis the remaining reserved slot. - An LSPosed hook in System UI forces the volume-panel Noise-Control tile available and routes its taps to our provider, so the ANC tile renders there too (for the active-output headphone).
Deeper design lives in docs/ARCHITECTURE.md.
Every supported device is one JSON manifest (schema v3). A manifest declares:
match— how to recognise the device (name regex / advertised UUIDs / model prefix).channels— named transport + protocol bundles (rfcommandaacpare live;ble_gattis a reserved slot) with adefault_channel.functions[]— the full reverse-engineered capability catalogue. Each function has a UItype(multitoggle/toggle/list/slider/info), its set/read command bytes, conflicts / dependencies, an injectability verdict, and a_verifiedflag (only hardware-confirmed controls inject by default).platforms— optional per-ROM injection bindings (currentlypixelos), so the same manifest can target other root+LSPosed-capable ROMs later.- Versioning —
schema_version(a hard compatibility gate) + a monotonicrevision(bump on any edit, drives OTA updates).
The app graceful-degrades: a function whose transport, render type, or surface the running build
can't handle is skipped, never crashing the page. The full field reference is
orchestra-manifests/schema/SCHEMA.md;
per-device protocol notes are in docs/devices/.
Device manifests live in a dedicated repository — orchestra-manifests —
organised by manufacturer, with a CI-generated index.json (a freshness gate fails any PR whose
index is stale).
The app uses that repo at runtime:
- It bundles a seed of the manifests + index in
assets/so it works offline on first run. - On launch it refreshes the index (12 h TTL) and highlights bonded devices that are eligible for hooking.
- It downloads / updates a device's manifest over HTTPS from the repo's raw URL, sha256-verified
against the index and gated by
revision. - You can sideload your own manifest from a file for testing — it takes highest precedence, is badged local / testing, and exposes all of its controls (bypassing the verified-default gate).
- Clone
orchestra-manifestsandnpm install. - Copy an existing manifest under
manifests/<manufacturer-slug>/to<your-device-id>.json. - Fill in
match, thechannels, and thefunctions[]capability list. Source command bytes from reverse-engineering references (e.g. OpenSCQ30) and mark every function_verified: falseuntil you've confirmed it live on the hardware. - Test on-device without rebuilding the app: drop the JSON on the phone and load it via the app's
debug → "Load manifest from file" (sideload). Confirmed controls → flip them to
_verified: true. - Bump
revision(andrevision_date), runnpm run build-index, and commit both the manifest and the regeneratedindex.json(CI enforces this). - Open a PR. See
schema/SCHEMA.mdfor the full schema andREADME.mdin that repo for the authoring workflow.
- A per-device in-app control screen (tap an AirPods device card in the Devices tab) renders
slider/levelandtextfunctions that can't be injected into the native About page — e.g. AirPods Pro 2's Adaptive Audio strength slider and Rename field, plus live battery/ear rows. A control shipped_verified: falsestill needs the Devices-tab opt-in before it appears here.list/ composite controls (EQ bands…) aren't covered by this screen yet. - "Act as Apple device" (AirPods, Devices tab — default off) trades media buttons for handoff, by design. When on, Orchestra spoofs the AirPods' Bluetooth Device-ID as Apple's, so the buds treat the Pixel as an Apple device — enabling Apple-style stay-multipoint and seamless audio handoff (e.g. Mac ↔ Pixel, the "Move to iPhone"-style switch). The catch is a firmware tradeoff, not an Orchestra bug: while spoofing, the buds route stem presses through Apple's protocol, so the Pixel's play / pause / next / previous stop working. Recovering them means telling the buds to hand their presses to the Pixel (a "takeover"), which makes the firmware treat the Pixel as its sole host and drop multipoint entirely — hardware-confirmed down to even a single-press takeover, and LibrePods hits the same wall (it, too, leaves default media presses to the standard path rather than taking them over). So it's one or the other: on → handoff + multipoint, no media buttons; off → media buttons + standard multipoint, no Apple handoff. (Long-press to cycle ANC keeps working either way — it's bud-native.)
Orchestra is an unofficial project, not affiliated with Google, Apple or Anker/Soundcore. It sends control frames to your own headphones; some protocol bytes are reverse-engineered and unverified controls are opt-in. Use at your own risk.
OpenSCQ30
GalaxyBudsClient
librepods
Licensed under GPL-3.0 — see LICENSE.