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 android.window; 18 19 import android.annotation.BinderThread; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.RequiresPermission; 23 import android.annotation.TestApi; 24 import android.app.ActivityManager; 25 import android.os.RemoteException; 26 import android.util.Singleton; 27 import android.view.SurfaceControl; 28 29 import java.util.List; 30 31 /** 32 * Interface for ActivityTaskManager/WindowManager to delegate control of tasks. 33 * @hide 34 */ 35 @TestApi 36 public class TaskOrganizer extends WindowOrganizer { 37 38 /** 39 * Register a TaskOrganizer to manage tasks as they enter the given windowing mode. 40 * If there was already a TaskOrganizer for this windowing mode it will be evicted 41 * and receive taskVanished callbacks in the process. 42 */ 43 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) registerOrganizer(int windowingMode)44 public final void registerOrganizer(int windowingMode) { 45 try { 46 getController().registerTaskOrganizer(mInterface, windowingMode); 47 } catch (RemoteException e) { 48 throw e.rethrowFromSystemServer(); 49 } 50 } 51 52 /** Unregisters a previously registered task organizer. */ 53 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) unregisterOrganizer()54 public final void unregisterOrganizer() { 55 try { 56 getController().unregisterTaskOrganizer(mInterface); 57 } catch (RemoteException e) { 58 throw e.rethrowFromSystemServer(); 59 } 60 } 61 62 /** 63 * Called when a task with the registered windowing mode can be controlled by this task 64 * organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer 65 * to show this task. 66 */ 67 @BinderThread onTaskAppeared(@onNull ActivityManager.RunningTaskInfo taskInfo, @NonNull SurfaceControl leash)68 public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo, 69 @NonNull SurfaceControl leash) {} 70 71 @BinderThread onTaskVanished(@onNull ActivityManager.RunningTaskInfo taskInfo)72 public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} 73 74 @BinderThread onTaskInfoChanged(@onNull ActivityManager.RunningTaskInfo taskInfo)75 public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} 76 77 @BinderThread onBackPressedOnTaskRoot(@onNull ActivityManager.RunningTaskInfo taskInfo)78 public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} 79 80 /** Creates a persistent root task in WM for a particular windowing-mode. */ 81 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) 82 @Nullable createRootTask(int displayId, int windowingMode)83 public static ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode) { 84 try { 85 return getController().createRootTask(displayId, windowingMode); 86 } catch (RemoteException e) { 87 throw e.rethrowFromSystemServer(); 88 } 89 } 90 91 /** Deletes a persistent root task in WM */ 92 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) deleteRootTask(@onNull WindowContainerToken task)93 public static boolean deleteRootTask(@NonNull WindowContainerToken task) { 94 try { 95 return getController().deleteRootTask(task); 96 } catch (RemoteException e) { 97 throw e.rethrowFromSystemServer(); 98 } 99 } 100 101 /** Gets direct child tasks (ordered from top-to-bottom) */ 102 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) 103 @Nullable getChildTasks( @onNull WindowContainerToken parent, @NonNull int[] activityTypes)104 public static List<ActivityManager.RunningTaskInfo> getChildTasks( 105 @NonNull WindowContainerToken parent, @NonNull int[] activityTypes) { 106 try { 107 return getController().getChildTasks(parent, activityTypes); 108 } catch (RemoteException e) { 109 throw e.rethrowFromSystemServer(); 110 } 111 } 112 113 /** Gets all root tasks on a display (ordered from top-to-bottom) */ 114 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) 115 @Nullable getRootTasks( int displayId, @NonNull int[] activityTypes)116 public static List<ActivityManager.RunningTaskInfo> getRootTasks( 117 int displayId, @NonNull int[] activityTypes) { 118 try { 119 return getController().getRootTasks(displayId, activityTypes); 120 } catch (RemoteException e) { 121 throw e.rethrowFromSystemServer(); 122 } 123 } 124 125 /** Get the root task which contains the current ime target */ 126 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) 127 @Nullable getImeTarget(int display)128 public static WindowContainerToken getImeTarget(int display) { 129 try { 130 return getController().getImeTarget(display); 131 } catch (RemoteException e) { 132 throw e.rethrowFromSystemServer(); 133 } 134 } 135 136 /** 137 * Set's the root task to launch new tasks into on a display. {@code null} means no launch 138 * root and thus new tasks just end up directly on the display. 139 */ 140 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) setLaunchRoot(int displayId, @NonNull WindowContainerToken root)141 public static void setLaunchRoot(int displayId, @NonNull WindowContainerToken root) { 142 try { 143 getController().setLaunchRoot(displayId, root); 144 } catch (RemoteException e) { 145 throw e.rethrowFromSystemServer(); 146 } 147 } 148 149 /** 150 * Requests that the given task organizer is notified when back is pressed on the root activity 151 * of one of its controlled tasks. 152 */ 153 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed)154 public void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) { 155 try { 156 getController().setInterceptBackPressedOnTaskRoot(mInterface, interceptBackPressed); 157 } catch (RemoteException e) { 158 throw e.rethrowFromSystemServer(); 159 } 160 } 161 162 private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() { 163 164 @Override 165 public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { 166 TaskOrganizer.this.onTaskAppeared(taskInfo, leash); 167 } 168 169 @Override 170 public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { 171 TaskOrganizer.this.onTaskVanished(taskInfo); 172 } 173 174 @Override 175 public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { 176 TaskOrganizer.this.onTaskInfoChanged(info); 177 } 178 179 @Override 180 public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) { 181 TaskOrganizer.this.onBackPressedOnTaskRoot(info); 182 } 183 }; 184 getController()185 private static ITaskOrganizerController getController() { 186 return ITaskOrganizerControllerSingleton.get(); 187 } 188 189 private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton = 190 new Singleton<ITaskOrganizerController>() { 191 @Override 192 protected ITaskOrganizerController create() { 193 try { 194 return getWindowOrganizerController().getTaskOrganizerController(); 195 } catch (RemoteException e) { 196 return null; 197 } 198 } 199 }; 200 } 201