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

Commit a2363540 authored by nttsai's avatar nttsai Committed by NT Tsai
Browse files

Fix a deadlock WMG->WMS, WMS->WMG

In ImmersiveModeConfirmation, the WindowManager operations shouldn't be
called while holding the WM lock. Thus, I remove the assigned operation of
mWindowManager member in the constructor function. Next, I add a private
function to get a valid mWindowManager member in 3 functions (handleHide,
handleShow, onAttachedToWindow). The 3 functions are called by a different
thread by specific events. It should avoid the deadlock we saw now.

Bug: 129101307, 128520392
Test: local build and manually test it for 2 times
Test Steps: 1. Boot up the device 2. Start Photo to view a photo in full
screen and exit full screen
Change-Id: If42f4fd6a31869d5eefa8b445c32665aef1ee07d
parent a498804d
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -90,8 +90,6 @@ public class ImmersiveModeConfirmation {
        mShowDelayMs = getNavBarExitDuration() * 3;
        mPanicThresholdMs = context.getResources()
                .getInteger(R.integer.config_immersive_mode_confirmation_panic);
        mWindowManager = (WindowManager)
                mContext.getSystemService(Context.WINDOW_SERVICE);
        mVrModeEnabled = vrModeEnabled;
    }

@@ -177,7 +175,7 @@ public class ImmersiveModeConfirmation {
    private void handleHide() {
        if (mClingWindow != null) {
            if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation");
            mWindowManager.removeView(mClingWindow);
            getWindowManager().removeView(mClingWindow);
            mClingWindow = null;
        }
    }
@@ -275,7 +273,7 @@ public class ImmersiveModeConfirmation {
            super.onAttachedToWindow();

            DisplayMetrics metrics = new DisplayMetrics();
            mWindowManager.getDefaultDisplay().getMetrics(metrics);
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            float density = metrics.density;

            getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
@@ -341,6 +339,19 @@ public class ImmersiveModeConfirmation {
        }
    }

    /**
     * DO HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD
     * The reason why we add this method is to avoid the deadlock of WMG->WMS and WMS->WMG
     * when ImmersiveModeConfirmation object is created.
     */
    private WindowManager getWindowManager() {
        if (mWindowManager == null) {
            mWindowManager = (WindowManager)
                      mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        return mWindowManager;
    }

    private void handleShow() {
        if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation");

@@ -352,7 +363,7 @@ public class ImmersiveModeConfirmation {

        // show the confirmation
        WindowManager.LayoutParams lp = getClingWindowLayoutParams();
        mWindowManager.addView(mClingWindow, lp);
        getWindowManager().addView(mClingWindow, lp);
    }

    private final Runnable mConfirm = new Runnable() {