scrcpy: Doesn't work after upgrading to Android 14

  • I have read the FAQ.
  • I have searched in existing issues.

Environment

  • OS: Windows 10
  • scrcpy version: 2.3
  • installation method: Windows Build 64bit
  • device model: samsung SM-S908B
  • Android version: 14

Describe the bug

After upgrading my phone to Android 14 (from Android 13) scrcpy stopped working with the following error. I also tried no-audio and all available encoders. Before the upgrade, it worked just fine.

[server] INFO: Device: [samsung] samsung SM-S908B (Android 14)
[server] ERROR: Exception on thread Thread[video,5,main]
java.lang.AssertionError: java.lang.reflect.InvocationTargetException
        at com.genymobile.scrcpy.wrappers.SurfaceControl.createDisplay(SurfaceControl.java:85)
        at com.genymobile.scrcpy.ScreenCapture.createDisplay(ScreenCapture.java:77)
        at com.genymobile.scrcpy.ScreenCapture.start(ScreenCapture.java:38)
        at com.genymobile.scrcpy.SurfaceEncoder.streamScreen(SurfaceEncoder.java:72)
        at com.genymobile.scrcpy.SurfaceEncoder.lambda$start$0$com-genymobile-scrcpy-SurfaceEncoder(SurfaceEncoder.java:253)
        at com.genymobile.scrcpy.SurfaceEncoder$$ExternalSyntheticLambda0.run(Unknown Source:4)
        at java.lang.Thread.run(Thread.java:1012)
Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.genymobile.scrcpy.wrappers.SurfaceControl.createDisplay(SurfaceControl.java:83)
        ... 6 more
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Configuration android.app.ConfigurationController.getConfiguration()' on a null object reference
        at android.app.ActivityThread.getConfiguration(ActivityThread.java:3899)
        at android.hardware.display.DisplayManagerGlobal.getDisplayInfoLocked(DisplayManagerGlobal.java:260)
        at android.hardware.display.DisplayManagerGlobal.getDisplayInfo(DisplayManagerGlobal.java:234)
        at android.hardware.display.DisplayManagerGlobal.getCompatibleDisplay(DisplayManagerGlobal.java:364)
        at android.hardware.display.DisplayManagerGlobal.getRealDisplay(DisplayManagerGlobal.java:397)
        at android.hardware.display.DisplayManagerGlobal.createVirtualDisplayWrapper(DisplayManagerGlobal.java:779)
        at android.hardware.display.DisplayManager.createVirtualDisplay(DisplayManager.java:2088)
        at android.view.SurfaceControl.createDisplay(SurfaceControl.java:2480)
        ... 8 more
INFO: Renderer: direct3d
ERROR: Demuxer 'audio': stream disabled due to connection error
INFO: Texture: 1440x3088
WARN: Device disconnected

Also, if I do video-source camera, I get a different error as below. I do not know whether the two things are related. Before upgrading, I could not access all cameras (either not listed or instantly disconnecting without error message) but only two, now this error occurs all the time.

[server] INFO: Device: [samsung] samsung SM-S908B (Android 14)
[server] ERROR: Exception on thread Thread[video,5,main]
java.lang.AssertionError: java.lang.reflect.InvocationTargetException
        at com.genymobile.scrcpy.wrappers.ServiceManager.getCameraManager(ServiceManager.java:146)
        at com.genymobile.scrcpy.CameraCapture.selectCamera(CameraCapture.java:97)
        at com.genymobile.scrcpy.CameraCapture.init(CameraCapture.java:75)
        at com.genymobile.scrcpy.SurfaceEncoder.streamScreen(SurfaceEncoder.java:55)
        at com.genymobile.scrcpy.SurfaceEncoder.lambda$start$0$com-genymobile-scrcpy-SurfaceEncoder(SurfaceEncoder.java:253)
        at com.genymobile.scrcpy.SurfaceEncoder$$ExternalSyntheticLambda0.run(Unknown Source:4)
        at java.lang.Thread.run(Thread.java:1012)
Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at com.genymobile.scrcpy.wrappers.ServiceManager.getCameraManager(ServiceManager.java:144)
        ... 6 more
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Context.checkSelfPermission(java.lang.String)' on a null object reference
        at android.content.ContextWrapper.checkSelfPermission(ContextWrapper.java:982)
        at android.hardware.camera2.CameraManager.<init>(CameraManager.java:229)
        ... 9 more
