• 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.app.TaskInfo.CameraCompatControlState;
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      * @hide
98      */
99     @BinderThread
addStartingWindow(@onNull StartingWindowInfo info, @NonNull IBinder appToken)100     public void addStartingWindow(@NonNull StartingWindowInfo info,
101             @NonNull IBinder appToken) {}
102 
103     /**
104      * Called when the Task want to remove the starting window.
105      * @param removalInfo The information used to remove the starting window.
106      * @hide
107      */
108     @BinderThread
removeStartingWindow(@onNull StartingWindowRemovalInfo removalInfo)109     public void removeStartingWindow(@NonNull StartingWindowRemovalInfo removalInfo) {}
110 
111     /**
112      * Called when the Task want to copy the splash screen.
113      */
114     @BinderThread
copySplashScreenView(int taskId)115     public void copySplashScreenView(int taskId) {}
116 
117     /**
118      * Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
119      * removed the splash screen view.
120      * @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
121      * @see SplashScreenView#remove()
122      */
123     @BinderThread
onAppSplashScreenViewRemoved(int taskId)124     public void onAppSplashScreenViewRemoved(int taskId) {
125     }
126 
127     /**
128      * Called when a task with the registered windowing mode can be controlled by this task
129      * organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
130      * to show this task.
131      */
132     @BinderThread
onTaskAppeared(@onNull ActivityManager.RunningTaskInfo taskInfo, @NonNull SurfaceControl leash)133     public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo,
134             @NonNull SurfaceControl leash) {}
135 
136     @BinderThread
onTaskVanished(@onNull ActivityManager.RunningTaskInfo taskInfo)137     public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
138 
139     @BinderThread
onTaskInfoChanged(@onNull ActivityManager.RunningTaskInfo taskInfo)140     public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
141 
142     @BinderThread
onBackPressedOnTaskRoot(@onNull ActivityManager.RunningTaskInfo taskInfo)143     public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
144 
145     /** @hide */
146     @BinderThread
onImeDrawnOnTask(int taskId)147     public void onImeDrawnOnTask(int taskId) {}
148 
149     /**
150      * Creates a persistent root task in WM for a particular windowing-mode.
151      * @param displayId The display to create the root task on.
152      * @param windowingMode Windowing mode to put the root task in.
153      * @param launchCookie Launch cookie to associate with the task so that is can be identified
154      *                     when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
155      * @param removeWithTaskOrganizer True if this task should be removed when organizer destroyed.
156      * @hide
157      */
158     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie, boolean removeWithTaskOrganizer)159     public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie,
160             boolean removeWithTaskOrganizer) {
161         try {
162             mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie,
163                     removeWithTaskOrganizer);
164         } catch (RemoteException e) {
165             throw e.rethrowFromSystemServer();
166         }
167     }
168 
169     /**
170      * Creates a persistent root task in WM for a particular windowing-mode.
171      * @param displayId The display to create the root task on.
172      * @param windowingMode Windowing mode to put the root task in.
173      * @param launchCookie Launch cookie to associate with the task so that is can be identified
174      *                     when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
175      */
176     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
177     @Nullable
createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie)178     public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
179         createRootTask(displayId, windowingMode, launchCookie, false /* removeWithTaskOrganizer */);
180     }
181 
182     /** Deletes a persistent root task in WM */
183     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
deleteRootTask(@onNull WindowContainerToken task)184     public boolean deleteRootTask(@NonNull WindowContainerToken task) {
185         try {
186             return mTaskOrganizerController.deleteRootTask(task);
187         } catch (RemoteException e) {
188             throw e.rethrowFromSystemServer();
189         }
190     }
191 
192     /** Gets direct child tasks (ordered from top-to-bottom) */
193     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
194     @Nullable
195     @SuppressLint("NullableCollection")
getChildTasks( @onNull WindowContainerToken parent, @NonNull int[] activityTypes)196     public List<ActivityManager.RunningTaskInfo> getChildTasks(
197             @NonNull WindowContainerToken parent, @NonNull int[] activityTypes) {
198         try {
199             return mTaskOrganizerController.getChildTasks(parent, activityTypes);
200         } catch (RemoteException e) {
201             throw e.rethrowFromSystemServer();
202         }
203     }
204 
205     /** Gets all root tasks on a display (ordered from top-to-bottom) */
206     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
207     @Nullable
208     @SuppressLint("NullableCollection")
getRootTasks( int displayId, @NonNull int[] activityTypes)209     public List<ActivityManager.RunningTaskInfo> getRootTasks(
210             int displayId, @NonNull int[] activityTypes) {
211         try {
212             return mTaskOrganizerController.getRootTasks(displayId, activityTypes);
213         } catch (RemoteException e) {
214             throw e.rethrowFromSystemServer();
215         }
216     }
217 
218     /** Get the {@link WindowContainerToken} of the task which contains the current ime target */
219     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
220     @Nullable
getImeTarget(int display)221     public WindowContainerToken getImeTarget(int display) {
222         try {
223             return mTaskOrganizerController.getImeTarget(display);
224         } catch (RemoteException e) {
225             throw e.rethrowFromSystemServer();
226         }
227     }
228 
229     /**
230      * Requests that the given task organizer is notified when back is pressed on the root activity
231      * of one of its controlled tasks.
232      */
233     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
setInterceptBackPressedOnTaskRoot(@onNull WindowContainerToken task, boolean interceptBackPressed)234     public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task,
235             boolean interceptBackPressed) {
236         try {
237             mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(task, interceptBackPressed);
238         } catch (RemoteException e) {
239             throw e.rethrowFromSystemServer();
240         }
241     }
242 
243 
244     /**
245      * Restarts the top activity in the given task by killing its process if it is visible.
246      * @hide
247      */
248     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
restartTaskTopActivityProcessIfVisible(@onNull WindowContainerToken task)249     public void restartTaskTopActivityProcessIfVisible(@NonNull WindowContainerToken task) {
250         try {
251             mTaskOrganizerController.restartTaskTopActivityProcessIfVisible(task);
252         } catch (RemoteException e) {
253             throw e.rethrowFromSystemServer();
254         }
255     }
256 
257     /**
258      * Updates a state of camera compat control for stretched issues in the viewfinder.
259      * @hide
260      */
261     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
updateCameraCompatControlState(@onNull WindowContainerToken task, @CameraCompatControlState int state)262     public void updateCameraCompatControlState(@NonNull WindowContainerToken task,
263             @CameraCompatControlState int state) {
264         try {
265             mTaskOrganizerController.updateCameraCompatControlState(task, state);
266         } catch (RemoteException e) {
267             throw e.rethrowFromSystemServer();
268         }
269     }
270 
271     /**
272      * Controls whether ignore orientation request logic in {@link
273      * com.android.server.wm.DisplayArea} is disabled at runtime and how to optionally map some
274      * requested orientation to others.
275      *
276      * @param isIgnoreOrientationRequestDisabled when {@code true}, the system always ignores the
277      *           value of  {@link com.android.server.wm.DisplayArea#getIgnoreOrientationRequest}
278      *           and app requested orientation is respected.
279      * @param fromOrientations The orientations we want to map to the correspondent orientations
280      *                        in toOrientation.
281      * @param toOrientations The orientations we map to the ones in fromOrientations at the same
282      *                       index
283      * @hide
284      */
285     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled, @Nullable int[] fromOrientations, @Nullable int[] toOrientations)286     public void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
287             @Nullable int[] fromOrientations, @Nullable int[] toOrientations) {
288         try {
289             mTaskOrganizerController.setOrientationRequestPolicy(isIgnoreOrientationRequestDisabled,
290                     fromOrientations, toOrientations);
291         } catch (RemoteException e) {
292             throw e.rethrowFromSystemServer();
293         }
294     }
295 
296     /**
297      * Gets the executor to run callbacks on.
298      * @hide
299      */
300     @NonNull
getExecutor()301     public Executor getExecutor() {
302         return mExecutor;
303     }
304 
305     private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
306         @Override
307         public void addStartingWindow(StartingWindowInfo windowInfo,
308                 IBinder appToken) {
309             mExecutor.execute(() -> TaskOrganizer.this.addStartingWindow(windowInfo, appToken));
310         }
311 
312         @Override
313         public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) {
314             mExecutor.execute(() -> TaskOrganizer.this.removeStartingWindow(removalInfo));
315         }
316 
317         @Override
318         public void copySplashScreenView(int taskId)  {
319             mExecutor.execute(() -> TaskOrganizer.this.copySplashScreenView(taskId));
320         }
321 
322         @Override
323         public void onAppSplashScreenViewRemoved(int taskId) {
324             mExecutor.execute(() -> TaskOrganizer.this.onAppSplashScreenViewRemoved(taskId));
325         }
326 
327         @Override
328         public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
329             mExecutor.execute(() -> TaskOrganizer.this.onTaskAppeared(taskInfo, leash));
330         }
331 
332         @Override
333         public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
334             mExecutor.execute(() -> TaskOrganizer.this.onTaskVanished(taskInfo));
335         }
336 
337         @Override
338         public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
339             mExecutor.execute(() -> TaskOrganizer.this.onTaskInfoChanged(info));
340         }
341 
342         @Override
343         public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) {
344             mExecutor.execute(() -> TaskOrganizer.this.onBackPressedOnTaskRoot(info));
345         }
346 
347         @Override
348         public void onImeDrawnOnTask(int taskId) {
349             mExecutor.execute(() -> TaskOrganizer.this.onImeDrawnOnTask(taskId));
350         }
351     };
352 
353     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
getController()354     private ITaskOrganizerController getController() {
355         try {
356             return getWindowOrganizerController().getTaskOrganizerController();
357         } catch (RemoteException e) {
358             return null;
359         }
360     }
361 }
362