Is the Android overlay pal part of v1? #47

Closed
opened 2026-07-30 13:15:05 +00:00 by aiko · 2 comments
Owner

Question

denpa#23 built a Kotlin overlay service that reparents the app's own WebView,
so one Android app switches between an overlay pal and the full receiver. It
compiles. It has never run on a device, and an Opus review raised 15 findings
against it.

v1's destination is the conversation works on desktop, tablet and phone. Is the
overlay one of the ways a conversation happens, or is it a mode that can wait?

The cost of keeping it is not just #23's own verification: its foreground
service is what makes the RECORD_AUDIO question in #35 and the
MediaProjection question in #36 collide in one process. Dropping it from v1
simplifies both.

The cost of dropping it is that #23 is already merged, so "not v1" means
deciding what happens to shipped-but-unverified code.

  • denpa#23, denpa#35, denpa#36

Map: aiko/denpa#41

## Question `denpa#23` built a Kotlin overlay service that reparents the app's own WebView, so one Android app switches between an overlay pal and the full receiver. It compiles. It has **never run on a device**, and an Opus review raised 15 findings against it. v1's destination is *the conversation works* on desktop, tablet and phone. Is the overlay one of the ways a conversation happens, or is it a mode that can wait? The cost of keeping it is not just `#23`'s own verification: its foreground service is what makes the `RECORD_AUDIO` question in `#35` and the `MediaProjection` question in `#36` collide in one process. Dropping it from v1 simplifies both. The cost of dropping it is that `#23` is already merged, so "not v1" means deciding what happens to shipped-but-unverified code. ## Related - `denpa#23`, `denpa#35`, `denpa#36` --- Map: `aiko/denpa#41`
Author
Owner

Bearing on this decision, from #44:

The overlay's foreground service does not help microphone access — it costs. SYSTEM_ALERT_WINDOW exempts an app from the FGS background-start restriction only; it is not on the while-in-use exemption list. So a running overlay FGS cannot start or promote to a microphone-typed FGS from the background — Android requires a visible activity, not a visible overlay window, and Android 15+ narrows the exemption further.

Workable shape if the overlay stays in v1: one service carrying specialUse|microphone, promoted by a second startForeground() at a moment when a real activity is visible. That is a real design constraint on the overlay, not a detail.

This removes the argument that the overlay's existing service is a shared asset the mic path can lean on.

