• 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_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
20 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
21 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
22 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
23 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
24 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
25 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
26 import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
27 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
28 import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
29 import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION;
30 import static android.window.DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT;
31 import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER;
32 import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
33 import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
34 
35 import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature;
36 import static com.android.server.wm.DisplayAreaPolicyBuilder.HierarchyBuilder;
37 
38 import android.annotation.Nullable;
39 import android.content.res.Resources;
40 import android.os.Bundle;
41 import android.text.TextUtils;
42 
43 import java.util.ArrayList;
44 import java.util.List;
45 
46 /**
47  * Policy that manages {@link DisplayArea}.
48  */
49 public abstract class DisplayAreaPolicy {
50     protected final WindowManagerService mWmService;
51 
52     /**
53      * The {@link RootDisplayArea} of the whole logical display. All {@link DisplayArea}s must be
54      * (direct or indirect) descendants of this area.
55      */
56     protected final RootDisplayArea mRoot;
57 
58     /**
59      * Constructs a new {@link DisplayAreaPolicy}
60      *
61      * @param wmService the window manager service instance
62      * @param root the root display area under which the policy operates
63      */
DisplayAreaPolicy(WindowManagerService wmService, RootDisplayArea root)64     protected DisplayAreaPolicy(WindowManagerService wmService, RootDisplayArea root) {
65         mWmService = wmService;
66         mRoot = root;
67     }
68 
69     /**
70      * Called to ask the policy to attach the given {@link WindowToken} to the {@link DisplayArea}
71      * hierarchy.
72      *
73      * <p>This must attach the token to {@link #mRoot} (or one of its descendants).
74      */
addWindow(WindowToken token)75     public abstract void addWindow(WindowToken token);
76 
77     /** Gets the {@link DisplayArea} with given window type and launched options */
findAreaForWindowType(int type, Bundle options, boolean ownerCanManageAppTokens, boolean roundedCornerOverlay)78     public abstract DisplayArea.Tokens findAreaForWindowType(int type, Bundle options,
79             boolean ownerCanManageAppTokens, boolean roundedCornerOverlay);
80 
81     /**
82      * Gets the set of {@link DisplayArea} that are created for the given feature to apply to.
83      */
getDisplayAreas(int featureId)84     public abstract List<DisplayArea<? extends WindowContainer>> getDisplayAreas(int featureId);
85 
86     /**
87      * @return the default/fallback {@link TaskDisplayArea} on the display.
88      */
getDefaultTaskDisplayArea()89     public abstract TaskDisplayArea getDefaultTaskDisplayArea();
90 
91     /** Returns the {@link TaskDisplayArea} specified by launch options. */
getTaskDisplayArea(@ullable Bundle options)92     public abstract TaskDisplayArea getTaskDisplayArea(@Nullable Bundle options);
93 
94     /** Provider for platform-default display area policy. */
95     static final class DefaultProvider implements DisplayAreaPolicy.Provider {
96         @Override
instantiate(WindowManagerService wmService, DisplayContent content, RootDisplayArea root, DisplayArea.Tokens imeContainer)97         public DisplayAreaPolicy instantiate(WindowManagerService wmService,
98                 DisplayContent content, RootDisplayArea root,
99                 DisplayArea.Tokens imeContainer) {
100             final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService,
101                     "DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);
102             final List<TaskDisplayArea> tdaList = new ArrayList<>();
103             tdaList.add(defaultTaskDisplayArea);
104 
105             // Define the features that will be supported under the root of the whole logical
106             // display. The policy will build the DisplayArea hierarchy based on this.
107             final HierarchyBuilder rootHierarchy = new HierarchyBuilder(root);
108             // Set the essential containers (even if the display doesn't support IME).
109             rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);
110             if (content.isTrusted()) {
111                 // Only trusted display can have system decorations.
112                 configureTrustedHierarchyBuilder(rootHierarchy, wmService, content);
113             }
114 
115             // Instantiate the policy with the hierarchy defined above. This will create and attach
116             // all the necessary DisplayAreas to the root.
117             return new DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService);
118         }
119 
configureTrustedHierarchyBuilder(HierarchyBuilder rootHierarchy, WindowManagerService wmService, DisplayContent content)120         private void configureTrustedHierarchyBuilder(HierarchyBuilder rootHierarchy,
121                 WindowManagerService wmService, DisplayContent content) {
122             // WindowedMagnification should be on the top so that there is only one surface
123             // to be magnified.
124             rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification",
125                     FEATURE_WINDOWED_MAGNIFICATION)
126                     .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
127                     .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
128                     // Make the DA dimmable so that the magnify window also mirrors the dim layer.
129                     .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)
130                     .build());
131             if (content.isDefaultDisplay) {
132                 // Only default display can have cutout.
133                 // See LocalDisplayAdapter.LocalDisplayDevice#getDisplayDeviceInfoLocked.
134                 rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "HideDisplayCutout",
135                         FEATURE_HIDE_DISPLAY_CUTOUT)
136                         .all()
137                         .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL, TYPE_STATUS_BAR,
138                                 TYPE_NOTIFICATION_SHADE)
139                         .build())
140                         .addFeature(new Feature.Builder(wmService.mPolicy, "OneHanded",
141                                 FEATURE_ONE_HANDED)
142                                 .all()
143                                 .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL,
144                                         TYPE_SECURE_SYSTEM_OVERLAY)
145                                 .build());
146             }
147             rootHierarchy
148                     .addFeature(new Feature.Builder(wmService.mPolicy, "FullscreenMagnification",
149                             FEATURE_FULLSCREEN_MAGNIFICATION)
150                             .all()
151                             .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, TYPE_INPUT_METHOD,
152                                     TYPE_INPUT_METHOD_DIALOG, TYPE_MAGNIFICATION_OVERLAY,
153                                     TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL)
154                             .build())
155                     .addFeature(new Feature.Builder(wmService.mPolicy, "ImePlaceholder",
156                             FEATURE_IME_PLACEHOLDER)
157                             .and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG)
158                             .build());
159         }
160     }
161 
162     /**
163      * Provider for {@link DisplayAreaPolicy} instances.
164      *
165      * <p>By implementing this interface and overriding the
166      * {@code config_deviceSpecificDisplayAreaPolicyProvider}, a device-specific implementations
167      * of {@link DisplayAreaPolicy} can be supplied.
168      */
169     public interface Provider {
170         /**
171          * Instantiates a new {@link DisplayAreaPolicy}. It should set up the {@link DisplayArea}
172          * hierarchy.
173          *
174          * @see DisplayAreaPolicy#DisplayAreaPolicy
175          */
instantiate(WindowManagerService wmService, DisplayContent content, RootDisplayArea root, DisplayArea.Tokens imeContainer)176         DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,
177                 RootDisplayArea root, DisplayArea.Tokens imeContainer);
178 
179         /**
180          * Instantiates the device-specific {@link Provider}.
181          */
fromResources(Resources res)182         static Provider fromResources(Resources res) {
183             String name = res.getString(
184                     com.android.internal.R.string.config_deviceSpecificDisplayAreaPolicyProvider);
185             if (TextUtils.isEmpty(name)) {
186                 return new DisplayAreaPolicy.DefaultProvider();
187             }
188             try {
189                 return (Provider) Class.forName(name).newInstance();
190             } catch (ReflectiveOperationException | ClassCastException e) {
191                 throw new IllegalStateException("Couldn't instantiate class " + name
192                         + " for config_deviceSpecificDisplayAreaPolicyProvider:"
193                         + " make sure it has a public zero-argument constructor"
194                         + " and implements DisplayAreaPolicy.Provider", e);
195             }
196         }
197     }
198 }
199