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

Commit 06aff34a authored by Michael Wright's avatar Michael Wright
Browse files

Introduce new lock to avoid lock-ordering issues.

Because of the way DMD was designed, technically the class lock is below
the syncroot in the lock ordering, meaning we can't call into any
general display classes while holding the class lock without creating
the possibility of deadlock. There's no real reason to use the class
lock in this situation though, so just introduce a local lock to
SensorObserver that can be above the syncroot and thus call into the
rest of the display stack at will.

Bug: 195713475
Test: atest DisplayModeDirectorTest
Change-Id: Ie32660ae3a3935f0fd4001ca73fecba1e4bbba7d
parent 2486a5f1
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.view.Display;
import android.view.DisplayInfo;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
@@ -2127,7 +2128,7 @@ public class DisplayModeDirector {
        }
    }

    private final class SensorObserver implements ProximityActiveListener,
    private static final class SensorObserver implements ProximityActiveListener,
            DisplayManager.DisplayListener {
        private final String mProximitySensorName = null;
        private final String mProximitySensorType = Sensor.STRING_TYPE_PROXIMITY;
@@ -2135,22 +2136,24 @@ public class DisplayModeDirector {
        private final BallotBox mBallotBox;
        private final Context mContext;
        private final Injector mInjector;
        @GuardedBy("mSensorObserverLock")
        private final SparseBooleanArray mDozeStateByDisplay = new SparseBooleanArray();
        private final Object mSensorObserverLock = new Object();

        private DisplayManager mDisplayManager;
        private DisplayManagerInternal mDisplayManagerInternal;
        @GuardedBy("mSensorObserverLock")
        private boolean mIsProxActive = false;
        private final SparseBooleanArray mDozeStateByDisplay;

        SensorObserver(Context context, BallotBox ballotBox, Injector injector) {
            mContext = context;
            mBallotBox = ballotBox;
            mInjector = injector;
            mDozeStateByDisplay = new SparseBooleanArray();
        }

        @Override
        public void onProximityActive(boolean isActive) {
            synchronized (mLock) {
            synchronized (mSensorObserverLock) {
                if (mIsProxActive != isActive) {
                    mIsProxActive = isActive;
                    recalculateVotesLocked();
@@ -2166,7 +2169,7 @@ public class DisplayModeDirector {
                    LocalServices.getService(SensorManagerInternal.class);
            sensorManager.addProximityActiveListener(BackgroundThread.getExecutor(), this);

            synchronized (mLock) {
            synchronized (mSensorObserverLock) {
                for (Display d : mDisplayManager.getDisplays()) {
                    mDozeStateByDisplay.put(d.getDisplayId(), mInjector.isDozeState(d));
                }
@@ -2196,6 +2199,7 @@ public class DisplayModeDirector {

        void dumpLocked(PrintWriter pw) {
            pw.println("  SensorObserver");
            synchronized (mSensorObserverLock) {
                pw.println("    mIsProxActive=" + mIsProxActive);
                pw.println("    mDozeStateByDisplay:");
                for (int i = 0; i < mDozeStateByDisplay.size(); i++) {
@@ -2204,11 +2208,12 @@ public class DisplayModeDirector {
                    pw.println("      " + id + " -> " + dozed);
                }
            }
        }

        @Override
        public void onDisplayAdded(int displayId) {
            boolean isDozeState = mInjector.isDozeState(mDisplayManager.getDisplay(displayId));
            synchronized (mLock) {
            synchronized (mSensorObserverLock) {
                mDozeStateByDisplay.put(displayId, isDozeState);
                recalculateVotesLocked();
            }
@@ -2217,7 +2222,7 @@ public class DisplayModeDirector {
        @Override
        public void onDisplayChanged(int displayId) {
            boolean wasDozeState = mDozeStateByDisplay.get(displayId);
            synchronized (mLock) {
            synchronized (mSensorObserverLock) {
                mDozeStateByDisplay.put(displayId,
                        mInjector.isDozeState(mDisplayManager.getDisplay(displayId)));
                if (wasDozeState != mDozeStateByDisplay.get(displayId)) {
@@ -2228,7 +2233,7 @@ public class DisplayModeDirector {

        @Override
        public void onDisplayRemoved(int displayId) {
            synchronized (mLock) {
            synchronized (mSensorObserverLock) {
                mDozeStateByDisplay.delete(displayId);
                recalculateVotesLocked();
            }