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