From 6db5c60751a9c0db378f85a8e7477c5b047de414 Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Fri, 16 Apr 2021 16:02:14 +0800 Subject: [PATCH] Introduce WindowToken Builder ... te improve readability. Also change remaining ctr's visibility to protected for ActivityRecord and WallpaperWindowToken to inherit. Test: touched tests Bug: 185460076 Change-Id: I3437771d417fd19ea58414e2189e2126bbcc1901 --- .../java/com/android/server/wm/ShellRoot.java | 7 +- .../server/wm/WindowManagerService.java | 32 +++++-- .../com/android/server/wm/WindowToken.java | 93 +++++++++++++++---- .../wm/DisplayAreaPolicyBuilderTest.java | 79 +++++++++------- .../android/server/wm/DisplayAreaTest.java | 4 +- .../wm/DualDisplayAreaGroupPolicyTest.java | 4 +- .../android/server/wm/WindowTokenTests.java | 64 +++++-------- 7 files changed, 178 insertions(+), 105 deletions(-) diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java index 0902948bf5597..b56e76d91370a 100644 --- a/services/core/java/com/android/server/wm/ShellRoot.java +++ b/services/core/java/com/android/server/wm/ShellRoot.java @@ -76,8 +76,11 @@ public class ShellRoot { throw new IllegalArgumentException(shellRootLayer + " is not an acceptable shell root layer."); } - mToken = new WindowToken( - dc.mWmService, client.asBinder(), windowType, true, dc, true, false); + mToken = new WindowToken.Builder(dc.mWmService, client.asBinder(), windowType) + .setDisplayContent(dc) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .build(); mSurfaceControl = mToken.makeChildSurface(null) .setContainerLayer() .setName("Shell Root Leash " + dc.getDisplayId()) diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c80a38fdb8385..630cd4516efb1 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1599,13 +1599,20 @@ public class WindowManagerService extends IWindowManager.Stub final IBinder binder = attrs.token != null ? attrs.token : windowContextToken; final Bundle options = mWindowContextListenerController .getOptions(windowContextToken); - token = new WindowToken(this, binder, type, false /* persistOnEmpty */, - displayContent, session.mCanAddInternalSystemWindow, - isRoundedCornerOverlay, true /* fromClientToken */, options); + token = new WindowToken.Builder(this, binder, type) + .setDisplayContent(displayContent) + .setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow) + .setRoundedCornerOverlay(isRoundedCornerOverlay) + .setFromClientToken(true) + .setOptions(options) + .build(); } else { final IBinder binder = attrs.token != null ? attrs.token : client.asBinder(); - token = new WindowToken(this, binder, type, false, displayContent, - session.mCanAddInternalSystemWindow, isRoundedCornerOverlay); + token = new WindowToken.Builder(this, binder, type) + .setDisplayContent(displayContent) + .setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow) + .setRoundedCornerOverlay(isRoundedCornerOverlay) + .build(); } } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { @@ -1676,8 +1683,10 @@ public class WindowManagerService extends IWindowManager.Stub // It is not valid to use an app token with other system types; we will // instead make a new token for it (as if null had been passed in for the token). attrs.token = null; - token = new WindowToken(this, client.asBinder(), type, false /* persistOnEmpty */, - displayContent, session.mCanAddInternalSystemWindow); + token = new WindowToken.Builder(this, client.asBinder(), type) + .setDisplayContent(displayContent) + .setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow) + .build(); } final WindowState win = new WindowState(this, session, client, token, parentWindow, @@ -2703,9 +2712,12 @@ public class WindowManagerService extends IWindowManager.Stub new WallpaperWindowToken(this, binder, true, dc, true /* ownerCanManageAppTokens */, options); } else { - new WindowToken(this, binder, type, true /* persistOnEmpty */, dc, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, options); + new WindowToken.Builder(this, binder, type) + .setDisplayContent(dc) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .setOptions(options) + .build(); } } } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index ef39560e59fce..fbfa400ba8520 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -53,6 +53,7 @@ import android.view.DisplayInfo; import android.view.InsetsState; import android.view.SurfaceControl; import android.view.WindowManager; +import android.view.WindowManager.LayoutParams.WindowType; import android.window.WindowContext; import com.android.internal.protolog.common.ProtoLog; @@ -70,10 +71,10 @@ import java.util.Comparator; class WindowToken extends WindowContainer { private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowToken" : TAG_WM; - // The actual token. + /** The actual token */ final IBinder token; - // The type of window this token is for, as per WindowManager.LayoutParams. + /** The type of window this token is for, as per {@link WindowManager.LayoutParams} */ final int windowType; /** @@ -86,8 +87,10 @@ class WindowToken extends WindowContainer { /** {@code true} if this holds the rounded corner overlay */ final boolean mRoundedCornerOverlay; - // Set if this token was explicitly added by a client, so should - // persist (not be removed) when all windows are removed. + /** + * Set if this token was explicitly added by a client, so should persist (not be removed) + * when all windows are removed. + */ boolean mPersistOnEmpty; // For printing. @@ -198,21 +201,15 @@ class WindowToken extends WindowContainer { return isFirstChildWindowGreaterThanSecond(newWindow, existingWindow) ? 1 : -1; }; - WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty, - DisplayContent dc, boolean ownerCanManageAppTokens) { + protected WindowToken(WindowManagerService service, IBinder _token, int type, + boolean persistOnEmpty, DisplayContent dc, boolean ownerCanManageAppTokens) { this(service, _token, type, persistOnEmpty, dc, ownerCanManageAppTokens, - false /* roundedCornerOverlay */); + false /* roundedCornerOverlay */, false /* fromClientToken */, null /* options */); } - WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty, - DisplayContent dc, boolean ownerCanManageAppTokens, boolean roundedCornerOverlay) { - this(service, _token, type, persistOnEmpty, dc, ownerCanManageAppTokens, - roundedCornerOverlay, false /* fromClientToken */, null /* options */); - } - - WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty, - DisplayContent dc, boolean ownerCanManageAppTokens, boolean roundedCornerOverlay, - boolean fromClientToken, @Nullable Bundle options) { + protected WindowToken(WindowManagerService service, IBinder _token, int type, + boolean persistOnEmpty, DisplayContent dc, boolean ownerCanManageAppTokens, + boolean roundedCornerOverlay, boolean fromClientToken, @Nullable Bundle options) { super(service); token = _token; windowType = type; @@ -770,7 +767,69 @@ class WindowToken extends WindowContainer { } @Override - @WindowManager.LayoutParams.WindowType int getWindowType() { + @WindowType int getWindowType() { return windowType; } + + static class Builder { + private final WindowManagerService mService; + private final IBinder mToken; + @WindowType + private final int mType; + + private boolean mPersistOnEmpty; + private DisplayContent mDisplayContent; + private boolean mOwnerCanManageAppTokens; + private boolean mRoundedCornerOverlay; + private boolean mFromClientToken; + @Nullable + private Bundle mOptions; + + Builder(WindowManagerService service, IBinder token, int type) { + mService = service; + mToken = token; + mType = type; + } + + /** @see WindowToken#mPersistOnEmpty */ + Builder setPersistOnEmpty(boolean persistOnEmpty) { + mPersistOnEmpty = persistOnEmpty; + return this; + } + + /** Sets the {@link DisplayContent} to be associated. */ + Builder setDisplayContent(DisplayContent dc) { + mDisplayContent = dc; + return this; + } + + /** @see WindowToken#mOwnerCanManageAppTokens */ + Builder setOwnerCanManageAppTokens(boolean ownerCanManageAppTokens) { + mOwnerCanManageAppTokens = ownerCanManageAppTokens; + return this; + } + + /** @see WindowToken#mRoundedCornerOverlay */ + Builder setRoundedCornerOverlay(boolean roundedCornerOverlay) { + mRoundedCornerOverlay = roundedCornerOverlay; + return this; + } + + /** @see WindowToken#mFromClientToken */ + Builder setFromClientToken(boolean fromClientToken) { + mFromClientToken = fromClientToken; + return this; + } + + /** @see WindowToken#mOptions */ + Builder setOptions(Bundle options) { + mOptions = options; + return this; + } + + WindowToken build() { + return new WindowToken(mService, mToken, mType, mPersistOnEmpty, mDisplayContent, + mOwnerCanManageAppTokens, mRoundedCornerOverlay, mFromClientToken, mOptions); + } + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java index 7df17fd4b3c6b..31d46125fd70e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java @@ -586,10 +586,13 @@ public class DisplayAreaPolicyBuilderTest { .setTaskDisplayAreas(Lists.newArrayList(mTda2))) .build(mWms); - final WindowToken token = new WindowToken(mWms, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, null /* options */); + final WindowToken token = new WindowToken.Builder(mWms, mock(IBinder.class), + TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .build(); + policy.addWindow(token); // By default, window are always added to the root. @@ -600,10 +603,13 @@ public class DisplayAreaPolicyBuilderTest { // When the window has options for target root id, attach it to the target root. final Bundle options = new Bundle(); options.putInt(KEY_ROOT_DISPLAY_AREA_ID, mGroupRoot2.mFeatureId); - final WindowToken token2 = new WindowToken(mWms, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, options); + final WindowToken token2 = new WindowToken.Builder(mWms, mock(IBinder.class), + TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .setOptions(options) + .build(); policy.addWindow(token2); assertThat(token2.isDescendantOf(mGroupRoot2)).isTrue(); @@ -631,14 +637,18 @@ public class DisplayAreaPolicyBuilderTest { }) .build(mWms); - final WindowToken token1 = new WindowToken(mWms, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, null /* options */); - final WindowToken token2 = new WindowToken(mWms, mock(IBinder.class), - TYPE_WALLPAPER, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, null /* options */); + final WindowToken token1 = new WindowToken.Builder(mWms, mock(IBinder.class), + TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .build(); + final WindowToken token2 = new WindowToken.Builder(mWms, mock(IBinder.class), + TYPE_WALLPAPER) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .build(); policy.addWindow(token1); policy.addWindow(token2); @@ -682,18 +692,26 @@ public class DisplayAreaPolicyBuilderTest { options1.putInt("HIERARCHY_ROOT_ID", mGroupRoot1.mFeatureId); final Bundle options2 = new Bundle(); options2.putInt("HIERARCHY_ROOT_ID", mGroupRoot2.mFeatureId); - final WindowToken token0 = new WindowToken(mWms, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, null /* options */); - final WindowToken token1 = new WindowToken(mWms, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, options1); - final WindowToken token2 = new WindowToken(mWms, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */, - false /* fromClientToken */, options2); + final WindowToken token0 = new WindowToken.Builder(mWms, mock(IBinder.class), + TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .build(); + final WindowToken token1 = new WindowToken.Builder(mWms, mock(IBinder.class), + TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .setOptions(options1) + .build(); + final WindowToken token2 = new WindowToken.Builder(mWms, mock(IBinder.class), + TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .setOptions(options2) + .build(); policy.addWindow(token0); policy.addWindow(token1); @@ -787,9 +805,8 @@ public class DisplayAreaPolicyBuilderTest { } private WindowToken tokenOfType(int type) { - WindowToken token = new WindowToken(mWms, new Binder(), type, false /* persistOnEmpty */, - mDisplayContent, false /* ownerCanManageAppTokens */); - return token; + return new WindowToken.Builder(mWms, new Binder(), type) + .setDisplayContent(mDisplayContent).build(); } private static void assertMatchLayerOrder(List> actualOrder, diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java index d4c956db90a9b..d5628fc9de48a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java @@ -586,8 +586,6 @@ public class DisplayAreaTest extends WindowTestsBase { } private WindowToken createWindowToken(int type) { - return new WindowToken(mWm, new Binder(), - type, false /* persist */, null /* displayContent */, - false /* canManageTokens */); + return new WindowToken.Builder(mWm, new Binder(), type).build(); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java index e9907c1fd1a51..bdc4b4eae6309 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java @@ -390,8 +390,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { } private WindowToken tokenOfType(int type) { - return new WindowToken(mWm, new Binder(), type, false /* persistOnEmpty */, - mDisplay, false /* ownerCanManageAppTokens */); + return new WindowToken.Builder(mWm, new Binder(), type) + .setDisplayContent(mDisplay).build(); } /** Display with two {@link DisplayAreaGroup}. Each of them take half of the screen. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index ed5f1d8c9fc5e..d048f1842aa3e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -183,30 +183,6 @@ public class WindowTokenTests extends WindowTestsBase { assertEquals(originalRotation, tokens[1].getWindowConfiguration().getRotation()); } - /** - * Test that {@link WindowToken} constructor parameters is set with expectation. - */ - @Test - public void testWindowTokenConstructorValidity() { - WindowToken token = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), - TYPE_TOAST, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */); - assertFalse(token.mRoundedCornerOverlay); - assertFalse(token.isFromClient()); - - token = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), TYPE_TOAST, - true /* persistOnEmpty */, mDisplayContent, true /* ownerCanManageAppTokens */, - true /* roundedCornerOverlay */); - assertTrue(token.mRoundedCornerOverlay); - assertFalse(token.isFromClient()); - - token = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), TYPE_TOAST, - true /* persistOnEmpty */, mDisplayContent, true /* ownerCanManageAppTokens */, - true /* roundedCornerOverlay */, true /* fromClientToken */, null /* options */); - assertTrue(token.mRoundedCornerOverlay); - assertTrue(token.isFromClient()); - } - /** * Test that {@link android.view.SurfaceControl} should not be created for the * {@link WindowToken} which was created for {@link WindowContext} initially, the @@ -214,19 +190,22 @@ public class WindowTokenTests extends WindowTestsBase { */ @Test public void testSurfaceCreatedForWindowToken() { - final WindowToken fromClientToken = new WindowToken(mDisplayContent.mWmService, - mock(IBinder.class), TYPE_APPLICATION_OVERLAY, true /* persistOnEmpty */, - mDisplayContent, true /* ownerCanManageAppTokens */, - true /* roundedCornerOverlay */, true /* fromClientToken */, null /* options */); + final WindowToken fromClientToken = new WindowToken.Builder(mDisplayContent.mWmService, + mock(IBinder.class), TYPE_APPLICATION_OVERLAY) + .setDisplayContent(mDisplayContent) + .setFromClientToken(true) + .build(); + assertNull(fromClientToken.mSurfaceControl); createWindow(null, TYPE_APPLICATION_OVERLAY, fromClientToken, "window"); assertNotNull(fromClientToken.mSurfaceControl); - final WindowToken nonClientToken = new WindowToken(mDisplayContent.mWmService, - mock(IBinder.class), TYPE_TOAST, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, true /* roundedCornerOverlay */, - false /* fromClientToken */, null /* options */); + final WindowToken nonClientToken = new WindowToken.Builder(mDisplayContent.mWmService, + mock(IBinder.class), TYPE_APPLICATION_OVERLAY) + .setDisplayContent(mDisplayContent) + .setFromClientToken(false) + .build(); assertNotNull(nonClientToken.mSurfaceControl); } @@ -237,18 +216,23 @@ public class WindowTokenTests extends WindowTestsBase { .mSelectRootForWindowFunc; spyOn(selectFunc); - final WindowToken token1 = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, true /* roundedCornerOverlay */, - false /* fromClientToken */, null /* options */); + final WindowToken token1 = new WindowToken.Builder(mDisplayContent.mWmService, + mock(IBinder.class), TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .build(); verify(selectFunc).apply(token1.windowType, null); final Bundle options = new Bundle(); - final WindowToken token2 = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), - TYPE_STATUS_BAR, true /* persistOnEmpty */, mDisplayContent, - true /* ownerCanManageAppTokens */, true /* roundedCornerOverlay */, - false /* fromClientToken */, options /* options */); + final WindowToken token2 = new WindowToken.Builder(mDisplayContent.mWmService, + mock(IBinder.class), TYPE_STATUS_BAR) + .setDisplayContent(mDisplayContent) + .setPersistOnEmpty(true) + .setOwnerCanManageAppTokens(true) + .setOptions(options) + .build(); verify(selectFunc).apply(token2.windowType, options); }