INFO: Renderer: direct3d
ERROR: Demuxer 'video': stream disabled due to connection error
ERROR: Demuxer 'audio': stream disabled due to connection error
ERROR: Demuxer error

EDIT by @rom1v: fixed in scrcpy 2.3.1.

old This will be fixed in the next version.

Meanwhile, replace this file in the scrcpy 2.3 directory:

  • scrcpy-server SHA-256: d3a1e798c490dd85e4bac19d5fb95b748f34f13c84676ddaa1f661ddb7ffc7e1

About this issue

  • Original URL
  • State: closed
  • Created 7 months ago
  • Reactions: 3
  • Comments: 42

Commits related to this issue

Most upvoted comments

Tried compile dev branch

Did you also compile the server? (install_release() only installs the latest release)

Instead, download scrcpy-server posted on the first post, and replace it in /usr/local/share/scrcpy/scrcpy-server.

@moe7863 No, the fix is in the first post of this thread.

I think 140a49b can fix it.

Please test:

 [`scrcpy-server`](https://tmp.rom1v.com/scrcpy/4467/5/scrcpy-server) `SHA-256: d3a1e798c490dd85e4bac19d5fb95b748f34f13c84676ddaa1f661ddb7ffc7e1`

This works for me for Device Share and Camera Share.

I think 140a49b can fix it.

Please test:

  • scrcpy-server SHA-256: d3a1e798c490dd85e4bac19d5fb95b748f34f13c84676ddaa1f661ddb7ffc7e1

this one works for me with android 14

Getting the same problem on macOS, also with a Samsung phone on Android 14:

scrcpy --no-audio -d
scrcpy 2.3 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  RFCW10T3PCB                     device  SM_S911B
/opt/homebrew/Cellar/scrcpy/2.3/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 98.4 MB/s (65851 bytes in 0.001s)
[server] INFO: Device: [samsung] samsung SM-S911B (Android 14)
[server] ERROR: Exception on thread Thread[binder:475_1,5,main]
java.lang.AssertionError: java.lang.reflect.InvocationTargetException
	at com.genymobile.scrcpy.wrappers.DisplayManager.getDisplayInfo(DisplayManager.java:86)
	at com.genymobile.scrcpy.Device$2.onDisplayFoldChanged(Device.java:113)
	at android.view.IDisplayFoldListener$Stub.onTransact(IDisplayFoldListener.java:90)
	at android.os.Binder.execTransactInternal(Binder.java:1380)
	at android.os.Binder.execTransact(Binder.java:1311)
Caused by: java.lang.reflect.InvocationTargetException
	at java.lang.reflect.Method.invoke(Native Method)
	at com.genymobile.scrcpy.wrappers.DisplayManager.getDisplayInfo(DisplayManager.java:72)
	... 4 more
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Configuration android.app.ConfigurationController.getConfiguration()' on a null object reference
	at android.app.ActivityThread.getConfiguration(ActivityThread.java:3899)
	at android.hardware.display.DisplayManagerGlobal.getDisplayInfoLocked(DisplayManagerGlobal.java:260)
	at android.hardware.display.DisplayManagerGlobal.getDisplayInfo(DisplayManagerGlobal.java:234)
	... 6 more
[server] ERROR: Exception on thread Thread[video,5,main]
java.lang.AssertionError: java.lang.reflect.InvocationTargetException
	at com.genymobile.scrcpy.wrappers.SurfaceControl.createDisplay(SurfaceControl.java:85)
	at com.genymobile.scrcpy.ScreenCapture.createDisplay(ScreenCapture.java:77)
	at com.genymobile.scrcpy.ScreenCapture.start(ScreenCapture.java:38)
	at com.genymobile.scrcpy.SurfaceEncoder.streamScreen(SurfaceEncoder.java:72)
	at com.genymobile.scrcpy.SurfaceEncoder.lambda$start$0$com-genymobile-scrcpy-SurfaceEncoder(SurfaceEncoder.java:253)
	at com.genymobile.scrcpy.SurfaceEncoder$$ExternalSyntheticLambda0.run(Unknown Source:4)
	at java.lang.Thread.run(Thread.java:1012)
Caused by: java.lang.reflect.InvocationTargetException
	at java.lang.reflect.Method.invoke(Native Method)
	at com.genymobile.scrcpy.wrappers.SurfaceControl.createDisplay(SurfaceControl.java:83)
	... 6 more
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Configuration android.app.ConfigurationController.getConfiguration()' on a null object reference
	at android.app.ActivityThread.getConfiguration(ActivityThread.java:3899)
	at android.hardware.display.DisplayManagerGlobal.getDisplayInfoLocked(DisplayManagerGlobal.java:260)
	at android.hardware.display.DisplayManagerGlobal.getDisplayInfo(DisplayManagerGlobal.java:234)
	at android.hardware.display.DisplayManagerGlobal.getCompatibleDisplay(DisplayManagerGlobal.java:364)
	at android.hardware.display.DisplayManagerGlobal.getRealDisplay(DisplayManagerGlobal.java:397)
	at android.hardware.display.DisplayManagerGlobal.createVirtualDisplayWrapper(DisplayManagerGlobal.java:779)
	at android.hardware.display.DisplayManager.createVirtualDisplay(DisplayManager.java:2088)
	at android.view.SurfaceControl.createDisplay(SurfaceControl.java:2480)
	... 8 more
INFO: Renderer: metal
INFO: Texture: 1080x2336
WARN: Device disconnected

Some added code in the vendor ROM (samsung-specific code) which causes issue if ActivityThread is not null but the configuration controller is null (because then thread.getConfiguration() throws a NullPointerException):

        if (CoreRune.MT_SUPPORT_COMPAT_SANDBOX) {
            ActivityThread thread = ActivityThread.currentActivityThread();
            Configuration currentConfig = thread != null ? thread.getConfiguration() : null;
            if (CompatSandbox.isDisplaySandboxingEnabled(currentConfig)) {

Let’s try to set a fake configuration controller:

diff
diff --git a/server/src/main/java/com/genymobile/scrcpy/Workarounds.java b/server/src/main/java/com/genymobile/scrcpy/Workarounds.java
index db9c96290..47c09b84e 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Workarounds.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Workarounds.java
@@ -91,6 +91,8 @@ public final class Workarounds {
         if (mustFillAppContext) {
             Workarounds.fillAppContext();
         }
+
+        fillConfigurationController();
     }
 
     @SuppressWarnings("deprecation")
@@ -149,6 +151,22 @@ public final class Workarounds {
         }
     }
 
+    private static void fillConfigurationController() {
+        try {
+            Class<?> configurationControllerClass = Class.forName("android.app.ConfigurationController");
+            Class<?> activityThreadInternalClass = Class.forName("android.app.ActivityThreadInternal");
+            Constructor<?> configurationControllerConstructor = configurationControllerClass.getDeclaredConstructor(activityThreadInternalClass);
+            configurationControllerConstructor.setAccessible(true);
+            Object configurationController = configurationControllerConstructor.newInstance(ACTIVITY_THREAD);
+
+            Field configurationControllerField = ACTIVITY_THREAD_CLASS.getDeclaredField("mConfigurationController");
+            configurationControllerField.setAccessible(true);
+            configurationControllerField.set(ACTIVITY_THREAD, configurationController);
+        } catch (Throwable throwable) {
+            Ln.d("Could not fill configuration: " + throwable.getMessage());
+        }
+    }
+
     static Context getSystemContext() {
         try {
             Method getSystemContextMethod = ACTIVITY_THREAD_CLASS.getDeclaredMethod("getSystemContext");

Replace this binary into your scrcpy 2.3 directory:

  • scrcpy-server SHA-256: 2ccffc7393767d15398742bfdecf2db642bb19ea837a76e31b2d0af8bf90b642