From 790ea5e58c97a8635ba0326b2b3268ef77bdaae0 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 3 Nov 2024 12:33:33 +0100 Subject: [PATCH] Check screen on for current displayId Since Android 14, the "screen on" state can be checked per-display. Refs PR #5442 --- .../main/java/com/genymobile/scrcpy/CleanUp.java | 2 +- .../com/genymobile/scrcpy/control/Controller.java | 4 ++-- .../java/com/genymobile/scrcpy/device/Device.java | 7 ++++--- .../genymobile/scrcpy/wrappers/PowerManager.java | 14 ++++++++++++-- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java index c8ee3ef4..343d854a 100644 --- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java +++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java @@ -137,7 +137,7 @@ public final class CleanUp { } } - if (Device.isScreenOn() && displayId != Device.DISPLAY_ID_NONE) { + if (displayId != Device.DISPLAY_ID_NONE && Device.isScreenOn(displayId)) { if (powerOffScreen) { Ln.i("Power off screen"); Device.powerOffScreen(displayId); diff --git a/server/src/main/java/com/genymobile/scrcpy/control/Controller.java b/server/src/main/java/com/genymobile/scrcpy/control/Controller.java index 533faa68..67a0115d 100644 --- a/server/src/main/java/com/genymobile/scrcpy/control/Controller.java +++ b/server/src/main/java/com/genymobile/scrcpy/control/Controller.java @@ -166,7 +166,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener { private void control() throws IOException { // on start, power on the device - if (powerOn && displayId == 0 && !Device.isScreenOn()) { + if (powerOn && displayId == 0 && !Device.isScreenOn(displayId)) { Device.pressReleaseKeycode(KeyEvent.KEYCODE_POWER, displayId, Device.INJECT_MODE_ASYNC); // dirty hack @@ -490,7 +490,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener { } private boolean pressBackOrTurnScreenOn(int action) { - if (Device.isScreenOn()) { + if (displayId == Device.DISPLAY_ID_NONE || Device.isScreenOn(displayId)) { return injectKeyEvent(action, KeyEvent.KEYCODE_BACK, 0, 0, Device.INJECT_MODE_ASYNC); } 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 5cd7a52a..e7a743f8 100644 --- a/server/src/main/java/com/genymobile/scrcpy/device/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/device/Device.java @@ -82,8 +82,9 @@ public final class Device { && injectKeyEvent(KeyEvent.ACTION_UP, keyCode, 0, 0, displayId, injectMode); } - public static boolean isScreenOn() { - return ServiceManager.getPowerManager().isScreenOn(); + public static boolean isScreenOn(int displayId) { + assert displayId != DISPLAY_ID_NONE; + return ServiceManager.getPowerManager().isScreenOn(displayId); } public static void expandNotificationPanel() { @@ -181,7 +182,7 @@ public final class Device { public static boolean powerOffScreen(int displayId) { assert displayId != DISPLAY_ID_NONE; - if (!isScreenOn()) { + if (!isScreenOn(displayId)) { return true; } return pressReleaseKeycode(KeyEvent.KEYCODE_POWER, displayId, Device.INJECT_MODE_ASYNC); diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/PowerManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/PowerManager.java index f62e5b8e..b5fefdd8 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/PowerManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/PowerManager.java @@ -1,7 +1,9 @@ package com.genymobile.scrcpy.wrappers; +import com.genymobile.scrcpy.AndroidVersions; import com.genymobile.scrcpy.util.Ln; +import android.os.Build; import android.os.IInterface; import java.lang.reflect.Method; @@ -21,14 +23,22 @@ public final class PowerManager { private Method getIsScreenOnMethod() throws NoSuchMethodException { if (isScreenOnMethod == null) { - isScreenOnMethod = manager.getClass().getMethod("isInteractive"); + if (Build.VERSION.SDK_INT >= AndroidVersions.API_34_ANDROID_14) { + isScreenOnMethod = manager.getClass().getMethod("isDisplayInteractive", int.class); + } else { + isScreenOnMethod = manager.getClass().getMethod("isInteractive"); + } } return isScreenOnMethod; } - public boolean isScreenOn() { + public boolean isScreenOn(int displayId) { + try { Method method = getIsScreenOnMethod(); + if (Build.VERSION.SDK_INT >= AndroidVersions.API_34_ANDROID_14) { + return (boolean) method.invoke(manager, displayId); + } return (boolean) method.invoke(manager); } catch (ReflectiveOperationException e) { Ln.e("Could not invoke method", e);