• 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 android.window;
18 
19 import android.annotation.BinderThread;
20 import android.annotation.CallSuper;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SuppressLint;
25 import android.annotation.TestApi;
26 import android.app.ActivityManager;
27 import android.os.IBinder;
28 import android.os.RemoteException;
29 import android.view.SurfaceControl;
30 
31 import com.android.internal.annotations.VisibleForTesting;
32 
33 import java.util.List;
34 import java.util.concurrent.Executor;
35 
36 /**
37  * Interface for ActivityTaskManager/WindowManager to delegate control of tasks.
38  * @hide
39  */
40 @TestApi
41 public class TaskOrganizer extends WindowOrganizer {
42 
43     private final ITaskOrganizerController mTaskOrganizerController;
44     // Callbacks WM Core are posted on this executor if it isn't null, otherwise direct calls are
45     // made on the incoming binder call.
46     private final Executor mExecutor;
47 
TaskOrganizer()48     public TaskOrganizer() {
49         this(null /*taskOrganizerController*/, null /*executor*/);
50     }
51 
52     /** @hide */
53     @VisibleForTesting
TaskOrganizer(ITaskOrganizerController taskOrganizerController, Executor executor)54     public TaskOrganizer(ITaskOrganizerController taskOrganizerController, Executor executor) {
55         mExecutor = executor != null ? executor : Runnable::run;
56         mTaskOrganizerController = taskOrganizerController != null
57                 ? taskOrganizerController : getController();
58     }
59 
60     /**
61      * Register a TaskOrganizer to manage tasks as they enter a supported windowing mode.
62      *
63      * @return a list of the tasks that should be managed by the organizer, not including tasks
64      *         created via {@link #createRootTask}.
65      */
66     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
67     @CallSuper
68     @NonNull
registerOrganizer()69     public List<TaskAppearedInfo> registerOrganizer() {
70         try {
71             return mTaskOrganizerController.registerTaskOrganizer(mInterface).getList();
72         } catch (RemoteException e) {
73             throw e.rethrowFromSystemServer();
74         }
75     }
76 
77     /** Unregisters a previously registered task organizer. */
78     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
79     @CallSuper
unregisterOrganizer()80     public void unregisterOrganizer() {
81         try {
82             mTaskOrganizerController.unregisterTaskOrganizer(mInterface);
83         } catch (RemoteException e) {
84             throw e.rethrowFromSystemServer();
85         }
86     }
87 
88     /**
89      * Called when a Task is starting and the system would like to show a UI to indicate that an
90      * application is starting. The client is responsible to add/remove the starting window if it
91      * has create a starting window for the Task.
92      *
93      * @param info The information about the Task that's available
94      * @hide
95      */
96     @BinderThread
addStartingWindow(@onNull StartingWindowInfo info)97     public void addStartingWindow(@NonNull StartingWindowInfo info) {}
98 
99     /**
100      * Called when the Task want to remove the starting window.
101      * @param removalInfo The information used to remove the starting window.
102      * @hide
103      */
104     @BinderThread
removeStartingWindow(@onNull StartingWindowRemovalInfo removalInfo)105     public void removeStartingWindow(@NonNull StartingWindowRemovalInfo removalInfo) {}
106 
107     /**
108      * Called when the Task want to copy the splash screen.
109      */
110     @BinderThread
copySplashScreenView(int taskId)111     public void copySplashScreenView(int taskId) {}
112 
113     /**
114      * Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
115      * removed the splash screen view.
116      * @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
117      * @see SplashScreenView#remove()
118      */
119     @BinderThread
onAppSplashScreenViewRemoved(int taskId)120     public void onAppSplashScreenViewRemoved(int taskId) {
121     }
122 
123     /**
124      * Called when a task with the registered windowing mode can be controlled by this task
125      * organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
126      * to show this task.
127      */
128     @BinderThread
onTaskAppeared(@onNull ActivityManager.RunningTaskInfo taskInfo, @NonNull SurfaceControl leash)129     public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo,
130             @NonNull SurfaceControl leash) {}
131 
132     @BinderThread
onTaskVanished(@onNull ActivityManager.RunningTaskInfo taskInfo)133     public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
134 
135     @BinderThread
onTaskInfoChanged(@onNull ActivityManager.RunningTaskInfo taskInfo)136     public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
137 
138     @BinderThread
onBackPressedOnTaskRoot(@onNull ActivityManager.RunningTaskInfo taskInfo)139     public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
140 
141     /** @hide */
142     @BinderThread
onImeDrawnOnTask(int taskId)143     public void onImeDrawnOnTask(int taskId) {}
144 
145     /**
146      * Creates a persistent root task in WM for a particular windowing-mode.
147      * @param displayId The display to create the root task on.
148      * @param windowingMode Windowing mode to put the root task in.
149      * @param launchCookie Launch cookie to associate with the task so that is can be identified
150      *                     when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
151      * @param removeWithTaskOrganizer True if this task should be removed when organizer destroyed.
152      * @hide
153      */
154     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie, boolean removeWithTaskOrganizer)155     public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie,
156             boolean removeWithTaskOrganizer) {
157         try {
158             mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie,
159                     removeWithTaskOrganizer);
160         } catch (RemoteException e) {
161             throw e.rethrowFromSystemServer();
162         }
163     }
164 
165     /**
166      * Creates a persistent root task in WM for a particular windowing-mode.
167      * @param displayId The display to create the root task on.
168      * @param windowingMode Windowing mode to put the root task in.
169      * @param launchCookie Launch cookie to associate with the task so that is can be identified
170      *                     when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
171      */
172     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
173     @Nullable
createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie)174     public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
175         createRootTask(displayId, windowingMode, launchCookie, false /* removeWithTaskOrganizer */);
176     }
177 
178     /** Deletes a persistent root task in WM */
179     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
deleteRootTask(@onNull WindowContainerToken task)180     public boolean deleteRootTask(@NonNull WindowContainerToken task) {
181         try {
182             return mTaskOrganizerController.deleteRootTask(task);
183         } catch (RemoteException e) {
184             throw e.rethrowFromSystemServer();
185         }
186     }
187 
188     /** Gets direct child tasks (ordered from top-to-bottom) */
189     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
190     @Nullable
191     @SuppressLint("NullableCollection")
getChildTasks( @onNull WindowContainerToken parent, @NonNull int[] activityTypes)192     public List<ActivityManager.RunningTaskInfo> getChildTasks(
193             @NonNull WindowContainerToken parent, @NonNull int[] activityTypes) {
194         try {
195             return mTaskOrganizerController.getChildTasks(parent, activityTypes);
196         } catch (RemoteException e) {
197             throw e.rethrowFromSystemServer();
198         }
199     }
200 
201     /** Gets all root tasks on a display (ordered from top-to-bottom) */
202     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
203     @Nullable
204     @SuppressLint("NullableCollection")
getRootTasks( int displayId, @NonNull int[] activityTypes)205     public List<ActivityManager.RunningTaskInfo> getRootTasks(
206             int displayId, @NonNull int[] activityTypes) {
207         try {
208             return mTaskOrganizerController.getRootTasks(displayId, activityTypes);
209         } catch (RemoteException e) {
210             throw e.rethrowFromSystemServer();
211         }
212     }
213 
214     /** Get the {@link WindowContainerToken} of the task which contains the current ime target */
215     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
216     @Nullable
getImeTarget(int display)217     public WindowContainerToken getImeTarget(int display) {
218         try {
219             return mTaskOrganizerController.getImeTarget(display);
220         } catch (RemoteException e) {
221             throw e.rethrowFromSystemServer();
222         }
223     }
224 
225     /**
226      * Requests that the given task organizer is notified when back is pressed on the root activity
227      * of one of its controlled tasks.
228      */
229     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
setInterceptBackPressedOnTaskRoot(@onNull WindowContainerToken task, boolean interceptBackPressed)230     public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task,
231             boolean interceptBackPressed) {
232         try {
233             mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(task, interceptBackPressed);
234         } catch (RemoteException e) {
235             throw e.rethrowFromSystemServer();
236         }
237     }
238 
239 
240     /**
241      * Restarts the top activity in the given task by killing its process if it is visible.
242      * @hide
243      */
244     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
restartTaskTopActivityProcessIfVisible(@onNull WindowContainerToken task)245     public void restartTaskTopActivityProcessIfVisible(@NonNull WindowContainerToken task) {
246         try {
247             mTaskOrganizerController.restartTaskTopActivityProcessIfVisible(task);
248         } catch (RemoteException e) {
249             throw e.rethrowFromSystemServer();
250         }
251     }
252 
253     /**
254      * Gets the executor to run callbacks on.
255      * @hide
256      */
257     @NonNull
getExecutor()258     public Executor getExecutor() {
259         return mExecutor;
260     }
261 
262     private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
263         @Override
264         public void addStartingWindow(StartingWindowInfo windowInfo) {
265             mExecutor.execute(() -> TaskOrganizer.this.addStartingWindow(windowInfo));
266         }
267 
268         @Override
269         public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) {
270             mExecutor.execute(() -> TaskOrganizer.this.removeStartingWindow(removalInfo));
271         }
272 
273         @Override
274         public void copySplashScreenView(int taskId)  {
275             mExecutor.execute(() -> TaskOrganizer.this.copySplashScreenView(taskId));
276         }
277 
278         @Override
279         public void onAppSplashScreenViewRemoved(int taskId) {
280             mExecutor.execute(() -> TaskOrganizer.this.onAppSplashScreenViewRemoved(taskId));
281         }
282 
283         @Override
284         public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
285             mExecutor.execute(() -> TaskOrganizer.this.onTaskAppeared(taskInfo, leash));
286         }
287 
288         @Override
289         public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
290             mExecutor.execute(() -> TaskOrganizer.this.onTaskVanished(taskInfo));
291         }
292 
293         @Override
294         public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
295             mExecutor.execute(() -> TaskOrganizer.this.onTaskInfoChanged(info));
296         }
297 
298         @Override
299         public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) {
300             mExecutor.execute(() -> TaskOrganizer.this.onBackPressedOnTaskRoot(info));
301         }
302 
303         @Override
304         public void onImeDrawnOnTask(int taskId) {
305             mExecutor.execute(() -> TaskOrganizer.this.onImeDrawnOnTask(taskId));
306         }
307     };
308 
309     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
getController()310     private ITaskOrganizerController getController() {
311         try {
312             return getWindowOrganizerController().getTaskOrganizerController();
313         } catch (RemoteException e) {
314             return null;
315         }
316     }
317 }
318