From 57ea97e14d6b877b7d7e1285d25076ef76793eca Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Fri, 8 May 2020 19:39:18 +0800 Subject: [PATCH] Ensure addWindow/relayoutWindow won't return stale controls In some cases, these functions would early return. For example, the client might try to relayout a window which has been removed. We need to make sure outActiveControls doesn't contain stale controls in such cases. This CL also makes outActiveControls non-null. Fix: 155857511 Test: atest --iterations 20 SessionLifecycleTest# testDatasetAuthResponseWhileAutofilledAppIsLifecycled Change-Id: I88a316374faa24233eda8e13902c48ed19c871aa --- .../java/com/android/server/wm/Session.java | 3 +- .../server/wm/WindowManagerService.java | 33 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index bf20cb907b712..f309716b63e74 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -91,6 +91,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { private float mLastReportedAnimatorScale; private String mPackageName; private String mRelayoutTag; + private final InsetsSourceControl[] mDummyControls = new InsetsSourceControl[0]; public Session(WindowManagerService service, IWindowSessionCallback callback) { mService = service; @@ -184,7 +185,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, new Rect() /* outFrame */, outContentInsets, outStableInsets, new DisplayCutout.ParcelableWrapper() /* cutout */, null /* outInputChannel */, - outInsetsState, null, UserHandle.getUserId(mUid)); + outInsetsState, mDummyControls, UserHandle.getUserId(mUid)); } @Override diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ae0c9b15689a8..2cba51f161fde 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1384,6 +1384,7 @@ public class WindowManagerService extends IWindowManager.Stub DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, int requestUserId) { + Arrays.fill(outActiveControls, null); int[] appOp = new int[1]; final boolean isRoundedCornerOverlay = (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0; @@ -2130,6 +2131,7 @@ public class WindowManagerService extends IWindowManager.Stub SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { + Arrays.fill(outActiveControls, null); int result = 0; boolean configChanged; final int pid = Binder.getCallingPid(); @@ -2467,23 +2469,20 @@ public class WindowManagerService extends IWindowManager.Stub } private void getInsetsSourceControls(WindowState win, InsetsSourceControl[] outControls) { - if (outControls != null) { - final InsetsSourceControl[] controls = - win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win); - Arrays.fill(outControls, null); - if (controls != null) { - final int length = Math.min(controls.length, outControls.length); - for (int i = 0; i < length; i++) { - // We will leave the critical section before returning the leash to the client, - // so we need to copy the leash to prevent others release the one that we are - // about to return. - // TODO: We will have an extra copy if the client is not local. - // For now, we rely on GC to release it. - // Maybe we can modify InsetsSourceControl.writeToParcel so it can release - // the extra leash as soon as possible. - outControls[i] = controls[i] != null - ? new InsetsSourceControl(controls[i]) : null; - } + final InsetsSourceControl[] controls = + win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win); + if (controls != null) { + final int length = Math.min(controls.length, outControls.length); + for (int i = 0; i < length; i++) { + // We will leave the critical section before returning the leash to the client, + // so we need to copy the leash to prevent others release the one that we are + // about to return. + // TODO: We will have an extra copy if the client is not local. + // For now, we rely on GC to release it. + // Maybe we can modify InsetsSourceControl.writeToParcel so it can release + // the extra leash as soon as possible. + outControls[i] = controls[i] != null + ? new InsetsSourceControl(controls[i]) : null; } } }