Refactor error handling in ListenService

This commit is contained in:
edr
2024-03-20 19:52:01 +01:00
parent 4bc2b0f8a7
commit 1018ded2d9

View File

@@ -134,32 +134,21 @@ class ListenService : Service() {
private fun doListen(address: String?, port: Int) { private fun doListen(address: String?, port: Int) {
val lt = Thread { val lt = Thread {
try { try {
Result.success(Socket(address, port)) val socket = Socket(address, port)
} catch (e : IOException) { val success = streamAudio(socket)
Result.failure(e) if (!success) {
}.fold(
{ streamAudio(it) }, // This also may return a failure
{ Result.failure(it) } // Or we already have one
).onFailure { e ->
when (e) {
is IOException -> Log.e(TAG, "Failed to stream audio", e)
else -> Log.e(TAG, "Failed to stream audio for other reason", e)
}
}
if (!Thread.currentThread().isInterrupted) {
// If this thread has not been interrupted, likely something
// bad happened with the connection to the child device. Play
// an alert to notify the user that the connection has been
// interrupted.
playAlert() playAlert()
errorCallback?.invoke() errorCallback?.invoke()
} }
} catch (e : IOException) {
Log.e(TAG, "Error opening socket to $address on port $port", e)
}
} }
this.listenThread = lt this.listenThread = lt
lt.start() lt.start()
} }
private fun streamAudio(socket: Socket): Result<Int> { private fun streamAudio(socket: Socket): Boolean {
Log.i(TAG, "Setting up stream") Log.i(TAG, "Setting up stream")
val audioTrack = AudioTrack(AudioManager.STREAM_MUSIC, val audioTrack = AudioTrack(AudioManager.STREAM_MUSIC,
frequency, frequency,
@@ -169,16 +158,16 @@ class ListenService : Service() {
AudioTrack.MODE_STREAM) AudioTrack.MODE_STREAM)
try { try {
audioTrack.play() audioTrack.play()
} } catch (e : java.lang.IllegalStateException) {
catch (e : java.lang.IllegalStateException) { Log.e(TAG, "Failed to play streamed audio audio for other reason", e)
return Result.failure(e) return false
} }
val inputStream = try { val inputStream = try {
socket.getInputStream() socket.getInputStream()
} } catch (e: IOException) {
catch (e: IOException) { Log.e(TAG, "Failed to read audio audio for socket", e)
return Result.failure(e) return false
} }
val readBuffer = ByteArray(byteBufferSize) val readBuffer = ByteArray(byteBufferSize)
@@ -187,7 +176,7 @@ class ListenService : Service() {
while (!Thread.currentThread().isInterrupted) { while (!Thread.currentThread().isInterrupted) {
val len = inputStream.read(readBuffer) val len = inputStream.read(readBuffer)
if (len < 0) { if (len < 0) {
return Result.success(len) return true
} }
val decoded: Int = AudioCodecDefines.CODEC.decode(decodedBuffer, readBuffer, len, 0) val decoded: Int = AudioCodecDefines.CODEC.decode(decodedBuffer, readBuffer, len, 0)
if (decoded > 0) { if (decoded > 0) {
@@ -198,13 +187,14 @@ class ListenService : Service() {
updateCallback?.invoke() updateCallback?.invoke()
} }
} }
return true
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Connection failed", e) Log.e(TAG, "Connection failed", e)
return false
} finally { } finally {
audioTrack.stop() audioTrack.stop()
socket.close() socket.close()
} }
return Result.success(0) // Not really a success, but that's how it maps
} }
private fun playAlert() { private fun playAlert() {