Android在开机初始化时构建了一个WindowContainer树型结构,最顶层是RootWindowContainer,RootWindowContainer的mChildren是DisplayContent,再下面是一些DisplayArea,再下来:
1,如果是系统窗口的话,就是一些DisplayArea.Tokens的Leaf节点,Leaf节点的child是WindowToken,WindowToken的child是WindowState,WindowState代表一个Window,它也可以有child(WindowState)。
2,如果是应用类型窗口的话,就是TaskDisplayArea(DefaultTaskDisplayArea)节点,TaskDisplayArea的child可以是TaskDisplayArea或者Task,Task的child一般是Task或者ActivityRecord,ActivityRecord的child是WindowState,WindowState代表一个Window,它也可以有child(WindowState)。
以上树型结构中所有节点都被抽象成WindowContainer,所有节点都是WindowContainer的直接或间接子类。
WindowContainer中包含几个关键成员:
// 父级
WindowContainer<WindowContainer> mParent;
// 子级
WindowList<E> mChildren = new WindowList<E>();
// Surface句柄,包含可绘制类型和容器类型
SurfaceControl mSurfaceControl;
Window Layer分配
构建WindowContainer树型结构时会调用addChild方法
protected void addChild(E child, Comparator<E> comparator) {
if (!child.mReparenting && child.getParent() != null) {
throw new IllegalArgumentException("addChild: container=" + child.getName()
+ " is already a child of container=" + child.getParent().getName()
+ " can't add to container=" + getName());
}
int positionToAdd = -1;
if (comparator != null) {
final int count = mChildren.size();
for (int i = 0; i < count; i++) {
if (comparator.compare(child, mChildren.get(i)) < 0) {
positionToAdd = i;
break;
}
}
}
if (positionToAdd == -1) {
mChildren.add(child);
} else {
mChildren.add(positionToAdd, child);
}
// Set the parent after we've actually added a child in case a subclass depends on this.
child.setParent(this);
}
final protected void setParent(WindowContainer<WindowContainer> parent) {
final WindowContainer oldParent = mParent;
mParent = parent;
if (mParent != null) {
mParent.onChildAdded(this);
} else if (mSurfaceAnimator.hasLeash()) {
mSurfaceAnimator.cancelAnimation();
}
if (!mReparenting) {
onSyncReparent(oldParent, mParent);
if (mParent != null && mParent.mDisplayContent != null
&& mDisplayContent != mParent.mDisplayContent) {
onDisplayChanged(mParent.mDisplayContent);
}
onParentChanged(mParent, oldParent);
}
}
@Override
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
onParentChanged(newParent, oldParent, null);
}
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent,
PreAssignChildLayersCallback callback) {
super.onParentChanged(newParent, oldParent);
if (mParent == null) {
return;
}
if (mSurfaceControl == null) {
// If we don't yet have a surface, but we now have a parent, we should
// build a surface.
createSurfaceControl(false /*force*/);
} else {
// If we have a surface but a new parent, we just need to perform a reparent. Go through
// surface animator such that hierarchy is preserved when animating, i.e.
// mSurfaceControl stays attached to the leash and we just reparent the leash to the
// new parent.
reparentSurfaceControl(getSyncTransaction(), mParent.mSurfaceControl);
}
if (callback != null) {
callback.onPreAssignChildLayers();
}
// Either way we need to ask the parent to assign us a Z-order.
mParent.assignChildLayers();
scheduleAnimation();
}
最终会调用WindowContainer的assignChildLayers()方法
// WindowContainer.java
void assignChildLayers() {
assignChildLayers(getSyncTransaction());
scheduleAnimation();
}
void assignChildLayers(Transaction t) {
int layer = 0;
// We use two passes as a way to promote children which
// need Z-boosting to the end of the list.
for (int j = 0; j < mChildren.size(); ++j) {
final WindowContainer wc = mChildren.get(j);
// 递归child的child,给child的所有子级分配layer
wc.assignChildLayers(t);
if (!wc.needsZBoost()) {
// 先分配不需要ZBoost的child,需要ZBoost的layer较高
wc.assignLayer(t, layer++);
}
}
for (int j = 0; j < mChildren.size(); ++j) {
final WindowContainer wc = mChildren.get(j);
if (wc.needsZBoost()) {
// 分配需要ZBoost的layer
wc.assignLayer(t, layer++);
}
}
if (mOverlayHost != null) {
mOverlayHost.setLayer(t, layer++);
}
}
void assignLayer(Transaction t, int layer) {
// Don't assign layers while a transition animation is playing
// TODO(b/173528115): establish robust best-practices around z-order fighting.
if (mTransitionController.isPlaying()) return;
final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
if (mSurfaceControl != null && changed) {
setLayer(t, layer);
mLastLayer = layer;
mLastRelativeToLayer = null;
}
}
protected void setLayer(Transaction t, int layer) {
if (mSurfaceFreezer.hasLeash()) {
// When the freezer has created animation leash parent for the window, set the layer
// there instead.
mSurfaceFreezer.setLayer(t, layer);
} else {
// Route through surface animator to accommodate that our surface control might be
// attached to the leash, and leash is attached to parent container.
mSurfaceAnimator.setLayer(t, layer);
}
}
以上是WindowContainer的assignChildLayers和assignLayer方法,
对于assignChildLayers方法,WindowContainer的部分子类还有自己的实现,除了调用WindowContainer的assignChildLayers方法还有些额外的处理。
主要看下TaskDisplayArea和WindowState的assignChildLayers方法实现:
TaskDisplayArea.assignChildLayers方法
// TaskDisplayArea.java
@Override
void assignChildLayers(SurfaceControl.Transaction t) {
// 先给RootTask分配layer
assignRootTaskOrdering(t);
// 然后递归所有子级并分配layer
for (int i = 0; i < mChildren.size(); i++) {
mChildren.get(i).assignChildLayers(t);
}
}
void assignRootTaskOrdering(SurfaceControl.Transaction t) {
if (getParent() == null) {
return;
}
mTmpAlwaysOnTopChildren.clear();
mTmpHomeChildren.clear();
mTmpNormalChildren.clear();
for (int i = 0; i < mChildren.size(); ++i) {
final WindowContainer child = mChildren.get(i);
final TaskDisplayArea childTda = child.asTaskDisplayArea();
if (childTda != null) {
final Task childTdaTopRootTask = childTda.getTopRootTask();
if (childTdaTopRootTask == null) {
mTmpNormalChildren.add(childTda);
} else if (childTdaTopRootTask.isAlwaysOnTop()) {
mTmpAlwaysOnTopChildren.add(childTda);
} else if (childTdaTopRootTask.isActivityTypeHome()) {
mTmpHomeChildren.add(childTda);
} else {
mTmpNormalChildren.add(childTda);
}
continue;
}
// 把所有RootTask归为三类,AlwaysOnTop,HomeTask, Normal
final Task childTask = child.asTask();
if (childTask.isAlwaysOnTop()) {
mTmpAlwaysOnTopChildren.add(childTask);
} else if (childTask.isActivityTypeHome()) {
mTmpHomeChildren.add(childTask);
} else {
mTmpNormalChildren.add(childTask);
}
}
int layer = 0;
// Place root home tasks to the bottom.
// home task在最底部,layer较小
layer = adjustRootTaskLayer(t, mTmpHomeChildren, layer);
//Normal其次
layer = adjustRootTaskLayer(t, mTmpNormalChildren, layer);
// TODO(b/207185041): Remove this divider workaround after we full remove leagacy split and
// make app pair split only have single root then we can just attach the
// divider to the single root task in shell.
layer = Math.max(layer, SPLIT_DIVIDER_LAYER + 1);
// AlwaysOnTop在最上面,layer较大
adjustRootTaskLayer(t, mTmpAlwaysOnTopChildren, layer);
t.setLayer(mSplitScreenDividerAnchor, SPLIT_DIVIDER_LAYER);
}
我们先看下WindowState.assignLayer方法
// WindowState.java
@Override
void assignLayer(Transaction t, int layer) {
if (mStartingData != null) {
// The starting window should cover the task.
//mStartingData != null表示这是个starting window,layer分配最高
t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
return;
}
// See comment in assignRelativeLayerForImeTargetChild
if (needsRelativeLayeringToIme()) {
getDisplayContent().assignRelativeLayerForImeTargetChild(t, this);
return;
}
// 调用父类即WindowContainer的assignLayer方法
super.assignLayer(t, layer);
}
我们知道,WindowContainer的assignChildLayers方法中,父级给子级分配layer一般是从mChildren的下标0开始遍历所有子级并递增的分配layer,也就是说mChildren列表按z顺序排列,最顶部的窗口容器位于列表的尾部。
那么WindowState添加到其父级的mChildren列表时,是根据什么来确定其在列表的位置呢?
非子Window是根据WindowState的mBaseLayer,mBaseLayer越大,z-order越高;
// WindowToken.java
void addWindow(final WindowState win) {
ProtoLog.d(WM_DEBUG_FOCUS,
"addWindow: win=%s Callers=%s", win, Debug.getCallers(5));
if (win.isChildWindow()) {
// Child windows are added to their parent windows.
return;
}
// This token is created from WindowContext and the client requests to addView now, create a
// surface for this token.
if (mSurfaceControl == null) {
createSurfaceControl(true /* force */);
// Layers could have been assigned before the surface was created, update them again
reassignLayer(getSyncTransaction());
}
if (!mChildren.contains(win)) {
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", win, this);
//
addChild(win, mWindowComparator);
mWmService.mWindowsChanged = true;
// TODO: Should we also be setting layout needed here and other places?
}
}
private final Comparator<WindowState> mWindowComparator =
(WindowState newWindow, WindowState existingWindow) -> {
final WindowToken token = WindowToken.this;
if (newWindow.mToken != token) {
throw new IllegalArgumentException("newWindow=" + newWindow
+ " is not a child of token=" + token);
}
if (existingWindow.mToken != token) {
throw new IllegalArgumentException("existingWindow=" + existingWindow
+ " is not a child of token=" + token);
}
return isFirstChildWindowGreaterThanSecond(newWindow, existingWindow) ? 1 : -1;
};
protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
WindowState existingWindow) {
// New window is considered greater if it has a higher or equal base layer.
// 添加非子Window时,比较mBaseLayer
return newWindow.mBaseLayer >= existingWindow.mBaseLayer;
}
// WindowContainer.java
protected void addChild(E child, Comparator<E> comparator) {
if (!child.mReparenting && child.getParent() != null) {
throw new IllegalArgumentException("addChild: container=" + child.getName()
+ " is already a child of container=" + child.getParent().getName()
+ " can't add to container=" + getName());
}
int positionToAdd = -1;
if (comparator != null) {
final int count = mChildren.size();
for (int i = 0; i < count; i++) {
// 此处comparator.compare结果<0,新的child就排在前面,layer就小一些
if (comparator.compare(child, mChildren.get(i)) < 0) {
positionToAdd = i;
break;
}
}
}
if (positionToAdd == -1) {
mChildren.add(child);
} else {
mChildren.add(positionToAdd, child);
}
// Set the parent after we've actually added a child in case a subclass depends on this.
child.setParent(this);
}
子Window是根据WindowState的mSubLayer,mSubLayer越大,z-order越高;
// WindowState.java
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState parentWindow, int appOp, WindowManager.LayoutParams a, int viewVisibility,
int ownerId, int showUserId, boolean ownerCanAddInternalSystemWindow,
PowerManagerWrapper powerManagerWrapper) {
super(service);
// ...
// Make sure we initial all fields before adding to parentWindow, to prevent exception
// during onDisplayChanged.
if (mIsChildWindow) {
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", this, parentWindow);
parentWindow.addChild(this, sWindowSubLayerComparator);
}
// ...
}
private static final Comparator<WindowState> sWindowSubLayerComparator =
new Comparator<WindowState>() {
@Override
public int compare(WindowState w1, WindowState w2) {
final int layer1 = w1.mSubLayer;
final int layer2 = w2.mSubLayer;
//添加子Window时,mSubLayer越小,layer也相对较低
if (layer1 < layer2 || (layer1 == layer2 && layer2 < 0 )) {
// We insert the child window into the list ordered by
// the sub-layer. For same sub-layers, the negative one
// should go below others; the positive one should go
// above others.
return -1;
}
return 1;
};
};
WindowState分配子Window的assignChildLayers方法
// WindowState.java
public void assignChildLayers(Transaction t) {
// The surface of the main window might be preserved. So the child window on top of the main
// window should be also on top of the preserved surface.
int layer = PRESERVED_SURFACE_LAYER + 1;
for (int i = 0; i < mChildren.size(); i++) {
final WindowState w = mChildren.get(i);
// APPLICATION_MEDIA_OVERLAY needs to go above APPLICATION_MEDIA
// while they both need to go below the main window. However the
// relative layering of multiple APPLICATION_MEDIA/OVERLAY has never
// been defined and so we can use static layers and leave it that way.
// TYPE_APPLICATION_MEDIA和TYPE_APPLICATION_MEDIA_OVERLAY类型子Window
//分别分配layer值-2和-1,表示在其主Window的下面,
//如果父Window已经有可绘制的mSurfaceControl,则调用assignRelativeLayer相对的方法
if (w.mAttrs.type == TYPE_APPLICATION_MEDIA) {
if (mWinAnimator.hasSurface()) {
w.assignRelativeLayer(t, mWinAnimator.mSurfaceController.mSurfaceControl, -2);
} else {
w.assignLayer(t, -2);
}
} else if (w.mAttrs.type == TYPE_APPLICATION_MEDIA_OVERLAY) {
if (mWinAnimator.hasSurface()) {
w.assignRelativeLayer(t, mWinAnimator.mSurfaceController.mSurfaceControl, -1);
} else {
w.assignLayer(t, -1);
}
} else {
//其他类型的子Window正常分配layer,正值
w.assignLayer(t, layer);
}
//递归子Window继续为其子级分配layer
w.assignChildLayers(t);
layer++;
}
}