赞
踩
尚未添加窗口的层级结构树,如图
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<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的父节点是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<E> 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<E> 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<E> comparator)
添加WindowState
通过前面的分析,添加窗口最终都是通过WindowContainer的void addChild(E child, int index)
和protected void addChild(E child, Comparator<E> comparator)
来添加的,我们来汇总一下这两种方法的调用情况与区别
调用void addChild(E child, int index)
的情况
调用protected void addChild(E child, Comparator<E> 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<E> comparator)
方法:
总结起来,addChild(E child, int index)方法允许直接指定子容器的插入位置,而addChild(E child, Comparator comparator)方法则通过比较器对子容器进行排序并添加到合适的位置。根据实际需求,可以选择适合的方法来添加子容器。
既然从上述分析中发现添加窗口最终都是通过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为例
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窗口相关流程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。