1 /*
2  * Copyright (C) 2016 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 com.android.server.wm;
18 
19 import android.app.ActivityManager;
20 import android.app.ActivityManager.RunningTaskInfo;
21 import android.app.ITaskStackListener;
22 import android.app.TaskInfo;
23 import android.app.TaskStackListener;
24 import android.content.ComponentName;
25 import android.os.Binder;
26 import android.os.Handler;
27 import android.os.Looper;
28 import android.os.Message;
29 import android.os.RemoteCallbackList;
30 import android.os.RemoteException;
31 import android.window.TaskSnapshot;
32 
33 import com.android.internal.annotations.GuardedBy;
34 import com.android.internal.os.SomeArgs;
35 
36 import java.util.ArrayList;
37 
38 class TaskChangeNotificationController {
39     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 2;
40     private static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 3;
41     private static final int NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 4;
42     private static final int NOTIFY_FORCED_RESIZABLE_MSG = 6;
43     private static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_ROOT_TASK_MSG = 7;
44     private static final int NOTIFY_TASK_ADDED_LISTENERS_MSG = 8;
45     private static final int NOTIFY_TASK_REMOVED_LISTENERS_MSG = 9;
46     private static final int NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG = 10;
47     private static final int NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG = 11;
48     private static final int NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS = 12;
49     private static final int NOTIFY_TASK_REMOVAL_STARTED_LISTENERS = 13;
50     private static final int NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG = 14;
51     private static final int NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG = 15;
52     private static final int NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG = 17;
53     private static final int NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG = 18;
54     private static final int NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG = 19;
55     private static final int NOTIFY_BACK_PRESSED_ON_TASK_ROOT = 20;
56     private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 21;
57     private static final int NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG = 22;
58     private static final int NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG = 23;
59     private static final int NOTIFY_TASK_FOCUS_CHANGED_MSG = 24;
60     private static final int NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG = 25;
61     private static final int NOTIFY_ACTIVITY_ROTATED_MSG = 26;
62     private static final int NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG = 27;
63     private static final int NOTIFY_LOCK_TASK_MODE_CHANGED_MSG = 28;
64 
65     // Delay in notifying task stack change listeners (in millis)
66     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
67 
68     private final ActivityTaskSupervisor mTaskSupervisor;
69     private final Handler mHandler;
70 
71     // Task stack change listeners in a remote process.
72     @GuardedBy("mRemoteTaskStackListeners")
73     private final RemoteCallbackList<ITaskStackListener> mRemoteTaskStackListeners =
74             new RemoteCallbackList<>();
75 
76     /*
77      * Task stack change listeners in a local process. Tracked separately so that they can be
78      * called on the same thread.
79      */
80     @GuardedBy("mLocalTaskStackListeners")
81     private final ArrayList<ITaskStackListener> mLocalTaskStackListeners = new ArrayList<>();
82 
83     private final TaskStackConsumer mNotifyTaskStackChanged = (l, m) -> {
84         l.onTaskStackChanged();
85     };
86 
87     private final TaskStackConsumer mNotifyTaskCreated = (l, m) -> {
88         l.onTaskCreated(m.arg1, (ComponentName) m.obj);
89     };
90 
91     private final TaskStackConsumer mNotifyTaskRemoved = (l, m) -> {
92         l.onTaskRemoved(m.arg1);
93     };
94 
95     private final TaskStackConsumer mNotifyTaskMovedToFront = (l, m) -> {
96         l.onTaskMovedToFront((RunningTaskInfo) m.obj);
97     };
98 
99     private final TaskStackConsumer mNotifyTaskDescriptionChanged = (l, m) -> {
100         l.onTaskDescriptionChanged((RunningTaskInfo) m.obj);
101     };
102 
103     private final TaskStackConsumer mNotifyBackPressedOnTaskRoot = (l, m) -> {
104         l.onBackPressedOnTaskRoot((RunningTaskInfo) m.obj);
105     };
106 
107     private final TaskStackConsumer mNotifyActivityRequestedOrientationChanged = (l, m) -> {
108         l.onActivityRequestedOrientationChanged(m.arg1, m.arg2);
109     };
110 
111     private final TaskStackConsumer mNotifyTaskRemovalStarted = (l, m) -> {
112         l.onTaskRemovalStarted((RunningTaskInfo) m.obj);
113     };
114 
115     private final TaskStackConsumer mNotifyActivityPinned = (l, m) -> {
116         l.onActivityPinned((String) m.obj /* packageName */, m.sendingUid /* userId */,
117                 m.arg1 /* taskId */, m.arg2 /* stackId */);
118     };
119 
120     private final TaskStackConsumer mNotifyActivityUnpinned = (l, m) -> {
121         l.onActivityUnpinned();
122     };
123 
124     private final TaskStackConsumer mNotifyActivityRestartAttempt = (l, m) -> {
125         SomeArgs args = (SomeArgs) m.obj;
126         l.onActivityRestartAttempt((RunningTaskInfo) args.arg1, args.argi1 != 0,
127                 args.argi2 != 0, args.argi3 != 0);
128     };
129 
130     private final TaskStackConsumer mNotifyActivityForcedResizable = (l, m) -> {
131         l.onActivityForcedResizable((String) m.obj, m.arg1, m.arg2);
132     };
133 
134     private final TaskStackConsumer mNotifyActivityDismissingDockedTask = (l, m) -> {
135         l.onActivityDismissingDockedTask();
136     };
137 
138     private final TaskStackConsumer mNotifyActivityLaunchOnSecondaryDisplayFailed = (l, m) -> {
139         l.onActivityLaunchOnSecondaryDisplayFailed((RunningTaskInfo) m.obj, m.arg1);
140     };
141 
142     private final TaskStackConsumer mNotifyActivityLaunchOnSecondaryDisplayRerouted = (l, m) -> {
143         l.onActivityLaunchOnSecondaryDisplayRerouted((RunningTaskInfo) m.obj, m.arg1);
144     };
145 
146     private final TaskStackConsumer mNotifyTaskProfileLocked = (l, m) -> {
147         l.onTaskProfileLocked((RunningTaskInfo) m.obj, m.arg1);
148     };
149 
150     private final TaskStackConsumer mNotifyTaskSnapshotChanged = (l, m) -> {
151         l.onTaskSnapshotChanged(m.arg1, (TaskSnapshot) m.obj);
152     };
153 
154     private final TaskStackConsumer mNotifyTaskDisplayChanged = (l, m) -> {
155         l.onTaskDisplayChanged(m.arg1, m.arg2);
156     };
157 
158     private final TaskStackConsumer mNotifyTaskListUpdated = (l, m) -> {
159         l.onRecentTaskListUpdated();
160     };
161 
162     private final TaskStackConsumer mNotifyTaskListFrozen = (l, m) -> {
163         l.onRecentTaskListFrozenChanged(m.arg1 != 0);
164     };
165 
166     private final TaskStackConsumer mNotifyTaskFocusChanged = (l, m) -> {
167         l.onTaskFocusChanged(m.arg1, m.arg2 != 0);
168     };
169 
170     private final TaskStackConsumer mNotifyTaskRequestedOrientationChanged = (l, m) -> {
171         l.onTaskRequestedOrientationChanged(m.arg1, m.arg2);
172     };
173 
174     private final TaskStackConsumer mNotifyOnActivityRotation = (l, m) -> {
175         l.onActivityRotation(m.arg1);
176     };
177 
178     private final TaskStackConsumer mNotifyTaskMovedToBack = (l, m) -> {
179         l.onTaskMovedToBack((RunningTaskInfo) m.obj);
180     };
181 
182     private final TaskStackConsumer mNotifyLockTaskModeChanged = (l, m) -> {
183         l.onLockTaskModeChanged(m.arg1);
184     };
185 
186     @FunctionalInterface
187     public interface TaskStackConsumer {
accept(ITaskStackListener t, Message m)188         void accept(ITaskStackListener t, Message m) throws RemoteException;
189     }
190 
191     private class MainHandler extends Handler {
MainHandler(Looper looper)192         public MainHandler(Looper looper) {
193             super(looper);
194         }
195 
196         @Override
handleMessage(Message msg)197         public void handleMessage(Message msg) {
198             switch (msg.what) {
199                 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG:
200                     forAllRemoteListeners(mNotifyTaskStackChanged, msg);
201                     break;
202                 case NOTIFY_TASK_ADDED_LISTENERS_MSG:
203                     forAllRemoteListeners(mNotifyTaskCreated, msg);
204                     break;
205                 case NOTIFY_TASK_REMOVED_LISTENERS_MSG:
206                     forAllRemoteListeners(mNotifyTaskRemoved, msg);
207                     break;
208                 case NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG:
209                     forAllRemoteListeners(mNotifyTaskMovedToFront, msg);
210                     break;
211                 case NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG:
212                     forAllRemoteListeners(mNotifyTaskDescriptionChanged, msg);
213                     break;
214                 case NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS:
215                     forAllRemoteListeners(mNotifyActivityRequestedOrientationChanged, msg);
216                     break;
217                 case NOTIFY_TASK_REMOVAL_STARTED_LISTENERS:
218                     forAllRemoteListeners(mNotifyTaskRemovalStarted, msg);
219                     break;
220                 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG:
221                     forAllRemoteListeners(mNotifyActivityPinned, msg);
222                     break;
223                 case NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG:
224                     forAllRemoteListeners(mNotifyActivityUnpinned, msg);
225                     break;
226                 case NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG:
227                     forAllRemoteListeners(mNotifyActivityRestartAttempt, msg);
228                     break;
229                 case NOTIFY_FORCED_RESIZABLE_MSG:
230                     forAllRemoteListeners(mNotifyActivityForcedResizable, msg);
231                     break;
232                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_ROOT_TASK_MSG:
233                     forAllRemoteListeners(mNotifyActivityDismissingDockedTask, msg);
234                     break;
235                 case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG:
236                     forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
237                     break;
238                 case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG:
239                     forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayRerouted, msg);
240                     break;
241                 case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
242                     forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
243                     break;
244                 case NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG:
245                     forAllRemoteListeners(mNotifyTaskSnapshotChanged, msg);
246                     break;
247                 case NOTIFY_BACK_PRESSED_ON_TASK_ROOT:
248                     forAllRemoteListeners(mNotifyBackPressedOnTaskRoot, msg);
249                     break;
250                 case NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG:
251                     forAllRemoteListeners(mNotifyTaskDisplayChanged, msg);
252                     break;
253                 case NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG:
254                     forAllRemoteListeners(mNotifyTaskListUpdated, msg);
255                     break;
256                 case NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG:
257                     forAllRemoteListeners(mNotifyTaskListFrozen, msg);
258                     break;
259                 case NOTIFY_TASK_FOCUS_CHANGED_MSG:
260                     forAllRemoteListeners(mNotifyTaskFocusChanged, msg);
261                     break;
262                 case NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG:
263                     forAllRemoteListeners(mNotifyTaskRequestedOrientationChanged, msg);
264                     break;
265                 case NOTIFY_ACTIVITY_ROTATED_MSG:
266                     forAllRemoteListeners(mNotifyOnActivityRotation, msg);
267                     break;
268                 case NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG:
269                     forAllRemoteListeners(mNotifyTaskMovedToBack, msg);
270                     break;
271                 case NOTIFY_LOCK_TASK_MODE_CHANGED_MSG:
272                     forAllRemoteListeners(mNotifyLockTaskModeChanged, msg);
273                     break;
274             }
275             if (msg.obj instanceof SomeArgs) {
276                 ((SomeArgs) msg.obj).recycle();
277             }
278         }
279     }
280 
TaskChangeNotificationController(ActivityTaskSupervisor taskSupervisor, Handler handler)281     TaskChangeNotificationController(ActivityTaskSupervisor taskSupervisor, Handler handler) {
282         mTaskSupervisor = taskSupervisor;
283         mHandler = new MainHandler(handler.getLooper());
284     }
285 
registerTaskStackListener(ITaskStackListener listener)286     public void registerTaskStackListener(ITaskStackListener listener) {
287         if (listener instanceof Binder) {
288             synchronized (mLocalTaskStackListeners) {
289                 if (!mLocalTaskStackListeners.contains(listener)) {
290                     if (listener instanceof TaskStackListener) {
291                         ((TaskStackListener) listener).setIsLocal();
292                     }
293                     mLocalTaskStackListeners.add(listener);
294                 }
295             }
296         } else if (listener != null) {
297             synchronized (mRemoteTaskStackListeners) {
298                 mRemoteTaskStackListeners.register(listener);
299             }
300         }
301     }
302 
unregisterTaskStackListener(ITaskStackListener listener)303     public void unregisterTaskStackListener(ITaskStackListener listener) {
304         if (listener instanceof Binder) {
305             synchronized (mLocalTaskStackListeners) {
306                 mLocalTaskStackListeners.remove(listener);
307             }
308         } else if (listener != null) {
309             synchronized (mRemoteTaskStackListeners) {
310                 mRemoteTaskStackListeners.unregister(listener);
311             }
312         }
313     }
314 
forAllRemoteListeners(TaskStackConsumer callback, Message message)315     private void forAllRemoteListeners(TaskStackConsumer callback, Message message) {
316         synchronized (mRemoteTaskStackListeners) {
317             for (int i = mRemoteTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
318                 try {
319                     // Make a one-way callback to the listener
320                     callback.accept(mRemoteTaskStackListeners.getBroadcastItem(i), message);
321                 } catch (RemoteException e) {
322                     // Handled by the RemoteCallbackList.
323                 }
324             }
325             mRemoteTaskStackListeners.finishBroadcast();
326         }
327     }
328 
forAllLocalListeners(TaskStackConsumer callback, Message message)329     private void forAllLocalListeners(TaskStackConsumer callback, Message message) {
330         synchronized (mLocalTaskStackListeners) {
331             for (int i = mLocalTaskStackListeners.size() - 1; i >= 0; i--) {
332                 try {
333                     callback.accept(mLocalTaskStackListeners.get(i), message);
334                 } catch (RemoteException e) {
335                     // Never thrown since this is called locally.
336                 }
337             }
338         }
339     }
340 
341     /** Notifies all listeners when the task stack has changed. */
notifyTaskStackChanged()342     void notifyTaskStackChanged() {
343         mTaskSupervisor.getActivityMetricsLogger().logWindowState();
344         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
345         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
346         forAllLocalListeners(mNotifyTaskStackChanged, msg);
347         // Only the main task stack change notification requires a delay.
348         mHandler.sendMessageDelayed(msg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
349     }
350 
351     /** Notifies all listeners when an Activity is pinned. */
notifyActivityPinned(ActivityRecord r)352     void notifyActivityPinned(ActivityRecord r) {
353         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
354         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG,
355                 r.getTask().mTaskId, r.getRootTaskId(), r.packageName);
356         msg.sendingUid = r.mUserId;
357         forAllLocalListeners(mNotifyActivityPinned, msg);
358         msg.sendToTarget();
359     }
360 
361     /** Notifies all listeners when an Activity is unpinned. */
notifyActivityUnpinned()362     void notifyActivityUnpinned() {
363         mHandler.removeMessages(NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG);
364         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG);
365         forAllLocalListeners(mNotifyActivityUnpinned, msg);
366         msg.sendToTarget();
367     }
368 
369     /**
370      * Notifies all listeners when an attempt was made to start an an activity that is already
371      * running, but the task is either brought to the front or a new Intent is delivered to it.
372      */
notifyActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible)373     void notifyActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
374             boolean clearedTask, boolean wasVisible) {
375         mHandler.removeMessages(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
376         final SomeArgs args = SomeArgs.obtain();
377         args.arg1 = task;
378         args.argi1 = homeTaskVisible ? 1 : 0;
379         args.argi2 = clearedTask ? 1 : 0;
380         args.argi3 = wasVisible ? 1 : 0;
381         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG,
382                         args);
383         forAllLocalListeners(mNotifyActivityRestartAttempt, msg);
384         msg.sendToTarget();
385     }
386 
notifyActivityDismissingDockedRootTask()387     void notifyActivityDismissingDockedRootTask() {
388         mHandler.removeMessages(NOTIFY_ACTIVITY_DISMISSING_DOCKED_ROOT_TASK_MSG);
389         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_ROOT_TASK_MSG);
390         forAllLocalListeners(mNotifyActivityDismissingDockedTask, msg);
391         msg.sendToTarget();
392     }
393 
notifyActivityForcedResizable(int taskId, int reason, String packageName)394     void notifyActivityForcedResizable(int taskId, int reason, String packageName) {
395         mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
396         final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId, reason,
397                 packageName);
398         forAllLocalListeners(mNotifyActivityForcedResizable, msg);
399         msg.sendToTarget();
400     }
401 
notifyActivityLaunchOnSecondaryDisplayFailed(TaskInfo ti, int requestedDisplayId)402     void notifyActivityLaunchOnSecondaryDisplayFailed(TaskInfo ti, int requestedDisplayId) {
403         mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG);
404         final Message msg = mHandler.obtainMessage(
405                 NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG, requestedDisplayId,
406                 0 /* unused */, ti);
407         forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
408         msg.sendToTarget();
409     }
410 
notifyActivityLaunchOnSecondaryDisplayRerouted(TaskInfo ti, int requestedDisplayId)411     void notifyActivityLaunchOnSecondaryDisplayRerouted(TaskInfo ti, int requestedDisplayId) {
412         mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG);
413         final Message msg = mHandler.obtainMessage(
414                 NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG, requestedDisplayId,
415                 0 /* unused */, ti);
416         forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayRerouted, msg);
417         msg.sendToTarget();
418     }
419 
notifyTaskCreated(int taskId, ComponentName componentName)420     void notifyTaskCreated(int taskId, ComponentName componentName) {
421         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
422                 taskId, 0 /* unused */, componentName);
423         forAllLocalListeners(mNotifyTaskCreated, msg);
424         msg.sendToTarget();
425     }
426 
notifyTaskRemoved(int taskId)427     void notifyTaskRemoved(int taskId) {
428         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVED_LISTENERS_MSG,
429                 taskId, 0 /* unused */);
430         forAllLocalListeners(mNotifyTaskRemoved, msg);
431         msg.sendToTarget();
432     }
433 
notifyTaskMovedToFront(TaskInfo ti)434     void notifyTaskMovedToFront(TaskInfo ti) {
435         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG, ti);
436         forAllLocalListeners(mNotifyTaskMovedToFront, msg);
437         msg.sendToTarget();
438     }
439 
notifyTaskDescriptionChanged(TaskInfo taskInfo)440     void notifyTaskDescriptionChanged(TaskInfo taskInfo) {
441         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG,
442                 taskInfo);
443         forAllLocalListeners(mNotifyTaskDescriptionChanged, msg);
444         msg.sendToTarget();
445 
446     }
447 
notifyActivityRequestedOrientationChanged(int taskId, int orientation)448     void notifyActivityRequestedOrientationChanged(int taskId, int orientation) {
449         final Message msg = mHandler.obtainMessage(
450                 NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS, taskId, orientation);
451         forAllLocalListeners(mNotifyActivityRequestedOrientationChanged, msg);
452         msg.sendToTarget();
453     }
454 
455     /**
456      * Notify listeners that the task is about to be finished before its surfaces are removed from
457      * the window manager. This allows interested parties to perform relevant animations before
458      * the window disappears.
459      */
notifyTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo)460     void notifyTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo) {
461         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskInfo);
462         forAllLocalListeners(mNotifyTaskRemovalStarted, msg);
463         msg.sendToTarget();
464     }
465 
466     /**
467      * Notify listeners that the task has been put in a locked state because one or more of the
468      * activities inside it belong to a managed profile user that has been locked.
469      */
notifyTaskProfileLocked(RunningTaskInfo taskInfo, int userId)470     void notifyTaskProfileLocked(RunningTaskInfo taskInfo, int userId) {
471         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG,
472                 userId, 0, taskInfo);
473         forAllLocalListeners(mNotifyTaskProfileLocked, msg);
474         msg.sendToTarget();
475     }
476 
477     /**
478      * Notify listeners that the snapshot of a task has changed.
479      */
notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot)480     void notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) {
481         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG,
482                 taskId, 0, snapshot);
483         forAllLocalListeners(mNotifyTaskSnapshotChanged, msg);
484         msg.sendToTarget();
485     }
486 
487     /**
488      * Notify listeners that an activity received a back press when there are no other activities
489      * in the back stack.
490      */
notifyBackPressedOnTaskRoot(TaskInfo taskInfo)491     void notifyBackPressedOnTaskRoot(TaskInfo taskInfo) {
492         final Message msg = mHandler.obtainMessage(NOTIFY_BACK_PRESSED_ON_TASK_ROOT,
493                 taskInfo);
494         forAllLocalListeners(mNotifyBackPressedOnTaskRoot, msg);
495         msg.sendToTarget();
496     }
497 
498     /**
499      * Notify listeners that a task is reparented to another display.
500      */
notifyTaskDisplayChanged(int taskId, int newDisplayId)501     void notifyTaskDisplayChanged(int taskId, int newDisplayId) {
502         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG,
503                 taskId, newDisplayId);
504         forAllLocalListeners(mNotifyTaskDisplayChanged, msg);
505         msg.sendToTarget();
506     }
507 
508     /**
509      * Called when any additions or deletions to the recent tasks list have been made.
510      */
notifyTaskListUpdated()511     void notifyTaskListUpdated() {
512         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG);
513         forAllLocalListeners(mNotifyTaskListUpdated, msg);
514         msg.sendToTarget();
515     }
516 
517     /** @see ITaskStackListener#onRecentTaskListFrozenChanged(boolean) */
notifyTaskListFrozen(boolean frozen)518     void notifyTaskListFrozen(boolean frozen) {
519         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG,
520                 frozen ? 1 : 0, 0 /* unused */);
521         forAllLocalListeners(mNotifyTaskListFrozen, msg);
522         msg.sendToTarget();
523     }
524 
525     /** @see ITaskStackListener#onTaskFocusChanged(int, boolean) */
notifyTaskFocusChanged(int taskId, boolean focused)526     void notifyTaskFocusChanged(int taskId, boolean focused) {
527         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_FOCUS_CHANGED_MSG,
528                 taskId, focused ? 1 : 0);
529         forAllLocalListeners(mNotifyTaskFocusChanged, msg);
530         msg.sendToTarget();
531     }
532 
533     /** @see android.app.ITaskStackListener#onTaskRequestedOrientationChanged(int, int) */
notifyTaskRequestedOrientationChanged(int taskId, int requestedOrientation)534     void notifyTaskRequestedOrientationChanged(int taskId, int requestedOrientation) {
535         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG,
536                 taskId, requestedOrientation);
537         forAllLocalListeners(mNotifyTaskRequestedOrientationChanged, msg);
538         msg.sendToTarget();
539     }
540 
541     /** @see android.app.ITaskStackListener#onActivityRotation(int) */
notifyOnActivityRotation(int displayId)542     void notifyOnActivityRotation(int displayId) {
543         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_ROTATED_MSG,
544                 displayId, 0 /* unused */);
545         forAllLocalListeners(mNotifyOnActivityRotation, msg);
546         msg.sendToTarget();
547     }
548 
549     /**
550      * Notify that a task is being moved behind home.
551      */
notifyTaskMovedToBack(TaskInfo ti)552     void notifyTaskMovedToBack(TaskInfo ti) {
553         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG, ti);
554         forAllLocalListeners(mNotifyTaskMovedToBack, msg);
555         msg.sendToTarget();
556     }
557 
notifyLockTaskModeChanged(int lockTaskModeState)558     void notifyLockTaskModeChanged(int lockTaskModeState) {
559         final Message msg = mHandler.obtainMessage(NOTIFY_LOCK_TASK_MODE_CHANGED_MSG,
560                 lockTaskModeState, 0 /* unused */);
561         forAllLocalListeners(mNotifyLockTaskModeChanged, msg);
562         msg.sendToTarget();
563     }
564 }
565