Android T ウィンドウ レベル 3 - 階層ツリーへのウィンドウの追加

順序

図に示すように、まだ追加されていないウィンドウの階層構造ツリー。DisplayArea
ここに画像の説明を挿入します階層内の各 DisplayArea には、階層値の範囲が含まれています。この階層値の範囲は、この DisplayArea が対応できるウィンドウの種類を示します。
ウィンドウの種類ごとに、WindowManagerPolicy.getWindowLayerFromTypeLw メソッドを通じて対応するレベル値を返すことができます。

/**
     * Returns the layer assignment for the window type. Allows you to control how different
     * kinds of windows are ordered on-screen.
     *
     * @param type The type of window being assigned.
     * @param canAddInternalSystemWindow If the owner window associated with the type we are
     *        evaluating can add internal system windows. I.e they have
     *        {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
     *        types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
     *        can be assigned layers greater than the layer for
     *        {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
     *        layers would be lesser.
     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
     */
    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
    
    
        return getWindowLayerFromTypeLw(type, canAddInternalSystemWindow,
                false /* roundedCornerOverlay */);
    }

    /**
     * Returns the layer assignment for the window type. Allows you to control how different
     * kinds of windows are ordered on-screen.
     *
     * @param type The type of window being assigned.
     * @param canAddInternalSystemWindow If the owner window associated with the type we are
     *        evaluating can add internal system windows. I.e they have
     *        {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
     *        types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
     *        can be assigned layers greater than the layer for
     *        {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
     *        layers would be lesser.
     * @param roundedCornerOverlay {#code true} to indicate that the owner window is rounded corner
     *                             overlay.
     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
     */
    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow,
            boolean roundedCornerOverlay) {
    
    
        // Always put the rounded corner layer to the top most.
        if (roundedCornerOverlay && canAddInternalSystemWindow) {
    
    
            return getMaxWindowLayer();
        }
        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
    
    
            return APPLICATION_LAYER;
        }

        switch (type) {
    
    
            case TYPE_WALLPAPER:
                // wallpaper is at the bottom, though the window manager may move it.
                return  1;
            case TYPE_PRESENTATION:
            case TYPE_PRIVATE_PRESENTATION:
            case TYPE_DOCK_DIVIDER:
            case TYPE_QS_DIALOG:
            case TYPE_PHONE:
                return  3;
            case TYPE_SEARCH_BAR:
                return  4;
            case TYPE_INPUT_CONSUMER:
                return  5;
            case TYPE_SYSTEM_DIALOG:
                return  6;
            case TYPE_TOAST:
                // toasts and the plugged-in battery thing
                return  7;
            case TYPE_PRIORITY_PHONE:
                // SIM errors and unlock.  Not sure if this really should be in a high layer.
                return  8;
            case TYPE_SYSTEM_ALERT:
                // like the ANR / app crashed dialogs
                // Type is deprecated for non-system apps. For system apps, this type should be
                // in a higher layer than TYPE_APPLICATION_OVERLAY.
                return  canAddInternalSystemWindow ? 12 : 9;
            case TYPE_APPLICATION_OVERLAY:
                return  11;
            case TYPE_INPUT_METHOD:
                // on-screen keyboards and other such input method user interfaces go here.
                return  13;
            case TYPE_INPUT_METHOD_DIALOG:
                // on-screen keyboards and other such input method user interfaces go here.
                return  14;
            case TYPE_STATUS_BAR:
                return  15;
            case TYPE_STATUS_BAR_ADDITIONAL:
                return  16;
            case TYPE_NOTIFICATION_SHADE:
                return  17;
            case TYPE_STATUS_BAR_SUB_PANEL:
                return  18;
            case TYPE_KEYGUARD_DIALOG:
                return  19;
            case TYPE_VOICE_INTERACTION_STARTING:
                return  20;
            case TYPE_VOICE_INTERACTION:
                // voice interaction layer should show above the lock screen.
                return  21;
            case TYPE_VOLUME_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  22;
            case TYPE_SYSTEM_OVERLAY:
                // the on-screen volume indicator and controller shown when the user
                // changes the device volume
                return  canAddInternalSystemWindow ? 23 : 10;
            case TYPE_NAVIGATION_BAR:
                // the navigation bar, if available, shows atop most things
                return  24;
            case TYPE_NAVIGATION_BAR_PANEL:
                // some panels (e.g. search) need to show on top of the navigation bar
                return  25;
            case TYPE_SCREENSHOT:
                // screenshot selection layer shouldn't go above system error, but it should cover
                // navigation bars at the very least.
                return  26;
            case TYPE_SYSTEM_ERROR:
                // system-level error dialogs
                return  canAddInternalSystemWindow ? 27 : 9;
            case TYPE_MAGNIFICATION_OVERLAY:
                // used to highlight the magnified portion of a display
                return  28;
            case TYPE_DISPLAY_OVERLAY:
                // used to simulate secondary display devices
                return  29;
            case TYPE_DRAG:
                // the drag layer: input for drag-and-drop is associated with this window,
                // which sits above all other focusable windows
                return  30;
            case TYPE_ACCESSIBILITY_OVERLAY:
                // overlay put by accessibility services to intercept user interaction
                return  31;
            case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
                return 32;
            case TYPE_SECURE_SYSTEM_OVERLAY:
                return  33;
            case TYPE_BOOT_PROGRESS:
                return  34;
            case TYPE_POINTER:
                // the (mouse) pointer layer
                return  35;
            default:
                Slog.e("WindowManager", "Unknown window type: " + type);
                return 3;
        }
    }

DisplayArea 階層には、ウィンドウの親ノードを直接収容できます。次の 3 種類があります。

  • TaskDisplayArea は、アプリ タイプのウィンドウを収容するために使用されます。Task のコンテナーは、階層構造ツリーの DefaultTaskDisplayArea に対応する TaskDisplayArea です。ActivityRecord のコンテナーは、Task です。
  • DisplayArea.Tokens は、非アプリ タイプのウィンドウに対応するために使用されます。WindowToken のコンテナーは、階層ツリーの Leaf ノードに対応する DisplayArea.Tokens です。このうち、WallpaperWindowToken は WindowToken を継承し、壁紙に関連するウィンドウを格納するために使用されます。
  • ImeContainer はインプットメソッドウィンドウを収容するために使用されます。インプットメソッドのコンテナは ImeContainer です。

ここでは、上記のコードと情報に基づいてadb shell dumpsys activity containers次の樹形図を単純に描画します。
ここに画像の説明を挿入します

ノードが追加されました

これらのウィンドウがいつ追加されたかを知るにはどうすればよいですか?
各ノードの親子関係を明確にする必要があります。これはキーコードを見つけるのに役立ちます。

タスク

ツリー図からadb shell dumpsys activity containers、Task ノードの親ノードが DefaultTaskDisplayArea であることがわかりますが、
ここに画像の説明を挿入します
もちろん、Task の親ノードが Task である別の状況も存在します。
ここに画像の説明を挿入します次に、addTask や addChild など、DefaultTaskDisplayArea と Task に Task の追加に関連するメソッドが必要です。

DefaultTaskDisplayArea を親ノードとして使用する

このアイデアに従って、TaskDisplayArea.java に関連するメソッドがあるかどうかを確認してみましょう。
コード パス: Frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java

    void addChild(WindowContainer child, int position) {
    
    
        if (child.asTaskDisplayArea() != null) {
    
    
            if (DEBUG_ROOT_TASK) {
    
    
                Slog.d(TAG_WM, "Set TaskDisplayArea=" + child + " on taskDisplayArea=" + this);
            }
            super.addChild(child, position);
        } else if (child.asTask() != null) {
    
    
            addChildTask(child.asTask(), position);
        } else {
    
    
            throw new IllegalArgumentException(
                    "TaskDisplayArea can only add Task and TaskDisplayArea, but found "
                            + child);
        }
    }

    private void addChildTask(Task task, int position) {
    
    
        if (DEBUG_ROOT_TASK) Slog.d(TAG_WM, "Set task=" + task + " on taskDisplayArea=" + this);

        addRootTaskReferenceIfNeeded(task);
        position = findPositionForRootTask(position, task, true /* adding */);

        super.addChild(task, position);
        if (mPreferredTopFocusableRootTask != null
                && task.isFocusable()
                && mPreferredTopFocusableRootTask.compareTo(task) < 0) {
    
    
            // Clear preferred top because the adding focusable task has a higher z-order.
            mPreferredTopFocusableRootTask = null;
        }
        mAtmService.updateSleepIfNeededLocked();
        onRootTaskOrderChanged(task);
    }

void addChild(WindowContainer child, int position)条件が満たされるとchild.asTask() != null呼び出されることがわかり、addChildTask(child.asTask(), position);これはタスクを追加するときに使用するメソッドでもあります。の中にキー呼び出しがあることがわかりますsuper.addChild(task, position);。これは、ここでの実際の追加が
WindowContainervoid addChild(E child, int index)
コード パスに対応していることを意味します: Frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

    /**
     * Adds the input window container has a child of this container at the input index.
     */
    @CallSuper
    void addChild(E child, int index) {
    
    
        if (!child.mReparenting && 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()
                    + "\n callers=" + Debug.getCallers(15, "\n"));
        }

        if ((index < 0 && index != POSITION_BOTTOM)
                || (index > mChildren.size() && index != POSITION_TOP)) {
    
    
            throw new IllegalArgumentException("addChild: invalid position=" + index
                    + ", children number=" + mChildren.size());
        }

        if (index == POSITION_TOP) {
    
    
            index = mChildren.size();
        } else if (index == POSITION_BOTTOM) {
    
    
            index = 0;
        }

        mChildren.add(index, child);

        // Set the parent after we've actually added a child in case a subclass depends on this.
        child.setParent(this);
    }

階層ツリーを構築するときに実際に呼び出されるメソッド。

タスクを親ノードとする

Task.java でノードを追加する関連メソッドを見つけます
。 コード パス: Frameworks/base/services/core/java/com/android/server/wm/Task.java

    void addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers) {
    
    
        Task task = child.asTask();
        try {
    
    
            if (task != null) {
    
    
                task.setForceShowForAllUsers(showForAllUsers);
            }
            // We only want to move the parents to the parents if we are creating this task at the
            // top of its root task.
            addChild(child, toTop ? MAX_VALUE : 0, toTop /*moveParents*/);
        } finally {
    
    
            if (task != null) {
    
    
                task.setForceShowForAllUsers(false);
            }
        }
    }
    /**
     * Put a Task in this root task. Used for adding only.
     * When task is added to top of the root task, the entire branch of the hierarchy (including
     * root task and display) will be brought to top.
     * @param child The child to add.
     * @param position Target position to add the task to.
     */
    private void addChild(WindowContainer child, int position, boolean moveParents) {
    
    
        // Add child task.
        addChild(child, null);

        // Move child to a proper position, as some restriction for position might apply.
        positionChildAt(position, child, moveParents /* includingParents */);
    }

ここでの実際の呼び出しはaddChild(child, null);WindowContainer です。その親クラス TaskFragment には入力パラメータに一致する addChild メソッドがないため、引き続きprotected void addChild(E child, Comparator<E> comparator)TaskFragment の親クラス WindowContainer でaddChild メソッドの
コード パスを検索します: Frameworks/base/services/core/java/ com/android/server/wm/WindowContainer.java

   /**
     * Adds the input window container has a child of this container in order based on the input
     * comparator.
     * @param child The window container to add as a child of this window container.
     * @param comparator Comparator to use in determining the position the child should be added to.
     *                   If null, the child will be added to the top.
     */
    @CallSuper
    protected void addChild(E child, Comparator<E> comparator) {
    
    
    	......
    	//记录插入数组的位置,若为-1则将当前child加入到后面
        int positionToAdd = -1;
        if (comparator != null) {
    
    
        	//判断当前节点中孩子的数量
        	//依次比较将要加入的窗口与已经存在的child的BaseLayer
        	//mChildren越大放到数组最前面
            final int count = mChildren.size();
            for (int i = 0; i < count; i++) {
    
    
            	//比较baseLayer,如果child大于列表中已经存在的,则需要返回1,否则返回-1
            	//新加入的的child大于mChildren.get(i)则返回1,小于则返回-1
            	//注:comparator比较器的逻辑见上面代码的mWindowComparator 
                if (comparator.compare(child, mChildren.get(i)) < 0) {
    
    
                	//记录当前要插入的位置
                    positionToAdd = i;
                    break;
                }
            }
        }
		//如果新加入的窗口大于现在所有窗口
        if (positionToAdd == -1) {
    
    
        	//将该窗口加入到列表最后
            mChildren.add(child);
        } else {
    
    
            mChildren.add(positionToAdd, child);
        }

        // Set the parent after we've actually added a child in case a subclass depends on this.
        //此处将child的mParent设置为this
        child.setParent(this);
    }

protected void addChild(E child, Comparator<E> comparator)これは addChild をオーバーロードしていますが、これは前のものとはvoid addChild(E child, int index)異なります。

活動記録

ActivityRecord の親ノードは Task です。同様に、Task.java で ActivityRecord を追加するメソッドを見つけます。
コード パス: Frameworks/base/services/core/java/com/android/server/wm/Task.java

    @Override
    void addChild(WindowContainer child, int index) {
    
    
        index = getAdjustedChildPosition(child, index);
        super.addChild(child, index);

        ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addChild: %s at top.", this);

        // A rootable task that is now being added to be the child of an organized task. Making
        // sure the root task references is keep updated.
        if (mTaskOrganizer != null && mCreatedByOrganizer && child.asTask() != null) {
    
    
            getDisplayArea().addRootTaskReferenceIfNeeded((Task) child);
        }

        // Make sure the list of display UID allowlists is updated
        // now that this record is in a new task.
        mRootWindowContainer.updateUIDsPresentOnDisplay();

        // Only pass minimum dimensions for pure TaskFragment. Task's minimum dimensions must be
        // passed from Task constructor.
        final TaskFragment childTaskFrag = child.asTaskFragment();
        if (childTaskFrag != null && childTaskFrag.asTask() == null) {
    
    
            childTaskFrag.setMinDimensions(mMinWidth, mMinHeight);
        }
    }

super.addChild(child, index);呼び出されるのは、Task の親クラス TaskFragment の addChild メソッドです。
コード パス: Frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java

    @Override
    void addChild(WindowContainer child, int index) {
    
    
        ActivityRecord r = topRunningActivity();
        mClearedTaskForReuse = false;
        mClearedTaskFragmentForPip = false;

        final ActivityRecord addingActivity = child.asActivityRecord();
        final boolean isAddingActivity = addingActivity != null;
        final Task task = isAddingActivity ? getTask() : null;

        // If this task had any activity before we added this one.
        boolean taskHadActivity = task != null && task.getTopMostActivity() != null;
        // getActivityType() looks at the top child, so we need to read the type before adding
        // a new child in case the new child is on top and UNDEFINED.
        final int activityType = task != null ? task.getActivityType() : ACTIVITY_TYPE_UNDEFINED;

        super.addChild(child, index);

        if (isAddingActivity && task != null) {
    
    

            // TODO(b/207481538): temporary per-activity screenshoting
            if (r != null && BackNavigationController.isScreenshotEnabled()) {
    
    
                ProtoLog.v(WM_DEBUG_BACK_PREVIEW, "Screenshotting Activity %s",
                        r.mActivityComponent.flattenToString());
                Rect outBounds = r.getBounds();
                SurfaceControl.ScreenshotHardwareBuffer backBuffer = SurfaceControl.captureLayers(
                        r.mSurfaceControl,
                        new Rect(0, 0, outBounds.width(), outBounds.height()),
                        1f);
                mBackScreenshots.put(r.mActivityComponent.flattenToString(), backBuffer);
            }
            child.asActivityRecord().inHistory = true;
            task.onDescendantActivityAdded(taskHadActivity, activityType, addingActivity);
        }
    }

super.addChild(child, index);TaskFragment の親クラス メソッド、つまり WindowContainer のメソッドを呼び出します。void addChild(E child, int index)

ウィンドウトークン

WindowToken の親ノードはリーフ ノードまたはインプット メソッド ノードであり、リーフ ノードとインプット メソッド ノードは実際には DisplayArea.Tokens 型です。
WallpaperWindowToken は WindowToken を継承しているため、同様です。
したがって、DisplayArea.java の Tokens クラスで WindowToken を追加する関連メソッドを見つけるだけで済みます。
コードパス: Frameworks/base/services/core/java/com/android/server/wm/DisplayArea.java

		void addChild(WindowToken token) {
    
    
            addChild(token, mWindowComparator);
        }

ここで呼ばれるものはaddChild(token, mWindowComparator);WindowContainerです。protected void addChild(E child, Comparator<E> comparator)

ウィンドウ状態

WindowState の親ノードは WindowToken と ActivityRecord です。WindowToken.java と ActivityRecord.java に WindowState を追加する方法を見つけます。

WindowToken を親ノードとして使用する場合

コードパス: Frameworks/base/services/core/java/com/android/server/wm/WindowToken.java

    void addWindow(final WindowState win) {
    
    
        ProtoLog.d(WM_DEBUG_FOCUS,
                "addWindow: win=%s Callers=%s", win, Debug.getCallers(5));

        if (win.isChildWindow()) {
    
    
            // Child windows are added to their parent windows.
            return;
        }
        // This token is created from WindowContext and the client requests to addView now, create a
        // surface for this token.
        if (mSurfaceControl == null) {
    
    
            createSurfaceControl(true /* force */);

            // Layers could have been assigned before the surface was created, update them again
            reassignLayer(getSyncTransaction());
        }
        if (!mChildren.contains(win)) {
    
    
            ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", win, this);
            addChild(win, mWindowComparator);
            mWmService.mWindowsChanged = true;
            // TODO: Should we also be setting layout needed here and other places?
        }
    }

addChild(win, mWindowComparator);protected void addChild(E child, Comparator<E> comparator)WindowContainerのWindowStateを追加するというものです。

ActivityRecord を親ノードとして使用する

コードパス: Frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java

    @Override
    void addWindow(WindowState w) {
    
    
        super.addWindow(w);

        boolean gotReplacementWindow = false;
        for (int i = mChildren.size() - 1; i >= 0; i--) {
    
    
            final WindowState candidate = mChildren.get(i);
            gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
        }

        // if we got a replacement window, reset the timeout to give drawing more time
        if (gotReplacementWindow) {
    
    
            mWmService.scheduleWindowReplacementTimeouts(this);
        }
        checkKeyguardFlagsChanged();
    }

ActivityRecord の親クラスは WindowToken であり、super.addWindow(w);WindowToken の addWindow メソッドを呼び出すため、最終的にprotected void addChild(E child, Comparator<E> comparator)WindowState は WindowContainer を通じて追加されます。

まとめ

これまでの分析で、ウィンドウの追加は最終的に WindowContainer の合計によって追加されることになりますが、void addChild(E child, int index)これらprotected void addChild(E child, Comparator<E> comparator)2 つのメソッドの呼び出し状況と違いをまとめてみましょう。

通話シーン

通話void addChild(E child, int index)状況

  1. DefaultTaskDisplayArea添加Task
  2. Task添加ActivityRecord

通話protected void addChild(E child, Comparator<E> comparator)状況

  1. Task添加Task
  2. リーフノードとインプットメソッドノード(Token)にWindowTokenを追加
  3. WindowToken添加WindowState
  4. ActivityRecord添加WindowState

差分を追加する

WindowContainer の void addChild(E child, int index) メソッドと protected void addChild(E child, Comparator comparator) メソッドの違いは何ですか?
それらの違いは実際には、サブコンテナを追加する方法と順序にあります。

void addChild(E child, int index)方法:

  • このメソッドは、渡されたインデックス パラメータを通じてサブコンテナの挿入位置を指定します。Index は、現在のコンテナのサブコンテナ リスト内のサブコンテナの位置インデックスを表します。
  • このメソッドを呼び出すと、コンパレータに基づいて並べ替えることなく、子コンテナが指定された位置に追加されます。
  • この方法は、サブコンテナの挿入位置を直接指定する必要がある場合に適しています。

protected void addChild(E child, Comparator<E> comparator)方法:

  • このメソッドは、渡された Comparator パラメータを通じてサブコンテナの並べ替えルールを定義します。
  • このメソッドを呼び出すと、子コンテナが現在のコンテナの子コンテナのリストに追加され、指定されたコンパレータに従って子コンテナが並べ替えられます。
  • この方法は、特定の並べ替えルールに従ってサブコンテナを動的に並べ替えるのに適しています。

要約すると、addChild(E child, int index) メソッドを使用すると、子コンテナの挿入位置を直接指定できます。一方、addChild(E child, Comparator comparator) メソッドは、コンパレータを使用して子コンテナを並べ替え、子コンテナを子コンテナに追加します。適切な位置。実際のニーズに基づいて、サブコンテナを追加する適切な方法を選択できます。

プロセス分析

ログを追加

上記の分析から、ウィンドウの追加は最終的にWindowContainer のvoid addChild(E child, int index)合計によって追加されることが判明したprotected void addChild(E child, Comparator<E> comparator)ため、関連するログを追加して、対応するプロセスがどのようなものであるかを確認できます。

    void addChild(E child, int index) {
    
    
        if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken || child instanceof WindowState) {
    
    
            android.util.Log.i("WindowContainer.TAG:", this + "addChild child = " + child , new Exception());
        }
        ......
    }
    protected void addChild(E child, Comparator<E> comparator) {
    
    
        if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken || child instanceof WindowState) {
    
    
            android.util.Log.i("WindowContainer.TAG:", this + "addChild Comparator child = " + child , new Exception());
        }
        ......
    }

スタック印刷処理

ここではランチャーとステータスバーを例として取り上げます

ランチャー

WindowContainer.TAG   : DefaultTaskDisplayArea@243571827 addChild child = Task{
    
    a13d730 #1 type=home ?? U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
WindowContainer.TAG   : java.lang.Exception
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
WindowContainer.TAG   : 	at com.android.server.wm.TaskDisplayArea.addChildTask(TaskDisplayArea.java:334)
WindowContainer.TAG   : 	at com.android.server.wm.TaskDisplayArea.addChild(TaskDisplayArea.java:320)
WindowContainer.TAG   : 	at com.android.server.wm.Task$Builder.build(Task.java:6551)
WindowContainer.TAG   : 	at com.android.server.wm.TaskDisplayArea.createRootTask(TaskDisplayArea.java:1066)
WindowContainer.TAG   : 	at com.android.server.wm.TaskDisplayArea.createRootTask(TaskDisplayArea.java:1040)
WindowContainer.TAG   : 	at com.android.server.wm.TaskDisplayArea.getOrCreateRootHomeTask(TaskDisplayArea.java:1640)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.setWindowManager(RootWindowContainer.java:1321)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityTaskManagerService.setWindowManager(ActivityTaskManagerService.java:1006)
WindowContainer.TAG   : 	at com.android.server.am.ActivityManagerService.setWindowManager(ActivityManagerService.java:1923)
WindowContainer.TAG   : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:1595)
WindowContainer.TAG   : 	at com.android.server.SystemServer.run(SystemServer.java:939)
WindowContainer.TAG   : 	at com.android.server.SystemServer.main(SystemServer.java:649)
WindowContainer.TAG   : 	at java.lang.reflect.Method.invoke(Native Method)
WindowContainer.TAG   : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
WindowContainer.TAG   : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
WindowContainer.TAG   : Task{
    
    a13d730 #1 type=home ?? U=0 visible=true visibleRequested=false mode=fullscreen translucent=true sz=0} addChild Comparator child = Task{
    
    63f31d4 #2 type=undefined A=1000:com.android.settings.FallbackHome U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
WindowContainer.TAG   : java.lang.Exception
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG   : 	at com.android.server.wm.Task.addChild(Task.java:5935)
WindowContainer.TAG   : 	at com.android.server.wm.Task.-$$Nest$maddChild(Unknown Source:0)
WindowContainer.TAG   : 	at com.android.server.wm.Task$Builder.build(Task.java:6548)
WindowContainer.TAG   : 	at com.android.server.wm.Task.reuseOrCreateTask(Task.java:5819)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2872)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1864)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStartController.startHomeActivity(ActivityStartController.java:179)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnTaskDisplayArea(RootWindowContainer.java:1493)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.lambda$startHomeOnDisplay$12$com-android-server-wm-RootWindowContainer(RootWindowContainer.java:1434)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer$$ExternalSyntheticLambda7.apply(Unknown Source:16)
WindowContainer.TAG   : 	at com.android.server.wm.TaskDisplayArea.reduceOnAllTaskDisplayAreas(TaskDisplayArea.java:513)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.reduceOnAllTaskDisplayAreas(WindowContainer.java:2283)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1433)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1420)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnAllDisplays(RootWindowContainer.java:1405)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityTaskManagerService$LocalService.startHomeOnAllDisplays(ActivityTaskManagerService.java:5892)
WindowContainer.TAG   : 	at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8203)
WindowContainer.TAG   : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2801)
WindowContainer.TAG   : 	at com.android.server.SystemServer.run(SystemServer.java:939)
WindowContainer.TAG   : 	at com.android.server.SystemServer.main(SystemServer.java:649)
WindowContainer.TAG   : 	at java.lang.reflect.Method.invoke(Native Method)
WindowContainer.TAG   : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
WindowContainer.TAG   : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
WindowContainer.TAG   : Task{
    
    63f31d4 #2 type=undefined A=1000:com.android.settings.FallbackHome U=0 rootTaskId=1 visible=true visibleRequested=false mode=fullscreen translucent=true sz=0} addChild child = ActivityRecord{
    
    983a135 u0 com.android.settings/.FallbackHome}
WindowContainer.TAG   : java.lang.Exception
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
WindowContainer.TAG   : 	at com.android.server.wm.TaskFragment.addChild(TaskFragment.java:1835)
WindowContainer.TAG   : 	at com.android.server.wm.Task.addChild(Task.java:1429)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:2927)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2877)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1864)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityStartController.startHomeActivity(ActivityStartController.java:179)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnTaskDisplayArea(RootWindowContainer.java:1493)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.lambda$startHomeOnDisplay$12$com-android-server-wm-RootWindowContainer(RootWindowContainer.java:1434)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer$$ExternalSyntheticLambda7.apply(Unknown Source:16)
WindowContainer.TAG   : 	at com.android.server.wm.TaskDisplayArea.reduceOnAllTaskDisplayAreas(TaskDisplayArea.java:513)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea.reduceOnAllTaskDisplayAreas(DisplayArea.java:404)
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.reduceOnAllTaskDisplayAreas(WindowContainer.java:2283)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1433)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnDisplay(RootWindowContainer.java:1420)
WindowContainer.TAG   : 	at com.android.server.wm.RootWindowContainer.startHomeOnAllDisplays(RootWindowContainer.java:1405)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityTaskManagerService$LocalService.startHomeOnAllDisplays(ActivityTaskManagerService.java:5892)
WindowContainer.TAG   : 	at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8203)
WindowContainer.TAG   : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2801)
WindowContainer.TAG   : 	at com.android.server.SystemServer.run(SystemServer.java:939)
WindowContainer.TAG   : 	at com.android.server.SystemServer.main(SystemServer.java:649)
WindowContainer.TAG   : 	at java.lang.reflect.Method.invoke(Native Method)
WindowContainer.TAG   : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
WindowContainer.TAG   : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
WindowContainer.TAG   : ActivityRecord{
    
    983a135 u0 com.android.settings/.FallbackHome} t2} addChild Comparator child = Window{
    
    ae9b359 u0 com.android.settings/com.android.settings.FallbackHome}
