Genymobile/scrcpy

Honor Android 14 devices --turn-screen-off failed

eiyooooo opened this issue · 10 comments

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

Environment

  • OS: [ALL]
  • scrcpy version: [2.4]
  • installation method: [ALL]
  • device model:Honor Android 14 devices, e.g. HONOR REP-AN00
  • Android version: [14]

Describe the bug
When server reaching here

loadMethod.invoke(Runtime.getRuntime(), displayControlClass, "android_servers");

server get killed, cause by

Native registration unable to find class 'com/android/server/TrustedUIService'; aborting...

Temporary solution: not change the power mode for all physical displays, use SurfaceControl to change only one display instead

My device is being affected by this bug too. @eiyooooo is there a walk-around for this issue? Thanks!

Is there a walk-around for this issue?

Temporary solution: not change the power mode for all physical displays, use SurfaceControl to change only one display instead

git diff
diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java
index 8d0ee231..671ef2c5 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Device.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Device.java
@@ -319,7 +319,8 @@ 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 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
+                && !(Build.BRAND.toLowerCase() + Build.MANUFACTURER.toLowerCase()).contains("honor")) {
             // On Android 14, these internal methods have been moved to DisplayControl
:

Note that Android Studio somehow does work with this.
Perhaps it would be good to check its code.

Also this update of Honor is terrible. Battery drains fast on it.

@eiyooooo Does this also work:

diff --git a/server/src/main/java/com/genymobile/scrcpy/device/Device.java b/server/src/main/java/com/genymobile/scrcpy/device/Device.java
index ae4f50e59..3bd6b04c7 100644
--- a/server/src/main/java/com/genymobile/scrcpy/device/Device.java
+++ b/server/src/main/java/com/genymobile/scrcpy/device/Device.java
@@ -323,7 +323,16 @@ 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) {
+        boolean applyToMultiPhysicalDisplays = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
+
+        if (applyToMultiPhysicalDisplays && Build.BRAND.equalsIgnoreCase("honor") && SurfaceControl.hasGetBuildInDisplayMethod()) {
+            // Workaround for Honor devices with Android 14:
+            //  - <https://github.com/Genymobile/scrcpy/issues/4823>
+            //  - <https://github.com/Genymobile/scrcpy/issues/4943>
+            applyToMultiPhysicalDisplays = false;
+        }
+
+        if (applyToMultiPhysicalDisplays) {
             // On Android 14, these internal methods have been moved to DisplayControl
             boolean useDisplayControl =
                     Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && !SurfaceControl.hasPhysicalDisplayIdsMethod();
diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java
index fc18a8e27..2ac1344e8 100644
--- a/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java
+++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/SurfaceControl.java
@@ -94,6 +94,15 @@ public final class SurfaceControl {
         return getBuiltInDisplayMethod;
     }
 
+    public static boolean hasGetBuildInDisplayMethod() {
+        try {
+            getGetBuiltInDisplayMethod();
+            return true;
+        } catch (NoSuchMethodException e) {
+            return false;
+        }
+    }
+
     public static IBinder getBuiltInDisplay() {
         try {
             Method method = getGetBuiltInDisplayMethod();

?

@rom1v Send me the files to run, and I will try...

@AndroidDeveloperLB The patch above applied on current master (basically v2.5):

  • scrcpy-server SHA-256: 1f17da76699caa3af102563362cc50647ecc9a2a270577e7585c4a54d3063fc

Does this also work:

I make a little improvement at #5109.

@rom1v About this:
#4823 (comment)

Seems to work fine too (on the device I've mentioned).
Please don't change it for other devices and Android versions though, as maybe it will be ok on Android 15, so please come back here after it's published to see if this fix is needed there as well, instead of applying this fix there too without a need for it.

Merged 👍 9d1d79b

Please don't change it for other devices and Android versions though

It is very specific to Honor on Android 14 where the alternate method exists.