Android development technology - WMS learning of vehicle technology

Window management core class introduction

DisplayContent, WindowToken and WindowState used by window management.

DisplayContent

It is used to manage all windows on a logical screen, and there will be several DisplayContents for several screens. Use displayId to distinguish.

Two windows with different DisplayContent will not have any coupling in layout, display order and animation processing. So, in these respects, DisplayContent is like an island, and all these operations can be performed independently inside it.

DisplayContent class declaration:

class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>{
    
        // Mapping from a token IBinder to a WindowToken object on this display.    private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();}   

The sub-container of DisplayContent is its internal class DisplayChildWindowContainer.
DisplayContent is used internally: the key-value pair with IBinder as key and WindowToken as value is stored in HashMap.
DisplayContent is initialized when Window is added to WMS.

WMS

public int addWindow(Session session, ..){
    
        final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);    ..}

mRoot is an object of RootWindowContainer type, and you can tell from its name that it is the root of the window container. Note that in the Window system, the RootWindowContainer node is the topmost parent container of the container.

class RootWindowContainer extends WindowContainer<DisplayContent> {
    
        DisplayContent getDisplayContentOrCreate(int displayId) {
    
            DisplayContent dc = getDisplayContent(displayId);        if (dc == null) {
    
                final Display display = mService.mDisplayManager.getDisplay(displayId);            if (display != null) {
    
                                  dc = createDisplayContent(display);                     }        }        return dc;    }   DisplayContent getDisplayContent(int displayId) {
    
          for (int i = mChildren.size() - 1; i >= 0; --i) {
    
              final DisplayContent current = mChildren.get(i);           if (current.getDisplayId() == displayId) {
    
                  return current;           }      }      return null;  }}

It inherits WindowContainer, where DisplayContent is a generic statement, indicating that the type of its sub-container is DisplayContent. It can also be known from the getDisplayContent method that its mChildren list is a collection of DisplayContent. This also shows that DisplayContent is also a container in disguise.

WindowToken
class declaration:

class WindowToken extends WindowContainer<WindowState>

表明 WindowToken 也是子容器,其子容器是 WindowState,所以 WindowState 也是一个容器。

WindowToken 在窗口体系中有两个作用:

    应用组件标识:将属于同一个应用组件的窗口组织在一起,这里的应用组件可以是:ActivityInputMethodWallpaper 以及 Dream。WMS 在对窗口的管理过程中用 WindowToken 来指代一个应用组件。例如在进行窗口的 Z-Order 排序时,属于同一个 WindowToken 的窗口会被安排在一起。
    令牌作用:WindowToken 由应用组件或其管理者负责向 WMS 声明并持有,应用组件在需要更新窗口时,需要向 WMS 提供令牌表明自己的身份, 并且窗口的类型必须与所持有的 WindowToken 的类型一致。

但是系统窗口是个例外,并不需要提供 token,WMS 会隐式声明一个WindowToken。那是不是说谁都可以添加系统窗口了呢?非也,在 addWindow 开始处就会调用下面代码:

mPolicy.checkAddPermission()

It requires the client to have the SYSTEM_ALERT_WINDOW or INTERNAL_SYSTEM_WINDOW permission to create a system type window. The relationship between Window and WindowToken is as follows:

insert image description hereWindowState
class declaration:

class WindowState extends WindowContainer

It shows that WindowState is also a WindowContainer container, but its sub-container is also WindowState. Generally, when a window has sub-window SUB_WINDOW, WindowState has sub-container nodes. WindowState represents a Window state attribute in WMS, and it stores all attribute information of a Window inside. Its relationship with View and WindowToken is as follows:
insert image description hereHow to view the current device Window status command?

