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