WindowContainer.TAG   : java.lang.Exception
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG   : 	at com.android.server.wm.WindowToken.addWindow(WindowToken.java:302)
WindowContainer.TAG   : 	at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:4212)
WindowContainer.TAG   : 	at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1773)
WindowContainer.TAG   : 	at com.android.server.wm.Session.addToDisplayAsUser(Session.java:209)
WindowContainer.TAG   : 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:652)
WindowContainer.TAG   : 	at com.android.server.wm.Session.onTransact(Session.java:175)
WindowContainer.TAG   : 	at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer.TAG   : 	at android.os.Binder.execTransact(Binder.java:1244)

ホーム タスクは、TaskDisplayArea によって子として直接保持されます。ここでは、初めて WMS を作成したときに Task{a13d730 #1 type=home が作成されていることがはっきりとわかります。TaskDisplayArea.getOrCreateRootHomeTask を渡し、com.android に進みます。 .server. .wm.WindowContainer.addChild の後に
、ホーム タスクは特定の Launcher タスクを追加します。ここでの始まりは、もちろん FallbackHome です。
特定のスタックを見ると、ActivityManagerService.systemReady のときに ActivityTaskManagerService$LocalService.startHomeOnAllDisplays がトリガーされ、その後 HomeActivity がプルアップされることがわかります。この時点ではまだ暗号化された状態なので、取得された Home は当然、最後に、ActivityRecord はプロセス間通信を通じて WindowState を追加します

ステータスバー

WindowContainer.TAG   : Leaf:15:15@65133355 addChild Comparator child = WindowToken{
    
    ea411e9 type=2000 android.os.BinderProxy@46a0296}
WindowContainer.TAG   : java.lang.Exception
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayArea$Tokens.addChild(DisplayArea.java:605)
WindowContainer.TAG   : 	at com.android.server.wm.DisplayContent.addWindowToken(DisplayContent.java:1235)
WindowContainer.TAG   : 	at com.android.server.wm.WindowToken.<init>(WindowToken.java:214)
WindowContainer.TAG   : 	at com.android.server.wm.WindowToken$Builder.build(WindowToken.java:817)
WindowContainer.TAG   : 	at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1577)
WindowContainer.TAG   : 	at com.android.server.wm.Session.addToDisplayAsUser(Session.java:209)
WindowContainer.TAG   : 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:652)
WindowContainer.TAG   : 	at com.android.server.wm.Session.onTransact(Session.java:175)
WindowContainer.TAG   : 	at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer.TAG   : 	at android.os.Binder.execTransact(Binder.java:1244)
WindowContainer.TAG   : WindowToken{
    
    ea411e9 type=2000 android.os.BinderProxy@46a0296} addChild Comparator child = Window{
    
    c86ce6e u0 StatusBar}
WindowContainer.TAG   : java.lang.Exception
WindowContainer.TAG   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:694)
WindowContainer.TAG   : 	at com.android.server.wm.WindowToken.addWindow(WindowToken.java:302)
WindowContainer.TAG   : 	at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1773)
WindowContainer.TAG   : 	at com.android.server.wm.Session.addToDisplayAsUser(Session.java:209)
WindowContainer.TAG   : 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:652)
WindowContainer.TAG   : 	at com.android.server.wm.Session.onTransact(Session.java:175)
WindowContainer.TAG   : 	at android.os.Binder.execTransactInternal(Binder.java:1280)
WindowContainer.TAG   : 	at android.os.Binder.execTransact(Binder.java:1244)

WindowToken と WindowState は両方とも、プロセス間通信 Session.addToDisplayAsUser を通じて呼び出されます。
WindowToken スタックではWindowContainer.TAG : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1577)、WindowToken は 1577 行目で追加され始め、WindowState スタックでは、WindowContainer.TAG : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1773)WindowToken を追加した直後の 1773 行目で WindowState が追加され始めます。
具体的な手順については、Android T WMS 画面関連の手順を参照してください。

おすすめ

転載: blog.csdn.net/yimelancholy/article/details/132722735