Don't add insets when a container is detached

It can happen when WM core receives a request from WM shell when
handling previous requests. The container is detached so it isn't
visible anymore and when it's attached again insets need to be updated
regardless.

Also clear mLocalInsetsSourceProviders when display changes, as they
hold references to the InsetsStateController of the previous display,
which could result in memory leaks or weird insets behaviors after
reparenting to a different display.

Bug: 238680143
Test: WM core doesn't throw this NPE anymore.
Change-Id: I9dc6e0b4ec2cca1d403f51ca361325de08421978
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 19b3384..2f95a54 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -429,6 +429,13 @@
         if (insetsTypes == null || insetsTypes.length == 0) {
             throw new IllegalArgumentException("Insets type not specified.");
         }
+        if (mDisplayContent == null) {
+            // This is possible this container is detached when WM shell is responding to a previous
+            // request. WM shell will be updated when this container is attached again and the
+            // insets need to be updated.
+            Slog.w(TAG, "Can't add local rect insets source provider when detached. " + this);
+            return;
+        }
         if (mLocalInsetsSourceProviders == null) {
             mLocalInsetsSourceProviders = new SparseArray<>();
         }
@@ -1011,6 +1018,9 @@
         if (dc != null && dc != this) {
             dc.getPendingTransaction().merge(mPendingTransaction);
         }
+        if (dc != this && mLocalInsetsSourceProviders != null) {
+            mLocalInsetsSourceProviders.clear();
+        }
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer child = mChildren.get(i);
             child.onDisplayChanged(dc);