1:WindowContainer
系統(tǒng)中的窗口window是放在一個容器中進行管理的险绘,它的名字就是WindowContainer,用來管理添加進來的子WindowContainer,在android系統(tǒng)中有下來的幾種WindowContainer
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這個方法主要是根據(jù)comparator來確定其具體的位置代咸,然后插入到合適的位置上呐芥,child.setParent(this);設(shè)置其父容器贩耐,這樣就能直接找到它的父容器
1.1:DisplayContent
DisplayContent對應(yīng)的是一塊顯示屏幕厦取,那么其不可能存在子屏幕的,也就是說它沒有addChild方法铡买,不過在其內(nèi)部有四個默認的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是一一對應(yīng)的,并且id也是一樣的谋旦,TaskStack存儲的是Task
1.3:Task
Task類似于任務(wù)棧屈尼,用來管理WindowToken/AppWindowToken的,和AMS端的TaskRecord是一一對應(yīng)的,并且id也是相同的
1.4:AppWindowToken/WindowToken
WindowToken關(guān)聯(lián)著一組token相同的WindowState,用來管理WindowState的
1.5:WindoState
WindowState是一個窗口單元甲捏,對應(yīng)于wms的一個窗口摊鸡,但是窗口有不同的類型蚕冬,有子窗口囤热,普通應(yīng)用程序窗口旁蔼,系統(tǒng)窗口疙教,子窗口和父窗口是共token的,因此WindowState有addChild的功能
2:WindowContainerController
我們都知道AMS和WMS兩者之間的數(shù)據(jù)都是一一對應(yīng)的限佩,那么它們之間是怎么建立連接的呢祟同,就是通過WindowContainerController建立它們之間的聯(lián)系的
2.1:DisplayWindowController
每創(chuàng)建一個ActivityDisplay的時候都會創(chuàng)建一個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的構(gòu)造方法中會創(chuàng)建一個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);
}
}
在其構(gòu)造方法中創(chuàng)建一個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);
}
在其構(gòu)造方法中創(chuàng)建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);
}
}
在其構(gòu)造方法中會創(chuàng)建一個AppWindowToken