android WMS--WindowContainer和Win

2020-07-03  本文已影响0人  android_coder
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

3:AMS和WMS数据结构对应关系
Controller.png
上一篇下一篇

猜你喜欢

热点阅读