From 40fbde90014f3e4f2bdca35ee8f44644641ffce4 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Thu, 27 Jan 2022 18:46:42 -0800 Subject: Improve handling of agent crashes With this change an agent crash triggers the "Lost connection to the device. See the error log." error message. Test: later Bug: N/A Change-Id: I0179b26a65a865d7e8284cf6663cd449cbc0d273 --- .../src/com/android/tools/idea/device/DeviceView.kt | 21 ++++++++++++++++----- .../com/android/tools/idea/device/VideoDecoder.kt | 16 ++++++++++++---- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'emulator') diff --git a/emulator/src/com/android/tools/idea/device/DeviceView.kt b/emulator/src/com/android/tools/idea/device/DeviceView.kt index 8279a2a1d74..7065517f142 100644 --- a/emulator/src/com/android/tools/idea/device/DeviceView.kt +++ b/emulator/src/com/android/tools/idea/device/DeviceView.kt @@ -156,6 +156,7 @@ class DeviceView( } } decoder.addFrameListener(object : VideoDecoder.FrameListener { + override fun onNewFrameAvailable() { EventQueue.invokeLater { if (frameNumber == 0) { @@ -167,6 +168,10 @@ class DeviceView( } } } + + override fun onEndOfVideoStream() { + showDisconnectedMessage("Lost connection to the device. See the error log.") + } }) deviceClient.startVideoDecoding(decoder) } @@ -175,11 +180,17 @@ class DeviceView( } catch (e: Throwable) { thisLogger().error("Failed to initialize the screen sharing agent", e) - EventQueue.invokeLater { - hideLongRunningOperationIndicatorInstantly() - disconnectedStateLabel.text = "Failed to initialize the device agent. See the error log." - add(disconnectedStateLabel) - } + showDisconnectedMessage("Failed to initialize the device agent. See the error log.") + } + } + + private fun showDisconnectedMessage(message: String) { + EventQueue.invokeLater { + decoder = null + hideLongRunningOperationIndicatorInstantly() + disconnectedStateLabel.text = message + add(disconnectedStateLabel) + revalidate() } } diff --git a/emulator/src/com/android/tools/idea/device/VideoDecoder.kt b/emulator/src/com/android/tools/idea/device/VideoDecoder.kt index 77fd1420fc6..3ee786d03c9 100644 --- a/emulator/src/com/android/tools/idea/device/VideoDecoder.kt +++ b/emulator/src/com/android/tools/idea/device/VideoDecoder.kt @@ -118,18 +118,26 @@ internal class VideoDecoder(private val videoChannel: SuspendingSocketChannel, @ } finally { decodingContext.close() + onEndOfVideoStream() } } } - private fun notifyFrameListeners() { + private fun onNewFrameAvailable() { for (listener in frameListeners) { listener.onNewFrameAvailable() } } + private fun onEndOfVideoStream() { + for (listener in frameListeners) { + listener.onEndOfVideoStream() + } + } + interface FrameListener { fun onNewFrameAvailable() + fun onEndOfVideoStream() } internal class VideoFrame( @@ -139,7 +147,7 @@ internal class VideoDecoder(private val videoChannel: SuspendingSocketChannel, @ val frameNumber: Long, val originationTime: Long) - private inner class DecodingContext { + private inner class DecodingContext : AutoCloseable { private val codec: AVCodec private val codecContext: AVCodecContext @@ -211,7 +219,7 @@ internal class VideoDecoder(private val videoChannel: SuspendingSocketChannel, @ } } - fun close() { + override fun close() { avcodec_close(codecContext) avcodec_free_context(codecContext) av_frame_free(decodingFrame) @@ -332,7 +340,7 @@ internal class VideoDecoder(private val videoChannel: SuspendingSocketChannel, @ header.originationTimestampUs / 1000) } - notifyFrameListeners() + onNewFrameAvailable() } private fun createSwsContext(renderingFrame: AVFrame): SwsContext { -- cgit v1.2.3