# ICAS Technical Specification
## Independent Concurrent Audio Streams

**Version:** 1.3  
**License:** MIT — Copyright (c) 2026 Kris Ledel  
**Status:** Concept specification with implementation constraints  
**Scope:** Android host stack (AOSP / custom ROM) over Bluetooth LE Audio unicast  
**Date:** 2026-09-20  
**Validation:** The feasibility gate in §18 has not passed on named hardware. This document remains a concept specification until that gate passes.

---

## 1. Purpose

Enable a single Android source device to keep multiple concurrent Bluetooth LE Audio unicast streams with *independent content*, so that:

- Media can render on device A
- Telephony, navigation, or other communication can render on device B
- One stream is not silently torn down because the other became active

ICAS is a **host, policy, audio-path, and focus specification**. It does not define a new radio PHY or a new Bluetooth core transport.

Shipping AOSP treats one LE Audio *group* as the active audio path. Switching the active group stops the previous group. Shared audio-client and codec/HAL state follows that single-owner model. Preferred devices alone do not create a second complete path through LeAudioService, the Bluetooth HAL, and the audio HAL.

---

## 2. Document type

This document defines the concept, requirements, and implementation sequence subject to feasibility testing.

Do not start P1 policy patches until §18 (feasibility gate) has produced:

- one named phone
- one pinned AOSP / Lineage revision
- two distinguishable test signals playing at the same time on two LE Audio sinks
- a written account of CIS count, CIG layout, HAL/offload assumptions, and whether two groups can stay streaming

Concurrent-group operation remains unvalidated until these results are available.

---

## 3. Non-goals (initial deliverable)

- New Bluetooth radio mechanism
- Bluetooth SIG New Work Proposal as first deliverable
- Classic A2DP + HFP coexistence (Tesla-class kits)
- Spatial / HRTF rendering
- Auracast / same-content broadcast
- Unprivileged Play Store app on stock OEM phones
- Support through strategy preferred-device APIs alone

Classic Bluetooth is outside the initial deliverable.

---

## 4. Problem statement

LE Audio allows multiple CIS and multiple ASEs. Android has strategy routing APIs and combined device routing (Android 12+).

Shipping stacks do not compose those into independent-content streams:

1. `LeAudioService` / native LE Audio keep a single `active_group_id_`. Setting a new active group stops the previous group's stream, then configures the new group.
2. Audio framework and Bluetooth audio HAL expose a shared client / configuration path sized for one active LE Audio session.
3. Call setup sets `A2dpSuspended` / `LeAudioSuspended`.
4. Audio focus and incoming-call mute can silence media even if the Bluetooth stream object still exists.
5. Controllers admit only a small number of concurrent CIS. A TWS pair already consumes one CIS per ear.

These constraints prevent reliable concurrent music playback on headphones and call or navigation playback on another LE Audio sink.

---

## 5. Definitions

