Skip to content

Commit

Permalink
Set power mode on all physical displays
Browse files Browse the repository at this point in the history
Android 10 and above support multiple physical displays. Apply power
mode to all of them.

Fixes #3716 <#3716>
  • Loading branch information
rom1v committed Feb 6, 2023
1 parent d2dce51 commit f2dee20
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
20 changes: 20 additions & 0 deletions server/src/main/java/com/genymobile/scrcpy/Device.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,26 @@ public boolean setClipboardText(String text) {
* @param mode one of the {@code POWER_MODE_*} constants
*/
public static boolean setScreenPowerMode(int mode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Change the power mode for all physical displays
long[] physicalDisplayIds = SurfaceControl.getPhysicalDisplayIds();
if (physicalDisplayIds == null) {
Ln.e("Could not get physical display ids");
return false;
}

boolean allOk = true;
for (long physicalDisplayId : physicalDisplayIds) {
IBinder binder = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
boolean ok = SurfaceControl.setDisplayPowerMode(binder, mode);
if (!ok) {
allOk = false;
}

This comment has been minimized.

Copy link
@brunoais

brunoais Mar 14, 2023

Contributor

For the future, @rom1v, I'd do those 3 lines like this:

allOk = SurfaceControl.setDisplayPowerMode(binder, mode) && allOk;
Or, if you don't like that way, there's also this way:
allOk = SurfaceControl.setDisplayPowerMode(binder, mode) ? allOk : false;

Just a suggestion you can consider for later time to shorten the codebase.

This comment has been minimized.

Copy link
@rom1v

rom1v Mar 15, 2023

Author Collaborator
diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java
index b66474b7e..3d83f73eb 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Device.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Device.java
@@ -288,10 +288,7 @@ public final class Device {
             boolean allOk = true;
             for (long physicalDisplayId : physicalDisplayIds) {
                 IBinder binder = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
-                boolean ok = SurfaceControl.setDisplayPowerMode(binder, mode);
-                if (!ok) {
-                    allOk = false;
-                }
+                allOk &= SurfaceControl.setDisplayPowerMode(binder, mode);
             }
             return allOk;
         }

?

This comment has been minimized.

Copy link
@brunoais

brunoais Mar 15, 2023

Contributor

Oh! I thought that wouldn't work because &= is for bitwise AND.
If it works, yeah! That's even better.

}
return allOk;
}

// Older Android versions, only 1 display
IBinder d = SurfaceControl.getBuiltInDisplay();
if (d == null) {
Ln.e("Could not get built-in display");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public final class SurfaceControl {

private static Method getBuiltInDisplayMethod;
private static Method setDisplayPowerModeMethod;
private static Method getPhysicalDisplayTokenMethod;
private static Method getPhysicalDisplayIdsMethod;

private SurfaceControl() {
// only static methods
Expand Down Expand Up @@ -98,7 +100,6 @@ private static Method getGetBuiltInDisplayMethod() throws NoSuchMethodException
}

public static IBinder getBuiltInDisplay() {

try {
Method method = getGetBuiltInDisplayMethod();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Expand All @@ -114,6 +115,40 @@ public static IBinder getBuiltInDisplay() {
}
}

private static Method getGetPhysicalDisplayTokenMethod() throws NoSuchMethodException {
if (getPhysicalDisplayTokenMethod == null) {
getPhysicalDisplayTokenMethod = CLASS.getMethod("getPhysicalDisplayToken", long.class);
}
return getPhysicalDisplayTokenMethod;
}

public static IBinder getPhysicalDisplayToken(long physicalDisplayId) {
try {
Method method = getGetPhysicalDisplayTokenMethod();
return (IBinder) method.invoke(null, physicalDisplayId);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
Ln.e("Could not invoke method", e);
return null;
}
}

private static Method getGetPhysicalDisplayIdsMethod() throws NoSuchMethodException {
if (getPhysicalDisplayIdsMethod == null) {
getPhysicalDisplayIdsMethod = CLASS.getMethod("getPhysicalDisplayIds");
}
return getPhysicalDisplayIdsMethod;
}

public static long[] getPhysicalDisplayIds() {
try {
Method method = getGetPhysicalDisplayIdsMethod();
return (long[]) method.invoke(null);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
Ln.e("Could not invoke method", e);
return null;
}
}

private static Method getSetDisplayPowerModeMethod() throws NoSuchMethodException {
if (setDisplayPowerModeMethod == null) {
setDisplayPowerModeMethod = CLASS.getMethod("setDisplayPowerMode", IBinder.class, int.class);
Expand Down

0 comments on commit f2dee20

Please sign in to comment.