Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 367d6ee5 authored by Chris Li's avatar Chris Li
Browse files

Introduce DisplayAreaHierarchyBuilder

(5/n DisplayArea Sibling Roots)

Refactor DisplayAreaPolicyBuilder to use it for creating display area
hierarchy below root.

The feature and hierarchy info will be stored in RootDisplayArea.

Bug: 157683117
Test: manual: test rotation and magnification
Test: atest WmTests:DisplayAreaPolicyBuilderTest
Test: atest WmTests:DisplayAreaProviderTest
Test: atest WmTests:WindowManagerServiceTests
Change-Id: I5b1f6dab2eb4061501c11548cac1764753378b3e
parent b285003a
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOW_TOKENS;

@@ -262,15 +261,6 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
        return this;
    }

    /**
     * Root of the display area hierarchy.
     */
    public static class Root extends DisplayArea<DisplayArea> {
        Root(WindowManagerService wms) {
            super(wms, Type.ANY, "DisplayArea.Root", FEATURE_ROOT);
        }
    }

    /**
     * DisplayArea that can be dimmed.
     */
+20 −48
Original line number Diff line number Diff line
@@ -34,55 +34,23 @@ import java.util.List;
 */
public abstract class DisplayAreaPolicy {
    protected final WindowManagerService mWmService;
    protected final DisplayContent mContent;

    /**
     * The root DisplayArea. Attach all DisplayAreas to this area (directly or indirectly).
     */
    protected final DisplayArea.Root mRoot;

    /**
     * The IME container. The IME's windows are automatically added to this container.
     */
    protected final DisplayArea<? extends WindowContainer> mImeContainer;

    /**
     * The task display areas. Tasks etc. are automatically added to these containers.
     */
    protected final List<TaskDisplayArea> mTaskDisplayAreas;
    protected final RootDisplayArea mRoot;

    /**
     * Construct a new {@link DisplayAreaPolicy}
     *
     * @param wmService the window manager service instance
     * @param content the display content for which the policy applies
     * @param root the root display area under which the policy operates
     * @param imeContainer the ime container that the policy must attach
     * @param taskDisplayAreas the task display areas that the policy must attach
     *
     * @see #attachDisplayAreas()
     */
    protected DisplayAreaPolicy(WindowManagerService wmService,
            DisplayContent content, DisplayArea.Root root,
            DisplayArea<? extends WindowContainer> imeContainer,
            List<TaskDisplayArea> taskDisplayAreas) {
    protected DisplayAreaPolicy(WindowManagerService wmService, RootDisplayArea root) {
        mWmService = wmService;
        mContent = content;
        mRoot = root;
        mImeContainer = imeContainer;
        mTaskDisplayAreas = taskDisplayAreas;
    }

    /**
     * Called to ask the policy to set up the DisplayArea hierarchy. At a minimum this must:
     *
     * - attach mImeContainer to mRoot (or one of its descendants)
     * - attach mTaskStacks to mRoot (or one of its descendants)
     *
     * Additionally, this is the right place to set up any other DisplayAreas as desired.
     */
    public abstract void attachDisplayAreas();

    /**
     * Called to ask the policy to attach the given WindowToken to the DisplayArea hierarchy.
     *
@@ -98,28 +66,28 @@ public abstract class DisplayAreaPolicy {
    /**
     * @return the number of task display areas on the display.
     */
    public int getTaskDisplayAreaCount() {
        return mTaskDisplayAreas.size();
    }
    public abstract int getTaskDisplayAreaCount();

    /**
     * @return the task display area at index.
     */
    public TaskDisplayArea getTaskDisplayAreaAt(int index) {
        return mTaskDisplayAreas.get(index);
    }
    public abstract TaskDisplayArea getTaskDisplayAreaAt(int index);

    /** Provider for platform-default display area policy. */
    static final class DefaultProvider implements DisplayAreaPolicy.Provider {
        @Override
        public DisplayAreaPolicy instantiate(WindowManagerService wmService,
                DisplayContent content, DisplayArea.Root root,
                DisplayContent content, RootDisplayArea root,
                DisplayArea<? extends WindowContainer> imeContainer) {
            final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService,
                    "DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);
            final List<TaskDisplayArea> tdaList = new ArrayList<>();
            tdaList.add(defaultTaskDisplayArea);
            return new DisplayAreaPolicyBuilder()

            // Define the features that will be supported under the root of the whole logical
            // display. The policy will build the DisplayArea hierarchy based on this.
            DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
                    new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
                    .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy,
                            "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION)
                            .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
@@ -133,7 +101,12 @@ public abstract class DisplayAreaPolicy {
                            .all()
                            .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL)
                            .build())
                    .build(wmService, content, root, imeContainer, tdaList);
                    .setImeContainer(imeContainer)
                    .setTaskDisplayAreas(tdaList);

            // Instantiate the policy with the hierarchy defined above. This will create and attach
            // all the necessary DisplayAreas to the root.
            return new DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService);
        }
    }

