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.ActivityManager.TaskSnapshot;
22 import android.app.ITaskStackListener;
23 import android.app.TaskInfo;
24 import android.content.ComponentName;
25 import android.os.Binder;
26 import android.os.Handler;
27 import android.os.IBinder;
28 import android.os.Looper;
29 import android.os.Message;
30 import android.os.RemoteCallbackList;
31 import android.os.RemoteException;
32 
33 import com.android.internal.os.SomeArgs;
34 
35 import java.util.ArrayList;
36 
37 class TaskChangeNotificationController {
38     private static final int LOG_STACK_STATE_MSG = 1;
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_STACK_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_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG = 20;
56     private static final int NOTIFY_BACK_PRESSED_ON_TASK_ROOT = 21;
57     private static final int NOTIFY_SINGLE_TASK_DISPLAY_DRAWN = 22;
58     private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 23;
59     private static final int NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG = 24;
60     private static final int NOTIFY_SINGLE_TASK_DISPLAY_EMPTY = 25;
61     private static final int NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG = 26;
62     private static final int NOTIFY_TASK_FOCUS_CHANGED_MSG = 27;
63     private static final int NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG = 28;
64     private static final int NOTIFY_ACTIVITY_ROTATED_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     // Global lock used by the service the instantiate objects of this class.
70     private final Object mServiceLock;
71     private final ActivityStackSupervisor mStackSupervisor;
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     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 mNotifyActivityDismissingDockedStack = (l, m) -> {
136         l.onActivityDismissingDockedStack();
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(m.arg1, m.arg2);
149     };
150 
151     private final TaskStackConsumer mNotifyTaskSnapshotChanged = (l, m) -> {
152         l.onTaskSnapshotChanged(m.arg1, (TaskSnapshot) m.obj);
153     };
154 
155     private final TaskStackConsumer mOnSizeCompatModeActivityChanged = (l, m) -> {
156         l.onSizeCompatModeActivityChanged(m.arg1, (IBinder) m.obj);
157     };
158 
159     private final TaskStackConsumer mNotifySingleTaskDisplayDrawn = (l, m) -> {
160         l.onSingleTaskDisplayDrawn(m.arg1);
161     };
162 
163     private final TaskStackConsumer mNotifySingleTaskDisplayEmpty = (l, m) -> {
164         l.onSingleTaskDisplayEmpty(m.arg1);
165     };
166 
167     private final TaskStackConsumer mNotifyTaskDisplayChanged = (l, m) -> {
168         l.onTaskDisplayChanged(m.arg1, m.arg2);
169     };
170 
171     private final TaskStackConsumer mNotifyTaskListUpdated = (l, m) -> {
172         l.onRecentTaskListUpdated();
173     };
174 
175     private final TaskStackConsumer mNotifyTaskListFrozen = (l, m) -> {
176         l.onRecentTaskListFrozenChanged(m.arg1 != 0);
177     };
178 
179     private final TaskStackConsumer mNotifyTaskFocusChanged = (l, m) -> {
180         l.onTaskFocusChanged(m.arg1, m.arg2 != 0);
181     };
182 
183     private final TaskStackConsumer mNotifyTaskRequestedOrientationChanged = (l, m) -> {
184         l.onTaskRequestedOrientationChanged(m.arg1, m.arg2);
185     };
186 
187     private final TaskStackConsumer mNotifyOnActivityRotation = (l, m) -> {
188         l.onActivityRotation(m.arg1);
189     };
190 
191     @FunctionalInterface
192     public interface TaskStackConsumer {
accept(ITaskStackListener t, Message m)193         void accept(ITaskStackListener t, Message m) throws RemoteException;
194     }
195 
196     private class MainHandler extends Handler {
MainHandler(Looper looper)197         public MainHandler(Looper looper) {
198             super(looper);
199         }
200 
201         @Override
handleMessage(Message msg)202         public void handleMessage(Message msg) {
203             switch (msg.what) {
204                 case LOG_STACK_STATE_MSG: {
205                     synchronized (mServiceLock) {
206                         mStackSupervisor.logStackState();
207                     }
208                     break;
209                 }
210                 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG:
211                     forAllRemoteListeners(mNotifyTaskStackChanged, msg);
212                     break;
213                 case NOTIFY_TASK_ADDED_LISTENERS_MSG:
214                     forAllRemoteListeners(mNotifyTaskCreated, msg);
215                     break;
216                 case NOTIFY_TASK_REMOVED_LISTENERS_MSG:
217                     forAllRemoteListeners(mNotifyTaskRemoved, msg);
218                     break;
219                 case NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG:
220                     forAllRemoteListeners(mNotifyTaskMovedToFront, msg);
221                     break;
222                 case NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG:
223                     forAllRemoteListeners(mNotifyTaskDescriptionChanged, msg);
224                     break;
225                 case NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS:
226                     forAllRemoteListeners(mNotifyActivityRequestedOrientationChanged, msg);
227                     break;
228                 case NOTIFY_TASK_REMOVAL_STARTED_LISTENERS:
229                     forAllRemoteListeners(mNotifyTaskRemovalStarted, msg);
230                     break;
231                 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG:
232                     forAllRemoteListeners(mNotifyActivityPinned, msg);
233                     break;
234                 case NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG:
235                     forAllRemoteListeners(mNotifyActivityUnpinned, msg);
236                     break;
237                 case NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG:
238                     forAllRemoteListeners(mNotifyActivityRestartAttempt, msg);
239                     break;
240                 case NOTIFY_FORCED_RESIZABLE_MSG:
241                     forAllRemoteListeners(mNotifyActivityForcedResizable, msg);
242                     break;
243                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
244                     forAllRemoteListeners(mNotifyActivityDismissingDockedStack, msg);
245                     break;
246                 case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG:
247                     forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
248                     break;
249                 case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG:
250                     forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayRerouted, msg);
251                     break;
252                 case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
253                     forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
254                     break;
255                 case NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG:
256                     forAllRemoteListeners(mNotifyTaskSnapshotChanged, msg);
257                     break;
258                 case NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG:
259                     forAllRemoteListeners(mOnSizeCompatModeActivityChanged, msg);
260                     break;
261                 case NOTIFY_BACK_PRESSED_ON_TASK_ROOT:
262                     forAllRemoteListeners(mNotifyBackPressedOnTaskRoot, msg);
263                     break;
264                 case NOTIFY_SINGLE_TASK_DISPLAY_DRAWN:
265                     forAllRemoteListeners(mNotifySingleTaskDisplayDrawn, msg);
266                     break;
267                 case NOTIFY_SINGLE_TASK_DISPLAY_EMPTY:
268                     forAllRemoteListeners(mNotifySingleTaskDisplayEmpty, msg);
269                     break;
270                 case NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG:
271                     forAllRemoteListeners(mNotifyTaskDisplayChanged, msg);
272                     break;
273                 case NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG:
274                     forAllRemoteListeners(mNotifyTaskListUpdated, msg);
275                     break;
276                 case NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG:
277                     forAllRemoteListeners(mNotifyTaskListFrozen, msg);
278                     break;
279                 case NOTIFY_TASK_FOCUS_CHANGED_MSG:
280                     forAllRemoteListeners(mNotifyTaskFocusChanged, msg);
281                     break;
282                 case NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG:
283                     forAllRemoteListeners(mNotifyTaskRequestedOrientationChanged, msg);
284                     break;
285                 case NOTIFY_ACTIVITY_ROTATED_MSG:
286                     forAllRemoteListeners(mNotifyOnActivityRotation, msg);
287                     break;
288             }
289             if (msg.obj instanceof SomeArgs) {
290                 ((SomeArgs) msg.obj).recycle();
291             }
292         }
293     }
294 
TaskChangeNotificationController(Object serviceLock, ActivityStackSupervisor stackSupervisor, Handler handler)295     public TaskChangeNotificationController(Object serviceLock,
296             ActivityStackSupervisor stackSupervisor, Handler handler) {
297         mServiceLock = serviceLock;
298         mStackSupervisor = stackSupervisor;
299         mHandler = new MainHandler(handler.getLooper());
300     }
301 
registerTaskStackListener(ITaskStackListener listener)302     public void registerTaskStackListener(ITaskStackListener listener) {
303         synchronized (mServiceLock) {
304             if (listener != null) {
305                 if (Binder.getCallingPid() == android.os.Process.myPid()) {
306                     if (!mLocalTaskStackListeners.contains(listener)) {
307                         mLocalTaskStackListeners.add(listener);
308                     }
309                 } else {
310                     mRemoteTaskStackListeners.register(listener);
311                 }
312             }
313         }
314     }
315 
unregisterTaskStackListener(ITaskStackListener listener)316     public void unregisterTaskStackListener(ITaskStackListener listener) {
317         synchronized (mServiceLock) {
318             if (listener != null) {
319                 if (Binder.getCallingPid() == android.os.Process.myPid()) {
320                     mLocalTaskStackListeners.remove(listener);
321                 } else {
322                     mRemoteTaskStackListeners.unregister(listener);
323                 }
324             }
325         }
326     }
327 
forAllRemoteListeners(TaskStackConsumer callback, Message message)328     private void forAllRemoteListeners(TaskStackConsumer callback, Message message) {
329         synchronized (mServiceLock) {
330             for (int i = mRemoteTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
331                 try {
332                     // Make a one-way callback to the listener
333                     callback.accept(mRemoteTaskStackListeners.getBroadcastItem(i), message);
334                 } catch (RemoteException e) {
335                     // Handled by the RemoteCallbackList.
336                 }
337             }
338             mRemoteTaskStackListeners.finishBroadcast();
339         }
340     }
341 
forAllLocalListeners(TaskStackConsumer callback, Message message)342     private void forAllLocalListeners(TaskStackConsumer callback, Message message) {
343         synchronized (mServiceLock) {
344             for (int i = mLocalTaskStackListeners.size() - 1; i >= 0; i--) {
345                 try {
346                     callback.accept(mLocalTaskStackListeners.get(i), message);
347                 } catch (RemoteException e) {
348                     // Never thrown since this is called locally.
349                 }
350             }
351         }
352     }
353 
354     /** Notifies all listeners when the task stack has changed. */
notifyTaskStackChanged()355     void notifyTaskStackChanged() {
356         mHandler.sendEmptyMessage(LOG_STACK_STATE_MSG);
357         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
358         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
359         forAllLocalListeners(mNotifyTaskStackChanged, msg);
360         // Only the main task stack change notification requires a delay.
361         mHandler.sendMessageDelayed(msg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
362     }
363 
364     /** Notifies all listeners when an Activity is pinned. */
notifyActivityPinned(ActivityRecord r)365     void notifyActivityPinned(ActivityRecord r) {
366         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
367         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG,
368                 r.getTask().mTaskId, r.getRootTaskId(), r.packageName);
369         msg.sendingUid = r.mUserId;
370         forAllLocalListeners(mNotifyActivityPinned, msg);
371         msg.sendToTarget();
372     }
373 
374     /** Notifies all listeners when an Activity is unpinned. */
notifyActivityUnpinned()375     void notifyActivityUnpinned() {
376         mHandler.removeMessages(NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG);
377         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG);
378         forAllLocalListeners(mNotifyActivityUnpinned, msg);
379         msg.sendToTarget();
380     }
381 
382     /**
383      * Notifies all listeners when an attempt was made to start an an activity that is already
384      * running, but the task is either brought to the front or a new Intent is delivered to it.
385      */
notifyActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible)386     void notifyActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
387             boolean clearedTask, boolean wasVisible) {
388         mHandler.removeMessages(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
389         final SomeArgs args = SomeArgs.obtain();
390         args.arg1 = task;
391         args.argi1 = homeTaskVisible ? 1 : 0;
392         args.argi2 = clearedTask ? 1 : 0;
393         args.argi3 = wasVisible ? 1 : 0;
394         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG,
395                         args);
396         forAllLocalListeners(mNotifyActivityRestartAttempt, msg);
397         msg.sendToTarget();
398     }
399 
notifyActivityDismissingDockedStack()400     void notifyActivityDismissingDockedStack() {
401         mHandler.removeMessages(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
402         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
403         forAllLocalListeners(mNotifyActivityDismissingDockedStack, msg);
404         msg.sendToTarget();
405     }
406 
notifyActivityForcedResizable(int taskId, int reason, String packageName)407     void notifyActivityForcedResizable(int taskId, int reason, String packageName) {
408         mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
409         final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId, reason,
410                 packageName);
411         forAllLocalListeners(mNotifyActivityForcedResizable, msg);
412         msg.sendToTarget();
413     }
414 
notifyActivityLaunchOnSecondaryDisplayFailed(TaskInfo ti, int requestedDisplayId)415     void notifyActivityLaunchOnSecondaryDisplayFailed(TaskInfo ti, int requestedDisplayId) {
416         mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG);
417         final Message msg = mHandler.obtainMessage(
418                 NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG, requestedDisplayId,
419                 0 /* unused */, ti);
420         forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
421         msg.sendToTarget();
422     }
423 
notifyActivityLaunchOnSecondaryDisplayRerouted(TaskInfo ti, int requestedDisplayId)424     void notifyActivityLaunchOnSecondaryDisplayRerouted(TaskInfo ti, int requestedDisplayId) {
425         mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG);
426         final Message msg = mHandler.obtainMessage(
427                 NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG, requestedDisplayId,
428                 0 /* unused */, ti);
429         forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayRerouted, msg);
430         msg.sendToTarget();
431     }
432 
notifyTaskCreated(int taskId, ComponentName componentName)433     void notifyTaskCreated(int taskId, ComponentName componentName) {
434         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
435                 taskId, 0 /* unused */, componentName);
436         forAllLocalListeners(mNotifyTaskCreated, msg);
437         msg.sendToTarget();
438     }
439 
notifyTaskRemoved(int taskId)440     void notifyTaskRemoved(int taskId) {
441         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVED_LISTENERS_MSG,
442                 taskId, 0 /* unused */);
443         forAllLocalListeners(mNotifyTaskRemoved, msg);
444         msg.sendToTarget();
445     }
446 
notifyTaskMovedToFront(TaskInfo ti)447     void notifyTaskMovedToFront(TaskInfo ti) {
448         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG, ti);
449         forAllLocalListeners(mNotifyTaskMovedToFront, msg);
450         msg.sendToTarget();
451     }
452 
notifyTaskDescriptionChanged(TaskInfo taskInfo)453     void notifyTaskDescriptionChanged(TaskInfo taskInfo) {
454         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG,
455                 taskInfo);
456         forAllLocalListeners(mNotifyTaskDescriptionChanged, msg);
457         msg.sendToTarget();
458 
459     }
460 
notifyActivityRequestedOrientationChanged(int taskId, int orientation)461     void notifyActivityRequestedOrientationChanged(int taskId, int orientation) {
462         final Message msg = mHandler.obtainMessage(
463                 NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS, taskId, orientation);
464         forAllLocalListeners(mNotifyActivityRequestedOrientationChanged, msg);
465         msg.sendToTarget();
466     }
467 
468     /**
469      * Notify listeners that the task is about to be finished before its surfaces are removed from
470      * the window manager. This allows interested parties to perform relevant animations before
471      * the window disappears.
472      */
notifyTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo)473     void notifyTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo) {
474         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskInfo);
475         forAllLocalListeners(mNotifyTaskRemovalStarted, msg);
476         msg.sendToTarget();
477     }
478 
479     /**
480      * Notify listeners that the task has been put in a locked state because one or more of the
481      * activities inside it belong to a managed profile user that has been locked.
482      */
notifyTaskProfileLocked(int taskId, int userId)483     void notifyTaskProfileLocked(int taskId, int userId) {
484         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG, taskId,
485                 userId);
486         forAllLocalListeners(mNotifyTaskProfileLocked, msg);
487         msg.sendToTarget();
488     }
489 
490     /**
491      * Notify listeners that the snapshot of a task has changed.
492      */
notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot)493     void notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) {
494         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG,
495                 taskId, 0, snapshot);
496         forAllLocalListeners(mNotifyTaskSnapshotChanged, msg);
497         msg.sendToTarget();
498     }
499 
500     /**
501      * Notify listeners that whether a size compatibility mode activity is using the override
502      * bounds which is not fit its parent.
503      */
notifySizeCompatModeActivityChanged(int displayId, IBinder activityToken)504     void notifySizeCompatModeActivityChanged(int displayId, IBinder activityToken) {
505         final Message msg = mHandler.obtainMessage(NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG,
506                 displayId, 0 /* unused */, activityToken);
507         forAllLocalListeners(mOnSizeCompatModeActivityChanged, msg);
508         msg.sendToTarget();
509     }
510 
511     /**
512      * Notify listeners that an activity received a back press when there are no other activities
513      * in the back stack.
514      */
notifyBackPressedOnTaskRoot(TaskInfo taskInfo)515     void notifyBackPressedOnTaskRoot(TaskInfo taskInfo) {
516         final Message msg = mHandler.obtainMessage(NOTIFY_BACK_PRESSED_ON_TASK_ROOT,
517                 taskInfo);
518         forAllLocalListeners(mNotifyBackPressedOnTaskRoot, msg);
519         msg.sendToTarget();
520     }
521 
522     /**
523      * Notify listeners that contents are drawn for the first time on a single task display.
524      */
notifySingleTaskDisplayDrawn(int displayId)525     void notifySingleTaskDisplayDrawn(int displayId) {
526         final Message msg = mHandler.obtainMessage(NOTIFY_SINGLE_TASK_DISPLAY_DRAWN,
527                 displayId, 0 /* unused */);
528         forAllLocalListeners(mNotifySingleTaskDisplayDrawn, msg);
529         msg.sendToTarget();
530     }
531 
532     /**
533      * Notify listeners that the last task is removed from a single task display.
534      */
notifySingleTaskDisplayEmpty(int displayId)535     void notifySingleTaskDisplayEmpty(int displayId) {
536         final Message msg = mHandler.obtainMessage(
537                 NOTIFY_SINGLE_TASK_DISPLAY_EMPTY,
538                 displayId, 0 /* unused */);
539         forAllLocalListeners(mNotifySingleTaskDisplayEmpty, msg);
540         msg.sendToTarget();
541     }
542 
543     /**
544      * Notify listeners that a task is reparented to another display.
545      */
notifyTaskDisplayChanged(int taskId, int newDisplayId)546     void notifyTaskDisplayChanged(int taskId, int newDisplayId) {
547         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG,
548                 taskId, newDisplayId);
549         forAllLocalListeners(mNotifyTaskStackChanged, msg);
550         msg.sendToTarget();
551     }
552 
553     /**
554      * Called when any additions or deletions to the recent tasks list have been made.
555      */
notifyTaskListUpdated()556     void notifyTaskListUpdated() {
557         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG);
558         forAllLocalListeners(mNotifyTaskListUpdated, msg);
559         msg.sendToTarget();
560     }
561 
562     /** @see ITaskStackListener#onRecentTaskListFrozenChanged(boolean) */
notifyTaskListFrozen(boolean frozen)563     void notifyTaskListFrozen(boolean frozen) {
564         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG,
565                 frozen ? 1 : 0, 0 /* unused */);
566         forAllLocalListeners(mNotifyTaskListFrozen, msg);
567         msg.sendToTarget();
568     }
569 
570     /** @see ITaskStackListener#onTaskFocusChanged(int, boolean) */
notifyTaskFocusChanged(int taskId, boolean focused)571     void notifyTaskFocusChanged(int taskId, boolean focused) {
572         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_FOCUS_CHANGED_MSG,
573                 taskId, focused ? 1 : 0);
574         forAllLocalListeners(mNotifyTaskFocusChanged, msg);
575         msg.sendToTarget();
576     }
577 
578     /** @see android.app.ITaskStackListener#onTaskRequestedOrientationChanged(int, int) */
notifyTaskRequestedOrientationChanged(int taskId, int requestedOrientation)579     void notifyTaskRequestedOrientationChanged(int taskId, int requestedOrientation) {
580         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG,
581                 taskId, requestedOrientation);
582         forAllLocalListeners(mNotifyTaskRequestedOrientationChanged, msg);
583         msg.sendToTarget();
584     }
585 
586     /** @see android.app.ITaskStackListener#onActivityRotation(int) */
notifyOnActivityRotation(int displayId)587     void notifyOnActivityRotation(int displayId) {
588         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_ROTATED_MSG,
589                 displayId, 0 /* unused */);
590         forAllLocalListeners(mNotifyOnActivityRotation, msg);
591         msg.sendToTarget();
592     }
593 }
594