diff options
| author | 2021-09-27 13:16:54 +0000 | |
|---|---|---|
| committer | 2021-09-27 13:16:54 +0000 | |
| commit | d92c7d85d79ff6bfc1dcb58651c5e528c1ff13e9 (patch) | |
| tree | 8689136596ea155f383306ba39f0e527bdb90063 | |
| parent | 4650065c80afd7e57c7fda6d8d65645385ed83bd (diff) | |
| parent | 812542c7369201918bab0ab262bcda728f21b40a (diff) | |
Merge "Wake foldable device when device unfolds." into sc-v2-dev
| -rw-r--r-- | core/java/android/os/PowerManager.java | 8 | ||||
| -rw-r--r-- | core/res/res/values/config.xml | 5 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/display/DisplayPowerController.java | 12 | ||||
| -rw-r--r-- | services/core/java/com/android/server/display/LogicalDisplayMapper.java | 42 |
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); |