package com.genymobile.scrcpy; import java.io.IOException; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public final class DeviceMessageSender { private final ControlChannel controlChannel; private Thread thread; private final BlockingQueue queue = new ArrayBlockingQueue<>(16); public DeviceMessageSender(ControlChannel controlChannel) { this.controlChannel = controlChannel; } public void send(DeviceMessage msg) { if (!queue.offer(msg)) { Ln.w("Device message dropped: " + msg.getType()); } } private void loop() throws IOException, InterruptedException { while (!Thread.currentThread().isInterrupted()) { DeviceMessage msg = queue.take(); controlChannel.send(msg); } } public void start() { thread = new Thread(() -> { try { loop(); } catch (IOException | InterruptedException e) { // this is expected on close } finally { Ln.d("Device message sender stopped"); } }, "control-send"); thread.start(); } public void stop() { if (thread != null) { thread.interrupt(); } } public void join() throws InterruptedException { if (thread != null) { thread.join(); } } }