1 /* 2 * Copyright (C) 2021 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 android.window; 18 19 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 20 import static android.view.Display.INVALID_DISPLAY; 21 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.UserIdInt; 25 import android.app.WindowConfiguration; 26 import android.content.ComponentName; 27 import android.content.Intent; 28 import android.content.IntentSender; 29 import android.content.pm.ActivityInfo; 30 import android.util.ArraySet; 31 32 import java.io.PrintWriter; 33 import java.util.List; 34 import java.util.Set; 35 import java.util.function.Supplier; 36 37 /** 38 * Abstract class to control the policies of the windows that can be displayed on the virtual 39 * display. 40 * 41 * @hide 42 */ 43 public abstract class DisplayWindowPolicyController { 44 /** 45 * The window flags that we are interested in. 46 * @see android.view.WindowManager.LayoutParams 47 * @see #keepActivityOnWindowFlagsChanged 48 */ 49 private int mWindowFlags; 50 51 /** 52 * The system window flags that we are interested in. 53 * @see android.view.WindowManager.LayoutParams 54 * @see #keepActivityOnWindowFlagsChanged 55 */ 56 private int mSystemWindowFlags; 57 58 /** 59 * The set of windowing mode that are supported in this display. 60 * @see android.app.WindowConfiguration.WindowingMode 61 */ 62 private final Set<Integer> mSupportedWindowingModes = new ArraySet<>(); 63 64 /** 65 * A controller to control the policies of the windows that can be displayed on the virtual 66 * display. 67 */ DisplayWindowPolicyController()68 public DisplayWindowPolicyController() { 69 synchronized (mSupportedWindowingModes) { 70 mSupportedWindowingModes.add(WindowConfiguration.WINDOWING_MODE_FULLSCREEN); 71 mSupportedWindowingModes.add(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); 72 } 73 } 74 75 /** 76 * Returns {@code true} if the given window flags contain the flags that we're interested in. 77 */ isInterestedWindowFlags(int windowFlags, int systemWindowFlags)78 public final boolean isInterestedWindowFlags(int windowFlags, int systemWindowFlags) { 79 return (mWindowFlags & windowFlags) != 0 || (mSystemWindowFlags & systemWindowFlags) != 0; 80 } 81 82 /** 83 * Sets the window flags that we’re interested in and expected 84 * #keepActivityOnWindowFlagsChanged to be called if any changes. 85 */ setInterestedWindowFlags(int windowFlags, int systemWindowFlags)86 public final void setInterestedWindowFlags(int windowFlags, int systemWindowFlags) { 87 mWindowFlags = windowFlags; 88 mSystemWindowFlags = systemWindowFlags; 89 } 90 91 /** 92 * Returns {@code true} if the given windowing mode is supported in this display. 93 */ isWindowingModeSupported( @indowConfiguration.WindowingMode int windowingMode)94 public final boolean isWindowingModeSupported( 95 @WindowConfiguration.WindowingMode int windowingMode) { 96 synchronized (mSupportedWindowingModes) { 97 return mSupportedWindowingModes.contains(windowingMode); 98 } 99 } 100 101 /** 102 * Sets the windowing modes are supported in this display. 103 * 104 * @param supportedWindowingModes The set of 105 * {@link android.app.WindowConfiguration.WindowingMode}. 106 */ setSupportedWindowingModes(Set<Integer> supportedWindowingModes)107 public final void setSupportedWindowingModes(Set<Integer> supportedWindowingModes) { 108 synchronized (mSupportedWindowingModes) { 109 mSupportedWindowingModes.clear(); 110 mSupportedWindowingModes.addAll(supportedWindowingModes); 111 } 112 } 113 114 /** 115 * @return the custom home component specified for the relevant display, if any. 116 */ 117 @Nullable getCustomHomeComponent()118 public abstract ComponentName getCustomHomeComponent(); 119 120 /** 121 * Returns {@code true} if all of the given activities can be launched on this virtual display 122 * in the configuration defined by the rest of the arguments. 123 * 124 * @see #canContainActivity 125 */ canContainActivities(@onNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode)126 public boolean canContainActivities(@NonNull List<ActivityInfo> activities, 127 @WindowConfiguration.WindowingMode int windowingMode) { 128 for (int i = 0; i < activities.size(); i++) { 129 if (!canContainActivity(activities.get(i), windowingMode, 130 /*launchingFromDisplayId=*/ INVALID_DISPLAY, /*isNewTask=*/ false)) { 131 return false; 132 } 133 } 134 return true; 135 } 136 137 /** 138 * Returns {@code true} if the given activity can be launched on this virtual display in the 139 * configuration defined by the rest of the arguments. If the given intent would be intercepted 140 * by the display owner then this means that the activity cannot be launched. 141 * 142 * The intentSender argument can provide an IntentSender for the original intent to be passed 143 * to any activity listeners, in case the activity cannot be launched. 144 */ canActivityBeLaunched(@onNull ActivityInfo activityInfo, @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected, @Nullable Supplier<IntentSender> intentSender)145 public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, 146 @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, 147 int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected, 148 @Nullable Supplier<IntentSender> intentSender); 149 150 /** 151 * Returns {@code true} if the given activity can be launched on this virtual display in the 152 * configuration defined by the rest of the arguments. 153 */ canContainActivity(@onNull ActivityInfo activityInfo, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask)154 protected abstract boolean canContainActivity(@NonNull ActivityInfo activityInfo, 155 @WindowConfiguration.WindowingMode int windowingMode, 156 int launchingFromDisplayId, boolean isNewTask); 157 158 /** 159 * Called when an Activity window is layouted with the new changes where contains the 160 * window flags that we’re interested in. 161 * Returns {@code false} if the Activity cannot remain on the display and the activity task will 162 * be moved back to default display. 163 */ keepActivityOnWindowFlagsChanged( ActivityInfo activityInfo, int windowFlags, int systemWindowFlags)164 public abstract boolean keepActivityOnWindowFlagsChanged( 165 ActivityInfo activityInfo, int windowFlags, int systemWindowFlags); 166 167 /** 168 * Returns {@code true} if the tasks which is on this virtual display can be showed in the 169 * host device of the recently launched activities list. 170 */ canShowTasksInHostDeviceRecents()171 public abstract boolean canShowTasksInHostDeviceRecents(); 172 173 /** 174 * This is called when the top activity of the display is changed. 175 */ onTopActivityChanged(ComponentName topActivity, int uid, @UserIdInt int userId)176 public void onTopActivityChanged(ComponentName topActivity, int uid, @UserIdInt int userId) {} 177 178 /** 179 * This is called when the apps that contains running activities on the display has changed. 180 * The running activities refer to the non-finishing activities regardless of they are running 181 * in a process. 182 */ onRunningAppsChanged(ArraySet<Integer> runningUids)183 public void onRunningAppsChanged(ArraySet<Integer> runningUids) {} 184 185 /** 186 * This is called when an Activity is entering PIP. 187 * Returns {@code true} if the Activity is allowed to enter PIP. 188 */ isEnteringPipAllowed(int uid)189 public boolean isEnteringPipAllowed(int uid) { 190 return isWindowingModeSupported(WINDOWING_MODE_PINNED); 191 } 192 193 /** Dump debug data */ dump(String prefix, final PrintWriter pw)194 public void dump(String prefix, final PrintWriter pw) { 195 pw.println(prefix + "DisplayWindowPolicyController{" + super.toString() + "}"); 196 pw.println(prefix + " mWindowFlags=" + mWindowFlags); 197 pw.println(prefix + " mSystemWindowFlags=" + mSystemWindowFlags); 198 } 199 } 200