adb shell dumpsys window windows    
Window #9 Window{
    
    884cb45 u0 com.android.messaging/com.android.messaging.ui.conversationlist.ConversationListActivity}:    mDisplayId=0 stackId=3 mSession=Session{
    
    f1b7b8e 4307:u0a10065} mClient=android.os.BinderProxy@a512fbc    mOwnerUid=10065 mShowToOwnerOnly=true package=com.android.messaging appop=NONE    mAttrs={
    
    (0,36)(828xwrap) gr=BOTTOM CENTER sim={
    
    adjust=pan forwardNavigation} ty=APPLICATION fmt=TRANSLUCENT wanim=0x7f130015      fl=DIM_BEHIND ALT_FOCUSABLE_IM HARDWARE_ACCELERATED      vsysui=LIGHT_STATUS_BAR LIGHT_NAVIGATION_BAR}    Requested w=828 h=290 mLayoutSeq=220    mBaseLayer=21000 mSubLayer=0    mToken=AppWindowToken{
    
    3f9efb8 token=Token{
    
    2b272cc ActivityRecord{
    
    55a41e u0 com.android.messaging/.ui.conversationlist.ConversationListActivity t8}}}    mAppToken=AppWindowToken{
    
    3f9efb8 token=Token{
    
    2b272cc ActivityRecord{
    
    55a41e u0 com.android.messaging/.ui.conversationlist.ConversationListActivity t8}}}...  

Next, the author takes the window addition operation as an example to explain the window management of WMS.

window add operation

public int addWindow(Session session, IWindow client, int seq,        WindowManager.LayoutParams attrs, int viewVisibility, int displayId,        Rect outContentInsets, Rect outStableInsets, Rect outOutsets,        InputChannel outInputChannel) {
    
        ...    int res = mPolicy.checkAddPermission(attrs, appOp);//1    ...    synchronized(mWindowMap) {        final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);//2        if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {            parentWindow = windowForClientLocked(null, attrs.token, false);//3        }        ...                    WindowToken token = displayContent.getWindowToken(                hasParent ? parentWindow.mAttrs.token : attrs.token);//4        if (token == null) {                                          final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();            token = new WindowToken(this, binder, type, false, displayContent,                    session.mCanAddInternalSystemWindow);//5        }         ...        final WindowState win = new WindowState(this, session, client, token, parentWindow,                appOp[0], seq, attrs, viewVisibility, session.mUid,                session.mCanAddInternalSystemWindow);//6        ...        mPolicy.adjustWindowParamsLw(win.mAttrs);//7        ...        if  (openInputChannels) {            win.openInputChannel(outInputChannel);//8        }        ...        mWindowMap.put(client.asBinder(), win);//9        ...        win.mToken.addWindow(win);//10        ...        displayContent.assignWindowLayers(false /* setLayoutNeeded */);//11        //12        if (focusChanged) {            mInputMonitor.setInputFocusLw(mCurrentFocus, false /*updateInputWindows*/);        }        mInputMonitor.updateInputWindowsLw(false /*force*/);    }    ...    return res;}

Note 1: Check the validity of the token and other permissions of the current Window.
Note 2: This has already been said in the introduction of DisplayContent. Use the sub-container of RootWindowContainer to get a DisplayContent. If it does not exist in the sub-container collection, get one and add it to the child collection. Note 3: If it is a sub-window such as Dialog
, Get the parent window, if not, report an exception that the parent window cannot be found.
Note 4: Use attr.token to get the corresponding WindowToken from the key-value pair mTokenMap of displayContent, and a group of Window is stored in WindowToken.
Note 5: If the WindowToken in 4 is null, create a WindowToken, pass in the attr.token and displayContent objects passed in from the app layer, and internally save the created WindowToken to displayContent Note 6: Create a WindowState and pass it
in All the properties related to Window, so WindowState exists as a Window property in WMS, and it will be added to WindowToken during the construction of WindowState.
Note 7: Adjust the attr attribute of window according to mPolicy, the implementation class of mPolicy is PhoneManagerPolicy.
Note 8: Execute the openInputChannel of WindowState, which mainly opens up the channel with the Input system to receive the input event request from IMS.
Note 9: Associate the Window object of the client app layer with WindowState, so that WMS can find the WindowState object in WMS through Window.
Note 10: win.mToken is the WindowToken object created earlier, so here is to add WindowState to the sub-container collection of WindowToken.
Note 11: Allocate the level of the window, here the setLayoutNeeded parameter is false, indicating that the Layout operation is not required.

Here is a summary of the addWindow method, which mainly creates a WindowState object corresponding to Window one by one, and inserts WindowState into the sub-container collection of the parent container WindowToken, and the WindowToken is stored in the key-value pair collection of DisplayContent. The three relationships can be briefly summarized as follows:
insert image description here

Guess you like

Origin blog.csdn.net/qq_24252589/article/details/131353002