diff options
| author | 2024-02-07 09:15:52 +0000 | |
|---|---|---|
| committer | 2024-02-07 09:15:52 +0000 | |
| commit | fc22d96e1c90426ef7c7d344037b7c3184aadb14 (patch) | |
| tree | e3c062c325e3e1a1e2637ecac5c648950b76dad9 | |
| parent | df4ad3a817651ecec41849c046e5ef2fe502ae66 (diff) | |
| parent | 577bd5402d3055befe933f8bcc7bf734236bb645 (diff) | |
Merge "Fix deadlock between WMGlobal and WMS" into main
| -rw-r--r-- | core/java/android/view/WindowManagerGlobal.java | 20 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 7 |
2 files changed, 25 insertions, 2 deletions
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index c49fce5b558f..848261db45bd 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -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( diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 57448cb34a43..366e1bb1f040 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -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; } /** |