From 133e4940fc956963dacd7a2730ce63f87c899812 Mon Sep 17 00:00:00 2001 From: Garfield Tan Date: Mon, 11 Jul 2022 15:41:29 -0700 Subject: [PATCH] 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 --- .../java/com/android/server/wm/WindowContainer.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 19b3384ee4042..2f95a546f1555 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 @@ class WindowContainer extends ConfigurationContainer< 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 @@ class WindowContainer extends ConfigurationContainer< 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);