android, desktop: don't probe duration synchronously when stopping recorder

AudioPlayer.start() synchronously invokes RecorderInterface.stopRecording.
RecorderNative.stop() ran runBlocking { progressJob.cancelAndJoin() }, which
waits for the progress coroutine's invokeOnCompletion handler - and that
handler calls realDuration(path). On Desktop realDuration goes through
AudioPlayer.duration which constructs a fresh AudioPlayerComponent and runs
media().startPaused() on the recording file VLC just released; that probe
is slow and on Waydroid sometimes never returns. A second realDuration call
for stop()'s return value duplicated the I/O.

Skip the runBlocking await and return wall-clock elapsed from progress()
instead of probing the file. The progressJob's invokeOnCompletion still
fires (now async on Default), so the recState transition still happens via
the existing listener path - just no longer blocking the caller.

durationMs reported to RecordingState.Finished by stopRecordingAndAddAudio
is now wall-clock elapsed rather than container-probed - tens of ms looser,
well below any user-visible threshold for a voice message.
This commit is contained in:
Narasimha-sc
2026-04-29 07:54:30 +00:00
parent ab4b056c60
commit f1c2b38c51
2 changed files with 4 additions and 7 deletions
@@ -78,15 +78,12 @@ actual class RecorderNative: RecorderInterface {
runCatching {
recorder?.release()
}
// Await coroutine finishes in order to send real duration to it's listener
runBlocking {
progressJob?.cancelAndJoin()
}
progressJob?.cancel()
progressJob = null
filePath = null
recorder = null
keepScreenOn(false)
return (realDuration(path) ?: 0).also { recStartedAt = null }
return (progress() ?: 0).also { recStartedAt = null }
}
private fun progress(): Int? = recStartedAt?.let { (System.currentTimeMillis() - it).toInt() }
@@ -70,11 +70,11 @@ actual class RecorderNative: RecorderInterface {
RecorderInterface.stopRecording = null
runCatching { player?.controls()?.stop() }
runCatching { player?.release() }
runBlocking { progressJob?.cancelAndJoin() }
progressJob?.cancel()
progressJob = null
filePath = null
player = null
return (realDuration(path) ?: 0).also { recStartedAt = null }
return (progress() ?: 0).also { recStartedAt = null }
}
private fun progress(): Int? = recStartedAt?.let { (System.currentTimeMillis() - it).toInt() }