From 41506bc601fd7fa75091552a4225a7d706376b5a Mon Sep 17 00:00:00 2001 From: Fabian Wiesel Date: Mon, 26 Feb 2024 20:42:45 +0100 Subject: [PATCH] Wrap java exceptions in runCatching blocks --- .../rochefort/childmonitor/ListenService.kt | 83 +++++++++++-------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/app/src/main/kotlin/de/rochefort/childmonitor/ListenService.kt b/app/src/main/kotlin/de/rochefort/childmonitor/ListenService.kt index 8e0fe33..088fc77 100644 --- a/app/src/main/kotlin/de/rochefort/childmonitor/ListenService.kt +++ b/app/src/main/kotlin/de/rochefort/childmonitor/ListenService.kt @@ -33,7 +33,7 @@ import android.util.Log import android.widget.Toast import androidx.core.app.NotificationCompat import androidx.core.app.ServiceCompat -import java.io.IOException +import java.io.InputStream import java.net.Socket class ListenService : Service() { @@ -136,11 +136,19 @@ class ListenService : Service() { private var updateCallback: (() -> Unit)? = null private fun doListen(address: String?, port: Int) { val lt = Thread { - try { - val socket = Socket(address, port) - streamAudio(socket) - } catch (e: IOException) { - Log.e(TAG, "Failed to stream audio", e) + Socket(address, port).use { socket -> + val result = runCatching { socket.getInputStream() } + if (result.isSuccess) { + result.getOrNull()?.let {inputStream -> + withAudioTrack { audioTrack -> + streamAudio(inputStream, audioTrack) + } + } + } + else { + val exception = result.exceptionOrNull() + Log.e(TAG, "Failed to stream audio", exception) + } } if (!Thread.currentThread().isInterrupted) { // If this thread has not been interrupted, likely something @@ -155,37 +163,44 @@ class ListenService : Service() { lt.start() } - @Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class) - private fun streamAudio(socket: Socket) { + private fun withAudioTrack(block: (AudioTrack) -> Unit): Unit { Log.i(TAG, "Setting up stream") val audioTrack = AudioTrack(AudioManager.STREAM_MUSIC, - frequency, - channelConfiguration, - audioEncoding, - bufferSize, - AudioTrack.MODE_STREAM) - val inputStream = socket.getInputStream() - var read = 0 - audioTrack.play() - try { - val readBuffer = ByteArray(byteBufferSize) - val decodedBuffer = ShortArray(byteBufferSize * 2) - while (socket.isConnected && read != -1 && !Thread.currentThread().isInterrupted) { - read = inputStream.read(readBuffer) - val decoded: Int = AudioCodecDefines.CODEC.decode(decodedBuffer, readBuffer, read, 0) - if (decoded > 0) { - audioTrack.write(decodedBuffer, 0, decoded) - val decodedBytes = ShortArray(decoded) - System.arraycopy(decodedBuffer, 0, decodedBytes, 0, decoded) - volumeHistory.onAudioData(decodedBytes) - updateCallback?.invoke() - } + frequency, + channelConfiguration, + audioEncoding, + bufferSize, + AudioTrack.MODE_STREAM) + val playback = runCatching { audioTrack.play() } + if (playback.isFailure) { + Log.e(TAG, "Failed to start output due to ", playback.exceptionOrNull()) + return + } + + runCatching { block(audioTrack) } + audioTrack.stop() + } + + private fun streamAudio(inputStream: InputStream, audioTrack: AudioTrack) { + val readBuffer = ByteArray(byteBufferSize) + val decodedBuffer = ShortArray(byteBufferSize * 2) + while (!Thread.currentThread().isInterrupted) { + val read = runCatching { inputStream.read(readBuffer) } + if (read.isFailure) { + return + } + val len = read.getOrDefault(-1) + if (len < 0) { + return + } + val decoded: Int = AudioCodecDefines.CODEC.decode(decodedBuffer, readBuffer, len, 0) + if (decoded > 0) { + audioTrack.write(decodedBuffer, 0, decoded) + val decodedBytes = ShortArray(decoded) + System.arraycopy(decodedBuffer, 0, decodedBytes, 0, decoded) + volumeHistory.onAudioData(decodedBytes) + updateCallback?.invoke() } - } catch (e: Exception) { - Log.e(TAG, "Connection failed", e) - } finally { - audioTrack.stop() - socket.close() } }