summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Charles Chen <charlesccchen@google.com> 2024-02-07 09:15:52 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-02-07 09:15:52 +0000
commitfc22d96e1c90426ef7c7d344037b7c3184aadb14 (patch)
treee3c062c325e3e1a1e2637ecac5c648950b76dad9
parentdf4ad3a817651ecec41849c046e5ef2fe502ae66 (diff)
parent577bd5402d3055befe933f8bcc7bf734236bb645 (diff)
Merge "Fix deadlock between WMGlobal and WMS" into main
-rw-r--r--core/java/android/view/WindowManagerGlobal.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java7
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;
}
/**