summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2021-09-27 13:16:54 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-09-27 13:16:54 +0000
commitd92c7d85d79ff6bfc1dcb58651c5e528c1ff13e9 (patch)
tree8689136596ea155f383306ba39f0e527bdb90063
parent4650065c80afd7e57c7fda6d8d65645385ed83bd (diff)
parent812542c7369201918bab0ab262bcda728f21b40a (diff)
Merge "Wake foldable device when device unfolds." into sc-v2-dev
-rw-r--r--core/java/android/os/PowerManager.java8
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java12
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplayMapper.java42
5 files changed, 55 insertions, 13 deletions
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 3aa0bcb6abee..4dae7c7c96d5 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -548,6 +548,7 @@ public final class PowerManager {
WAKE_REASON_HDMI,
WAKE_REASON_DISPLAY_GROUP_ADDED,
WAKE_REASON_DISPLAY_GROUP_TURNED_ON,
+ WAKE_REASON_UNFOLD_DEVICE
})
@Retention(RetentionPolicy.SOURCE)
public @interface WakeReason{}
@@ -647,6 +648,12 @@ public final class PowerManager {
public static final int WAKE_REASON_DISPLAY_GROUP_TURNED_ON = 11;
/**
+ * Wake up reason code: Waking the device due to unfolding of a foldable device.
+ * @hide
+ */
+ public static final int WAKE_REASON_UNFOLD_DEVICE = 12;
+
+ /**
* Convert the wake reason to a string for debugging purposes.
* @hide
*/
@@ -664,6 +671,7 @@ public final class PowerManager {
case WAKE_REASON_LID: return "WAKE_REASON_LID";
case WAKE_REASON_DISPLAY_GROUP_ADDED: return "WAKE_REASON_DISPLAY_GROUP_ADDED";
case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON";
+ case WAKE_REASON_UNFOLD_DEVICE: return "WAKE_REASON_UNFOLD_DEVICE";
default: return Integer.toString(wakeReason);
}
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ed80013ff412..cbe0eef6408b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -654,6 +654,11 @@
-->
</integer-array>
+ <!-- When entering this device state (defined in device_state_configuration.xml),
+ we should wake the device. -1 to disable the feature (do not wake on any device-state
+ transition). -->
+ <integer name="config_deviceStateOnWhichToWakeUp">-1</integer>
+
<!-- Indicate the display area rect for foldable devices in folded state. -->
<string name="config_foldedArea"></string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0c0db2c4e549..fbc629e2dc81 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3846,6 +3846,7 @@
<!-- For Foldables -->
<java-symbol type="array" name="config_foldedDeviceStates" />
+ <java-symbol type="integer" name="config_deviceStateOnWhichToWakeUp" />
<java-symbol type="string" name="config_foldedArea" />
<java-symbol type="bool" name="config_supportsConcurrentInternalDisplays" />
<java-symbol type="bool" name="config_unfoldTransitionEnabled" />
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index abbe13ac260f..1063481d6788 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -721,13 +721,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
final IBinder token = device.getDisplayTokenLocked();
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
mHandler.post(() -> {
- if (mDisplayDevice == device) {
- return;
+ if (mDisplayDevice != device) {
+ mDisplayDevice = device;
+ mUniqueDisplayId = uniqueId;
+ mDisplayDeviceConfig = config;
+ loadFromDisplayDeviceConfig(token, info);
+ updatePowerState();
}
- mDisplayDevice = device;
- mUniqueDisplayId = uniqueId;
- mDisplayDeviceConfig = config;
- loadFromDisplayDeviceConfig(token, info);
});
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 973dcc4c79e5..0fbc3e8fb89a 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -22,6 +22,8 @@ import android.hardware.devicestate.DeviceStateManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -69,7 +71,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
public static final int DISPLAY_GROUP_EVENT_CHANGED = 2;
public static final int DISPLAY_GROUP_EVENT_REMOVED = 3;
- private static final int TIMEOUT_STATE_TRANSITION_MILLIS = 500;
+ private static final int TIMEOUT_STATE_TRANSITION_MILLIS = 300;
private static final int MSG_TRANSITION_TO_PENDING_DEVICE_STATE = 1;
@@ -98,6 +100,11 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private final boolean mSupportsConcurrentInternalDisplays;
/**
+ * Wake the device when transitioning into this device state.
+ */
+ private final int mDeviceStateOnWhichToWakeUp;
+
+ /**
* Map of all logical displays indexed by logical display id.
* Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache.
* TODO: multi-display - Move the aforementioned comment?
@@ -113,6 +120,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private final Listener mListener;
private final DisplayManagerService.SyncRoot mSyncRoot;
private final LogicalDisplayMapperHandler mHandler;
+ private final PowerManager mPowerManager;
/**
* Has an entry for every logical display that the rest of the system has been notified about.
@@ -150,12 +158,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
@NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
@NonNull Handler handler) {
mSyncRoot = syncRoot;
+ mPowerManager = context.getSystemService(PowerManager.class);
mHandler = new LogicalDisplayMapperHandler(handler.getLooper());
mDisplayDeviceRepo = repo;
mListener = listener;
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
mSupportsConcurrentInternalDisplays = context.getResources().getBoolean(
com.android.internal.R.bool.config_supportsConcurrentInternalDisplays);
+ mDeviceStateOnWhichToWakeUp = context.getResources().getInteger(
+ com.android.internal.R.integer.config_deviceStateOnWhichToWakeUp);
mDisplayDeviceRepo.addListener(this);
mDeviceStateToLayoutMap = new DeviceStateToLayoutMap();
}
@@ -318,6 +329,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
ipw.println("mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
ipw.println("mCurrentLayout=" + mCurrentLayout);
+ ipw.println("mDeviceStateOnWhichToWakeUp=" + mDeviceStateOnWhichToWakeUp);
final int logicalDisplayCount = mLogicalDisplays.size();
ipw.println();
@@ -335,7 +347,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
}
void setDeviceStateLocked(int state) {
- Slog.i(TAG, "Requesting Transition to state: " + state);
+ final boolean isInteractive = mPowerManager.isInteractive();
+ Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
+ + ", interactive=" + isInteractive);
// As part of a state transition, we may need to turn off some displays temporarily so that
// the transition is smooth. Plus, on some devices, only one internal displays can be
// on at a time. We use DISPLAY_PHASE_LAYOUT_TRANSITION to mark a display that needs to be
@@ -344,8 +358,13 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
resetLayoutLocked(mDeviceState, state, LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION);
}
mPendingDeviceState = state;
- if (areAllTransitioningDisplaysOffLocked()) {
- // Nothing to wait on, we're good to go
+ final boolean wakeDevice = mPendingDeviceState == mDeviceStateOnWhichToWakeUp
+ && !isInteractive;
+
+ // If all displays are off already, we can just transition here, unless the device is asleep
+ // and we plan on waking it up. In that case, fall through to the call to wakeUp, and defer
+ // the final transition until later once the device is awake.
+ if (areAllTransitioningDisplaysOffLocked() && !wakeDevice) {
transitionToPendingStateLocked();
return;
}
@@ -356,6 +375,14 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
// Send the transitioning phase updates to DisplayManager so that the displays can
// start turning OFF in preparation for the new layout.
updateLogicalDisplaysLocked();
+
+ if (wakeDevice) {
+ // We already told the displays to turn off, now we need to wake the device as
+ // we transition to this new state. We do it here so that the waking happens between the
+ // transition from one layout to another.
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_UNFOLD_DEVICE,
+ "server.display:unfold");
+ }
mHandler.sendEmptyMessageDelayed(MSG_TRANSITION_TO_PENDING_DEVICE_STATE,
TIMEOUT_STATE_TRANSITION_MILLIS);
}
@@ -482,6 +509,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
assignDisplayGroupLocked(display);
mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED);
+ // The display is involved in a display layout transition
} else if (updateState == UPDATE_STATE_TRANSITION) {
mLogicalDisplaysToUpdate.put(displayId,
LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION);
@@ -672,14 +700,14 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
// We consider a display-device as changing/transition if
// 1) It's already marked as transitioning
- // 2) It's going from enabled to disabled
+ // 2) It's going from enabled to disabled, or vice versa
// 3) It's enabled, but it's mapped to a new logical display ID. To the user this
// would look like apps moving from one screen to another since task-stacks stay
// with the logical display [ID].
final boolean isTransitioning =
(logicalDisplay.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION)
- || (wasEnabled && !willBeEnabled)
- || (wasEnabled && deviceHasNewLogicalDisplayId);
+ || (wasEnabled != willBeEnabled)
+ || deviceHasNewLogicalDisplayId;
if (isTransitioning) {
setDisplayPhase(logicalDisplay, phase);