文章目录
- 序
- 节点添加
- Task
- 以DefaultTaskDisplayArea为父节点
- 以Task为父节点
- ActivityRecord
- WindowToken
- WindowState
- 以WindowToken为父节点
- 以ActivityRecord为父节点
- 小结
- 调用场景
- 添加差异
- 流程分析
- 添加log
- 堆栈打印流程
- Launcher
- StatusBar
序
尚未添加窗口的层级结构树,如图
DisplayArea层级结构中的每一个DisplayArea,都包含着一个层级值范围,这个层级值范围表明了这个DisplayArea可以容纳哪些类型的窗口。
每种窗口类型,都可以通过WindowManagerPolicy.getWindowLayerFromTypeLw方法,返回一个相应的层级值。
/**
* Returns the layer assignment for the window type. Allows you to control how different
* kinds of windows are ordered on-screen.
*
* @param type The type of window being assigned.
* @param canAddInternalSystemWindow If the owner window associated with the type we are
* evaluating can add internal system windows. I.e they have
* {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
* types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
* can be assigned layers greater than the layer for
* {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
* layers would be lesser.
* @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
*/
default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
return getWindowLayerFromTypeLw(type, canAddInternalSystemWindow,
false /* roundedCornerOverlay */);
}
/**
* Returns the layer assignment for the window type. Allows you to control how different
* kinds of windows are ordered on-screen.
*
* @param type The type of window being assigned.
* @param canAddInternalSystemWindow If the owner window associated with the type we are
* evaluating can add internal system windows. I.e they have
* {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
* types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
* can be assigned layers greater than the layer for
* {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
* layers would be lesser.
* @param roundedCornerOverlay {#code true} to indicate that the owner window is rounded corner
* overlay.
* @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
*/
default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow,
boolean roundedCornerOverlay) {
// Always put the rounded corner layer to the top most.
if (roundedCornerOverlay && canAddInternalSystemWindow) {
return getMaxWindowLayer();
}
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
return APPLICATION_LAYER;
}
switch (type) {
case TYPE_WALLPAPER:
// wallpaper is at the bottom, though the window manager may move it.
return 1;
case TYPE_PRESENTATION:
case TYPE_PRIVATE_PRESENTATION:
case TYPE_DOCK_DIVIDER:
case TYPE_QS_DIALOG:
case TYPE_PHONE:
return 3;
case TYPE_SEARCH_BAR:
return 4;
case TYPE_INPUT_CONSUMER:
return 5;
case TYPE_SYSTEM_DIALOG:
return 6;
case TYPE_TOAST:
// toasts and the plugged-in battery thing
return 7;
case TYPE_PRIORITY_PHONE:
// SIM errors and unlock. Not sure if this really should be in a high layer.
return 8;
case TYPE_SYSTEM_ALERT:
// like the ANR / app crashed dialogs
// Type is deprecated for non-system apps. For system apps, this type should be
// in a higher layer than TYPE_APPLICATION_OVERLAY.
return canAddInternalSystemWindow ? 12 : 9;
case TYPE_APPLICATION_OVERLAY:
return 11;
case TYPE_INPUT_METHOD:
// on-screen keyboards and other such input method user interfaces go here.
return 13;
case TYPE_INPUT_METHOD_DIALOG:
// on-screen keyboards and other such input method user interfaces go here.
return 14;
case TYPE_STATUS_BAR:
return 15;
case TYPE_STATUS_BAR_ADDITIONAL:
return 16;
case TYPE_NOTIFICATION_SHADE:
return 17;
case TYPE_STATUS_BAR_SUB_PANEL:
return 18;
case TYPE_KEYGUARD_DIALOG:
return 19;
case TYPE_VOICE_INTERACTION_STARTING:
return 20;
case TYPE_VOICE_INTERACTION:
// voice interaction layer should show above the lock screen.
return 21;
case TYPE_VOLUME_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
return 22;
case TYPE_SYSTEM_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
return canAddInternalSystemWindow ? 23 : 10;
case TYPE_NAVIGATION_BAR:
// the navigation bar, if available, shows atop most things
return 24;
case TYPE_NAVIGATION_BAR_PANEL:
// some panels (e.g. search) need to show on top of the navigation bar
return 25;
case TYPE_SCREENSHOT:
// screenshot selection layer shouldn't go above system error, but it should cover
// navigation bars at the very least.
return 26;
case TYPE_SYSTEM_ERROR:
// system-level error dialogs
return canAddInternalSystemWindow ? 27 : 9;
case TYPE_MAGNIFICATION_OVERLAY:
// used to highlight the magnified portion of a display
return 28;
case TYPE_DISPLAY_OVERLAY:
// used to simulate secondary display devices
return 29;
case TYPE_DRAG:
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
return 30;
case TYPE_ACCESSIBILITY_OVERLAY:
// overlay put by accessibility services to intercept user interaction
return 31;
case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
return 32;
case TYPE_SECURE_SYSTEM_OVERLAY:
return 33;
case TYPE_BOOT_PROGRESS:
return 34;
case TYPE_POINTER:
// the (mouse) pointer layer
return 35;
default:
Slog.e("WindowManager", "Unknown window type: " + type);
return 3;
}
}
在DisplayArea层级结构中,可以直接容纳窗口的父节点,有三种类型:
- TaskDisplayArea用于容纳App类型窗口,Task的容器是TaskDisplayArea,该容器也就是对应我们层级结构树中的DefaultTaskDisplayArea,ActivityRecord的容器是Task
- DisplayArea.Tokens用于容纳非App类型窗口,WindowToken的容器是DisplayArea.Tokens,该容器对应层级结构树中的Leaf节点。其中WallpaperWindowToken继承WindowToken,是用来存放和Wallpaper相关的窗口
- ImeContainer用于容纳输入法窗口,输入法的容器是ImeContainer
这里我们根据上面的代码,以及adb shell dumpsys activity containers
的信息简单画出如下树形图
节点添加
如何知道这些窗口是在什么时候添加的?
我们需要理清各个节点的父子关系,从有助于我们找到关键代码
Task
从以及adb shell dumpsys activity containers
和树形图我们知道Task节点的父亲是DefaultTaskDisplayArea
当然还有一种情况是Task的父节点为Task的情况。
那么DefaultTaskDisplayArea和Task中一定有添加Task相关的方法,比如addTask、addChild。
以DefaultTaskDisplayArea为父节点
我们顺着这个思路在TaskDisplayArea.java中看看有没有相关方法
代码路径:frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
void addChild(WindowContainer child, int position) {
if (child.asTaskDisplayArea() != null) {
if (DEBUG_ROOT_TASK) {
Slog.d(TAG_WM, "Set TaskDisplayArea=" + child + " on taskDisplayArea=" + this);
}
super.addChild(child, position);
} else if (child.asTask() != null) {
addChildTask(child.asTask(), position);
} else {
throw new IllegalArgumentException(
"TaskDisplayArea can only add Task and TaskDisplayArea, but found "
+ child);
}
}
private void addChildTask(Task task, int position) {
if (DEBUG_ROOT_TASK) Slog.d(TAG_WM, "Set task=" + task + " on taskDisplayArea=" + this);
addRootTaskReferenceIfNeeded(task);
position = findPositionForRootTask(position, task, true /* adding */);
super.addChild(task, position);
if (mPreferredTopFocusableRootTask != null
&& task.isFocusable()
&& mPreferredTopFocusableRootTask.compareTo(task) < 0) {
// Clear preferred top because the adding focusable task has a higher z-order.
mPreferredTopFocusableRootTask = null;
}
mAtmService.updateSleepIfNeededLocked();
onRootTaskOrderChanged(task);
}
我们发现在void addChild(WindowContainer child, int position)
中满足条件child.asTask() != null
时,就会调用addChildTask(child.asTask(), position);
这也是我们添加Task的方法。可以看到里面有一个关键的调用super.addChild(task, position);
,也就是说实际的添加在这里
对应的是WindowContainer的void addChild(E child, int index)
代码路径:frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
/**
* Adds the input window container has a child of this container at the input index.
*/
@CallSuper
void addChild(E child, int index) {
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()
+ "\n callers=" + Debug.getCallers(15, "\n"));
}
if ((index < 0 && index != POSITION_BOTTOM)
|| (index > mChildren.size() && index != POSITION_TOP)) {
throw new IllegalArgumentException("addChild: invalid position=" + index
+ ", children number=" + mChildren.size());
}
if (index == POSITION_TOP) {
index = mChildren.size();
} else if (index == POSITION_BOTTOM) {
index = 0;
}
mChildren.add(index, child);
// Set the parent after we've actually added a child in case a subclass depends on this.
child.setParent(this);
}
实际上调用的我们构建层级结构树时的方法。
以Task为父节点
在Task.java中查找添加节点的相关方法
代码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java
void addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers) {
Task task = child.asTask();
try {
if (task != null) {
task.setForceShowForAllUsers(showForAllUsers);
}
// We only want to move the parents to the parents if we are creating this task at the
// top of its root task.
addChild(child, toTop ? MAX_VALUE : 0, toTop /*moveParents*/);
} finally {
if (task != null) {
task.setForceShowForAllUsers(false);
}
}
}
/**
* Put a Task in this root task. Used for adding only.
* When task is added to top of the root task, the entire branch of the hierarchy (including
* root task and display) will be brought to top.
* @param child The child to add.
* @param position Target position to add the task to.
*/
private void addChild(WindowContainer child, int position, boolean moveParents) {
// Add child task.
addChild(child, null);
// Move child to a proper position, as some restriction for position might apply.
positionChildAt(position, child, moveParents /* includingParents */);
}
这里的addChild(child, null);
实际调用的是WindowContainer的protected void addChild(E child, Comparator<E> comparator)
,因为其父类TaskFragment中没有符合该入参的addChild方法,因此继续向上查找TaskFragment的父类WindowContainer中的addChild方法
代码路径:frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
/**
* Adds the input window container has a child of this container in order based on the input
* comparator.
* @param child The window container to add as a child of this window container.
* @param comparator Comparator to use in determining the position the child should be added to.
* If null, the child will be added to the top.
*/
@CallSuper
protected void addChild(E child, Comparator<E> comparator) {
......
//记录插入数组的位置,若为-1则将当前child加入到后面
int positionToAdd = -1;
if (comparator != null) {
//判断当前节点中孩子的数量
//依次比较将要加入的窗口与已经存在的child的BaseLayer
//mChildren越大放到数组最前面
final int count = mChildren.size();
for (int i = 0; i < count; i++) {
//比较baseLayer,如果child大于列表中已经存在的,则需要返回1,否则返回-1
//新加入的的child大于mChildren.get(i)则返回1,小于则返回-1
//注:comparator比较器的逻辑见上面代码的mWindowComparator
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的mParent设置为this
child.setParent(this);
}
protected void addChild(E child, Comparator<E> comparator)
是重载addChild,和之前的void addChild(E child, int index)
有所不同
ActivityRecord
ActivityRecord的父节点是Task,同样的在Task.java中找添加ActivityRecord的方法
代码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java
@Override
void addChild(WindowContainer child, int index) {
index = getAdjustedChildPosition(child, index);
super.addChild(child, index);
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addChild: %s at top.", this);
// A rootable task that is now being added to be the child of an organized task. Making
// sure the root task references is keep updated.
if (mTaskOrganizer != null && mCreatedByOrganizer && child.asTask() != null) {
getDisplayArea().addRootTaskReferenceIfNeeded((Task) child);
}
// Make sure the list of display UID allowlists is updated
// now that this record is in a new task.
mRootWindowContainer.updateUIDsPresentOnDisplay();
// Only pass minimum dimensions for pure TaskFragment. Task's minimum dimensions must be
// passed from Task constructor.
final TaskFragment childTaskFrag = child.asTaskFragment();
if (childTaskFrag != null && childTaskFrag.asTask() == null) {
childTaskFrag.setMinDimensions(mMinWidth, mMinHeight);
}
}
super.addChild(child, index);
调用的是Task父类TaskFragment的addChild方法
代码路径:frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
@Override
void addChild(WindowContainer child, int index) {
ActivityRecord r = topRunningActivity();
mClearedTaskForReuse = false;
mClearedTaskFragmentForPip = false;
final ActivityRecord addingActivity = child.asActivityRecord();
final boolean isAddingActivity = addingActivity != null;
final Task task = isAddingActivity ? getTask() : null;
// If this task had any activity before we added this one.
boolean taskHadActivity = task != null && task.getTopMostActivity() != null;
// getActivityType() looks at the top child, so we need to read the type before adding
// a new child in case the new child is on top and UNDEFINED.
final int activityType = task != null ? task.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
super.addChild(child, index);
if (isAddingActivity && task != null) {
// TODO(b/207481538): temporary per-activity screenshoting
if (r != null && BackNavigationController.isScreenshotEnabled()) {
ProtoLog.v(WM_DEBUG_BACK_PREVIEW, "Screenshotting Activity %s",
r.mActivityComponent.flattenToString());
Rect outBounds = r.getBounds();
SurfaceControl.ScreenshotHardwareBuffer backBuffer = SurfaceControl.captureLayers(
r.mSurfaceControl,
new Rect(0, 0, outBounds.width(), outBounds.height()),
1f);
mBackScreenshots.put(r.mActivityComponent.flattenToString(), backBuffer);
}
child.asActivityRecord().inHistory = true;
task.onDescendantActivityAdded(taskHadActivity, activityType, addingActivity);
}
}
super.addChild(child, index);
调用TaskFragment父类方法,即WindowContainer的void addChild(E child, int index)
WindowToken
WindowToken的父节点是叶子节点或者输入法节点,叶子节点和输入法节点其实都是DisplayArea.Tokens类型。
WallpaperWindowToken继承WindowToken,因此同理。
所以我们只需在DisplayArea.java的Tokens类中查找相关的添加WindowToken的方法。
代码路径:frameworks/base/services/core/java/com/android/server/wm/DisplayArea.java
void addChild(WindowToken token) {
addChild(token, mWindowComparator);
}
这里的addChild(token, mWindowComparator);
调用的就是WindowContainer的protected void addChild(E child, Comparator<E> comparator)
WindowState
WindowState的父节点是WindowToken和ActivityRecord,我们在WindowToken.java和中ActivityRecord.java找添加WindowState的方法
以WindowToken为父节点
代码路径:frameworks/base/services/core/java/com/android/server/wm/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?
}
}
addChild(win, mWindowComparator);
调用的就是WindowContainer的protected void addChild(E child, Comparator<E> comparator)
添加WindowState
以ActivityRecord为父节点
代码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
@Override
void addWindow(WindowState w) {
super.addWindow(w);
boolean gotReplacementWindow = false;
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState candidate = mChildren.get(i);
gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
}
// if we got a replacement window, reset the timeout to give drawing more time
if (gotReplacementWindow) {
mWmService.scheduleWindowReplacementTimeouts(this);
}
checkKeyguardFlagsChanged();
}
ActivityRecord的父类是WindowToken,其super.addWindow(w);
调用的就是WindowToken的addWindow方法,因此最终也是通过WindowContainer的protected void addChild(E child, Comparator<E> comparator)
添加WindowState
小结
通过前面的分析,添加窗口最终都是通过WindowContainer的void addChild(E child, int index)
和protected void addChild(E child, Comparator<E> comparator)
来添加的,我们来汇总一下这两种方法的调用情况与区别
调用场景
调用void addChild(E child, int index)
的情况
- DefaultTaskDisplayArea添加Task
- Task添加ActivityRecord
调用protected void addChild(E child, Comparator<E> comparator)
的情况
- Task添加Task
- 叶子节点和输入法节点(Token)添加WindowToken
- WindowToken添加WindowState
- ActivityRecord添加WindowState
添加差异
WindowContainer中的void addChild(E child, int index)和protected void addChild(E child, Comparator comparator)方法区别是什么?
它们之间的区别其实在于添加子容器的方式和顺序。
void addChild(E child, int index)
方法:
- 该方法通过传入的index参数指定了子容器的插入位置。index表示子容器在当前容器的子容器列表中的位置索引。
- 调用该方法会将子容器添加到指定的位置,而不会根据任何比较器进行排序。
- 这种方式适用于需要直接指定子容器的插入位置的情况。
protected void addChild(E child, Comparator<E> comparator)
方法:
- 该方法通过传入的Comparator参数定义了子容器的排序规则。
- 调用该方法会将子容器添加到当前容器的子容器列表中,并根据指定的比较器对子容器进行排序。
- 这种方式适用于根据特定的排序规则对子容器进行动态排序的情况。
总结起来,addChild(E child, int index)方法允许直接指定子容器的插入位置,而addChild(E child, Comparator comparator)方法则通过比较器对子容器进行排序并添加到合适的位置。根据实际需求,可以选择适合的方法来添加子容器。
流程分析
添加log
既然从上述分析中发现添加窗口最终都是通过WindowContainer的void addChild(E child, int index)
和protected void addChild(E child, Comparator<E> comparator)
来添加的,那么我们可以添加相关的log,来看看其对应的流程是怎么样的
void addChild(E child, int index) {
if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken || child instanceof WindowState) {
android.util.Log.i("WindowContainer.TAG:", this + "addChild child = " + child , new Exception());
}
......
}
protected void addChild(E child, Comparator<E> comparator) {
if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken || child instanceof WindowState) {
android.util.Log.i("WindowContainer.TAG:", this + "addChild Comparator child = " + child , new Exception());
}
......
}
堆栈打印流程
这里我们以Launcher和StatusBar为例
Launcher
WindowContainer.TAG : DefaultTaskDisplayArea@243571827 addChild child = Task{a13d730 #1 type=home ?? U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
WindowContainer.TAG : java.lang.Exception
WindowContainer.TAG : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
WindowContainer.TAG : at com.android.server.wm.TaskDisplayArea.addChildTask(TaskDisplayArea.java:334)
WindowContainer.TAG : at com.android.server.wm.TaskDisplayArea.addChild(TaskDisplayArea.java:320)
WindowContainer.TAG : at com.android.server.wm.Task$Builder.build(Task.java:6551)
WindowContainer.TAG : at com.android.server.wm.TaskDisplayArea.createRootTask(TaskDisplayArea.java:1066)
WindowContainer.TAG : at com.android.server.wm.TaskDisplayArea.createRootTask(TaskDisplayArea.java:1040)
WindowContainer.TAG : at com.android.server.wm.TaskDisplayArea.getOrCreateRootHomeTask(TaskDisplayArea.java:1640)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.setWindowManager(RootWindowContainer.java:1321)
WindowContainer.TAG : at com.android.server.wm.ActivityTaskManagerService.setWindowManager(ActivityTaskManagerService.java:1006)
WindowContainer.TAG : at com.android.server.am.ActivityManagerService.setWindowManager(ActivityManagerService.java:1923)
WindowContainer.TAG : at com.android.server.SystemServer.startOtherServices(SystemServer.java:1595)
WindowContainer.TAG : at com.android.server.SystemServer.run(SystemServer.java:939)
WindowContainer.TAG : at com.android.server.SystemServer.main(SystemServer.java:649)
WindowContainer.TAG : at java.lang.reflect.Method.invoke(Native Method)
WindowContainer.TAG : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
WindowContainer.TAG : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
WindowContainer.TAG : Task{a13d730 #1 type=home ?? U=0 visible=true visibleRequested=false mode=fullscreen translucent=true sz=0} addChild Comparator child = Task{63f31d4 #2 type=undefined A=1000:com.android.settings.FallbackHome U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
WindowContainer.TAG : java.lang.Exception
WindowContainer.TAG : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG : at com.android.server.wm.Task.addChild(Task.java:5935)
WindowContainer.TAG : at com.android.server.wm.Task.-$$Nest$maddChild(Unknown Source:0)
WindowContainer.TAG : at com.android.server.wm.Task$Builder.build(Task.java:6548)
WindowContainer.TAG : at com.android.server.wm.Task.reuseOrCreateTask(Task.java:5819)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2872)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1864)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
WindowContainer.TAG : at com.android.server.wm.ActivityStartController.startHomeActivity(ActivityStartController.java:179)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnTaskDisplayArea(RootWindowContainer.java:1493)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.lambda$startHomeOnDisplay$12$com-android-server-wm-RootWindowContainer(RootWindowContainer.java:1434)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer$$ExternalSyntheticLambda7.apply(Unknown Source:16)
WindowContainer.TAG : at com.android.server.wm.TaskDisplayArea.reduceOnAllTaskDisplayAreas(TaskDisplayArea.java:513)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.WindowContainer.reduceOnAllTaskDisplayAreas(WindowContainer.java:2283)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1433)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1420)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnAllDisplays(RootWindowContainer.java:1405)
WindowContainer.TAG : at com.android.server.wm.ActivityTaskManagerService$LocalService.startHomeOnAllDisplays(ActivityTaskManagerService.java:5892)
WindowContainer.TAG : at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8203)
WindowContainer.TAG : at com.android.server.SystemServer.startOtherServices(SystemServer.java:2801)
WindowContainer.TAG : at com.android.server.SystemServer.run(SystemServer.java:939)
WindowContainer.TAG : at com.android.server.SystemServer.main(SystemServer.java:649)
WindowContainer.TAG : at java.lang.reflect.Method.invoke(Native Method)
WindowContainer.TAG : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
WindowContainer.TAG : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
WindowContainer.TAG : Task{63f31d4 #2 type=undefined A=1000:com.android.settings.FallbackHome U=0 rootTaskId=1 visible=true visibleRequested=false mode=fullscreen translucent=true sz=0} addChild child = ActivityRecord{983a135 u0 com.android.settings/.FallbackHome}
WindowContainer.TAG : java.lang.Exception
WindowContainer.TAG : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
WindowContainer.TAG : at com.android.server.wm.TaskFragment.addChild(TaskFragment.java:1835)
WindowContainer.TAG : at com.android.server.wm.Task.addChild(Task.java:1429)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:2927)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2877)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1864)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
WindowContainer.TAG : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
WindowContainer.TAG : at com.android.server.wm.ActivityStartController.startHomeActivity(ActivityStartController.java:179)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnTaskDisplayArea(RootWindowContainer.java:1493)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.lambda$startHomeOnDisplay$12$com-android-server-wm-RootWindowContainer(RootWindowContainer.java:1434)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer$$ExternalSyntheticLambda7.apply(Unknown Source:16)
WindowContainer.TAG : at com.android.server.wm.TaskDisplayArea.reduceOnAllTaskDisplayAreas(TaskDisplayArea.java:513)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG : at com.android.server.wm.WindowContainer.reduceOnAllTaskDisplayAreas(WindowContainer.java:2283)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1433)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1420)
WindowContainer.TAG : at com.android.server.wm.RootWindowContainer.startHomeOnAllDisplays(RootWindowContainer.java:1405)
WindowContainer.TAG : at com.android.server.wm.ActivityTaskManagerService$LocalService.startHomeOnAllDisplays(ActivityTaskManagerService.java:5892)
WindowContainer.TAG : at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8203)
WindowContainer.TAG : at com.android.server.SystemServer.startOtherServices(SystemServer.java:2801)
WindowContainer.TAG : at com.android.server.SystemServer.run(SystemServer.java:939)
WindowContainer.TAG : at com.android.server.SystemServer.main(SystemServer.java:649)
WindowContainer.TAG : at java.lang.reflect.Method.invoke(Native Method)
WindowContainer.TAG : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
WindowContainer.TAG : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
WindowContainer.TAG : ActivityRecord{983a135 u0 com.android.settings/.FallbackHome} t2} addChild Comparator child = Window{ae9b359 u0 com.android.settings/com.android.settings.FallbackHome}
WindowContainer.TAG : java.lang.Exception
WindowContainer.TAG : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG : at com.android.server.wm.WindowToken.addWindow(WindowToken.java:302)
WindowContainer.TAG : at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:4212)
WindowContainer.TAG : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1773)
WindowContainer.TAG : at com.android.server.wm.Session.addToDisplayAsUser(Session.java:209)
WindowContainer.TAG : at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:652)
WindowContainer.TAG : at com.android.server.wm.Session.onTransact(Session.java:175)
WindowContainer.TAG : at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer.TAG : at android.os.Binder.execTransact(Binder.java:1244)
home task直接被TaskDisplayArea持有为孩子,这里可以明显看出Task{a13d730 #1 type=home 是在第一次创建WMS就已经创建好了,通过的是TaskDisplayArea.getOrCreateRootHomeTask开始一直到com.android.server.wm.WindowContainer.addChild
之后home task加入一个具体Launcher的task,这里最开始当然是我们的FallbackHome。
具体堆栈可以看出是ActivityManagerService.systemReady时候触发了ActivityTaskManagerService$LocalService.startHomeOnAllDisplays然后把HomeActivity拉起,由于此时还是加密状态,所以获取的的Home当然是setting的fallbackhome
最后ActivityRecord添加WindowState,就是通过跨进程通信addWindow。
StatusBar
WindowContainer.TAG : Leaf:15:15@65133355 addChild Comparator child = WindowToken{ea411e9 type=2000 android.os.BinderProxy@46a0296}
WindowContainer.TAG : java.lang.Exception
WindowContainer.TAG : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG : at com.android.server.wm.DisplayArea$Tokens.addChild(DisplayArea.java:605)
WindowContainer.TAG : at com.android.server.wm.DisplayContent.addWindowToken(DisplayContent.java:1235)
WindowContainer.TAG : at com.android.server.wm.WindowToken.<init>(WindowToken.java:214)
WindowContainer.TAG : at com.android.server.wm.WindowToken$Builder.build(WindowToken.java:817)
WindowContainer.TAG : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1577)
WindowContainer.TAG : at com.android.server.wm.Session.addToDisplayAsUser(Session.java:209)
WindowContainer.TAG : at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:652)
WindowContainer.TAG : at com.android.server.wm.Session.onTransact(Session.java:175)
WindowContainer.TAG : at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer.TAG : at android.os.Binder.execTransact(Binder.java:1244)
WindowContainer.TAG : WindowToken{ea411e9 type=2000 android.os.BinderProxy@46a0296} addChild Comparator child = Window{c86ce6e u0 StatusBar}
WindowContainer.TAG : java.lang.Exception
WindowContainer.TAG : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG : at com.android.server.wm.WindowToken.addWindow(WindowToken.java:302)
WindowContainer.TAG : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1773)
WindowContainer.TAG : at com.android.server.wm.Session.addToDisplayAsUser(Session.java:209)
WindowContainer.TAG : at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:652)
WindowContainer.TAG : at com.android.server.wm.Session.onTransact(Session.java:175)
WindowContainer.TAG : at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer.TAG : at android.os.Binder.execTransact(Binder.java:1244)
WindowToken和WindowState都是通过跨进程通信Session.addToDisplayAsUser来调用。
WindowToken的堆栈中WindowContainer.TAG : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1577)
,在1577行开始添加WindowToken,而WindowState的堆栈中WindowContainer.TAG : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1773)
1773行开始添加WindowState,正好是在添加WindowToken之后。
具体流程可参考Android T WMS窗口相关流程