Skip to content

Feat/android fgs survive task removal - #1234

Open
mdydek wants to merge 10 commits into
mainfrom
feat/android-fgs-survive-task-removal
Open

Feat/android fgs survive task removal#1234
mdydek wants to merge 10 commits into
mainfrom
feat/android-fgs-survive-task-removal

Conversation

@mdydek

@mdydek mdydek commented Aug 17, 2026

Copy link
Copy Markdown
Member

Closes #

⚠️ Breaking changes ⚠️

  • get rid of the icons in the recording notification, the ui is different based on the manufacturer, android versions, thus the current approach is to fallback to simple text buttons, which will be placed by the system possibly in the correct arrangement

Introduced changes

Checklist

  • Linked relevant issue
  • Updated relevant documentation
  • Added/Conducted relevant tests
  • Performed self-review of the code
  • Updated Web Audio API coverage
  • Added support for web
  • Updated old arch android spec file

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

WPT non-regression comparison

ERROR — the comparison did not produce a report; the test run itself likely failed.

Workflow run · this comment is updated on every push.

mdydek and others added 6 commits August 17, 2026 13:56
The recording notification's pause, resume and stop actions now act on the
recorder natively, so they keep working after the app task is removed while
the foreground service (stopWithTask=false) keeps the recording alive:

- ActiveRecorderHandle: process-global one-slot handle to the live recorder
  (registered by AudioRecorderHostObject), with a consume-once stash of the
  file info produced by a native stop
- NativeRecorderControl: static-JNI entry points callable from Kotlin without
  a React context; the notification receiver stops/pauses/resumes through it
  on an executor and still emits the matching AudioEvent so a live app can
  sync its UI (new event: RECORDING_NOTIFICATION_STOP)
- RecordingNotification rewritten to standard NotificationCompat actions
  (RemoteViews layouts removed), rebuilt on every show(); adds stop action,
  action titles, deepLinkUri tap routing (ACTION_VIEW) and a chronometer that
  excludes paused spans; native pause/resume re-post the notification so the
  action button flips without JS
- onErrorAfterClose now restores the pre-teardown state after a stream
  reclaim instead of force-resuming a paused recording

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mdydek
mdydek marked this pull request as ready for review August 20, 2026 11:38
@closetcaiman closetcaiman added feature New user-facing features or major capabilities android Native Android implementation, C++/Java/Kotlin bindings, or Android-specific issues labels Aug 20, 2026
</TabItem>
</Tabs>

### Keeping the recording alive when the app is closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this android specific? Maybe we could add a badge?

assignOnErrorCallbackId(0);
}
void assignOnErrorCallbackId(uint64_t callbackId);
// Defined inline so AudioRecorder.cpp doesn't drag this class's whole

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to omit/reduce this trip to gain access to Recorder?

Comment on lines 223 to +276
@@ -247,75 +229,86 @@ class RecordingNotification(
state.contentText ?: "Audio recording is in progress/paused"
}
state.smallIconResourceName =
if (options?.hasKey("smallIconResourceName") ==
true
) {
if (options?.hasKey("smallIconResourceName") == true) {
options.getString("smallIconResourceName")
} else {
state.smallIconResourceName ?: null
state.smallIconResourceName
}
state.largeIconResourceName =
if (options?.hasKey("largeIconResourceName") ==
true
) {
if (options?.hasKey("largeIconResourceName") == true) {
options.getString("largeIconResourceName")
} else {
state.largeIconResourceName ?: null
state.largeIconResourceName
}
state.backgroundColor = if (options?.hasKey("color") == true) options.getInt("color") else state.backgroundColor
state.showStopAction =
if (options?.hasKey("showStopAction") == true) {
options.getBoolean("showStopAction")
} else {
state.showStopAction
}
state.pauseActionTitle =
if (options?.hasKey("pauseActionTitle") == true) {
options.getString("pauseActionTitle")
} else {
state.pauseActionTitle
}
state.resumeActionTitle =
if (options?.hasKey("resumeActionTitle") == true) {
options.getString("resumeActionTitle")
} else {
state.resumeActionTitle
}
state.pauseIconResourceName =
if (options?.hasKey("pauseIconResourceName") ==
true
) {
options.getString("pauseIconResourceName")
state.stopActionTitle =
if (options?.hasKey("stopActionTitle") == true) {
options.getString("stopActionTitle")
} else {
state.pauseIconResourceName ?: null
state.stopActionTitle
}
state.resumeIconResourceName =
if (options?.hasKey("resumeIconResourceName") ==
true
) {
options.getString("resumeIconResourceName")
state.deepLinkUri = if (options?.hasKey("deepLinkUri") == true) options.getString("deepLinkUri") else state.deepLinkUri
state.usesChronometer =
if (options?.hasKey("usesChronometer") == true) {
options.getBoolean("usesChronometer")
} else {
state.resumeIconResourceName ?: null
state.usesChronometer
}
state.backgroundColor = if (options?.hasKey("color") == true) options.getInt("color") else state.backgroundColor ?: null
// Unlike the other options, `paused` resets when absent so the notification never
// sticks in the paused look.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we refactor this to use some helper methods? All these state modifications share the logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

android Native Android implementation, C++/Java/Kotlin bindings, or Android-specific issues feature New user-facing features or major capabilities

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants