Sitelet https://github.com/nextcloud/talk-android/pull/6817
Skip to content

fix(chat): keep a voice recording running over a screen rotation - #6817

Open
ToteMeiSter wants to merge 1 commit into
nextcloud:masterfrom
ToteMeiSter:fix/voice-recording-stops-on-rotation
Open

ToteMeiSter wants to merge 1 commit into
nextcloud:masterfrom
ToteMeiSter:fix/voice-recording-stops-on-rotation

Conversation

@ToteMeiSter

Copy link
Copy Markdown
Contributor

🖼️ Screenshots

🏚️ Before 🏡 After
After rotation the screen still shows a running (locked) recording, but the recorder was stopped; a truncated file is sent The recording goes on over the rotation and the whole message is sent

Problem

Record a voice message, lock it (slide up) and rotate the screen. The UI keeps showing a running recording, but the audio is cut off at the moment of the rotation. What is sent is a truncated file.

Cause

On master the stop of the chat lifecycle always stops the recorder:

  • app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt, onStop() (around line 478): mediaRecorderManager.handleOnStop()
  • app/src/main/java/com/nextcloud/talk/chat/data/io/MediaRecorderManager.kt, handleOnStop() (line 168) calls stop(), which stops and releases the MediaRecorder.

A rotation recreates ChatActivity and therefore also runs onStop. The ViewModel survives and keeps the locked and inProgress state, so the UI and the recorder disagree.

Change

ChatViewModel.onStop() skips handleOnStop() when the stopping lifecycle owner is an activity that is changing its configuration (isChangingConfigurations). The check is read from the owner on purpose: ON_STOP reaches the observer from onActivityPreStopped (API 29+), before the body of ChatActivity.onStop() runs, so a flag set there would come too late.

Leaving the chat still stops the recording as before.

Unit test

None. The changed code is the lifecycle callback of ChatViewModel (heavy dependency graph and an init block that collects repository flows) and MediaRecorder itself, neither of which can be exercised in a plain JVM unit test without large mocking scaffolding that is not used for ChatViewModel elsewhere. The change is a single guarded call.

How to check on a device

  1. Open a chat, hold the microphone button, slide up to lock.
  2. Speak, rotate the device, speak again, then press send.
  3. Before: the audio ends at the rotation. After: the whole message is there.
  4. Start a locked recording and leave the chat: the recording stops as before.

The symptom and the fix were checked by the author on a Huawei DEL-LX9 with a fork build. In the fork the same check is wired differently (its chat view model observes a lifecycle of its own), so this exact change was built and unit-tested here, but not yet run on a device.

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔖 Capability is checked or not needed
  • 🔙 Backport requests are created or not needed: /backport to stable-xx.x
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

The change was written with the help of Claude Code (Anthropic). The author reviewed the code, built it and ran the unit tests. The behavior was checked on a device with the fork variant of the fix.

A rotation stops the chat activity. ChatViewModel.onStop then stopped the
MediaRecorder, while the locked and in-progress state of the recording stayed.
The screen still showed a running recording and a truncated file was sent.

The view model now keeps the recorder running when the stopping activity is
changing its configuration. It reads this from the lifecycle owner: ON_STOP
reaches the observer before the body of Activity.onStop runs (API 29+), so a
flag set by the activity in onStop would come too late.
The recorder is still stopped when the user leaves the chat.

Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru>
Assisted-by: Claude-Code:claude-opus-5-5
@coderabbitai

coderabbitai Bot commented Oct 4, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ca17f351-2219-41d4-9e28-2e7e3d0b3a26
📥 Commits

Reviewing files that changed from the base of the PR and between 1e9c2f1 and d7add6b.

📒 Files selected for processing (1)
  • app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

ChatViewModel.onStop now skips mediaRecorderManager.handleOnStop() when its owner is an Activity that is changing configurations. Otherwise, it continues to stop the recorder.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to d7add

The change keeps a voice recording running through screen rotation while still stopping it when the user leaves the chat. No concrete merge-blocking risk was found. The change has not yet been tested on a device, so a quick manual rotation check is worthwhile.

Security Architecture Review

Security architecture risk: 🔵 Low · up to d7add

The change preserves an already authorized voice recording through screen rotation. Normal stopping and cancellation controls remain, but interrupted recreation and exceptional cleanup are not fully established.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The supported exposure change is longer capture by an already-active recorder during configuration recreation. The examined change does not add another recording session, broaden upload destination selection, or grant additional permissions.

Trust Boundaries and Controls

  • observed — The inspected touch entrypoint checks microphone and file permissions before starting recording. The retention decision reads the Activity's configuration-change state; other lifecycle owners and Activities not changing configurations still invoke recorder cleanup.

Resilience and Maintainability Implications

  • observed — Existing normal stop handling releases the recorder and guards repeated stops after release. Its exception path can skip release before clearing the recorder reference, so unconditional cleanup under failure is not established. This behavior predates the PR; the changed callback does not modify it.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: keeping a voice recording active during screen rotation.
Description check ✅ Passed The description explains the problem, cause, change, testing rationale, and device-check steps. It includes the screenshots, checklist, and AI disclosure. The TODO section is absent, and the milestone…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mahibi

mahibi commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

Hi @ToteMeiSter thank you for your contributions.
We will review them soon

@ToteMeiSter

Copy link
Copy Markdown
Contributor Author

This is a bug fix and all CodeRabbit review threads are resolved. Once it is approved and merged, would it be possible to backport it to stable-25.0.x (e.g. for 25.0.3)? The bug is present in v25.0.2.

Suggested command for a maintainer after merge: /backport to stable-25.0.x

This comment was drafted with AI assistance (Claude Code).

@mahibi
mahibi self-requested a review October 6, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews AI assisted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants