The article only records your own understanding and is for your reference only.
Each display device has a display object, which is managed by displaymanagerservice.
1. displaycontent ()
<span style="font-size:18px;"> DisplayContent(Display display, WindowManagerService service) { mDisplay = display; mDisplayId = display.getDisplayId(); display.getDisplayInfo(mDisplayInfo); isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; mService = service; StackBox newBox = new StackBox(service, this, null); mStackBoxes.add(newBox); TaskStack newStack = new TaskStack(service, HOME_STACK_ID, this); newStack.mStackBox = newBox; newBox.mStack = newStack; mHomeStack = newStack; }</span>
In WMS, each Display object will give it a new displaycontent and save the display-related window information. This can be seen from the WMS constructor. The displaycontent () constructor also shows that each displaycontent contains at least one stackbox and taskstack.
Createdisplaycontentlocked () --> getdisplaycontentlocked () --> WMS. newdisplaycontentlocked () --> New displaycontent ();
<span style="font-size:18px;">WindowManagerService(){ ............ Display[] displays = mDisplayManager.getDisplays(); for (Display display : displays) { createDisplayContentLocked(display); } ........}</span>
2. minitialdisplaywidth, minitialdisplayheight, and minitialdisplaydensity
The initial screen width, height, and density are saved.
3. mdisplayinfo
As can be seen from the displaycontent () constructor in Article 1, mdisplayinfo is obtained from the display and stores information about the display.
4. layoutneeded
When layout is required for a window, layoutneeded is set to true.
5. mstackboxes
Normally, two stackboxes are saved in mstackboxes. One stackbox (0) contains only launcher, And the other stackbox contains all other windows.
① Stackbox. mparent
<span style="font-size:18px;"> /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this * is this entire size of mDisplayContent. */</span>
Mparent indicates which stackbox is split, but mparent of stackbox 0 and stackbox 1 is null.
② Stackbox. mbounds
WMS. extends mlayoutlockedinner () --> displaycontent. setstackboxsize () --> stackbox. setstackboxsizes () --> mbounds. Set (bounds );
Bounds size comes from mpolicy. getcontentrectlw (bounds );
<span style="font-size:18px;"> public void getContentRectLw(Rect r) { r.set(mContentLeft, mContentTop, mContentRight, mContentBottom); }</span>For mobile phones of sizes 720*1280, (mcontentleft, mcontenttop, mcontentright, mcontentbottom) = (,), the height of the status bar is kicked out, So mbounds =)
③ Stackbox. mvertical
This variable indicates whether the split direction of mfirst and msecond is vertical split or left/right split. For details, see the split () function.
/** Relative orientation of mfirst and msecond .*/
④ Stackbox. layoutneeded
⑤ Stackbox.
⑥ Stackbox. mstack
/** Stack of tasks, this is null exactly when mfirst and msecond are non-null .*/
6. stackbox. Split ()
Stackbox split function. The split two stackboxes are stored in mfirst and msecond respectively (binary tree split ).
<span style="font-size:18px;"> TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) { if (mStackBoxId != relativeStackBoxId) { if (mStack != null) { return null; } TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight); if (stack != null) { return stack; } return mSecond.split(stackId, relativeStackBoxId, position, weight); } TaskStack stack = new TaskStack(mService, stackId, mDisplayContent); TaskStack firstStack; TaskStack secondStack; if (position == TASK_STACK_GOES_BEFORE) { position = TASK_STACK_TO_LEFT_OF; } else if (position == TASK_STACK_GOES_AFTER) { // TODO: Test Configuration here for LTR/RTL. position = TASK_STACK_TO_RIGHT_OF; } switch (position) { default: case TASK_STACK_TO_LEFT_OF: case TASK_STACK_TO_RIGHT_OF: mVertical = false; if (position == TASK_STACK_TO_LEFT_OF) { mWeight = weight; firstStack = stack; secondStack = mStack; } else { mWeight = 1.0f - weight; firstStack = mStack; secondStack = stack; } break; case TASK_STACK_GOES_ABOVE: case TASK_STACK_GOES_BELOW: mVertical = true; if (position == TASK_STACK_GOES_ABOVE) { mWeight = weight; firstStack = stack; secondStack = mStack; } else { mWeight = 1.0f - weight; firstStack = mStack; secondStack = stack; } break; } mFirst = new StackBox(mService, mDisplayContent, this); firstStack.mStackBox = mFirst; mFirst.mStack = firstStack; mSecond = new StackBox(mService, mDisplayContent, this); secondStack.mStackBox = mSecond; mSecond.mStack = secondStack; mStack = null; return stack; }</span>There are only two scenarios for Splitting:
① Transfer the stackbox. mstack of the split node to the new mfirst. mstack. msecond. mstack = new taskstack (mservice, stackid, mdisplaycontent );
② Transfer the stackbox. mstack of the split node to the new msecond. mstack. mfirst. mstack = new taskstack (mservice, stackid, mdisplaycontent );
In the preceding two cases, the split node stackbox. mstack will set null.
The code above can also be concluded that the split node is the leaf node of the binary tree. Only the leaf node can be split. Only the mstack variable of the leaf node is not null. It can also be said that a stackbox leaf node corresponds to a taskstack.
From the source code of android4.4, currently, the displaycontent of default_display has two stackbox Binary Trees, both of which have not been split yet and only contain one root node.
8. taskstack class
A leaf node of the stackbox Binary Tree corresponds to a taskstack.
① Taskstack. mstackid, "stackid the ID of the new taskstack to create ."
② Taskstack. mtasks stores all tasks in the task stack. A taskstack can contain many task tasks.
③ Taskstack. mdimlayer
④ Taskstack. mdimwinanimator
⑤ Taskstack. manimationbackgroundsurface
⑥ Taskstack. manimationbackgroundanimator