A small helpdesk system: an office Pixel running a patched GrapheneOS Dialer answers technician calls, records both call legs as separate channels, and a Ruby backend transcribes them through Whisper and files an AI summary against the caller. Squashed to a single commit for sharing. No credentials are included; secrets live outside the repo in /etc/helpdesk/env on the server or a gitignored .claude/env.local locally. See .claude/env.local.example for the shape. Start at README.md, then docs/architecture.md.
49 lines
2.8 KiB
Markdown
49 lines
2.8 KiB
Markdown
# components/dialer-patch
|
|
|
|
The GrapheneOS Dialer patch: auto-record on answer, call webhooks to the backend, recording upload,
|
|
and the reverse command channel (answer/mute/hold/dial from the console). It runs as a privileged
|
|
system app inside a self-built OS image - a normal app can't capture call audio - so this directory
|
|
holds only our sources, and the huge upstream Dialer tree is fetched separately
|
|
(`resources/scripts/`, git-ignored).
|
|
|
|
Base: the in-tree `callrecV2` recording implementation (Dialer commit `6f68bcbd`).
|
|
|
|
## Layout
|
|
|
|
- `overlay/java/com/android/dialer/helpdesk/` - all new code, one package. Entry points:
|
|
`CallEventEmitter` (webhooks), `HelpdeskRecordingBridge` (upload), `HelpdeskCommandService` +
|
|
`CommandChannelClient` (the always-on reverse channel), `HelpdeskConfig` (URL + credentials),
|
|
`HelpdeskHeartbeat`, `ContactsSyncer`, and the pure-logic helpers under `http/`, `queue/`,
|
|
`command/`, `util/`. Each file's header says what it does. `DualLegCapture` records the two call
|
|
legs as separate channels; the alignment logic it depends on lives in `util/LegInterleaver` so it
|
|
can be tested off-device.
|
|
- `patches/0001-0011` - the changes to AOSP files, one concern per patch: register the emitter
|
|
(0001), recording auto-start and hold behaviour (0002, 0007), force `VOICE_CALL` capture (0003),
|
|
pre-grant `RECORD_AUDIO` (0004), foreground-service manifest bits (0005), allow cleartext for dev
|
|
LAN backends (0006), landscape in-call UI (0008), keep our notification channel alive (0009),
|
|
runtime-selectable recording quality plus a per-speaker capture probe (0010), recording the two
|
|
call legs as separate channels (0011).
|
|
- `overlay/etc/default-permissions/` - the pre-grant XML.
|
|
- `tests/` - off-device tests, see below.
|
|
- `apply.sh` - copies the overlay and applies all patches into a Dialer tree (`DIALER_TREE`, defaults
|
|
to the build box's `/build/grapheneos/...`). Idempotent; safe to re-run.
|
|
|
|
The companion `components/sepolicy-patch` is required in the same image - without its property
|
|
context the Dialer can't read the `persist.helpdesk.*` configuration at all.
|
|
|
|
## Build and flash
|
|
|
|
`docs/runbooks/graphene-build.md` (Linux) and `docs/runbooks/windows-wsl2-build.md`. How the device
|
|
finds and authenticates to the backend, including every config property and a troubleshooting table:
|
|
`docs/phone-connectivity.md`. The wire contract: `docs/device-api.md`.
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
tests/run.sh # compiles the pure-logic classes and cross-checks them against the Ruby backend
|
|
tests/integration.sh # signed HTTP against a real local backend (starts one on :4055)
|
|
```
|
|
|
|
Both need a JDK (the GrapheneOS prebuilt at `/build/grapheneos/prebuilts/jdk/...` or a system javac)
|
|
and Ruby. The cross-checks matter because several classes mirror backend logic byte-for-byte: E.164
|
|
normalization, business hours, the HMAC recipe, the command-verb set.
|