From b13aece7a1f756a96ca98ca92bb4d43ae22caad4 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Tue, 20 Dec 2022 10:38:39 +0100 Subject: [PATCH] Adapt ClipboardManager for Android 13 A new "attributionTag" parameter has been added to the methods getPrimaryClip(), setPrimaryClip() and addPrimaryClipChangedListener() of IClipboard.aidl. Refs Fixes #3497 --- .../scrcpy/wrappers/ClipboardManager.java | 52 ++++++++++++++----- 1 file changed, 39 insertions(+), 13 deletions(-) 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 e25b6e994c..aeb5935778 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java @@ -15,6 +15,9 @@ public class ClipboardManager { private Method getPrimaryClipMethod; private Method setPrimaryClipMethod; private Method addPrimaryClipChangedListener; + private boolean alternativeGetMethod; + private boolean alternativeSetMethod; + private boolean alternativeAddListenerMethod; public ClipboardManager(IInterface manager) { this.manager = manager; @@ -25,7 +28,12 @@ private Method getGetPrimaryClipMethod() throws NoSuchMethodException { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { getPrimaryClipMethod = manager.getClass().getMethod("getPrimaryClip", String.class); } else { - getPrimaryClipMethod = manager.getClass().getMethod("getPrimaryClip", String.class, int.class); + try { + getPrimaryClipMethod = manager.getClass().getMethod("getPrimaryClip", String.class, int.class); + } catch (NoSuchMethodException e) { + getPrimaryClipMethod = manager.getClass().getMethod("getPrimaryClip", String.class, String.class, int.class); + alternativeGetMethod = true; + } } } return getPrimaryClipMethod; @@ -36,23 +44,34 @@ private Method getSetPrimaryClipMethod() throws NoSuchMethodException { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { setPrimaryClipMethod = manager.getClass().getMethod("setPrimaryClip", ClipData.class, String.class); } else { - setPrimaryClipMethod = manager.getClass().getMethod("setPrimaryClip", ClipData.class, String.class, int.class); + try { + setPrimaryClipMethod = manager.getClass().getMethod("setPrimaryClip", ClipData.class, String.class, int.class); + } catch (NoSuchMethodException e) { + setPrimaryClipMethod = manager.getClass().getMethod("setPrimaryClip", ClipData.class, String.class, String.class, int.class); + alternativeSetMethod = true; + } } } return setPrimaryClipMethod; } - private static ClipData getPrimaryClip(Method method, IInterface manager) throws InvocationTargetException, IllegalAccessException { + private static ClipData getPrimaryClip(Method method, boolean alternativeMethod, IInterface manager) + throws InvocationTargetException, IllegalAccessException { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { return (ClipData) method.invoke(manager, ServiceManager.PACKAGE_NAME); } + if (alternativeMethod) { + return (ClipData) method.invoke(manager, ServiceManager.PACKAGE_NAME, null, ServiceManager.USER_ID); + } return (ClipData) method.invoke(manager, ServiceManager.PACKAGE_NAME, ServiceManager.USER_ID); } - private static void setPrimaryClip(Method method, IInterface manager, ClipData clipData) + private static void setPrimaryClip(Method method, boolean alternativeMethod, IInterface manager, ClipData clipData) throws InvocationTargetException, IllegalAccessException { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { method.invoke(manager, clipData, ServiceManager.PACKAGE_NAME); + } else if (alternativeMethod) { + method.invoke(manager, clipData, ServiceManager.PACKAGE_NAME, null, ServiceManager.USER_ID); } else { method.invoke(manager, clipData, ServiceManager.PACKAGE_NAME, ServiceManager.USER_ID); } @@ -61,7 +80,7 @@ private static void setPrimaryClip(Method method, IInterface manager, ClipData c public CharSequence getText() { try { Method method = getGetPrimaryClipMethod(); - ClipData clipData = getPrimaryClip(method, manager); + ClipData clipData = getPrimaryClip(method, alternativeGetMethod, manager); if (clipData == null || clipData.getItemCount() == 0) { return null; } @@ -76,7 +95,7 @@ public boolean setText(CharSequence text) { try { Method method = getSetPrimaryClipMethod(); ClipData clipData = ClipData.newPlainText(null, text); - setPrimaryClip(method, manager, clipData); + setPrimaryClip(method, alternativeSetMethod, manager, clipData); return true; } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { Ln.e("Could not invoke method", e); @@ -84,13 +103,14 @@ public boolean setText(CharSequence text) { } } - private static void addPrimaryClipChangedListener(Method method, IInterface manager, IOnPrimaryClipChangedListener listener) - throws InvocationTargetException, IllegalAccessException { + private static void addPrimaryClipChangedListener(Method method, boolean alternativeMethod, IInterface manager, + IOnPrimaryClipChangedListener listener) throws InvocationTargetException, IllegalAccessException { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { method.invoke(manager, listener, ServiceManager.PACKAGE_NAME); - } else { + } else if (alternativeMethod) { + method.invoke(manager, listener, ServiceManager.PACKAGE_NAME, null, ServiceManager.USER_ID); + } else method.invoke(manager, listener, ServiceManager.PACKAGE_NAME, ServiceManager.USER_ID); - } } private Method getAddPrimaryClipChangedListener() throws NoSuchMethodException { @@ -99,8 +119,14 @@ private Method getAddPrimaryClipChangedListener() throws NoSuchMethodException { addPrimaryClipChangedListener = manager.getClass() .getMethod("addPrimaryClipChangedListener", IOnPrimaryClipChangedListener.class, String.class); } else { - addPrimaryClipChangedListener = manager.getClass() - .getMethod("addPrimaryClipChangedListener", IOnPrimaryClipChangedListener.class, String.class, int.class); + try { + addPrimaryClipChangedListener = manager.getClass() + .getMethod("addPrimaryClipChangedListener", IOnPrimaryClipChangedListener.class, String.class, int.class); + } catch (NoSuchMethodException e) { + addPrimaryClipChangedListener = manager.getClass() + .getMethod("addPrimaryClipChangedListener", IOnPrimaryClipChangedListener.class, String.class, String.class, int.class); + alternativeAddListenerMethod = true; + } } } return addPrimaryClipChangedListener; @@ -109,7 +135,7 @@ private Method getAddPrimaryClipChangedListener() throws NoSuchMethodException { public boolean addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) { try { Method method = getAddPrimaryClipChangedListener(); - addPrimaryClipChangedListener(method, manager, listener); + addPrimaryClipChangedListener(method, alternativeAddListenerMethod, manager, listener); return true; } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { Ln.e("Could not invoke method", e);