Merge "Introduce WindowToken Builder" into sc-dev
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -1543,13 +1543,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) {
|
||||
@@ -1620,8 +1627,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,
|
||||
@@ -2647,9 +2656,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<WindowState> {
|
||||
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<WindowState> {
|
||||
/** {@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<WindowState> {
|
||||
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<WindowState> {
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DisplayArea<?>> actualOrder,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user