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

Commit 577bd540 authored by Charles Chen's avatar Charles Chen
Browse files

Fix deadlock between WMGlobal and WMS

In the system server, there may be a deadlock between WMGlobal and WMS
A possible scenario is:
WMS holds globalLock and call WMGlobal#getWindowManagerService,
which required to lock WMGlobal instance, while the other compnent
holds WMGlobal and call WMS API directly without binder call,
which requires WM gobalLock.

This CL sets WMS for system proces. In this way,
WMGlobal#getWindowManagerService could be used direcly without holding
WMGlobal instance and prevent deadlock.

Test: atest WmTests
Bug: 320848325
Change-Id: I2617d4139d4305161d6712d92a90fd9207d8227c
parent b416a714
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -179,9 +179,29 @@ public final class WindowManagerGlobal {
        }
    }

    /**
     * Sets {@link com.android.server.wm.WindowManagerService} for the system process.
     * <p>
     * It is needed to prevent possible deadlock. A possible scenario is:
     * In system process, WMS holds {@link com.android.server.wm.WindowManagerGlobalLock} to call
     * {@code WindowManagerGlobal} APIs and wait to lock {@code WindowManagerGlobal} itself
     * (i.e. call {@link #getWindowManagerService()} in the global lock), while
     * another component may lock {@code WindowManagerGlobal} and wait to lock
     * {@link com.android.server.wm.WindowManagerGlobalLock}(i.e call {@link #addView} in the
     * system process, which calls to {@link com.android.server.wm.WindowManagerService} API
     * directly).
     */
    public static void setWindowManagerServiceForSystemProcess(@NonNull IWindowManager wms) {
        sWindowManagerService = wms;
    }

    @Nullable
    @UnsupportedAppUsage
    public static IWindowManager getWindowManagerService() {
        if (sWindowManagerService != null) {
            // Use WMS directly without locking WMGlobal to prevent deadlock.
            return sWindowManagerService;
        }
        synchronized (WindowManagerGlobal.class) {
            if (sWindowManagerService == null) {
                sWindowManagerService = IWindowManager.Stub.asInterface(
+5 −2
Original line number Diff line number Diff line
@@ -1114,8 +1114,11 @@ public class WindowManagerService extends IWindowManager.Stub
    public static WindowManagerService main(final Context context, final InputManagerService im,
            final boolean showBootMsgs, WindowManagerPolicy policy,
            ActivityTaskManagerService atm) {
        return main(context, im, showBootMsgs, policy, atm, new DisplayWindowSettingsProvider(),
                SurfaceControl.Transaction::new, SurfaceControl.Builder::new);
        final WindowManagerService wms = main(context, im, showBootMsgs, policy, atm,
                new DisplayWindowSettingsProvider(), SurfaceControl.Transaction::new,
                SurfaceControl.Builder::new);
        WindowManagerGlobal.setWindowManagerServiceForSystemProcess(wms);
        return wms;
    }

    /**