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
This commit is contained in:
Sean Stout
2021-04-20 15:51:15 -07:00
parent 7f0b986741
commit 93992527af

View File

@@ -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();