Bearing on this decision, from [#44](https://git.aiko.works/aiko/denpa/issues/44): **The overlay's foreground service does not help microphone access — it costs.** `SYSTEM_ALERT_WINDOW` exempts an app from the FGS *background-start* restriction only; it is **not** on the while-in-use exemption list. So a running overlay FGS cannot start or promote to a `microphone`-typed FGS from the background — Android requires a visible **activity**, not a visible overlay window, and Android 15+ narrows the exemption further. Workable shape if the overlay stays in v1: one service carrying `specialUse|microphone`, promoted by a second `startForeground()` at a moment when a real activity is visible. That is a real design constraint on the overlay, not a detail. This removes the argument that the overlay's existing service is a shared asset the mic path can lean on.
aiko self-assigned this 2026-07-30 13:53:51 +00:00
Author
Owner

Resolution

No. The overlay pal is v2. The full receiver is the only Android surface in v1, on both the phone and the tablet. #23's Kotlin stays in the tree but its service stops being started.

Why

The structural argument for keeping it did not survive #44. The case for the overlay being cheap was that it already runs a foreground service, so the microphone path could lean on it. It cannot: SYSTEM_ALERT_WINDOW exempts an app from the FGS background-start restriction only, and is not on the while-in-use exemption list. A running overlay service cannot start or promote to a microphone-typed service from the background — Android requires a visible activity, not a visible overlay window, and Android 15+ narrows the exemption further. The phone now attached runs Android 17 (SDK 37), newer than anything that research covered, and every release since 14 has tightened these rules.

So the overlay was never a shared asset. It was a second foreground service competing for the same process, and dropping it removes a whole design problem from #43 (the audio boundary), #35 (the Android capture path) and #45 (MediaProjection) simultaneously.

And it is the weakest-evidenced thing on the board. #23 compiles, has never run on a device, and carries 15 unaddressed review findings. v1's proof is a real conversation on three surfaces; the overlay is a second way of being present, not a way of having a conversation.

The consequence, stated plainly

#23 is merged into main at 19bf953. "Not v1" does not delete it — it leaves shipped, unverified code in the tree that nothing reaches. That is the same shape as denpa#27's listener with no producer, and it is a real cost, accepted deliberately here rather than discovered later. The mitigation is that it must be unreachable on purpose and say so, not merely unused: the service is not started, and the reason is written where the next reader will find it.

Chosen over reverting it out of main because the code was never proven to work either way, so a revert buys honesty in the history at the price of a re-apply later against nothing verified.

What this hands the rest of the map

  • #43 — the audio boundary no longer has to accommodate an overlay service. One capture owner, one lifecycle, promoted from a visible activity.
  • #45 — the MediaProjection question loses its "second service type on an existing service" wrinkle.
  • #35/#36 — the Android halves get simpler; the RECORD_AUDIO × startForeground reasoning #23 had to do does not carry forward.

Filed as work on denpa#23, which is relabelled v2 and now carries the disable.

## Resolution **No. The overlay pal is v2.** The full receiver is the only Android surface in v1, on both the phone and the tablet. `#23`'s Kotlin stays in the tree but its service stops being started. ### Why **The structural argument for keeping it did not survive [#44](https://git.aiko.works/aiko/denpa/issues/44).** The case for the overlay being cheap was that it already runs a foreground service, so the microphone path could lean on it. It cannot: `SYSTEM_ALERT_WINDOW` exempts an app from the FGS *background-start* restriction only, and is **not** on the while-in-use exemption list. A running overlay service cannot start or promote to a `microphone`-typed service from the background — Android requires a visible **activity**, not a visible overlay window, and Android 15+ narrows the exemption further. The phone now attached runs **Android 17 (SDK 37)**, newer than anything that research covered, and every release since 14 has tightened these rules. So the overlay was never a shared asset. It was a second foreground service competing for the same process, and dropping it removes a whole design problem from [#43](https://git.aiko.works/aiko/denpa/issues/43) (the audio boundary), `#35` (the Android capture path) and [#45](https://git.aiko.works/aiko/denpa/issues/45) (`MediaProjection`) simultaneously. **And it is the weakest-evidenced thing on the board.** `#23` compiles, has never run on a device, and carries 15 unaddressed review findings. v1's proof is a real conversation on three surfaces; the overlay is a second way of being present, not a way of having a conversation. ### The consequence, stated plainly `#23` is merged into `main` at `19bf953`. "Not v1" does not delete it — it leaves shipped, unverified code in the tree that nothing reaches. That is the same shape as `denpa#27`'s listener with no producer, and it is a real cost, accepted deliberately here rather than discovered later. The mitigation is that it must be **unreachable on purpose and say so**, not merely unused: the service is not started, and the reason is written where the next reader will find it. Chosen over reverting it out of `main` because the code was never proven to work either way, so a revert buys honesty in the history at the price of a re-apply later against nothing verified. ### What this hands the rest of the map - **`#43`** — the audio boundary no longer has to accommodate an overlay service. One capture owner, one lifecycle, promoted from a visible activity. - **`#45`** — the `MediaProjection` question loses its "second service type on an existing service" wrinkle. - **`#35`/`#36`** — the Android halves get simpler; the `RECORD_AUDIO` × `startForeground` reasoning `#23` had to do does not carry forward. Filed as work on [`denpa#23`](https://git.aiko.works/aiko/denpa/issues/23), which is relabelled `v2` and now carries the disable.
aiko closed this issue 2026-07-30 13:58:58 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiko/denpa#47
No description provided.