美文网首页
android WMS--WindowContainer和Win

android WMS--WindowContainer和Win

作者: android_coder | 来源:发表于2020-07-03 18:09 被阅读0次
    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

    相关文章

      网友评论

          本文标题:android WMS--WindowContainer和Win

          本文链接:https://www.haomeiwen.com/subject/utgsqktx.html