diff --git a/server/src/main/aidl/android/content/IOnPrimaryClipChangedListener.aidl b/server/src/main/aidl/android/content/IOnPrimaryClipChangedListener.aidl new file mode 100644 index 00000000..46d7f7ca --- /dev/null +++ b/server/src/main/aidl/android/content/IOnPrimaryClipChangedListener.aidl @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2008, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +/** + * {@hide} + */ +oneway interface IOnPrimaryClipChangedListener { + void dispatchPrimaryClipChanged(); +} diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java index 6aa339a1..3b277f4c 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/Device.java @@ -6,6 +6,7 @@ import com.genymobile.scrcpy.wrappers.ServiceManager; import com.genymobile.scrcpy.wrappers.SurfaceControl; import com.genymobile.scrcpy.wrappers.WindowManager; +import android.content.IOnPrimaryClipChangedListener; import android.graphics.Rect; import android.os.Build; import android.os.IBinder; @@ -66,6 +67,14 @@ public final class Device { } }, displayId); + serviceManager.getClipboardManager().addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() { + @Override + public void dispatchPrimaryClipChanged() { + String s = getClipboardText(); + Ln.i("clipboard changed = " + s); + } + }); + if ((displayInfoFlags & DisplayInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) == 0) { Ln.w("Display doesn't have FLAG_SUPPORTS_PROTECTED_BUFFERS flag, mirroring can be restricted"); } diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index 651affde..bacd9865 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -171,7 +171,7 @@ public class ScreenEncoder implements Device.RotationListener { } private static IBinder createDisplay() { - return SurfaceControl.createDisplay("scrcpy", true); + return SurfaceControl.createDisplay("scrcpy", false); } private static void configure(MediaCodec codec, MediaFormat format) { diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java index 7a3bfafb..e25b6e99 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java @@ -3,6 +3,7 @@ package com.genymobile.scrcpy.wrappers; import com.genymobile.scrcpy.Ln; import android.content.ClipData; +import android.content.IOnPrimaryClipChangedListener; import android.os.Build; import android.os.IInterface; @@ -13,6 +14,7 @@ public class ClipboardManager { private final IInterface manager; private Method getPrimaryClipMethod; private Method setPrimaryClipMethod; + private Method addPrimaryClipChangedListener; public ClipboardManager(IInterface manager) { this.manager = manager; @@ -81,4 +83,37 @@ public class ClipboardManager { return false; } } + + private static void addPrimaryClipChangedListener(Method method, IInterface manager, IOnPrimaryClipChangedListener listener) + throws InvocationTargetException, IllegalAccessException { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + method.invoke(manager, listener, ServiceManager.PACKAGE_NAME); + } else { + method.invoke(manager, listener, ServiceManager.PACKAGE_NAME, ServiceManager.USER_ID); + } + } + + private Method getAddPrimaryClipChangedListener() throws NoSuchMethodException { + if (addPrimaryClipChangedListener == null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + addPrimaryClipChangedListener = manager.getClass() + .getMethod("addPrimaryClipChangedListener", IOnPrimaryClipChangedListener.class, String.class); + } else { + addPrimaryClipChangedListener = manager.getClass() + .getMethod("addPrimaryClipChangedListener", IOnPrimaryClipChangedListener.class, String.class, int.class); + } + } + return addPrimaryClipChangedListener; + } + + public boolean addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) { + try { + Method method = getAddPrimaryClipChangedListener(); + addPrimaryClipChangedListener(method, manager, listener); + return true; + } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { + Ln.e("Could not invoke method", e); + return false; + } + } }