Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93992527 authored by Sean Stout's avatar Sean Stout
Browse files

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
parent 7f0b9867
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -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,17 +2927,14 @@ public final class PowerManagerService extends SystemService
    private void scheduleSandmanLocked() {
        if (!mSandmanScheduled) {
            mSandmanScheduled = true;
            for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
                if (mDisplayGroupPowerStateMapper.isSandmanSupported(id)) {
                    Message msg = mHandler.obtainMessage(MSG_SANDMAN);
                    msg.arg1 = id;
                    msg.setAsynchronous(true);
                    mHandler.sendMessage(msg);
                }
            }

    private void handleSandman() {
        for (int id : mDisplayGroupPowerStateMapper.getDisplayGroupIdsLocked()) {
            if (mDisplayGroupPowerStateMapper.isSandmanSupported(id)) {
                handleSandman(id);
            }
        }
    }

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