Closed Namelesswonder closed 1 year ago
Thank you for your report.
Unfortunately, AOSP sources for this version are not available yet.
So it seems that there are two issues:
invoke method java.lang.NoSuchMethodException: android.content.IClipboard$Stub$Proxy.addPrimaryClipChangedListener[interface android.content.IOnPrimaryClipChangedListener, class java.lang.String, class java.lang.String, int]
(unrelated to audio)
and
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Context.getDeviceId()' on a null object reference
What is the value of Build.VERSION.SDK_INT
on your device?
Does it work with the following patch?
diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java
index 5800487da..cb9a1e4ab 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Server.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Server.java
@@ -86,7 +86,7 @@ public final class Server {
// Before Android 11, audio is not supported.
// Since Android 12, we can properly set a context on the AudioRecord.
// Only on Android 11 we must fill app info for the AudioRecord to work.
- mustFillAppInfo |= audio && Build.VERSION.SDK_INT == Build.VERSION_CODES.R;
+ mustFillAppInfo |= audio;
if (mustFillAppInfo) {
Workarounds.fillAppInfo();
What is the value of Build.VERSION.SDK_INT on your device?
It's still 33 (Build.VERSION_CODES.TIRAMISU
)
at android.media.AudioRecord.resolveSessionId(AudioRecord.java:1093)
Decompiled source:
private static int resolveSessionId(Context context, int requestedSessionId) {
int deviceId;
VirtualDeviceManager vdm;
if (requestedSessionId != 0) {
return requestedSessionId;
}
if (context == null || (deviceId = context.getDeviceId()) == 0 || (vdm = (VirtualDeviceManager) context.getSystemService(VirtualDeviceManager.class)) == null || vdm.getDevicePolicy(deviceId, 1) == 0) {
return 0;
}
return vdm.getAudioRecordingSessionId(deviceId);
}
Returning 0 looks fine.
diff --git a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java
index 844d6bd8..d611c642 100644
--- a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java
+++ b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java
@@ -31,6 +31,10 @@ public final class FakeContext extends ContextWrapper {
return PACKAGE_NAME;
}
+ public int getDeviceId(){
+ return 0;
+ }
+
@TargetApi(Build.VERSION_CODES.S)
@Override
public AttributionSource getAttributionSource() {
This works on Android 14 RC2 emulator. It's a new method in Context
class, so no @Override
until SDK upgrade.
java.lang.NoSuchMethodException: android.content.IClipboard$Stub$Proxy.addPrimaryClipChangedListener[interface android.content.IOnPrimaryClipChangedListener, class java.lang.String, class java.lang.String, int]
public static class Default implements IClipboard {
public ClipData getPrimaryClip(String pkg, String attributionTag, int userId, int deviceId) {}
public void setPrimaryClip(ClipData clip, String callingPackage, String attributionTag, int userId, int deviceId) {}
public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener, String callingPackage, String attributionTag, int userId, int deviceId) {}
}
What is the value of Build.VERSION.SDK_INT on your device?
It's still 33 (
Build.VERSION_CODES.TIRAMISU
)at android.media.AudioRecord.resolveSessionId(AudioRecord.java:1093)
Decompiled source:
private static int resolveSessionId(Context context, int requestedSessionId) { int deviceId; VirtualDeviceManager vdm; if (requestedSessionId != 0) { return requestedSessionId; } if (context == null || (deviceId = context.getDeviceId()) == 0 || (vdm = (VirtualDeviceManager) context.getSystemService(VirtualDeviceManager.class)) == null || vdm.getDevicePolicy(deviceId, 1) == 0) { return 0; } return vdm.getAudioRecordingSessionId(deviceId); }
Returning 0 looks fine.
diff --git a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java index 844d6bd8..d611c642 100644 --- a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java +++ b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java @@ -31,6 +31,10 @@ public final class FakeContext extends ContextWrapper { return PACKAGE_NAME; } + public int getDeviceId(){ + return 0; + } + @TargetApi(Build.VERSION_CODES.S) @Override public AttributionSource getAttributionSource() {
This works on Android 14 RC2 emulator. It's a new method in
Context
class, so no@Override
until SDK upgrade.
Yep, just that patch is making audio work on the Pixel 7 Pro running Android 14 Developer Preview 2. Also no side effects as I tested with a Pixel XL running Android 11 and it's still fine after the patch.
diff --git a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java index 844d6bd8..d611c642 100644 --- a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java +++ b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java @@ -31,6 +31,10 @@ public final class FakeContext extends ContextWrapper { return PACKAGE_NAME; } + public int getDeviceId(){ + return 0; + } + @TargetApi(Build.VERSION_CODES.S) @Override public AttributionSource getAttributionSource() {
This works on Android 14 RC2 emulator. It's a new method in Context class, so no @Override until SDK upgrade.
Thank you :+1:
However, I'm surprised, because the error message suggests that the context is null
, not that the getDeviceId()
method is not found :confused:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Context.getDeviceId()' on a null object reference at android.content.ContextWrapper.getDeviceId(ContextWrapper.java:1226)
However, I'm surprised, because the error message suggests that the context is null, not that the
getDeviceId()
method is not found :confused:
Oh, probably because the default implementation delegates to the inner context, which is null
:ok_hand:
Please test/review branch android14
, and confirm that it fixes both audio and clipboard errors.
Please test/review branch
android14
, and confirm that it fixes both audio and clipboard errors.
Audio issues are resolved, however the clipboard errors are only semi-resolved.
Device to computer clipboard works, computer clipboard to device text entry works, however computer to device clipboard sync errors and causes the controller to crash leading to the controller crashing and input no longer working.
03-18 15:51:27.448 24914 24933 D scrcpy : Controller stopped
03-18 15:51:27.449 24914 24933 E AndroidRuntime: FATAL EXCEPTION: Thread-2
03-18 15:51:27.449 24914 24933 E AndroidRuntime: PID: 24914
03-18 15:51:27.449 24914 24933 E AndroidRuntime: java.lang.IllegalArgumentException: Wrong number ofarguments; expected 5, got 3
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.wrappers.ClipboardManager.setPrimaryClip(ClipboardManager.java:97)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.wrappers.ClipboardManager.setText(ClipboardManager.java:126)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.Device.setClipboardText(Device.java:271)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.Controller.setClipboard(Controller.java:394)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.Controller.handleEvent(Controller.java:160)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.Controller.control(Controller.java:83)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.Controller.lambda$start$0$com-genymobile-scrcpy-Controller(Controller.java:90)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at com.genymobile.scrcpy.Controller$$ExternalSyntheticLambda0.run(Unknown Source:2)
03-18 15:51:27.449 24914 24933 E AndroidRuntime: at java.lang.Thread.run(Thread.java:1012)
03-18 15:51:27.449 24914 24933 E scrcpy : Exception on thread Thread[Thread-2,5,main]
03-18 15:51:27.449 24914 24933 E scrcpy : java.lang.IllegalArgumentException: Wrong number of arguments; expected 5, got 3
03-18 15:51:27.449 24914 24933 E scrcpy : at java.lang.reflect.Method.invoke(Native Method)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.wrappers.ClipboardManager.setPrimaryClip(ClipboardManager.java:97)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.wrappers.ClipboardManager.setText(ClipboardManager.java:126)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.Device.setClipboardText(Device.java:271)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.Controller.setClipboard(Controller.java:394)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.Controller.handleEvent(Controller.java:160)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.Controller.control(Controller.java:83)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.Controller.lambda$start$0$com-genymobile-scrcpy-Controller(Controller.java:90)
03-18 15:51:27.449 24914 24933 E scrcpy : at com.genymobile.scrcpy.Controller$$ExternalSyntheticLambda0.run(Unknown Source:2)
03-18 15:51:27.449 24914 24933 E scrcpy : at java.lang.Thread.run(Thread.java:1012)
I've also done some more testing on the shortcuts and all work except for trying to turn the display off while mirroring.
03-18 16:44:22.446 873 897 E scrcpy : Could not invoke method
03-18 16:44:22.446 873 897 E scrcpy : java.lang.NoSuchMethodException: android.view.SurfaceControl.getPhysicalDisplayIds []
03-18 16:44:22.446 873 897 E scrcpy : at java.lang.Class.getMethod(Class.java:2771)
03-18 16:44:22.446 873 897 E scrcpy : at java.lang.Class.getMethod(Class.java:2351)
03-18 16:44:22.446 873 897 E scrcpy : at com.genymobile.scrcpy.wrappers.SurfaceControl.getGetPhysicalDisplayIdsMethod(SurfaceControl.java:137)
03-18 16:44:22.446 873 897 E scrcpy : at com.genymobile.scrcpy.wrappers.SurfaceControl.getPhysicalDisplayIds(SurfaceControl.java:144)
03-18 16:44:22.446 873 897 E scrcpy : at com.genymobile.scrcpy.Device.setScreenPowerMode(Device.java:282)
03-18 16:44:22.446 873 897 E scrcpy : at com.genymobile.scrcpy.Controller.handleEvent(Controller.java:165)
03-18 16:44:22.446 873 897 E scrcpy : at com.genymobile.scrcpy.Controller.control(Controller.java:83)
03-18 16:44:22.446 873 897 E scrcpy : at com.genymobile.scrcpy.Controller.lambda$start$0$com-genymobile-scrcpy-Controller(Controller.java:90)
03-18 16:44:22.446 873 897 E scrcpy : at com.genymobile.scrcpy.Controller$$ExternalSyntheticLambda0.run(Unknown Source:2)
03-18 16:44:22.446 873 897 E scrcpy : at java.lang.Thread.run(Thread.java:1012)
03-18 16:44:22.452 873 897 E scrcpy : Could not get physical display ids
however computer to device clipboard sync errors and causes the controller to crash leading to the controller crashing and input no longer working.
Oops, stupid mistake in my code. I just force-pushed android14
. Could you retry, please?
I've also done some more testing on the shortcuts and all work except for trying to turn the display off while mirroring.
Thank you for your tests :+1:
java.lang.NoSuchMethodException: android.view.SurfaceControl.getPhysicalDisplayIds []
Could you please post your framework.jar
?
adb pull /system/framework/framework.jar
Oops, stupid mistake in my code. I just force-pushed
android14
. Could you retry, please?
That fixes the issue. Also tested on Android 11 and no regressions.
Could you please post your
framework.jar
?
Hmm, SurfaceControl.getPhysicalDisplayIds()
does not exist anymore, and I don't know how it was replaced.
What if you just bypass the multi-display code:
diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java
index 3d83f73eb..0f181d8f6 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Device.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Device.java
@@ -277,7 +277,7 @@ public final class Device {
* @param mode one of the {@code POWER_MODE_*} constants
*/
public static boolean setScreenPowerMode(int mode) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ if (false && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Change the power mode for all physical displays
long[] physicalDisplayIds = SurfaceControl.getPhysicalDisplayIds();
if (physicalDisplayIds == null) {
Still a no go.
03-19 12:15:16.425 25899 25920 E scrcpy : Could not invoke method
03-19 12:15:16.425 25899 25920 E scrcpy : java.lang.NoSuchMethodException: android.view.SurfaceControl.getInternalDisplayToken []
03-19 12:15:16.425 25899 25920 E scrcpy : at java.lang.Class.getMethod(Class.java:2771)
03-19 12:15:16.425 25899 25920 E scrcpy : at java.lang.Class.getMethod(Class.java:2351)
03-19 12:15:16.425 25899 25920 E scrcpy : at com.genymobile.scrcpy.wrappers.SurfaceControl.getGetBuiltInDisplayMethod(SurfaceControl.java:96)
03-19 12:15:16.425 25899 25920 E scrcpy : at com.genymobile.scrcpy.wrappers.SurfaceControl.getBuiltInDisplay(SurfaceControl.java:104)
03-19 12:15:16.425 25899 25920 E scrcpy : at com.genymobile.scrcpy.Device.setScreenPowerMode(Device.java:297)
03-19 12:15:16.425 25899 25920 E scrcpy : at com.genymobile.scrcpy.Controller.handleEvent(Controller.java:165)
03-19 12:15:16.425 25899 25920 E scrcpy : at com.genymobile.scrcpy.Controller.control(Controller.java:83)
03-19 12:15:16.425 25899 25920 E scrcpy : at com.genymobile.scrcpy.Controller.lambda$start$0$com-genymobile-scrcpy-Controller(Controller.java:90)
03-19 12:15:16.425 25899 25920 E scrcpy : at com.genymobile.scrcpy.Controller$$ExternalSyntheticLambda0.run(Unknown Source:2)
03-19 12:15:16.425 25899 25920 E scrcpy : at java.lang.Thread.run(Thread.java:1012)
03-19 12:15:16.428 25899 25920 E scrcpy : Could not get built-in display
Hmm… ok, so I don't know :confused:
As a side note, there is a new class android.view.ScreenCapture
that may be relevant in Android 14, but I don't know how to get a valid displayToken
to call setDisplayPowerMode()
.
I merged 57f879d68a72c0d84f17d71ddf49c3b564bc614c (clipboard) and 2fff9b9edf749dd7a8ccf36fe2df3c3587f535ab (context/audio) to make scrcpy work on Android 14 preview 2. It remains the "turn screen off" feature, but I don't know how to fix it.
(now that the source code of Android 14 is released)
java.lang.NoSuchMethodException: android.view.SurfaceControl.getPhysicalDisplayIds []
It seems that the methods getPhysicalDisplayIds()
and getPhysicalDisplayToken()
have just been moved from SurfaceControl
to DisplayControl
in Android 14: https://github.com/aosp-mirror/platform_frameworks_base/blob/android-14.0.0_r2/services/core/java/com/android/server/display/DisplayControl.java#L94-L106
I don't have any device with Android 14 to test though.
Oh, I hadn't noticed, this class is in services/
(so it is not accessible from the running process, it is used by a server server in another process), so we can't access it from scrcpy :/
This is caused by this commit: https://github.com/aosp-mirror/platform_frameworks_base/commit/e2f333728788ad88a65208a6119aed90e13e7040
Is there any workaround for this? root? Brightness?
Is there perhaps an issue-tracker post about this, so we can star it, and maybe Google will allow it again?
I opened an issue: https://issuetracker.google.com/issues/303565669
Please do not comment on that issue just to say that you are impacted, this would just add noise.
(now that the source code of Android 14 is released)
java.lang.NoSuchMethodException: android.view.SurfaceControl.getPhysicalDisplayIds []
It seems that the methods
getPhysicalDisplayIds()
andgetPhysicalDisplayToken()
have just been moved fromSurfaceControl
toDisplayControl
in Android 14: https://github.com/aosp-mirror/platform_frameworks_base/blob/android-14.0.0_r2/services/core/java/com/android/server/display/DisplayControl.java#L94-L106I don't have any device with Android 14 to test though.
I can test for you on my pixel 6a
It remains 3 scrcpy features broken in Android 14:
Environment
Bug
Audio stream doesn't get initialized. This happens with all of the supported codecs
Logs
scrcpy --list-encoders
scrcpy console log
adb logcat