尚未添加窗口的层级结构树,如图
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层级结构中,可以直接容纳窗口的父节点,有三种类型:
这里我们根据上面的代码,以及adb shell dumpsys activity containers
的信息简单画出如下树形图
如何知道这些窗口是在什么时候添加的?
我们需要理清各个节点的父子关系,从有助于我们找到关键代码
从以及adb shell dumpsys activity containers
和树形图我们知道Task节点的父亲是DefaultTaskDisplayArea
当然还有一种情况是Task的父节点为Task的情况。
那么DefaultTaskDisplayArea和Task中一定有添加Task相关的方法,比如addTask、addChild。
我们顺着这个思路在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.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
,因为其父类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
是重载addChild,和之前的void addChild(E child, int index)
有所不同
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的父节点是叶子节点或者输入法节点,叶子节点和输入法节点其实都是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
WindowState的父节点是WindowToken和ActivityRecord,我们在WindowToken.java和中ActivityRecord.java找添加WindowState的方法
代码路径: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
添加WindowState
代码路径: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
添加WindowState
通过前面的分析,添加窗口最终都是通过WindowContainer的void addChild(E child, int index)
和protected void addChild(E child, Comparator
来添加的,我们来汇总一下这两种方法的调用情况与区别
调用void addChild(E child, int index)
的情况
调用protected void addChild(E child, Comparator
的情况
WindowContainer中的void addChild(E child, int index)和protected void addChild(E child, Comparator comparator)方法区别是什么?
它们之间的区别其实在于添加子容器的方式和顺序。
void addChild(E child, int index)
方法:
protected void addChild(E child, Comparator
方法:
总结起来,addChild(E child, int index)方法允许直接指定子容器的插入位置,而addChild(E child, Comparator comparator)方法则通过比较器对子容器进行排序并添加到合适的位置。根据实际需求,可以选择适合的方法来添加子容器。
既然从上述分析中发现添加窗口最终都是通过WindowContainer的void addChild(E child, int index)
和protected void addChild(E child, 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为例
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。
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窗口相关流程