AXP Magisk resurrection track: Speckit 009 port AXP/LOS22 to LOS23.

Ship Magisk like GOLDEN; KernelSU optional recycle only; parallel to sunfish-a16-rom standby.
This commit is contained in:
sunfish-admin committed 2026-09-16 21:56:22 +00:00
commit 12d2179c20
150 files changed
+26263

No files matched your search

@@ -0,0 +1,27 @@
# Specification Quality Checklist: Call recording + FLAG_SECURE
**Purpose**: Validate specification completeness before planning
**Created**: 2026-09-16
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation-only jargon in Success Criteria
- [x] Requirements are testable
- [x] Scope (global toggles only) is explicit
- [x] Non-goals documented
- [x] LAB-only constraint present
## Completeness
- [x] User stories cover call-rec and FLAG_SECURE
- [x] Secure setting names proposed
- [x] Default OFF behaviour stated
- [x] EXTENDROM / AXP GOLDEN call-rec references noted in design doc
- [x] FLAG_SECURE scope is global only (per-app not planned)
## Notes
Ready for `/speckit-plan` when owner starts implementation on `rom-dev01`.
Investigate Dialer gate on LOS 23.2 before coding call-rec (A15 EXTENDROM
overlay dirs were empty; A11 is reference only).
@@ -0,0 +1,32 @@
# Contract: Call recording surface
**Feature**: `008-call-rec-flag-secure`
**Consumers**: LAB validation (`quickstart.md`)
## Secure setting
| Item | Value |
|------|--------|
| Key | `Settings.Secure.extendrom_call_recording` |
| Values | `null`/`0` = stock country rules; `1` = ignore country deny |
| Readback | `adb shell settings get secure extendrom_call_recording` |
| Write | Developer Options switch or `settings put secure … 0\|1` |
## Dialer behaviour
| Condition | Expected |
|-----------|----------|
| Feature off / setting `0` | `CallRecorder.canRecordInCurrentCountry()` uses `call_record_states.xml` |
| Setting `1` and recording enabled | `canRecordInCurrentCountry()` true → record control available |
| `call_recording_enabled` false | Still disabled (override does not invent recording capability) |
## UI
- Developer Options entry with legal responsibility summary (EXTENDROM-style).
- Reset to `0` when Developer Options master is disabled.
## Evidence
- Setting readback 0/1.
- In-call record start with setting `1` produces a file; note path under
`/srv/rom/artifacts/008-call-rec-flag-secure/call-rec/`.
@@ -0,0 +1,34 @@
# Contract: FLAG_SECURE / screenshot surface
**Feature**: `008-call-rec-flag-secure`
**Consumers**: LAB validation (`quickstart.md`)
## Secure setting
| Item | Value |
|------|--------|
| Key | `Settings.Secure.disable_secure_windows` (AOSP `DISABLE_SECURE_WINDOWS`) |
| Values | `null`/`0` = stock `FLAG_SECURE`; `1` = global capture override |
| Readback | `adb shell settings get secure disable_secure_windows` |
| UI preference key | `allow_flag_secure_override` (writes the Secure key above) |
| Scope | **Global** (all apps); per-app lists not planned |
| Note | WMS only applies this on **debuggable** builds (`ro.debuggable`) |
## Capture behaviour
| Condition | Expected |
|-----------|----------|
| Setting `0`, secure window | System screenshot / screen record blocked as stock |
| Setting `1`, same window | System screenshot / screen record succeeds |
| Setting `1`, DRM/HW buffer edge cases | May still fail — document if observed |
## UI
- Developer Options switch; short summary that this weakens app privacy.
- Reset to `0` when Developer Options master is disabled.
## Evidence
- Setting readback 0/1.
- Before/after screenshots (or failure toast) stored under
`/srv/rom/artifacts/008-call-rec-flag-secure/flag-secure/`.
@@ -0,0 +1,52 @@
# Data model: `008-call-rec-flag-secure`
## Entities
### SecureSettingCallRec
| Field | Type | Rules |
|-------|------|--------|
| key | string | `extendrom_call_recording` |
| value | int | `0` (default) or `1` |
| namespace | Secure | `Settings.Secure` |
**Transitions**: DO switch ON → `1`; OFF → `0`; Developer Options master
disabled → force `0`.
### SecureSettingFlagSecure
| Field | Type | Rules |
|-------|------|--------|
| key | string | `disable_secure_windows` (DO pref `allow_flag_secure_override`) |
| value | int | `0` (default) or `1` |
| namespace | Secure | `Settings.Secure` |
**Transitions**: same as call-rec.
### DialerCountryPolicy
| Field | Type | Rules |
|-------|------|--------|
| iso | string | ISO country from `GeoUtil.getCurrentCountryIso` |
| allowed | bool | from `call_record_states.xml` unless override ON |
**Effective allow** =
`CallRecorderService.isEnabled(context)` AND
(`extendrom_call_recording == 1` OR country map allows iso).
### CapturePolicy
| Field | Type | Rules |
|-------|------|--------|
| windowSecure | bool | app set `FLAG_SECURE` |
| override | bool | `disable_secure_windows == 1` |
**Effective block screenshot** = `windowSecure && !override` (for covered
system capture paths).
## Relationships
- Both Secure settings are owned by Settings Developer Options controllers.
- Dialer reads call-rec setting only in `canRecordInCurrentCountry()` (and any
equivalent callers).
- Framework/SystemUI reads FLAG_SECURE override on capture / secure checks.
+110
View File
@@ -0,0 +1,110 @@
# Implementation Plan: Call recording unlock + FLAG_SECURE override
**Branch**: `008-call-rec-flag-secure` | **Date**: 2026-09-16 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/008-call-rec-flag-secure/spec.md`
(roadmap `008` + `009`, global Developer Options toggles only).
## Summary
Ship two native Developer Options switches (same pattern as `005`
`allow_signature_fake`):
1. **Disable call recording restrictions** →
`Settings.Secure.extendrom_call_recording` (GOLDEN / EXTENDROM
`ER_ALLOW_ANY_CALL_REC`) — when ON, Dialer
`CallRecorder.canRecordInCurrentCountry()` allows recording regardless of
`call_record_states.xml` country flags.
2. **Allow screenshots of secure windows** →
`Settings.Secure.allow_flag_secure_override` — when ON, system capture
paths ignore `FLAG_SECURE` globally.
References: AXP GOLDEN Secure dump (`extendrom_call_recording=1`) +
EXTENDROM `er.sh` F_CALLREC / `overlays/call-rec` / `config/call-rec`.
FLAG_SECURE is project-native (not AXP catalog). Re-validate on LOS 23.2 /
A16. No Magisk / LSPosed / Zygisk at runtime. LAB only.
## Technical Context
**Language/Version**: Java (Dialer, Settings, frameworks/base); Secure settings;
optional Kotlin if Settings already uses it for DO controllers
**Primary Dependencies**: LOS 23.2 Dialer (`CallRecorder`,
`call_record_states.xml`); Settings Developer Options; SystemUI / WM capture
surfaces; EXTENDROM call-rec reference on
`/srv/rom/references/extendrom`
**Storage**: `Settings.Secure` keys; meta-repo patches under
`vendor/sunfish-a16/patches/008-…`
**Testing**: LAB flash/`adb`; `settings get/put`; call-record file evidence;
screenshot of secure window; Magisk-free image
**Target Platform**: Pixel 4a LAB `11231JEC207477`; Android 16 / LOS 23.2
**Project Type**: Android ROM (Dialer + Settings + frameworks)
**Performance Goals**: N/A (correctness)
**Constraints**: LAB only; default OFF; global only (no per-app); attributable
patches; no root modules; legal warning on call-rec UI
**Scale/Scope**: Two DO preferences; one Dialer gate; one (or few) capture /
`FLAG_SECURE` enforcement sites; docs + LAB evidence
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
| Gate | Status |
|------|--------|
| LAB only; never GOLDEN | pass |
| Native call recording; re-validate A16 (no blind AXP XML) | pass (Dialer gate located on LOS 23.2) |
| FLAG_SECURE: default stock; user global override; no LSPosed | pass (global only) |
| No Magisk as production stage | pass |
| Small attributable reversible patches | pass (EXTENDROM F_CALLREC / native FLAG_SECURE) |
| Do not pull banking / incomplete `007` into this feature | pass |
**Post-design**: unchanged — FLAG_SECURE is global-only (not planned per-app);
capture paths that stay DRM-blocked must be documented if found on LAB.
## Project Structure
### Documentation (this feature)
```text
specs/008-call-rec-flag-secure/
├── plan.md # this file
├── research.md # Phase 0
├── data-model.md # Phase 1
├── quickstart.md # Phase 1
├── contracts/
│ ├── call-recording-surface.md
│ └── flag-secure-surface.md
└── tasks.md # /speckit-tasks (not this command)
```
### Host + tree
```text
# Meta-repo
vendor/sunfish-a16/patches/008-call-rec-flag-secure/ # apply scripts (to add)
docs/008-009-design.md
# rom-dev01
/srv/rom/src/lineage/packages/apps/Dialer/
java/com/android/incallui/call/CallRecorder.java # canRecordInCurrentCountry()
java/com/android/dialer/callrecord/res/xml/call_record_states.xml
/srv/rom/src/lineage/packages/apps/Settings/ # DO controllers + strings
/srv/rom/src/lineage/frameworks/base/ # Secure settings + FLAG_SECURE
/srv/rom/references/extendrom/overlays/call-rec/
/srv/rom/references/extendrom/config/call-rec/
/srv/rom/artifacts/008-call-rec-flag-secure/ # LAB evidence
```
**Structure Decision**: Same as `005` — attributable patches applied on the
LOS tree via `vendor/sunfish-a16` scripts; meta-repo holds specs/docs/scripts,
not megapatches of Dialer/frameworks.
## Complexity Tracking
| Violation | Why needed | Simpler alternative rejected because |
|-----------|------------|--------------------------------------|
| Frameworks / SystemUI patches for FLAG_SECURE | Constitution requires native override | Magisk module forbidden in production |
| Dialer patch (not overlay-only) | Country gate is Java `canRecordInCurrentCountry()` | Blind A11 overlay alone does not wire the Secure setting |
## Phase 0 / Phase 1
See `research.md`, `data-model.md`, `contracts/*`, `quickstart.md`.
@@ -0,0 +1,69 @@
# Quickstart: `008` call-rec + FLAG_SECURE (LAB)
**Device**: LAB only `11231JEC207477`
**Build**: bacon/image with `008-call-rec-flag-secure` applied
**Evidence root**: `/srv/rom/artifacts/008-call-rec-flag-secure/`
## Prerequisites
- Magisk **not** required (must work without it).
- Developer Options enabled.
- Contracts: [call-recording-surface.md](./contracts/call-recording-surface.md),
[flag-secure-surface.md](./contracts/flag-secure-surface.md).
## 1. Defaults
```bash
adb -s 11231JEC207477 shell settings get secure extendrom_call_recording
adb -s 11231JEC207477 shell settings get secure disable_secure_windows
# expect 0 or null
```
## 2. Call recording (region unlock)
1. Open **Developer Options** → enable **Disable call recording restrictions**.
2. Confirm:
```bash
adb shell settings get secure extendrom_call_recording
# expect 1
```
3. Place or receive a call with Dialer → start recording → stop → confirm file
(Downloads / Dialer recordings — note path).
4. Disable the switch (or turn off Developer Options) → confirm setting `0`
and that a restricted country would hide/deny record (or document LAB
country ISO + XML flag).
Store notes + path under `…/call-rec/`.
## 3. FLAG_SECURE override
1. Enable **Allow screenshots of secure windows** in Developer Options.
2. Confirm:
```bash
adb shell settings get secure disable_secure_windows
# expect 1
```
3. Open an app/window that sets `FLAG_SECURE` (e.g. password manager, banking
login, or a tiny test APK).
4. With toggle **OFF**: system screenshot should fail / blank.
5. With toggle **ON**: screenshot or screen record should succeed.
6. Toggle OFF again → secure behaviour restored.
Store images/notes under `…/flag-secure/`.
## 4. Pass criteria
- [ ] Both settings default OFF after fresh boot / DO off
- [ ] Call-rec ON → recording works; OFF → stock policy
- [ ] FLAG_SECURE ON → capture works; OFF → blocked
- [ ] No Magisk installed for the successful run
## Notes
- User is responsible for call-recording legality.
- DRM-protected surfaces may still resist capture; note exceptions.
- `user` build retest before release claims (`011`).
@@ -0,0 +1,61 @@
# Research: `008-call-rec-flag-secure`
## Decision: Call-rec = AXP GOLDEN / EXTENDROM native model
**Decision**: Port EXTENDROM `F_CALLREC` (same behaviour as AXP GOLDEN), not
Magisk Dialer RRO.
**GOLDEN evidence**: LAB dump already has
`extendrom_call_recording=1` in
`.local-artifacts/002-golden/20260915-spoofing-phonesky/settings/secure-*.txt`.
**Mechanism** (`/srv/rom/references/extendrom/er.sh`):
1. Overlay Dialer `config.xml`: `call_recording_enabled=true`,
`call_recording_audio_source=4`.
2. Settings DO: category + legal info + switch
`extendrom_call_recording`.
3. Controllers: `ER_CallRecPreferenceController` /
`ER_CallRecInfo` → `Settings.Secure.ER_ALLOW_ANY_CALL_REC`.
4. `Settings.java`:
`ER_ALLOW_ANY_CALL_REC = "extendrom_call_recording"`.
5. Dialer `CallRecorder.canRecordInCurrentCountry()`: if Secure int == 1,
return `true` before country XML map.
**Secure key (product)**: `extendrom_call_recording` (GOLDEN-compatible).
Do **not** invent `allow_call_recording_any_region` for call-rec.
**Alternatives rejected**:
- Magisk static RRO of `call_record_states.xml` — always-on, not native ROM,
no DO parity with GOLDEN.
- Blind A11 overlay-only without Dialer Java gate — may no-op on A16.
## Decision: FLAG_SECURE = AOSP `disable_secure_windows` + DO
**Decision**: Do **not** invent a second frameworks hook. LOS 23.2 / A16 already
has `Settings.Secure.DISABLE_SECURE_WINDOWS` wired through
`WindowManagerService` → `WindowState.isSecureLocked()`. Ship a Developer
Options switch (preference key `allow_flag_secure_override`) that writes
`disable_secure_windows`.
**Constraint**: WMS applies the setting only on debuggable builds
(`ro.debuggable`). LAB `userdebug` is in scope; `user` retest before release.
**Alternatives rejected**: Magisk `services.jar` dex patchers as shipping
mechanism.
## Decision: Packaging = `vendor/sunfish-a16` apply like `005`
Idempotent script under `patches/008-call-rec-flag-secure/`, EXTENDROM/`er.sh`
attribution for call-rec.
## Decision: Combined feature directory
One Spec Kit feature absorbs roadmap `008` + `009`.
## Decision: No Magisk artifacts in the repo
Owner-supplied Magisk zips were temporary agent aids only; removed from the
working tree. Implementation references EXTENDROM + GOLDEN dumps + A16 source
inventory.
+170
View File
@@ -0,0 +1,170 @@
# Feature Specification: Call recording unlock + FLAG_SECURE override
**Feature Branch**: `008-call-rec-flag-secure`
**Created**: 2026-09-16
**Status**: Draft
**Input**: Deliver constitution items `008` and `009` together as native ROM
features with two Developer Options toggles (global only). Call recording =
disable region/country restrictions via **AXP GOLDEN / EXTENDROM native**
`extendrom_call_recording` DO gate. FLAG_SECURE = optional global allow
screenshots/capture of secure windows (native frameworks + DO). Pattern
matches `005` DO style. No LSPosed/Zygisk/Magisk runtime. LAB only.
**Design**: [`docs/008-009-design.md`](../../docs/008-009-design.md)
## Absorbs roadmap
| # | Theme | In this feature |
|---|--------|-----------------|
| 008 | Unrestricted call recording (region) | Yes |
| 009 | FLAG_SECURE override | Yes — **global only** |
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Call recording region unlock toggle (Priority: P1)
As a LAB/daily-driver user, I can enable **Disable call recording
restrictions** under Developer Options. When ON, the Dialer no longer blocks
recording solely because of country/region rules. When OFF, stock LOS
restrictions apply.
**Why this priority**: Core `008` value; small surface; matches EXTENDROM/AXP
intent without porting full AXP recording UX.
**Independent Test**: Toggle setting; `settings get secure
extendrom_call_recording`; attempt call recording on LAB Dialer with
toggle on vs off.
**Acceptance Scenarios**:
1. **Given** a build with this feature on LAB, **When** Developer Options is
opened, **Then** a switch for disabling call-recording region restrictions
is visible (with a short legal responsibility summary).
2. **Given** the switch is OFF (default), **When** Dialer evaluates recording
eligibility, **Then** stock country/region rules apply.
3. **Given** the switch is ON, **When** the user records a call with the
system Dialer, **Then** recording is not refused solely due to region /
country policy, and a recording artifact is produced.
4. **Given** Developer Options is disabled globally, **When** that happens,
**Then** `extendrom_call_recording` returns to `0`.
---
### User Story 2 - Global FLAG_SECURE / screenshot override (Priority: P1)
As a LAB/daily-driver user, I can enable **Allow screenshots of secure
windows** under Developer Options. When ON, screenshots and screen capture
work even if apps set `FLAG_SECURE`. When OFF, Android’s normal secure-window
behaviour applies. The override is **global** (all apps).
**Why this priority**: Constitution `009` project requirement; same DO pattern
as spoofing.
**Independent Test**: App or screen that sets `FLAG_SECURE`; capture with
toggle OFF (expect fail) and ON (expect success);
`settings get secure disable_secure_windows`.
**Acceptance Scenarios**:
1. **Given** a build with this feature on LAB, **When** Developer Options is
opened, **Then** a switch for secure-window screenshot override is visible.
2. **Given** the switch is OFF (default), **When** the user tries to screenshot
a `FLAG_SECURE` window, **Then** capture is blocked as on stock.
3. **Given** the switch is ON, **When** the user screenshots or screen-records
that same window, **Then** capture succeeds.
4. **Given** Developer Options is disabled globally, **When** that happens,
**Then** `disable_secure_windows` returns to `0`.
---
### User Story 3 - Native, attributable packaging (Priority: P2)
As a maintainer, both behaviours ship in the bacon/ROM tree via
`vendor/sunfish-a16` patches (idempotent apply), sourced from EXTENDROM /
AXP GOLDEN call-rec (and native FLAG_SECURE work), without Magisk modules.
**Why this priority**: Constitution: native ROM, attributable, reversible.
**Independent Test**: Patch script dry-run; tree markers; no Magisk zip in
artifacts required for the feature to work after flash.
**Acceptance Scenarios**:
1. **Given** a clean LOS tree after `repo sync`, **When** the apply script
runs, **Then** it is idempotent and records source attribution.
2. **Given** a flashed LAB image, **When** Magisk is not installed, **Then**
both toggles still function.
---
### Edge Cases
- Dialer path renamed on A16 → re-locate gate; do not assume A11 overlay paths.
- Call recording legal in some jurisdictions only → UI must warn; feature does
not claim legality.
- Some capture paths (DRM / hardware buffers) may still block — document if a
specific path remains blocked after toggle ON.
- `user` builds: follow same policy as `005` for whether DO toggles are
available (document decision in plan if it differs from `userdebug` LAB).
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: System MUST expose Developer Options switch **Disable call
recording restrictions** backed by
`Settings.Secure.extendrom_call_recording` ∈ {`0`,`1`}, default `0`.
- **FR-002**: When that setting is `1`, Dialer MUST NOT deny call recording
solely due to country/region restriction logic.
- **FR-003**: When that setting is `0`, Dialer MUST use stock restriction
behaviour.
- **FR-004**: System MUST expose Developer Options switch **Allow screenshots
of secure windows** backed by
`Settings.Secure.disable_secure_windows` (DO: `allow_flag_secure_override`) ∈ {`0`,`1`}, default `0`.
- **FR-005**: When that setting is `1`, system screenshot and screen-capture
paths MUST allow capture of windows that set `FLAG_SECURE` (global).
- **FR-006**: When that setting is `0`, `FLAG_SECURE` MUST behave as stock.
- **FR-007**: Both settings MUST reset to `0` when Developer Options is turned
off (same pattern as EXTENDROM / `005`).
- **FR-008**: Implementation MUST NOT require Magisk, LSPosed, or Zygisk at
runtime.
- **FR-009**: Patches MUST be attributable (EXTENDROM/`er.sh` F_CALLREC for
call-rec; native frameworks for FLAG_SECURE) and apply via
`vendor/sunfish-a16/patches/…`.
- **FR-010**: Validation MUST be LAB-only (`11231JEC207477`).
### Key Entities
- **SecureSetting**: `extendrom_call_recording`,
`disable_secure_windows`.
- **DeveloperOptionsController**: preference controllers writing those
settings.
- **DialerRecordingPolicy**: country/region gate gated by call-rec setting.
- **SecureCapturePolicy**: framework capture/`FLAG_SECURE` enforcement gated
by screenshot setting.
## Success Criteria *(mandatory)*
- **SC-001**: On LAB, both settings read `0` after fresh boot / DO off.
- **SC-002**: With call-rec toggle ON, operator completes a recorded call and
stores evidence under `/srv/rom/artifacts/008-…/call-rec/`.
- **SC-003**: With screenshot toggle ON, operator captures a previously secure
window; evidence under `/srv/rom/artifacts/008-…/flag-secure/`.
- **SC-004**: Toggles OFF restore stock deny behaviour for the same tests.
- **SC-005**: Feature works on a Magisk-free LAB image.
## Assumptions
- LOS 23.2 Dialer still has an identifiable country/region recording gate (or
equivalent CarrierConfig path) that can be overridden.
- “Screenshot” includes the system screenshot gesture and common screen-record
entry points; exotic DRM paths may remain blocked (document).
- FLAG_SECURE is **global only** (not planned: per-app lists).
- `007` remains incomplete; this feature does not depend on KernelSU.
## Out of scope
- AXP full call-recording automation UI.
- Per-app FLAG_SECURE lists.
- Relocked AVB / signed release (`011`).
- Banking PASS (`007`).
+226
View File
@@ -0,0 +1,226 @@
# Tasks: Call recording unlock + FLAG_SECURE override (`008`/`009`)
**Input**: Design docs from `/specs/008-call-rec-flag-secure/`
**Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`,
`contracts/`, `quickstart.md`; constitution native-ROM rules; **AXP GOLDEN /
EXTENDROM call-rec model** (not Magisk modules)
**Primary oracle (call-rec)**: AXP/EXTENDROM native stack — same Secure key
already observed on GOLDEN LAB dump
(`.local-artifacts/002-golden/…/settings/secure-*.txt` →
`extendrom_call_recording=1`):
| Piece | Host reference |
|-------|----------------|
| Apply logic | `/srv/rom/references/extendrom/er.sh` (`F_CALLREC` / unrestricted call recording) |
| DO controllers | `/srv/rom/references/extendrom/config/call-rec/…/CallRecPreferenceController.java` (+ Info) |
| Strings / Dialer config overlay | `/srv/rom/references/extendrom/overlays/call-rec/` |
| Docs | `/srv/rom/references/axp/archive/…/knowledge/callrec/` |
**FLAG_SECURE**: project-specific native DO (not AXP Pro catalog). Magisk
modules are **agent-only mental aids** if ever consulted — **never** ship,
install, or task-move zips into the tree.
**Organization**: US1 call-rec (GOLDEN model) → US2 FLAG_SECURE → US3 packaging.
**Out of scope**: Magisk/Zygisk runtime; static Dialer RRO product; per-app
FLAG_SECURE lists (not planned); full AXP auto-record policy UI; `007`; GOLDEN
flash; commit/MR.
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no incomplete deps)
- **[Story]**: US1…US3 from `spec.md`
## Path conventions
- Meta repo: `vendor/sunfish-a16/`, `docs/`, `specs/008-call-rec-flag-secure/`
- Build host: `/srv/rom/src/lineage/`, `/srv/rom/references/extendrom/`,
`/srv/rom/artifacts/008-call-rec-flag-secure/`
- GOLDEN settings sample (read-only): `.local-artifacts/002-golden/`
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Artifact dirs + patch scaffolding; **no Magisk zip handling**
- [x] T001 [P] Create host dirs `/srv/rom/artifacts/008-call-rec-flag-secure/`
(`call-rec/`, `flag-secure/`) and `/srv/rom/logs/008-build/`
(android-build writable)
- [x] T002 [P] Add stub `docs/008-call-rec-flag-secure-runbook.md` (GOLDEN/
EXTENDROM call-rec map, Secure keys, LAB serial, apply order)
- [x] T003 [P] Create `vendor/sunfish-a16/patches/008-call-rec-flag-secure/README.md`
(idempotent apply like `005-sigspoof`; attribute EXTENDROM/`er.sh` F_CALLREC;
FLAG_SECURE as native project patch)
**Checkpoint**: Dirs + stubs exist
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Port map from GOLDEN/EXTENDROM onto LOS 23.2 paths; Secure key
plumbing; **no bacon yet**
**⚠️ CRITICAL**: Blocks all user stories
- [x] T004 Extract F_CALLREC steps from
`/srv/rom/references/extendrom/er.sh` into a checklist in
`docs/008-call-rec-flag-secure-runbook.md` (Settings controllers, Secure
`ER_ALLOW_ANY_CALL_REC` = `"extendrom_call_recording"`, DO XML, Dialer
`CallRecorder.canRecordInCurrentCountry` early-return, Dialer
`config.xml` overlay)
- [x] T005 [P] Confirm LOS 23.2 Dialer still uses
`/srv/rom/src/lineage/packages/apps/Dialer/java/com/android/incallui/call/CallRecorder.java`
and that stock `call_recording_enabled` / audio source match or need
EXTENDROM overlay (`call_recording_enabled=true`,
`call_recording_audio_source=4`)
- [x] T006 [P] Inventory A16 `FLAG_SECURE` / screenshot / screen-record sites
under `/srv/rom/src/lineage/frameworks/base/` (+ SystemUI); list candidates
in the runbook (native source patches only)
- [x] T007 [P] Locate Settings development dashboard +
`development_settings.xml` paths on LOS 23.2 (same family as `005`)
- [x] T008 Scaffold idempotent
`vendor/sunfish-a16/patches/008-call-rec-flag-secure/apply_008_call_rec_flag_secure.py`
(dry-run + markers; body filled by story tasks)
**Checkpoint**: Foundation ready — US1/US2 can proceed in parallel
---
## Phase 3: User Story 1 — Call recording (GOLDEN / EXTENDROM model) (P1) 🎯 MVP
**Goal**: Native DO **Disable call recording restrictions** writing Secure
`extendrom_call_recording` (GOLDEN-compatible); Dialer allows any country when
`1`
**Independent Test**: `adb shell settings get secure extendrom_call_recording`;
toggle; record call per `quickstart.md` and
`contracts/call-recording-surface.md`
### Implementation for User Story 1
- [x] T009 [P] [US1] Port EXTENDROM strings + DO category/switch/info into
`/srv/rom/src/lineage/packages/apps/Settings/` (keys
`extendrom_call_recording*`, legal details text from EXTENDROM overlay)
- [x] T010 [P] [US1] Add `ER_CallRecPreferenceController` + `ER_CallRecInfo`
(or equivalent names) under Settings development; wire into
`DevelopmentSettingsDashboardFragment`; reset Secure to `0` when DO
master disabled
- [x] T011 [US1] Add
`Settings.Secure.ER_ALLOW_ANY_CALL_REC = "extendrom_call_recording"` in
`/srv/rom/src/lineage/frameworks/base/core/java/android/provider/Settings.java`
- [x] T012 [US1] Patch
`CallRecorder.canRecordInCurrentCountry()` to early-return `true` when
`Settings.Secure.getInt(…, "extendrom_call_recording", 0) == 1` (same
injection as `er.sh` F_CALLREC)
- [x] T013 [P] [US1] Ensure Dialer call-rec config enabled for sunfish
(EXTENDROM overlay values) under Dialer
`callrecord/res/values/config.xml` or product overlay
- [x] T014 [US1] Encode US1 changes into
`vendor/sunfish-a16/patches/008-call-rec-flag-secure/apply_008_call_rec_flag_secure.py`
with EXTENDROM/`er.sh` attribution
- [ ] T015 [US1] LAB validate *(blocked: wait 008-bacon + Magisk-free flash)* on `11231JEC207477`; evidence under
`/srv/rom/artifacts/008-call-rec-flag-secure/call-rec/`
**Checkpoint**: US1 independently testable (MVP)
---
## Phase 4: User Story 2 — Global FLAG_SECURE override (P1)
**Goal**: DO **Allow screenshots of secure windows** → Secure
`allow_flag_secure_override`; native capture paths honour it globally
**Independent Test**: Secure window OFF fail / ON success;
`settings get secure allow_flag_secure_override`; `quickstart.md` §FLAG_SECURE
### Implementation for User Story 2
- [x] T016 [P] [US2] Settings strings + switch for FLAG_SECURE override under
`/srv/rom/src/lineage/packages/apps/Settings/`
- [x] T017 [P] [US2] Preference controller for
`Settings.Secure.allow_flag_secure_override` with DO-master reset to `0`
- [x] T018 [US2] Implement override in inventoried frameworks/SystemUI paths
(T006) — **source only**, no jar binary patchers
- [x] T019 [US2] Encode US2 into
`vendor/sunfish-a16/patches/008-call-rec-flag-secure/apply_008_call_rec_flag_secure.py`
- [ ] T020 [US2] LAB validate *(blocked: wait 008-bacon + Magisk-free flash)*; evidence under
`/srv/rom/artifacts/008-call-rec-flag-secure/flag-secure/`; note any
remaining DRM blocks in the runbook
**Checkpoint**: US1 + US2 both work
---
## Phase 5: User Story 3 — Native attributable packaging (P2)
**Goal**: Idempotent `vendor/sunfish-a16` apply; Magisk-free image
**Independent Test**: Apply dry-run twice; feature works without Magisk
(SC-005)
- [x] T021 [US3] Finish apply script (idempotent, backups, clear missing-path
errors); README lists every touched path
- [ ] T022 [US3] Apply on `rom-dev01`, bacon detached *(apply done; bacon session `008-bacon` running)* via
`/srv/rom/artifacts/bin/rom-detach`, flash LAB **without** Magisk modules
for this feature
- [ ] T023 [US3] Record Magisk-free PASS *(blocked: post-flash)* under
`/srv/rom/artifacts/008-call-rec-flag-secure/` + runbook
**Checkpoint**: Packaging complete
---
## Phase 6: Polish & Cross-Cutting
- [x] T024 [P] Sync `docs/008-009-design.md`, `research.md`, contracts, and
GOLDEN inventory note (`extendrom_call_recording` on GOLDEN) with final
A16 paths
- [x] T025 [P] Verify DO master-off resets **both** Secure keys to `0`
- [ ] T026 Run full `quickstart.md` *(blocked: post-flash)* checklist; evidence index README under
`/srv/rom/artifacts/008-call-rec-flag-secure/`
- [x] T027 [P] Document `user` vs `userdebug` DO availability (same caution as
`005`)
---
## Dependencies & Execution Order
- **Setup → Foundational → US1 ∥ US2 → US3 → Polish**
- **US1** after Phase 2; no dep on US2
- **US2** after Phase 2; no dep on US1 (coordinate Settings XML)
- **US3** after US1+US2 encoded in apply script
### Parallel opportunities
- T001 ∥ T002 ∥ T003
- T004 then T005 ∥ T006 ∥ T007
- After Phase 2: US1 track (T009–T013) ∥ US2 track (T016–T018)
- T024 ∥ T025 ∥ T027
---
## Implementation Strategy
### MVP
1. Setup + Foundational (esp. T004/T005 from `er.sh`)
2. US1 GOLDEN call-rec → LAB evidence
3. Then US2 FLAG_SECURE
4. US3 packaging + Magisk-free proof
### Suggested MVP scope
**US1 only** (native EXTENDROM/GOLDEN call-rec). US2 still required before
calling roadmap `008`+`009` done.
---
## Notes
- Product is **native ROM** patches. Magisk zips are not part of the feature.
- Prefer Secure-setting Dialer gate (GOLDEN) over always-on country XML RRO.
- Prefer frameworks source patches over `services.jar` binary patching.
- LAB only: `11231JEC207477`. Owner handles commit/MR.