1:WindowContainer
系统中的窗口window是放在一个容器中进行管理的,它的名字就是WindowContainer,用来管理添加进来的子WindowContainer,在android系统中有下来的几种WindowContainer
EB8A91CC-88FA-4912-8108-037AA2F3CCA2.png
WindowContainer有一个成员变量:WindowList<E> mChildren,用来保存添加进来的子容器,添加的流程大概是
protected void addChild(E child, Comparator<E> comparator) {
if (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);
}
onChildAdded(child);
// Set the parent after we've actually added a child in case a subclass depends on this.
child.setParent(this);
}
addChild这个方法主要是根据comparator来确定其具体的位置,然后插入到合适的位置上,child.setParent(this);设置其父容器,这样就能直接找到它的父容器
1.1:DisplayContent
DisplayContent对应的是一块显示屏幕,那么其不可能存在子屏幕的,也就是说它没有addChild方法,不过在其内部有四个默认的container,分别用来存储不同类型的窗口,还有一个HashMap<IBinder, WindowToken> mTokenMap用来保存当前显示屏幕上的所有的窗口
/** The containers below are the only child containers the display can have. */
// Contains all window containers that are related to apps (Activities)
private final TaskStackContainers mTaskStackContainers = new TaskStackContainers(mService);
// Contains all non-app window containers that should be displayed above the app containers
// (e.g. Status bar)
private final AboveAppWindowContainers mAboveAppWindowsContainers =
new AboveAppWindowContainers("mAboveAppWindowsContainers", mService);
// Contains all non-app window containers that should be displayed below the app containers
// (e.g. Wallpaper).
private final NonAppWindowContainers mBelowAppWindowsContainers =
new NonAppWindowContainers("mBelowAppWindowsContainers", mService);
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
// window containers together and move them in-sync if/when needed. We use a subclass of
// WindowContainer which is omitted from screen magnification, as the IME is never magnified.
private final NonMagnifiableWindowContainers mImeWindowsContainers =
new NonMagnifiableWindowContainers("mImeWindowsContainers", mService);
private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
1.2:TaskStack
TaskStack用来管理WMS端的栈,和AMS的ActivityStack是一一对应的,并且id也是一样的,TaskStack存储的是Task
1.3:Task
Task类似于任务栈,用来管理WindowToken/AppWindowToken的,和AMS端的TaskRecord是一一对应的,并且id也是相同的
1.4:AppWindowToken/WindowToken
WindowToken关联着一组token相同的WindowState,用来管理WindowState的
1.5:WindoState
WindowState是一个窗口单元,对应于wms的一个窗口,但是窗口有不同的类型,有子窗口,普通应用程序窗口,系统窗口,子窗口和父窗口是共token的,因此WindowState有addChild的功能
2:WindowContainerController
我们都知道AMS和WMS两者之间的数据都是一一对应的,那么它们之间是怎么建立连接的呢,就是通过WindowContainerController建立它们之间的联系的
windowController.png
2.1:DisplayWindowController
每创建一个ActivityDisplay的时候都会创建一个DisplayWindowController
ActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
this(supervisor, supervisor.mDisplayManager.getDisplay(displayId));
}
ActivityDisplay(ActivityStackSupervisor supervisor, Display display) {
mSupervisor = supervisor;
mDisplayId = display.getDisplayId();
mDisplay = display;
mWindowContainerController = createWindowContainerController();
updateBounds();
}
public DisplayWindowController(Display display, WindowContainerListener listener) {
super(listener, WindowManagerService.getInstance());
mDisplayId = display.getDisplayId();
synchronized (mWindowMap) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
mRoot.createDisplayContent(display, this /* controller */);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
if (mContainer == null) {
throw new IllegalArgumentException("Trying to add display=" + display
+ " dc=" + mRoot.getDisplayContent(mDisplayId));
}
}
}
在DisplayWIndowController的构造方法中会创建一个DisplayContent
2:2:StackWindowController
public StackWindowController(int stackId, StackWindowListener listener,
int displayId, boolean onTop, Rect outBounds, WindowManagerService service) {
super(listener, service);
mStackId = stackId;
mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
synchronized (mWindowMap) {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
if (dc == null) {
throw new IllegalArgumentException("Trying to add stackId=" + stackId
+ " to unknown displayId=" + displayId);
}
dc.createStack(stackId, onTop, this);
getRawBounds(outBounds);
}
}
在其构造方法中创建一个TaskStack
2:3:TaskWindowContainerController
public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
StackWindowController stackController, int userId, Rect bounds, int resizeMode,
boolean supportsPictureInPicture, boolean toTop, boolean showForAllUsers,
TaskDescription taskDescription, WindowManagerService service) {
super(listener, service);
mTaskId = taskId;
mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
synchronized(mWindowMap) {
if (DEBUG_STACK) Slog.i(TAG_WM, "TaskWindowContainerController: taskId=" + taskId
+ " stack=" + stackController + " bounds=" + bounds);
final TaskStack stack = stackController.mContainer;
if (stack == null) {
throw new IllegalArgumentException("TaskWindowContainerController: invalid stack="
+ stackController);
}
EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
final Task task = createTask(taskId, stack, userId, resizeMode,
supportsPictureInPicture, taskDescription);
final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
// We only want to move the parents to the parents if we are creating this task at the
// top of its stack.
stack.addTask(task, position, showForAllUsers, toTop /* moveParents */);
}
}
@VisibleForTesting
Task createTask(int taskId, TaskStack stack, int userId, int resizeMode,
boolean supportsPictureInPicture, TaskDescription taskDescription) {
return new Task(taskId, stack, userId, mService, resizeMode, supportsPictureInPicture,
taskDescription, this);
}
在其构造方法中创建Task
2:4:AppWindowContainerController
public AppWindowContainerController(TaskWindowContainerController taskController,
IApplicationToken token, AppWindowContainerListener listener, int index,
int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos,
WindowManagerService service) {
super(listener, service);
mHandler = new H(service.mH.getLooper());
mToken = token;
synchronized(mWindowMap) {
AppWindowToken atoken = mRoot.getAppWindowToken(mToken.asBinder());
if (atoken != null) {
// TODO: Should this throw an exception instead?
Slog.w(TAG_WM, "Attempted to add existing app token: " + mToken);
return;
}
final Task task = taskController.mContainer;
if (task == null) {
throw new IllegalArgumentException("AppWindowContainerController: invalid "
+ " controller=" + taskController);
}
atoken = createAppWindow(mService, token, voiceInteraction, task.getDisplayContent(),
inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdkVersion,
requestedOrientation, rotationAnimationHint, configChanges, launchTaskBehind,
alwaysFocusable, this);
if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
+ " controller=" + taskController + " at " + index);
task.addChild(atoken, index);
}
}
在其构造方法中会创建一个AppWindowToken
网友评论