From be9ebef02cdaf289e82fe609eb0cb84ea8cee18b Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Thu, 20 Jan 2022 01:56:26 +0000 Subject: [PATCH] Defer sleeping / waking the device on device state changes. This is really a short-term hack to unblock development. The display SyncRoot is above the power lock in the system lock order, which means the current code is thoeretically safe. Unfortunately, in practice it isn't since a a couple releases ago when DisplayManagerService started grabbing the SyncRoot while PowerManagerService called into it. Given how much has grown on top of that change, it's somewhat difficult to quickly untangle in order to get everything back into a safe state. In the interim, deferring these calls removes the one place where we have the lock inversion happen consistently, putting everything back to how it's worked for the last couple releases Bug: 214872018 Test: manual fold + unfold, no ANRs Change-Id: I8bc242dec91f59b96b1c3ed7bcf929d0798d4ba3 --- .../android/server/display/LogicalDisplayMapper.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 7719dfec928bd..93c73be5021e9 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -397,12 +397,16 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { // 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.post(() -> { + mPowerManager.wakeUp(SystemClock.uptimeMillis(), + PowerManager.WAKE_REASON_UNFOLD_DEVICE, "server.display:unfold"); + }); } else if (sleepDevice) { // Send the device to sleep when required. - mPowerManager.goToSleep(SystemClock.uptimeMillis(), - PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD, 0); + mHandler.post(() -> { + mPowerManager.goToSleep(SystemClock.uptimeMillis(), + PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD, 0); + }); } }