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.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; 20 21 import android.content.res.Resources; 22 import android.text.TextUtils; 23 24 import java.util.ArrayList; 25 import java.util.List; 26 27 /** 28 * Policy that manages DisplayAreas. 29 */ 30 public abstract class DisplayAreaPolicy { 31 protected final WindowManagerService mWmService; 32 protected final DisplayContent mContent; 33 34 /** 35 * The root DisplayArea. Attach all DisplayAreas to this area (directly or indirectly). 36 */ 37 protected final DisplayArea.Root mRoot; 38 39 /** 40 * The IME container. The IME's windows are automatically added to this container. 41 */ 42 protected final DisplayArea<? extends WindowContainer> mImeContainer; 43 44 /** 45 * The task display areas. Tasks etc. are automatically added to these containers. 46 */ 47 protected final List<TaskDisplayArea> mTaskDisplayAreas; 48 49 /** 50 * Construct a new {@link DisplayAreaPolicy} 51 * 52 * @param wmService the window manager service instance 53 * @param content the display content for which the policy applies 54 * @param root the root display area under which the policy operates 55 * @param imeContainer the ime container that the policy must attach 56 * @param taskDisplayAreas the task display areas that the policy must attach 57 * 58 * @see #attachDisplayAreas() 59 */ DisplayAreaPolicy(WindowManagerService wmService, DisplayContent content, DisplayArea.Root root, DisplayArea<? extends WindowContainer> imeContainer, List<TaskDisplayArea> taskDisplayAreas)60 protected DisplayAreaPolicy(WindowManagerService wmService, 61 DisplayContent content, DisplayArea.Root root, 62 DisplayArea<? extends WindowContainer> imeContainer, 63 List<TaskDisplayArea> taskDisplayAreas) { 64 mWmService = wmService; 65 mContent = content; 66 mRoot = root; 67 mImeContainer = imeContainer; 68 mTaskDisplayAreas = taskDisplayAreas; 69 } 70 71 /** 72 * Called to ask the policy to set up the DisplayArea hierarchy. At a minimum this must: 73 * 74 * - attach mImeContainer to mRoot (or one of its descendants) 75 * - attach mTaskStacks to mRoot (or one of its descendants) 76 * 77 * Additionally, this is the right place to set up any other DisplayAreas as desired. 78 */ attachDisplayAreas()79 public abstract void attachDisplayAreas(); 80 81 /** 82 * Called to ask the policy to attach the given WindowToken to the DisplayArea hierarchy. 83 * 84 * This must attach the token to mRoot (or one of its descendants). 85 */ addWindow(WindowToken token)86 public abstract void addWindow(WindowToken token); 87 88 /** 89 * @return the number of task display areas on the display. 90 */ getTaskDisplayAreaCount()91 public int getTaskDisplayAreaCount() { 92 return mTaskDisplayAreas.size(); 93 } 94 95 /** 96 * @return the task display area at index. 97 */ getTaskDisplayAreaAt(int index)98 public TaskDisplayArea getTaskDisplayAreaAt(int index) { 99 return mTaskDisplayAreas.get(index); 100 } 101 102 /** Provider for platform-default display area policy. */ 103 static final class DefaultProvider implements DisplayAreaPolicy.Provider { 104 @Override instantiate(WindowManagerService wmService, DisplayContent content, DisplayArea.Root root, DisplayArea<? extends WindowContainer> imeContainer)105 public DisplayAreaPolicy instantiate(WindowManagerService wmService, 106 DisplayContent content, DisplayArea.Root root, 107 DisplayArea<? extends WindowContainer> imeContainer) { 108 final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService, 109 "DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER); 110 final List<TaskDisplayArea> tdaList = new ArrayList<>(); 111 tdaList.add(defaultTaskDisplayArea); 112 return new DisplayAreaPolicyBuilder() 113 .build(wmService, content, root, imeContainer, tdaList); 114 } 115 } 116 117 /** 118 * Provider for {@link DisplayAreaPolicy} instances. 119 * 120 * By implementing this interface and overriding the 121 * {@code config_deviceSpecificDisplayAreaPolicyProvider}, a device-specific implementations 122 * of {@link DisplayAreaPolicy} can be supplied. 123 */ 124 public interface Provider { 125 /** 126 * Instantiate a new DisplayAreaPolicy. 127 * 128 * @see DisplayAreaPolicy#DisplayAreaPolicy 129 */ instantiate(WindowManagerService wmService, DisplayContent content, DisplayArea.Root root, DisplayArea<? extends WindowContainer> imeContainer)130 DisplayAreaPolicy instantiate(WindowManagerService wmService, 131 DisplayContent content, DisplayArea.Root root, 132 DisplayArea<? extends WindowContainer> imeContainer); 133 134 /** 135 * Instantiate the device-specific {@link Provider}. 136 */ fromResources(Resources res)137 static Provider fromResources(Resources res) { 138 String name = res.getString( 139 com.android.internal.R.string.config_deviceSpecificDisplayAreaPolicyProvider); 140 if (TextUtils.isEmpty(name)) { 141 return new DisplayAreaPolicy.DefaultProvider(); 142 } 143 try { 144 return (Provider) Class.forName(name).newInstance(); 145 } catch (ReflectiveOperationException | ClassCastException e) { 146 throw new IllegalStateException("Couldn't instantiate class " + name 147 + " for config_deviceSpecificDisplayAreaPolicyProvider:" 148 + " make sure it has a public zero-argument constructor" 149 + " and implements DisplayAreaPolicy.Provider", e); 150 } 151 } 152 } 153 } 154