Move clipboard management to Controller
Continue to declutter the global Device. PR #5370 <https://github.com/Genymobile/scrcpy/pull/5370>
This commit is contained in:
parent
7cfefae5e1
commit
d916429566
@ -9,7 +9,6 @@ import com.genymobile.scrcpy.audio.AudioRawRecorder;
|
|||||||
import com.genymobile.scrcpy.audio.AudioSource;
|
import com.genymobile.scrcpy.audio.AudioSource;
|
||||||
import com.genymobile.scrcpy.control.ControlChannel;
|
import com.genymobile.scrcpy.control.ControlChannel;
|
||||||
import com.genymobile.scrcpy.control.Controller;
|
import com.genymobile.scrcpy.control.Controller;
|
||||||
import com.genymobile.scrcpy.control.DeviceMessage;
|
|
||||||
import com.genymobile.scrcpy.device.ConfigurationException;
|
import com.genymobile.scrcpy.device.ConfigurationException;
|
||||||
import com.genymobile.scrcpy.device.DesktopConnection;
|
import com.genymobile.scrcpy.device.DesktopConnection;
|
||||||
import com.genymobile.scrcpy.device.Device;
|
import com.genymobile.scrcpy.device.Device;
|
||||||
@ -142,7 +141,7 @@ public final class Server {
|
|||||||
boolean sendDummyByte = options.getSendDummyByte();
|
boolean sendDummyByte = options.getSendDummyByte();
|
||||||
boolean camera = video && options.getVideoSource() == VideoSource.CAMERA;
|
boolean camera = video && options.getVideoSource() == VideoSource.CAMERA;
|
||||||
|
|
||||||
final Device device = camera ? null : new Device(options);
|
final Device device = camera ? null : new Device();
|
||||||
|
|
||||||
Workarounds.apply();
|
Workarounds.apply();
|
||||||
|
|
||||||
@ -158,10 +157,6 @@ public final class Server {
|
|||||||
ControlChannel controlChannel = connection.getControlChannel();
|
ControlChannel controlChannel = connection.getControlChannel();
|
||||||
Controller controller = new Controller(
|
Controller controller = new Controller(
|
||||||
device, options.getDisplayId(), controlChannel, cleanUp, options.getClipboardAutosync(), options.getPowerOn());
|
device, options.getDisplayId(), controlChannel, cleanUp, options.getClipboardAutosync(), options.getPowerOn());
|
||||||
device.setClipboardListener(text -> {
|
|
||||||
DeviceMessage msg = DeviceMessage.createClipboard(text);
|
|
||||||
controller.getSender().send(msg);
|
|
||||||
});
|
|
||||||
asyncProcessors.add(controller);
|
asyncProcessors.add(controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,11 @@ import com.genymobile.scrcpy.device.Device;
|
|||||||
import com.genymobile.scrcpy.device.Point;
|
import com.genymobile.scrcpy.device.Point;
|
||||||
import com.genymobile.scrcpy.device.Position;
|
import com.genymobile.scrcpy.device.Position;
|
||||||
import com.genymobile.scrcpy.util.Ln;
|
import com.genymobile.scrcpy.util.Ln;
|
||||||
|
import com.genymobile.scrcpy.wrappers.ClipboardManager;
|
||||||
import com.genymobile.scrcpy.wrappers.InputManager;
|
import com.genymobile.scrcpy.wrappers.InputManager;
|
||||||
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||||
|
|
||||||
|
import android.content.IOnPrimaryClipChangedListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
@ -23,6 +25,7 @@ import java.io.IOException;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class Controller implements AsyncProcessor {
|
public class Controller implements AsyncProcessor {
|
||||||
|
|
||||||
@ -48,6 +51,8 @@ public class Controller implements AsyncProcessor {
|
|||||||
|
|
||||||
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
|
private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
|
||||||
|
|
||||||
|
private final AtomicBoolean isSettingClipboard = new AtomicBoolean();
|
||||||
|
|
||||||
private long lastTouchDown;
|
private long lastTouchDown;
|
||||||
private final PointersState pointersState = new PointersState();
|
private final PointersState pointersState = new PointersState();
|
||||||
private final MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[PointersState.MAX_POINTERS];
|
private final MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[PointersState.MAX_POINTERS];
|
||||||
@ -69,6 +74,29 @@ public class Controller implements AsyncProcessor {
|
|||||||
if (!supportsInputEvents) {
|
if (!supportsInputEvents) {
|
||||||
Ln.w("Input events are not supported for secondary displays before Android 10");
|
Ln.w("Input events are not supported for secondary displays before Android 10");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clipboardAutosync) {
|
||||||
|
// If control and autosync are enabled, synchronize Android clipboard to the computer automatically
|
||||||
|
ClipboardManager clipboardManager = ServiceManager.getClipboardManager();
|
||||||
|
if (clipboardManager != null) {
|
||||||
|
clipboardManager.addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() {
|
||||||
|
@Override
|
||||||
|
public void dispatchPrimaryClipChanged() {
|
||||||
|
if (isSettingClipboard.get()) {
|
||||||
|
// This is a notification for the change we are currently applying, ignore it
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String text = Device.getClipboardText();
|
||||||
|
if (text != null) {
|
||||||
|
DeviceMessage msg = DeviceMessage.createClipboard(text);
|
||||||
|
sender.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Ln.w("No clipboard manager, copy-paste between device and computer will not work");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UhidManager getUhidManager() {
|
private UhidManager getUhidManager() {
|
||||||
@ -148,10 +176,6 @@ public class Controller implements AsyncProcessor {
|
|||||||
sender.join();
|
sender.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceMessageSender getSender() {
|
|
||||||
return sender;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean handleEvent() throws IOException {
|
private boolean handleEvent() throws IOException {
|
||||||
ControlMessage msg;
|
ControlMessage msg;
|
||||||
try {
|
try {
|
||||||
@ -452,7 +476,9 @@ public class Controller implements AsyncProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean setClipboard(String text, boolean paste, long sequence) {
|
private boolean setClipboard(String text, boolean paste, long sequence) {
|
||||||
boolean ok = device.setClipboardText(text);
|
isSettingClipboard.set(true);
|
||||||
|
boolean ok = Device.setClipboardText(text);
|
||||||
|
isSettingClipboard.set(false);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
Ln.i("Device clipboard set");
|
Ln.i("Device clipboard set");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.genymobile.scrcpy.device;
|
package com.genymobile.scrcpy.device;
|
||||||
|
|
||||||
import com.genymobile.scrcpy.AndroidVersions;
|
import com.genymobile.scrcpy.AndroidVersions;
|
||||||
import com.genymobile.scrcpy.Options;
|
|
||||||
import com.genymobile.scrcpy.util.Ln;
|
import com.genymobile.scrcpy.util.Ln;
|
||||||
import com.genymobile.scrcpy.video.ScreenInfo;
|
import com.genymobile.scrcpy.video.ScreenInfo;
|
||||||
import com.genymobile.scrcpy.wrappers.ClipboardManager;
|
import com.genymobile.scrcpy.wrappers.ClipboardManager;
|
||||||
@ -11,7 +10,6 @@ import com.genymobile.scrcpy.wrappers.ServiceManager;
|
|||||||
import com.genymobile.scrcpy.wrappers.SurfaceControl;
|
import com.genymobile.scrcpy.wrappers.SurfaceControl;
|
||||||
import com.genymobile.scrcpy.wrappers.WindowManager;
|
import com.genymobile.scrcpy.wrappers.WindowManager;
|
||||||
|
|
||||||
import android.content.IOnPrimaryClipChangedListener;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@ -21,7 +19,6 @@ import android.view.InputEvent;
|
|||||||
import android.view.KeyCharacterMap;
|
import android.view.KeyCharacterMap;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public final class Device {
|
public final class Device {
|
||||||
@ -36,43 +33,8 @@ public final class Device {
|
|||||||
public static final int LOCK_VIDEO_ORIENTATION_UNLOCKED = -1;
|
public static final int LOCK_VIDEO_ORIENTATION_UNLOCKED = -1;
|
||||||
public static final int LOCK_VIDEO_ORIENTATION_INITIAL = -2;
|
public static final int LOCK_VIDEO_ORIENTATION_INITIAL = -2;
|
||||||
|
|
||||||
public interface ClipboardListener {
|
|
||||||
void onClipboardTextChanged(String text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClipboardListener clipboardListener;
|
|
||||||
private final AtomicBoolean isSettingClipboard = new AtomicBoolean();
|
|
||||||
|
|
||||||
private final AtomicReference<ScreenInfo> screenInfo = new AtomicReference<>(); // set by the ScreenCapture instance
|
private final AtomicReference<ScreenInfo> screenInfo = new AtomicReference<>(); // set by the ScreenCapture instance
|
||||||
|
|
||||||
public Device(Options options) {
|
|
||||||
if (options.getControl() && options.getClipboardAutosync()) {
|
|
||||||
// If control and autosync are enabled, synchronize Android clipboard to the computer automatically
|
|
||||||
ClipboardManager clipboardManager = ServiceManager.getClipboardManager();
|
|
||||||
if (clipboardManager != null) {
|
|
||||||
clipboardManager.addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() {
|
|
||||||
@Override
|
|
||||||
public void dispatchPrimaryClipChanged() {
|
|
||||||
if (isSettingClipboard.get()) {
|
|
||||||
// This is a notification for the change we are currently applying, ignore it
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
synchronized (Device.this) {
|
|
||||||
if (clipboardListener != null) {
|
|
||||||
String text = getClipboardText();
|
|
||||||
if (text != null) {
|
|
||||||
clipboardListener.onClipboardTextChanged(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Ln.w("No clipboard manager, copy-paste between device and computer will not work");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Point getPhysicalPoint(Position position) {
|
public Point getPhysicalPoint(Position position) {
|
||||||
// it hides the field on purpose, to read it with atomic access
|
// it hides the field on purpose, to read it with atomic access
|
||||||
@SuppressWarnings("checkstyle:HiddenField")
|
@SuppressWarnings("checkstyle:HiddenField")
|
||||||
@ -142,10 +104,6 @@ public final class Device {
|
|||||||
return ServiceManager.getPowerManager().isScreenOn();
|
return ServiceManager.getPowerManager().isScreenOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setClipboardListener(ClipboardListener clipboardListener) {
|
|
||||||
this.clipboardListener = clipboardListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void expandNotificationPanel() {
|
public static void expandNotificationPanel() {
|
||||||
ServiceManager.getStatusBarManager().expandNotificationsPanel();
|
ServiceManager.getStatusBarManager().expandNotificationsPanel();
|
||||||
}
|
}
|
||||||
@ -170,7 +128,7 @@ public final class Device {
|
|||||||
return s.toString();
|
return s.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setClipboardText(String text) {
|
public static boolean setClipboardText(String text) {
|
||||||
ClipboardManager clipboardManager = ServiceManager.getClipboardManager();
|
ClipboardManager clipboardManager = ServiceManager.getClipboardManager();
|
||||||
if (clipboardManager == null) {
|
if (clipboardManager == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -185,10 +143,7 @@ public final class Device {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isSettingClipboard.set(true);
|
return clipboardManager.setText(text);
|
||||||
boolean ok = clipboardManager.setText(text);
|
|
||||||
isSettingClipboard.set(false);
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user