@@ -146,16 +119,15 @@ public abstract class DisplayAreaPolicy {
     */
    public interface Provider {
        /**
         * Instantiate a new DisplayAreaPolicy.
         * Instantiates a new DisplayAreaPolicy. It should set up the {@link DisplayArea} hierarchy.
         *
         * @see DisplayAreaPolicy#DisplayAreaPolicy
         */
        DisplayAreaPolicy instantiate(WindowManagerService wmService,
                DisplayContent content, DisplayArea.Root root,
                DisplayArea<? extends WindowContainer> imeContainer);
        DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,
                RootDisplayArea root, DisplayArea<? extends WindowContainer> imeContainer);

        /**
         * Instantiate the device-specific {@link Provider}.
         * Instantiates the device-specific {@link Provider}.
         */
        static Provider fromResources(Resources res) {
            String name = res.getString(
+245 −153

File changed.

Preview size limit exceeded, changes collapsed.

+1 −2
Original line number Diff line number Diff line
@@ -231,7 +231,7 @@ import java.util.function.Predicate;
 * Utility class for keeping track of the WindowStates and other pertinent contents of a
 * particular Display.
 */
class DisplayContent extends DisplayArea.Root implements WindowManagerPolicy.DisplayContentInfo {
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
    private static final String TAG_STACK = TAG + POSTFIX_STACK;

@@ -989,7 +989,6 @@ class DisplayContent extends DisplayArea.Root implements WindowManagerPolicy.Dis
        // Setup the policy and build the display area hierarchy.
        mDisplayAreaPolicy = mWmService.mDisplayAreaPolicyProvider.instantiate(
                mWmService, this /* content */, this /* root */, mImeWindowsContainers);
        mDisplayAreaPolicy.attachDisplayAreas();

        // Sets the display content for the children.
        onDisplayChanged(this);
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm;

import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;

import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Root of a {@link DisplayArea} hierarchy. It can be either the {@link DisplayContent} as the root
 * of the whole logical display, or the root of a {@link DisplayArea} group.
 */
class RootDisplayArea extends DisplayArea<DisplayArea> {

    /** {@link Feature} that are supported in this {@link DisplayArea} hierarchy. */
    List<DisplayAreaPolicyBuilder.Feature> mFeatures;

    /**
     * Mapping from policy supported {@link Feature} to list of {@link DisplayArea} created to cover
     * all the window types that the {@link Feature} will be applied to.
     */
    Map<Feature, List<DisplayArea<? extends WindowContainer>>> mFeatureToDisplayAreas;

    /** Mapping from window layer to {@link DisplayArea.Tokens} that holds windows on that layer. */
    private DisplayArea.Tokens[] mAreaForLayer;

    /**
     * List of {@link TaskDisplayArea} that are attached to this {@link DisplayArea} hierarchy. The
     * order is the same as their z-order.
     *
     * TODO(b/157683117): Instead of caching the TDAs, always traverse the hierarchy to get them.
     */
    ArrayList<TaskDisplayArea> mTaskDisplayAreas;

    /** Whether the hierarchy has been built. */
    private boolean mHasBuiltHierarchy;

    RootDisplayArea(WindowManagerService wms) {
        super(wms, Type.ANY, "RootDisplayArea", FEATURE_ROOT);
    }

    /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */
    DisplayArea.Tokens findAreaForToken(WindowToken token) {
        int windowLayerFromType = token.getWindowLayerFromType();
        if (windowLayerFromType == APPLICATION_LAYER) {
            throw new IllegalArgumentException(
                    "There shouldn't be WindowToken on APPLICATION_LAYER");
        } else if (token.mRoundedCornerOverlay) {
            windowLayerFromType = mAreaForLayer.length - 1;
        }
        return mAreaForLayer[windowLayerFromType];
    }

    /** Callback after {@link DisplayArea} hierarchy has been built. */
    void onHierarchyBuilt(ArrayList<Feature> features, DisplayArea.Tokens[] areaForLayer,
            Map<Feature, List<DisplayArea<? extends WindowContainer>>> featureToDisplayAreas,
            ArrayList<TaskDisplayArea> taskDisplayAreas) {
        if (mHasBuiltHierarchy) {
            throw new IllegalStateException("Root should only build the hierarchy once");
        }
        mHasBuiltHierarchy = true;
        mFeatures = Collections.unmodifiableList(features);
        mAreaForLayer = areaForLayer;
        mTaskDisplayAreas = taskDisplayAreas;
        mFeatureToDisplayAreas = featureToDisplayAreas;
    }
}
Loading