| Term | Meaning |
|------|---------|
| CIS | Connected Isochronous Stream. Point-to-point isochronous transport. |
| CIG | Connected Isochronous Group. Every CIS belongs to exactly one CIG. A CIG may contain one CIS or many. A CIG supplies a common timing reference. It does **not** require identical content. |
| ASE | Audio Stream Endpoint (BAP / ASCS). |
| Stream | One enabled ASE bound to one CIS (and therefore to that CIS's CIG). |
| Independent stream | Stream whose payload is not a copy of another stream. |
| Session | OS audio session (usage, content type, source). |
| Strategy | AudioPolicy class such as MEDIA, PHONE, SONIFICATION. |
| Context | LE Audio Audio Context bitfield (Media, Conversational, …). |
| LE Audio group | Android/Fluoride grouping of devices (often a CSIP Coordinated Set). Current code allows one active group. |
| Independent Stream Group (ISG) | Host-side policy grouping of streams that must stay concurrently owned. Not a Core term. |
| Coordinated Set | CAP/CSIP set (typical TWS). One *logical* sink to the user. Multiple CIS on the air. |
| Complete audio path | App/mixer → AudioPolicy → audio HAL → Bluetooth audio HAL / offload → CIS → sink render. |

---

## 6. Requirements

### 6.1 Functional

**R1 — Independent unicast streams**  
When feasibility is proven on the target controller, the host shall keep two complete audio paths active to two different LE Audio sinks (or sink groups) with different content.

**R2 — Concurrent group ownership**  
The host shall be able to own more than one streaming LE Audio group at a time. Activating group B shall not imply `GroupStop` / stream teardown of group A.

**R3 — Separate codec and HAL paths**  
Each concurrent stream shall have distinct configuration and data-path state through LeAudio native, Bluetooth audio HAL, and audio HAL. Shared singleton session state does not meet this requirement.

**R4 — Context coexistence**  
Enabling a Conversational stream shall not require release of a Media stream unless an acceptor withdraws availability or admission fails.

**R5 — Session-to-stream mapping**  
The host shall map sessions to streams by strategy and/or explicit policy.

**R6 — CIG usage**  
Every CIS belongs to a CIG. ICAS shall assign CIGs explicitly:

- Coordinated Set (TWS): one CIG containing the set's CIS members (shared timing, typically related channels of one mix).
- Independent content to unrelated sinks: **separate CIGs** as the default design choice, so ISO intervals and QoS can differ. Same-CIG independent content is allowed by Core but is not the ICAS default.

CIG membership is a timing/scheduling choice, not a content-identity rule.

**R7 — Admission with a complete outcome**  
If a new stream cannot be admitted, the host shall apply §11 and produce a user-visible, logged, recoverable outcome.

**R8 — Bidirectional sessions**  
A communication session may use sink ASE and source ASE on different devices. Uplink device is mandatory and explicit.

**R9 — Audio focus and call mute**  
ICAS shall define focus, ducking, and incoming-call mute when outputs differ. A live CIS is not sufficient if the media app is paused or the framework mutes `USAGE_MEDIA` / `USAGE_GAME` during a call.

**R10 — Per-stream volume**  
Each independent stream has independent volume (VCP on the acceptor, else host attenuation).

**R11 — Backward compatibility**  
With ICAS disabled, behavior equals current AOSP: one active group, call suspends media.

**R12 — Resource accounting**  
Admission counts **CIS**, not logical sinks. A stereo TWS pair is one logical sink and typically two CIS.

### 6.2 Non-functional

- No regression for single headset or TWS Coordinated Sets when ICAS is off, and no regression of TWS sync when ICAS is on and the pair is one logical sink.
- No silent mid-stream teardown without a logged ICAS reason code.
- Feature gated by system property / developer option.
- Validation results apply only to the tested hardware.

---

## 7. Architecture

```
App AudioTrack / Telecom
        │
        ▼
Audio focus + ICAS focus policy
        │
        ▼
AudioPolicy / AudioService
  - strategy → device
  - admission (§11)
        │
        ▼
LeAudioService + native
  - concurrent group ownership
  - per-group stream state
        │
        ▼
Audio HAL + Bluetooth audio HAL / offload
  - one data path per concurrent stream
        │
        ▼
Controller ISO scheduler
  - CIS in CIGs (every CIS has a CIG)
        │
        ▼
Sink A (MEDIA)                 Sink B (CALL ± uplink)
```

Preferred-device APIs are the *policy input*. They do not construct the second path.

---

## 8. Host mapping

| Android usage / strategy | LE Audio Context | Default ICAS path |
|--------------------------|------------------|-------------------|
| USAGE_MEDIA, GAME, MOVIE | Media | Stream MEDIA |
| USAGE_VOICE_COMMUNICATION, INCALL | Conversational | Stream CALL |
| USAGE_ASSISTANCE_NAVIGATION_GUIDANCE | configurable | CALL if a car/comms device is selected, else MEDIA |
| USAGE_NOTIFICATION, ALARM, RINGTONE | Ringtone / Notifications | CALL device if present, else default |

ICAS intent:

```
STRATEGY_MEDIA device ≠ STRATEGY_PHONE device
⇒ request two complete paths, then admit or apply §11
```

Same-content fan-out (Dual Audio / sharing / combined routing of one mix) is a different mode and must not be reused as a substitute for independent content.

---

## 9. Audio focus

Keeping a Bluetooth stream alive does not keep media audible.

Current platform behavior that ICAS must override or wrap when outputs differ:

- Apps receive `AUDIOFOCUS_LOSS` / `AUDIOFOCUS_LOSS_TRANSIENT` on call and often pause.
- From Android 12 the system can force fade-out on focus loss.
- Incoming cellular call can mute `USAGE_MEDIA` and `USAGE_GAME` players that already hold focus.
- `AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK` ducks rather than pauses; many media apps still pause.

### 9.1 ICAS focus policy when MEDIA and CALL devices differ

| Event | Media path (device A) | Call path (device B) |
|-------|------------------------|----------------------|
| Call starts, admission OK | Default: **no duck, no pause**. Duck on A only if user policy requires it. | Call audio + explicit uplink |
| Call starts, admission FAIL | Apply §11. If call takes B and media cannot stay on A, pause media with an explicit ICAS reason, not a generic focus loss. | Call proceeds on B or handset per §11 |
| Navigation prompt on B | Duck or pause A only if both would be heard by the same listener; default no pause when devices differ | Prompt on B |
| User starts media during an active call | Allowed on A if admission OK. Retain A as the media destination. | Unchanged |

### 9.2 Implementation consequence

Focus policy requires AudioService / Telecom / InCallUi cooperation or an ICAS-specific focus owner that:

- requests call focus without causing media on the other device to pause
- suppresses incoming-call mute for MEDIA players routed to a different device
- documents that some apps will still pause themselves; those apps are out of host control unless they honor a new contract

Implement this policy in **P3**, after a dual-render path exists.

---

## 10. Transport: CIG and CIS

### 10.1 Core facts

- Every CIS belongs to a CIG.
- A CIG may contain a single CIS.
- Multiple CIS in one CIG share ISO_Interval and a common timing reference. Content may still differ (Core example: different languages).
- All CIS in a CIG share the same Central and the same framed/FT configuration constraints.

### 10.2 ICAS default

| Situation | CIG layout |
|-----------|------------|
| TWS / Coordinated Set, one mix | One CIG, one CIS per member as required by the set |
| Independent content, unrelated sinks | Two CIGs (CIG_MEDIA, CIG_CALL), each typically one CIS unless the sink itself is a set |
| Same sink, media + mic | Still one device; CIS count depends on sink/source ASEs |

Separate CIGs are chosen so media and call can use different ISO intervals and QoS. They are not required merely because content differs.

### 10.3 Establishment sketch (after concurrent groups exist)

```
Connect sink A, sink B
Discover PACS / Available Contexts

MEDIA:
  Config Codec / QoS on A's sink ASE
  HCI_LE_Set_CIG_Parameters (CIG_ID = MEDIA)
  HCI_LE_Create_CIS
  Enable ASE, Streaming_Audio_Contexts = Media

CALL:
  Config Codec / QoS on B's sink ASE and source ASE if uplink is B
  HCI_LE_Set_CIG_Parameters (CIG_ID = CALL)
  HCI_LE_Create_CIS
  Enable ASE, Streaming_Audio_Contexts = Conversational
```

If uplink is the phone microphone, CALL needs a downlink CIS to B and no CIS on A for the microphone.

---

## 11. Admission and complete outcomes

Before stream N+1, estimate:

- Remaining CIS budget (TWS pair uses two if both ears have CIS)
- ISO-interval collision across CIGs
- ACL + scan + retransmission budget
- HAL/offload session slots (may be 1 even when the controller has 2+ CIS)

### 11.1 Priority

```
active CALL > incoming CALL > MEDIA > navigation-as-media > notifications
```

### 11.2 Required outcomes

**Case A — Media playing on A, incoming call, both fit (after optional MEDIA bitrate downshift)**  
Admit CALL on B. Keep MEDIA on A. Apply §9 focus policy (default: media keeps playing).

**Case B — Media playing on A, incoming call, cannot fit even after MEDIA downshift**  
Must pick one, in this order unless user policy overrides:

1. Place CALL audio + uplink on the **handset** (speaker + built-in mic). Keep MEDIA on A.
2. If the user has locked calls to device B (car), **pause MEDIA** with reason `ICAS_ADMISSION_PREEMPT_MEDIA_FOR_CALL`, move CALL to B, and restore MEDIA when the call ends if A is still available.
3. Never drop an **active** CALL to admit MEDIA.

**Case C — Call already active on B, new MEDIA cannot fit**  
Reject MEDIA (`ICAS_ADMISSION_DENIED_CALL_HOLDS_RADIO`). Call unchanged. User-visible: media stays on speaker or fails to route to A.

**Case D — Notifications / ringtone**  
Prefer B if present. If no CIS left, use handset. Never preempt CALL.

Every branch sets an `ICAS_REASON_*` code, log line, and (for user-visible cases) a status the System UI can show.

### 11.3 TWS accounting

Treat a Coordinated Set as one logical sink in UI and strategy mapping.  
Treat it as **N CIS** in admission, where N is the number of CIS the set actually uses (commonly 2).

---

## 12. Microphone / uplink

Illegal state: CALL downlink to B with no designated uplink.

Default:

1. If B exposes a source ASE and the user chose B as communication device → uplink B
2. Else phone built-in mic
3. Never silently use A's headset mic for a call that renders on B

Uplink device is stored on the CALL session and included in T8–T10 tests.

---

## 13. AOSP constraints

Representative AOSP LE Audio behavior:

- Java `LeAudioService.setActiveGroupWithDevice()` calls `groupSetActive(groupId)`
- Native layer keeps `active_group_id_`
- On group switch: stop previous group stream, configure the new group
- Public docs: one connected LE Audio set as the active audio device at a time
- Audio HAL / offload often assume one LE Audio configuration at a time

Concurrent rendering on two preferred devices requires the following supporting changes:

1. Concurrent `streaming` groups in native LE Audio (or an equivalent multi-session object)
2. Per-group codec, QoS, and ISO state
3. Two live data paths in Bluetooth audio HAL and audio HAL (or proven host-encode of the second path)
4. AudioPolicy mixPorts that can feed those two paths at once

These changes are prerequisites for R1.

---

## 14. Feature flags

```
persist.bluetooth.icas.enabled=true
persist.bluetooth.icas.allow_concurrent_media_call=true
persist.bluetooth.icas.focus.keep_media_on_other_device=true
```

Default all false. Disabled behavior = stock AOSP.

---

## 15. Implementation sequence (after feasibility)

**G0 — Feasibility gate (§18)**  
Mandatory. No policy patch is in scope until G0 passes or its failure on the target phone is documented.

**P0 — Instrumentation**  
Log `active_group_id_`, group stop/start, `LeAudioSuspended`, HAL session create/release, focus gain/loss, incoming-call mute.

**P1 — Dual render path (media + media)**  
First engineering milestone: two independent MEDIA-like signals to two sinks, without telephony.

**P2 — Concurrent group + HAL ownership**  
Replace single `active_group_id_` with a multi-session model. Prove two paths survive group operations.

**P3 — Focus policy**  
§9. Incoming-call mute exemption when devices differ.

**P4 — Communication audio**  
VoIP first (app-driven uplink/downlink), then cellular Telecom path.

**P5 — Admission engine**  
§11 complete outcomes, TWS CIS counting, bitrate downshift.

**P6 — Volume and recovery**  
Per-stream VCP/host volume; disconnect and failed-admission recovery.

Changes to `LeAudioSuspended` behavior are deferred until P1 provides dual rendering. Disabling suspension without a second path creates undefined HAL state.

---

## 16. Tests

### 16.1 Bind tests to hardware

Record in the test report:

- Phone model and SoC / BT controller
- AOSP or Lineage revision SHA
- Two sink models
- HCI snoop file id

### 16.2 Cases

| ID | Setup | Expected |
|----|--------|----------|
| T0 | G0 feasibility | Controller + HAL can or cannot keep ≥2 CIS in two CIGs under load. Written result. |
| T1 | Media → A | A plays, B silent |
| T2 | Call → B only | B plays, A silent; uplink defined |
| T3 | Two distinguishable tones → A and B | Both render different signals ≥30 s, no unexpected ASE Release |
| T3b | Repeat T3 across 10 connect cycles | Same |
| T4 | ICAS off, media A + call B | Stock AOSP: media suspended or group stopped |
| T5 | Call ends after T3/T8 | Media on A continues |
| T6 | Admission fail, call incoming | Outcome is exactly one of §11 Case B.1 or B.2 |
| T7 | TWS as logical A | UI: one sink. Admission: N CIS. Sync inside the set preserved |
| T8 | Media A + VoIP B | Different content; uplink on recorded device |
| T9 | Media A + cellular call | Focus policy §9; media not generically muted if on A and call on B and admission OK |
| T10 | Mic: call on B, uplink phone vs B | Only the chosen uplink is active |
| T11 | Independent volume | Changing VCP/host volume on A does not change B |
| T12 | Disconnect A during dual | B continues; MEDIA recovers or fails with reason |
| T13 | Failed-admission recovery | After call ends, MEDIA can return to A without reboot |

G0 and T3 provide initial public evidence. T8–T13 must also pass before concurrent call and media playback can be considered implementable.

---

## 17. Compliance

- Coordinated Set default behavior unchanged for CSIP sets.
- Auracast unchanged.
- OEM Dual Audio / sharing: document collisions; do not silently reuse those paths for independent content.
- Concurrent groups require a compatibility mechanism for the public `BluetoothLeAudio` “one active set” contract, such as a new API or hidden multi-session support.

---

## 18. Feasibility gate

The following constraints must be resolved before proceeding.

| ID | Question | Fail means |
|----|----------|------------|
| F1 | How many concurrent CIS does this phone’s controller sustain in two CIGs with different ISO intervals, while ACL and scanning continue? | Validation on this phone is limited to software routing |
| F2 | Does vendor BT HAL / DSP offload support two encode/decode sessions, or only one? | The second path requires host encoding; otherwise implementation cannot proceed |
| F3 | Can native LE Audio be changed to two streaming groups without stopping the first, on this revision? | Preferred-device settings cannot enable concurrent groups |
| F4 | Do OEM overlays re-assert suspend/focus mute? | Suspend and focus policy require changes beyond feature flags |

G0 procedure:

1. Pin phone + AOSP SHA.
2. Enable HCI snoop.
3. Attempt two CIGs / two CIS with two test tones (T3), even if via debug hooks rather than product policy.
4. Write F1–F4 answers with traces.
5. Only then schedule P2–P6.

---

## 19. First milestone

**Milestone M1**

- Named phone
- Pinned AOSP/Lineage revision
- Two LE Audio sinks
- Two distinguishable test signals (e.g. 440 Hz on A, 880 Hz on B) rendering simultaneously for ≥30 s
- HCI log showing two CIS, CIG IDs recorded
- Short report: F1–F3

Then add communication audio, focus, and cellular calls.

Establish the complete audio paths before changing suspension policy or relying on preferred-device settings.

---

## 20. Classic Bluetooth appendix

Classic Bluetooth is outside the initial deliverable. A2DP + HFP on one controller generally cannot carry independent high-quality media and a call. AAOS multi-zone provides prior art for independent audio zones inside a vehicle rather than phone-as-source ICAS.

---

## 21. Decision record

| Decision | Choice |
|----------|--------|
| Document type | Concept spec + feasibility-gated sequence |
| Primary platform | AOSP / custom ROM |
| Transport | LE Audio unicast |
| CIG | Always present; separate CIGs default for independent sinks |
| First milestone | Dual test tones on two sinks (M1 / T3) |
| Call/media | After M1, with focus policy and §11 outcomes |
| Classic / Tesla | Out of initial deliverable |
| TWS | One logical sink, N CIS for admission |

---

## 22. Revision history

| Ver | Change |
|-----|--------|
| 1.2 | Initial host/policy spec |
| 1.3 | Concurrent groups and HAL paths; audio focus; corrected CIG model; complete admission outcomes; TWS CIS accounting; feasibility gate; M1 dual-tone milestone; expanded tests |
