From c2b7562c1cd1f2e02a3e200bc9267a97d42f7a67 Mon Sep 17 00:00:00 2001 From: 0xharkirat Date: Sat, 4 Apr 2026 13:55:19 +1100 Subject: [PATCH 1/2] Add OACP v0.3 SDK integration with activity + broadcast dispatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Integrates the OACP Kotlin SDK (oacp-android-release.aar) for voice control via the Hark assistant. Two dispatch patterns used: - start_recording: type=activity — Hark calls startActivity() directly, opening the app and starting the RecorderService. Handled via intent filter on MainActivity + onNewIntent(). - pause/resume/stop/discard: type=broadcast — Hark sends broadcast, OacpActionReceiver (extends OacpReceiver from SDK) handles in background. Files added: - app/libs/oacp-android-release.aar — OACP SDK - app/src/main/assets/oacp.json — capability manifest (5 capabilities) - app/src/main/assets/OACP.md — LLM context for disambiguation - app/src/main/kotlin/.../oacp/OacpActionReceiver.kt — broadcast handler Files modified: - app/build.gradle.kts — SDK + annotation dependency - AndroidManifest.xml — activity intent filter + receiver registration - MainActivity.kt — onNewIntent() handles OACP start recording intent Co-Authored-By: Claude Opus 4.6 (1M context) --- app/build.gradle.kts | 2 + app/libs/oacp-android-release.aar | Bin 0 -> 26898 bytes app/src/main/AndroidManifest.xml | 14 ++ app/src/main/assets/OACP.md | 18 ++ app/src/main/assets/oacp.json | 178 ++++++++++++++++++ .../voicerecorder/activities/MainActivity.kt | 30 ++- .../voicerecorder/oacp/OacpActionReceiver.kt | 38 ++++ 7 files changed, 278 insertions(+), 2 deletions(-) create mode 100644 app/libs/oacp-android-release.aar create mode 100644 app/src/main/assets/OACP.md create mode 100644 app/src/main/assets/oacp.json create mode 100644 app/src/main/kotlin/org/fossify/voicerecorder/oacp/OacpActionReceiver.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 238ea798..de25fc34 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -147,4 +147,6 @@ dependencies { implementation(libs.tandroidlame) implementation(libs.autofittextview) detektPlugins(libs.compose.detekt) + implementation(files("libs/oacp-android-release.aar")) + implementation("androidx.annotation:annotation:1.7.1") } diff --git a/app/libs/oacp-android-release.aar b/app/libs/oacp-android-release.aar new file mode 100644 index 0000000000000000000000000000000000000000..3e8af3659a413506e98ca801295981aa6ed8c888 GIT binary patch literal 26898 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 Qkl(w)_t + + + + + + + + + + + + + + + OacpResult.success("Recording paused") + action.endsWith(".oacp.ACTION_RESUME_RECORDING") -> + OacpResult.success("Recording resumed") + action.endsWith(".oacp.ACTION_STOP_RECORDING") -> + OacpResult.success("Recording stopped and saved") + action.endsWith(".oacp.ACTION_DISCARD_RECORDING") -> + OacpResult.success("Recording discarded") + else -> null + } + } +} From 914d0dcf21eed96a63c1a26bd9f310e25ac90026 Mon Sep 17 00:00:00 2001 From: 0xharkirat Date: Sat, 4 Apr 2026 14:02:14 +1100 Subject: [PATCH 2/2] Add OACP integration documentation Documents how OACP was added: files changed, two dispatch patterns (activity for foreground, broadcast for background), BAL restrictions, onNewIntent handling, and adb test commands. Co-Authored-By: Claude Opus 4.6 (1M context) --- OACP_INTEGRATION.md | 122 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 OACP_INTEGRATION.md diff --git a/OACP_INTEGRATION.md b/OACP_INTEGRATION.md new file mode 100644 index 00000000..349a3161 --- /dev/null +++ b/OACP_INTEGRATION.md @@ -0,0 +1,122 @@ +# OACP Integration — Fossify Voice Recorder + +How voice control was added to Fossify Voice Recorder using the OACP Kotlin SDK. + +## Overview + +This integration allows users to control Voice Recorder via the Hark voice assistant. Five capabilities are exposed: + +| Capability | Dispatch | What it does | +|-----------|----------|-------------| +| `start_recording` | **activity** | Opens the app and starts recording | +| `pause_recording` | broadcast | Pauses active recording (background) | +| `resume_recording` | broadcast | Resumes paused recording (background) | +| `stop_recording` | broadcast | Stops and saves recording (background) | +| `discard_recording` | broadcast | Discards recording without saving (background) | + +## Why two dispatch types? + +Android 14+ blocks `startActivity()` from BroadcastReceivers (Background Activity Launch restrictions). So: + +- **`start_recording`** needs to open the app UI, so it uses `type=activity`. Hark calls `startActivity()` directly from the foreground — no BAL restrictions. +- **`pause/resume/stop/discard`** don't need UI — they work in the background via `type=broadcast`. The `OacpReceiver` from the SDK handles these. + +## Files added + +| File | Purpose | +|------|---------| +| `app/libs/oacp-android-release.aar` | OACP Kotlin SDK | +| `app/src/main/assets/oacp.json` | Capability manifest (5 capabilities with rich metadata for embedding-based matching) | +| `app/src/main/assets/OACP.md` | LLM context for disambiguation | +| `app/src/main/kotlin/.../oacp/OacpActionReceiver.kt` | Broadcast handler for background actions | + +## Files modified + +### `app/build.gradle.kts` +```kotlin +dependencies { + implementation(files("libs/oacp-android-release.aar")) + implementation("androidx.annotation:annotation:1.7.1") +} +``` + +### `app/src/main/AndroidManifest.xml` + +Activity intent filter on MainActivity (for `start_recording`): +```xml + + + + + + + +``` + +Receiver registration (for background actions): +```xml + + + + + + + + +``` + +### `app/src/main/kotlin/.../activities/MainActivity.kt` + +Handle OACP intent in `onCreate()` (fresh launch) and `onNewIntent()` (singleTask redelivery): + +```kotlin +// In onCreate(), after permission check: +val shouldAutoRecord = config.recordAfterLaunch || + intent?.action?.endsWith(".oacp.ACTION_START_RECORDING") == true + +if (shouldAutoRecord && !RecorderService.isRunning) { + Intent(this, RecorderService::class.java).apply { + try { startService(this) } catch (_: Exception) { } + } +} +``` + +```kotlin +override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + handleOacpIntent() +} + +private fun handleOacpIntent() { + if (intent?.action?.endsWith(".oacp.ACTION_START_RECORDING") != true) return + intent?.action = null // consume so it doesn't re-trigger + binding.viewPager.currentItem = 0 // switch to recorder tab + if (RecorderService.isRunning) return + Intent(this, RecorderService::class.java).apply { + try { startService(this) } catch (_: Exception) { } + } +} +``` + +**Key detail:** `onNewIntent()` is critical for `singleTask` activities. Without it, the OACP intent is silently dropped when the activity is already in memory. + +## Testing with adb + +```bash +# Verify capabilities are served +adb shell content read --uri "content://org.fossify.voicerecorder.debug.oacp/manifest" + +# Test activity dispatch (opens app) +adb shell am start -a org.fossify.voicerecorder.debug.oacp.ACTION_START_RECORDING \ + -n org.fossify.voicerecorder.debug/org.fossify.voicerecorder.activities.MainActivity + +# Test broadcast dispatch (background) +adb shell am broadcast -a org.fossify.voicerecorder.debug.oacp.ACTION_PAUSE_RECORDING \ + -p org.fossify.voicerecorder.debug +``` + +## SDK auto-registration + +The `OacpProvider` ContentProvider is auto-registered via Android manifest merger from the SDK. No manual registration needed. It serves `oacp.json` and `OACP.md` at `content://${applicationId}.oacp/manifest` and `content://${applicationId}.oacp/context`.