From 93992527af701c99ca3fb4abe265d1cc7c0995d8 Mon Sep 17 00:00:00 2001 From: Sean Stout Date: Tue, 20 Apr 2021 15:51:15 -0700 Subject: [PATCH] Fix sandman crash It was possible for the system to crash when trying to handle sandman because the DisplayGroupPowerStateMapper was being accessed without holding the Power Lock. This change ensures that DisplayGroupPowerStateMapper is only accessed while holding the lock which prevents this crash from happening. Bug: 185419869 Change-Id: I96ca47335430023b6e2ac4b6f6e499fa3dc5a53b --- .../server/power/PowerManagerService.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 8052522602090..c4aca6c184536 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -102,6 +102,7 @@ import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.internal.display.BrightnessSynchronizer; import com.android.internal.os.BackgroundThread; +import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.server.EventLogTags; @@ -2926,16 +2927,13 @@ public final class PowerManagerService extends SystemService private void scheduleSandmanLocked() { if (!mSandmanScheduled) { mSandmanScheduled = true; - Message msg = mHandler.obtainMessage(MSG_SANDMAN); - msg.setAsynchronous(true); - mHandler.sendMessage(msg); - } - } - - private void handleSandman() { - for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { - if (mDisplayGroupPowerStateMapper.isSandmanSupported(id)) { - handleSandman(id); + for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) { + if (mDisplayGroupPowerStateMapper.isSandmanSupported(id)) { + Message msg = mHandler.obtainMessage(MSG_SANDMAN); + msg.arg1 = id; + msg.setAsynchronous(true); + mHandler.sendMessage(msg); + } } } } @@ -2953,6 +2951,11 @@ public final class PowerManagerService extends SystemService final int wakefulness; synchronized (mLock) { mSandmanScheduled = false; + final int[] ids = mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked(); + if (!ArrayUtils.contains(ids, groupId)) { + // Group has been removed. + return; + } // TODO (b/175764708): Support per-display doze. wakefulness = getWakefulnessLocked(); if ((wakefulness == WAKEFULNESS_DREAMING || wakefulness == WAKEFULNESS_DOZING) && @@ -2986,6 +2989,12 @@ public final class PowerManagerService extends SystemService // Update dream state. synchronized (mLock) { + final int[] ids = mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked(); + if (!ArrayUtils.contains(ids, groupId)) { + // Group has been removed. + return; + } + // Remember the initial battery level when the dream started. if (startDreaming && isDreaming) { mBatteryLevelWhenDreamStarted = mBatteryLevel; @@ -4770,7 +4779,7 @@ public final class PowerManagerService extends SystemService handleUserActivityTimeout(); break; case MSG_SANDMAN: - handleSandman(); + handleSandman(msg.arg1); break; case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT: handleScreenBrightnessBoostTimeout();