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