Merge "Fix deadlock between WMGlobal and WMS" into main
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index c49fce5..848261d 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -179,9 +179,29 @@
}
}
+ /**
+ * 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 57448cb..366e1bb 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 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;
}
/**