Shell cmd power-reset instead of power-on
power-on command may not work as expected,
when display already asleep. The semantics
of power-off command means we need a
power-reset command to reset the display
to a state it supposed to have by removing
the 'overridden' power state.
Change-Id: Ib7acfa6cb7687df4f19877e3b9cf9b8d768151d6
Bug: 292300981
Test: atest DisplayManagerServiceTest
Test: adb shell cmd display power-off 0
Test: adb shell cmd display power-reset 0
Flag: EXEMPT bugfix in a new shell command not used anywhere
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 8519722..8748bb1 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -549,15 +549,20 @@
}
/**
- * Request to power a display ON or OFF.
+ * Request to power a display OFF or reset it to a power state it supposed to have.
+ * @param displayId the id of the display
+ * @param state one of {@link android.view.Display#STATE_UNKNOWN} (to reset the state to
+ * the one the display should have had now), {@link android.view.Display#STATE_OFF}.
+ * @return true if successful, false otherwise
* @hide
*/
@RequiresPermission("android.permission.MANAGE_DISPLAYS")
- public boolean requestDisplayPower(int displayId, boolean on) {
+ public boolean requestDisplayPower(int displayId, int state) {
try {
- return mDm.requestDisplayPower(displayId, on);
+ return mDm.requestDisplayPower(displayId, state);
} catch (RemoteException ex) {
- Log.e(TAG, "Error trying to request display power " + on, ex);
+ Log.e(TAG, "Error trying to request display power:"
+ + " state=" + state, ex);
return false;
}
}
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index b7c02b0..28c71d9 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -236,9 +236,9 @@
@EnforcePermission("MANAGE_DISPLAYS")
void disableConnectedDisplay(int displayId);
- // Request to power display ON or OFF.
+ // Request to power display OFF or reset it to a power state it supposed to have.
@EnforcePermission("MANAGE_DISPLAYS")
- boolean requestDisplayPower(int displayId, boolean on);
+ boolean requestDisplayPower(int displayId, int state);
// Restricts display modes to specified modeIds.
@EnforcePermission("RESTRICT_DISPLAY_MODES")
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 2d5f38e..08a9a77 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -822,6 +822,13 @@
}
@VisibleForTesting
+ void setDisplayState(int displayId, int state) {
+ synchronized (mSyncRoot) {
+ mDisplayStates.setValueAt(displayId, state);
+ }
+ }
+
+ @VisibleForTesting
Handler getDisplayHandler() {
return mHandler;
}
@@ -3406,27 +3413,39 @@
}
}
- boolean requestDisplayPower(int displayId, boolean on) {
+ boolean requestDisplayPower(int displayId, int requestedState) {
synchronized (mSyncRoot) {
final var display = mLogicalDisplayMapper.getDisplayLocked(displayId);
if (display == null) {
- Slog.w(TAG, "requestDisplayPower: Cannot find a display with displayId="
+ Slog.w(TAG, "requestDisplayPower: Cannot find the display with displayId="
+ displayId);
return false;
}
+ var state = requestedState;
+ if (state == Display.STATE_UNKNOWN) {
+ state = mDisplayStates.get(displayId);
+ }
+
final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
+ var brightnessState = brightnessPair.brightness;
+ if (state == Display.STATE_OFF) {
+ brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
+ }
+
var runnable = display.getPrimaryDisplayDeviceLocked().requestDisplayStateLocked(
- on ? Display.STATE_ON : Display.STATE_OFF,
- on ? brightnessPair.brightness : PowerManager.BRIGHTNESS_OFF_FLOAT,
+ state,
+ brightnessState,
brightnessPair.sdrBrightness,
display.getDisplayOffloadSessionLocked());
if (runnable == null) {
- Slog.w(TAG, "requestDisplayPower: Cannot update the power state to ON=" + on
- + " for a display with displayId=" + displayId + ", runnable is null");
+ Slog.w(TAG, "requestDisplayPower: Cannot set power state = " + state
+ + " for the display with displayId=" + displayId + ","
+ + " requestedState=" + requestedState + ": runnable is null");
return false;
}
runnable.run();
- Slog.i(TAG, "requestDisplayPower(displayId=" + displayId + ", on=" + on + ")");
+ Slog.i(TAG, "requestDisplayPower(displayId=" + displayId
+ + ", requestedState=" + requestedState + "): state set to " + state);
}
return true;
}
@@ -4655,9 +4674,9 @@
}
@EnforcePermission(MANAGE_DISPLAYS)
- public boolean requestDisplayPower(int displayId, boolean on) {
+ public boolean requestDisplayPower(int displayId, int state) {
requestDisplayPower_enforcePermission();
- return DisplayManagerService.this.requestDisplayPower(displayId, on);
+ return DisplayManagerService.this.requestDisplayPower(displayId, state);
}
@EnforcePermission(RESTRICT_DISPLAY_MODES)
diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
index d973b71..9eef657 100644
--- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
+++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
@@ -106,10 +106,10 @@
return setDisplayEnabled(true);
case "disable-display":
return setDisplayEnabled(false);
- case "power-on":
- return requestDisplayPower(true);
+ case "power-reset":
+ return requestDisplayPower(Display.STATE_UNKNOWN);
case "power-off":
- return requestDisplayPower(false);
+ return requestDisplayPower(Display.STATE_OFF);
default:
return handleDefaultCommands(cmd);
}
@@ -183,6 +183,10 @@
pw.println(" disable-display DISPLAY_ID");
pw.println(" Disable the DISPLAY_ID. Only possible if this is a connected display.");
}
+ pw.println(" power-reset DISPLAY_ID");
+ pw.println(" Turn the DISPLAY_ID power to a state the display supposed to have.");
+ pw.println(" power-off DISPLAY_ID");
+ pw.println(" Turn the display DISPLAY_ID power off.");
pw.println();
Intent.printIntentArgsHelp(pw , "");
}
@@ -597,7 +601,7 @@
return 0;
}
- private int requestDisplayPower(boolean enable) {
+ private int requestDisplayPower(int state) {
final String displayIdText = getNextArg();
if (displayIdText == null) {
getErrPrintWriter().println("Error: no displayId specified");
@@ -610,7 +614,7 @@
getErrPrintWriter().println("Error: invalid displayId: '" + displayIdText + "'");
return 1;
}
- mService.requestDisplayPower(displayId, enable);
+ mService.requestDisplayPower(displayId, state);
return 0;
}
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 211ab03..d268637 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -2584,18 +2584,19 @@
LogicalDisplay display =
logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true);
+ displayManager.setDisplayState(display.getDisplayIdLocked(), Display.STATE_ON);
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
- assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), false))
- .isTrue();
+ assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+ Display.STATE_OFF)).isTrue();
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_OFF);
- assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), true))
- .isTrue();
+ assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+ Display.STATE_UNKNOWN)).isTrue();
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
@@ -2621,8 +2622,10 @@
assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
.isEqualTo(Display.STATE_ON);
- assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, true));
- assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, false));
+ assertThrows(SecurityException.class,
+ () -> bs.requestDisplayPower(displayId, Display.STATE_UNKNOWN));
+ assertThrows(SecurityException.class,
+ () -> bs.requestDisplayPower(displayId, Display.STATE_OFF));
}
@Test