• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wm;
18 
19 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
20 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
21 import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
22 import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER;
23 
24 import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature;
25 
26 import android.annotation.Nullable;
27 
28 import com.android.server.policy.WindowManagerPolicy;
29 
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Map;
34 
35 /**
36  * Root of a {@link DisplayArea} hierarchy. It can be either the {@link DisplayContent} as the root
37  * of the whole logical display, or a {@link DisplayAreaGroup} as the root of a partition of the
38  * logical display.
39  */
40 class RootDisplayArea extends DisplayArea.Dimmable {
41 
42     /** {@link Feature} that are supported in this {@link DisplayArea} hierarchy. */
43     List<DisplayAreaPolicyBuilder.Feature> mFeatures;
44 
45     /**
46      * Mapping from policy supported {@link Feature} to list of {@link DisplayArea} created to cover
47      * all the window types that the {@link Feature} will be applied to.
48      */
49     Map<Feature, List<DisplayArea<WindowContainer>>> mFeatureToDisplayAreas;
50 
51     /** Mapping from window layer to {@link DisplayArea.Tokens} that holds windows on that layer. */
52     private DisplayArea.Tokens[] mAreaForLayer;
53 
54     /** Whether the hierarchy has been built. */
55     private boolean mHasBuiltHierarchy;
56 
RootDisplayArea(WindowManagerService wms, String name, int featureId)57     RootDisplayArea(WindowManagerService wms, String name, int featureId) {
58         super(wms, Type.ANY, name, featureId);
59     }
60 
61     @Override
getRootDisplayArea()62     RootDisplayArea getRootDisplayArea() {
63         return this;
64     }
65 
66     @Override
asRootDisplayArea()67     RootDisplayArea asRootDisplayArea() {
68         return this;
69     }
70 
71     /** Whether the orientation (based on dimensions) of this root is different from the Display. */
isOrientationDifferentFromDisplay()72     boolean isOrientationDifferentFromDisplay() {
73         return false;
74     }
75 
76     /**
77      * Places the IME container below this root, so that it's bounds and config will be updated to
78      * match the root.
79      */
placeImeContainer(DisplayArea.Tokens imeContainer)80     void placeImeContainer(DisplayArea.Tokens imeContainer) {
81         final RootDisplayArea previousRoot = imeContainer.getRootDisplayArea();
82 
83         List<Feature> features = mFeatures;
84         for (int i = 0; i < features.size(); i++) {
85             Feature feature = features.get(i);
86             if (feature.getId() == FEATURE_IME_PLACEHOLDER) {
87                 List<DisplayArea<WindowContainer>> imeDisplayAreas =
88                         mFeatureToDisplayAreas.get(feature);
89                 if (imeDisplayAreas.size() != 1) {
90                     throw new IllegalStateException("There must be exactly one DisplayArea for the "
91                             + "FEATURE_IME_PLACEHOLDER");
92                 }
93 
94                 previousRoot.updateImeContainerForLayers(null /* imeContainer */);
95                 imeContainer.reparent(imeDisplayAreas.get(0), POSITION_TOP);
96                 updateImeContainerForLayers(imeContainer);
97                 return;
98             }
99         }
100         throw new IllegalStateException(
101                 "There is no FEATURE_IME_PLACEHOLDER in this root to place the IME container");
102     }
103 
104     /**
105      * Finds the {@link DisplayArea.Tokens} in {@code mAreaForLayer} that this type of window
106      * should be attached to.
107      * <p>
108      * Note that in most cases, users are expected to call
109      * {@link DisplayContent#findAreaForToken(WindowToken)} to find a {@link DisplayArea} in
110      * {@link DisplayContent} level instead of calling this inner method.
111      * </p>
112      */
113     @Nullable
findAreaForTokenInLayer(WindowToken token)114     DisplayArea.Tokens findAreaForTokenInLayer(WindowToken token) {
115         return findAreaForWindowTypeInLayer(token.windowType, token.mOwnerCanManageAppTokens,
116                 token.mRoundedCornerOverlay);
117     }
118 
119     /** @see #findAreaForTokenInLayer(WindowToken)  */
120     @Nullable
findAreaForWindowTypeInLayer(int windowType, boolean ownerCanManageAppTokens, boolean roundedCornerOverlay)121     DisplayArea.Tokens findAreaForWindowTypeInLayer(int windowType, boolean ownerCanManageAppTokens,
122             boolean roundedCornerOverlay) {
123         int windowLayerFromType = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
124                 ownerCanManageAppTokens, roundedCornerOverlay);
125         if (windowLayerFromType == APPLICATION_LAYER) {
126             throw new IllegalArgumentException(
127                     "There shouldn't be WindowToken on APPLICATION_LAYER");
128         }
129         return mAreaForLayer[windowLayerFromType];
130     }
131 
132     /** Callback after {@link DisplayArea} hierarchy has been built. */
onHierarchyBuilt(ArrayList<Feature> features, DisplayArea.Tokens[] areaForLayer, Map<Feature, List<DisplayArea<WindowContainer>>> featureToDisplayAreas)133     void onHierarchyBuilt(ArrayList<Feature> features, DisplayArea.Tokens[] areaForLayer,
134             Map<Feature, List<DisplayArea<WindowContainer>>> featureToDisplayAreas) {
135         if (mHasBuiltHierarchy) {
136             throw new IllegalStateException("Root should only build the hierarchy once");
137         }
138         mHasBuiltHierarchy = true;
139         mFeatures = Collections.unmodifiableList(features);
140         mAreaForLayer = areaForLayer;
141         mFeatureToDisplayAreas = featureToDisplayAreas;
142     }
143 
updateImeContainerForLayers(@ullable DisplayArea.Tokens imeContainer)144     private void updateImeContainerForLayers(@Nullable DisplayArea.Tokens imeContainer) {
145         final WindowManagerPolicy policy = mWmService.mPolicy;
146         mAreaForLayer[policy.getWindowLayerFromTypeLw(TYPE_INPUT_METHOD)] = imeContainer;
147         mAreaForLayer[policy.getWindowLayerFromTypeLw(TYPE_INPUT_METHOD_DIALOG)] = imeContainer;
148     }
149 }
150