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 java.util.ArrayList;
34 
35 class TaskChangeNotificationController {
36     private static final int LOG_STACK_STATE_MSG = 1;
37     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 2;
38     private static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 3;
39     private static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 4;
40     private static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 5;
41     private static final int NOTIFY_FORCED_RESIZABLE_MSG = 6;
42     private static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 7;
43     private static final int NOTIFY_TASK_ADDED_LISTENERS_MSG = 8;
44     private static final int NOTIFY_TASK_REMOVED_LISTENERS_MSG = 9;
45     private static final int NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG = 10;
46     private static final int NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG = 11;
47     private static final int NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS = 12;
48     private static final int NOTIFY_TASK_REMOVAL_STARTED_LISTENERS = 13;
49     private static final int NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG = 14;
50     private static final int NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG = 15;
51     private static final int NOTIFY_PINNED_STACK_ANIMATION_STARTED_LISTENERS_MSG = 16;
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_SINGLE_TASK_DISPLAY_EMPTY = 23;
59     private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 24;
60 
61     // Delay in notifying task stack change listeners (in millis)
62     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
63 
64     // Global lock used by the service the instantiate objects of this class.
65     private final Object mServiceLock;
66     private final ActivityStackSupervisor mStackSupervisor;
67     private final Handler mHandler;
68 
69     // Task stack change listeners in a remote process.
70     private final RemoteCallbackList<ITaskStackListener> mRemoteTaskStackListeners =
71             new RemoteCallbackList<>();
72 
73     /*
74      * Task stack change listeners in a local process. Tracked separately so that they can be
75      * called on the same thread.
76      */
77     private final ArrayList<ITaskStackListener> mLocalTaskStackListeners = new ArrayList<>();
78 
79     private final TaskStackConsumer mNotifyTaskStackChanged = (l, m) -> {
80         l.onTaskStackChanged();
81     };
82 
83     private final TaskStackConsumer mNotifyTaskCreated = (l, m) -> {
84         l.onTaskCreated(m.arg1, (ComponentName) m.obj);
85     };
86 
87     private final TaskStackConsumer mNotifyTaskRemoved = (l, m) -> {
88         l.onTaskRemoved(m.arg1);
89     };
90 
91     private final TaskStackConsumer mNotifyTaskMovedToFront = (l, m) -> {
92         l.onTaskMovedToFront((RunningTaskInfo) m.obj);
93     };
94 
95     private final TaskStackConsumer mNotifyTaskDescriptionChanged = (l, m) -> {
96         l.onTaskDescriptionChanged((RunningTaskInfo) m.obj);
97     };
98 
99     private final TaskStackConsumer mNotifyBackPressedOnTaskRoot = (l, m) -> {
100         l.onBackPressedOnTaskRoot((RunningTaskInfo) m.obj);
101     };
102 
103     private final TaskStackConsumer mNotifyActivityRequestedOrientationChanged = (l, m) -> {
104         l.onActivityRequestedOrientationChanged(m.arg1, m.arg2);
105     };
106 
107     private final TaskStackConsumer mNotifyTaskRemovalStarted = (l, m) -> {
108         l.onTaskRemovalStarted((RunningTaskInfo) m.obj);
109     };
110 
111     private final TaskStackConsumer mNotifyActivityPinned = (l, m) -> {
112         l.onActivityPinned((String) m.obj /* packageName */, m.sendingUid /* userId */,
113                 m.arg1 /* taskId */, m.arg2 /* stackId */);
114     };
115 
116     private final TaskStackConsumer mNotifyActivityUnpinned = (l, m) -> {
117         l.onActivityUnpinned();
118     };
119 
120     private final TaskStackConsumer mNotifyPinnedActivityRestartAttempt = (l, m) -> {
121         l.onPinnedActivityRestartAttempt(m.arg1 != 0);
122     };
123 
124     private final TaskStackConsumer mNotifyPinnedStackAnimationStarted = (l, m) -> {
125         l.onPinnedStackAnimationStarted();
126     };
127 
128     private final TaskStackConsumer mNotifyPinnedStackAnimationEnded = (l, m) -> {
129         l.onPinnedStackAnimationEnded();
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 mNotifyActivityDismissingDockedStack = (l, m) -> {
137         l.onActivityDismissingDockedStack();
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(m.arg1, m.arg2);
150     };
151 
152     private final TaskStackConsumer mNotifyTaskSnapshotChanged = (l, m) -> {
153         l.onTaskSnapshotChanged(m.arg1, (TaskSnapshot) m.obj);
154     };
155 
156     private final TaskStackConsumer mOnSizeCompatModeActivityChanged = (l, m) -> {
157         l.onSizeCompatModeActivityChanged(m.arg1, (IBinder) m.obj);
158     };
159 
160     private final TaskStackConsumer mNotifySingleTaskDisplayDrawn = (l, m) -> {
161         l.onSingleTaskDisplayDrawn(m.arg1);
162     };
163 
164     private final TaskStackConsumer mNotifySingleTaskDisplayEmpty = (l, m) -> {
165         l.onSingleTaskDisplayEmpty(m.arg1);
166     };
167 
168     private final TaskStackConsumer mNotifyTaskDisplayChanged = (l, m) -> {
169         l.onTaskDisplayChanged(m.arg1, m.arg2);
170     };
171 
172     @FunctionalInterface
173     public interface TaskStackConsumer {
accept(ITaskStackListener t, Message m)174         void accept(ITaskStackListener t, Message m) throws RemoteException;
175     }
176 
177     private class MainHandler extends Handler {
MainHandler(Looper looper)178         public MainHandler(Looper looper) {
179             super(looper);
180         }
181 
182         @Override
handleMessage(Message msg)183         public void handleMessage(Message msg) {
184             switch (msg.what) {
185                 case LOG_STACK_STATE_MSG: {
186                     synchronized (mServiceLock) {
187                         mStackSupervisor.logStackState();
188                     }
189                     break;
190                 }
191                 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG:
192                     forAllRemoteListeners(mNotifyTaskStackChanged, msg);
193                     break;
194                 case NOTIFY_TASK_ADDED_LISTENERS_MSG:
195                     forAllRemoteListeners(mNotifyTaskCreated, msg);
196                     break;
197                 case NOTIFY_TASK_REMOVED_LISTENERS_MSG:
198                     forAllRemoteListeners(mNotifyTaskRemoved, msg);
199                     break;
200                 case NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG:
201                     forAllRemoteListeners(mNotifyTaskMovedToFront, msg);
202                     break;
203                 case NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG:
204                     forAllRemoteListeners(mNotifyTaskDescriptionChanged, msg);
205                     break;
206                 case NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS:
207                     forAllRemoteListeners(mNotifyActivityRequestedOrientationChanged, msg);
208                     break;
209                 case NOTIFY_TASK_REMOVAL_STARTED_LISTENERS:
210                     forAllRemoteListeners(mNotifyTaskRemovalStarted, msg);
211                     break;
212                 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG:
213                     forAllRemoteListeners(mNotifyActivityPinned, msg);
214                     break;
215                 case NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG:
216                     forAllRemoteListeners(mNotifyActivityUnpinned, msg);
217                     break;
218                 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG:
219                     forAllRemoteListeners(mNotifyPinnedActivityRestartAttempt, msg);
220                     break;
221                 case NOTIFY_PINNED_STACK_ANIMATION_STARTED_LISTENERS_MSG:
222                     forAllRemoteListeners(mNotifyPinnedStackAnimationStarted, msg);
223                     break;
224                 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG:
225                     forAllRemoteListeners(mNotifyPinnedStackAnimationEnded, msg);
226                     break;
227                 case NOTIFY_FORCED_RESIZABLE_MSG:
228                     forAllRemoteListeners(mNotifyActivityForcedResizable, msg);
229                     break;
230                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
231                     forAllRemoteListeners(mNotifyActivityDismissingDockedStack, msg);
232                     break;
233                 case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG:
234                     forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
235                     break;
236                 case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG:
237                     forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayRerouted, msg);
238                     break;
239                 case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
240                     forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
241                     break;
242                 case NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG:
243                     forAllRemoteListeners(mNotifyTaskSnapshotChanged, msg);
244                     break;
245                 case NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG:
246                     forAllRemoteListeners(mOnSizeCompatModeActivityChanged, msg);
247                     break;
248                 case NOTIFY_BACK_PRESSED_ON_TASK_ROOT:
249                     forAllRemoteListeners(mNotifyBackPressedOnTaskRoot, msg);
250                     break;
251                 case NOTIFY_SINGLE_TASK_DISPLAY_DRAWN:
252                     forAllRemoteListeners(mNotifySingleTaskDisplayDrawn, msg);
253                     break;
254                 case NOTIFY_SINGLE_TASK_DISPLAY_EMPTY:
255                     forAllRemoteListeners(mNotifySingleTaskDisplayEmpty, msg);
256                     break;
257                 case NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG:
258                     forAllRemoteListeners(mNotifyTaskDisplayChanged, msg);
259                     break;
260             }
261         }
262     }
263 
TaskChangeNotificationController(Object serviceLock, ActivityStackSupervisor stackSupervisor, Handler handler)264     public TaskChangeNotificationController(Object serviceLock,
265             ActivityStackSupervisor stackSupervisor, Handler handler) {
266         mServiceLock = serviceLock;
267         mStackSupervisor = stackSupervisor;
268         mHandler = new MainHandler(handler.getLooper());
269     }
270 
registerTaskStackListener(ITaskStackListener listener)271     public void registerTaskStackListener(ITaskStackListener listener) {
272         synchronized (mServiceLock) {
273             if (listener != null) {
274                 if (Binder.getCallingPid() == android.os.Process.myPid()) {
275                     if (!mLocalTaskStackListeners.contains(listener)) {
276                         mLocalTaskStackListeners.add(listener);
277                     }
278                 } else {
279                     mRemoteTaskStackListeners.register(listener);
280                 }
281             }
282         }
283     }
284 
unregisterTaskStackListener(ITaskStackListener listener)285     public void unregisterTaskStackListener(ITaskStackListener listener) {
286         synchronized (mServiceLock) {
287             if (listener != null) {
288                 if (Binder.getCallingPid() == android.os.Process.myPid()) {
289                     mLocalTaskStackListeners.remove(listener);
290                 } else {
291                     mRemoteTaskStackListeners.unregister(listener);
292                 }
293             }
294         }
295     }
296 
forAllRemoteListeners(TaskStackConsumer callback, Message message)297     private void forAllRemoteListeners(TaskStackConsumer callback, Message message) {
298         synchronized (mServiceLock) {
299             for (int i = mRemoteTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
300                 try {
301                     // Make a one-way callback to the listener
302                     callback.accept(mRemoteTaskStackListeners.getBroadcastItem(i), message);
303                 } catch (RemoteException e) {
304                     // Handled by the RemoteCallbackList.
305                 }
306             }
307             mRemoteTaskStackListeners.finishBroadcast();
308         }
309     }
310 
forAllLocalListeners(TaskStackConsumer callback, Message message)311     private void forAllLocalListeners(TaskStackConsumer callback, Message message) {
312         synchronized (mServiceLock) {
313             for (int i = mLocalTaskStackListeners.size() - 1; i >= 0; i--) {
314                 try {
315                     callback.accept(mLocalTaskStackListeners.get(i), message);
316                 } catch (RemoteException e) {
317                     // Never thrown since this is called locally.
318                 }
319             }
320         }
321     }
322 
323     /** Notifies all listeners when the task stack has changed. */
notifyTaskStackChanged()324     void notifyTaskStackChanged() {
325         mHandler.sendEmptyMessage(LOG_STACK_STATE_MSG);
326         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
327         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
328         forAllLocalListeners(mNotifyTaskStackChanged, msg);
329         // Only the main task stack change notification requires a delay.
330         mHandler.sendMessageDelayed(msg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
331     }
332 
333     /** Notifies all listeners when an Activity is pinned. */
notifyActivityPinned(ActivityRecord r)334     void notifyActivityPinned(ActivityRecord r) {
335         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
336         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG,
337                 r.getTaskRecord().taskId, r.getStackId(), r.packageName);
338         msg.sendingUid = r.mUserId;
339         forAllLocalListeners(mNotifyActivityPinned, msg);
340         msg.sendToTarget();
341     }
342 
343     /** Notifies all listeners when an Activity is unpinned. */
notifyActivityUnpinned()344     void notifyActivityUnpinned() {
345         mHandler.removeMessages(NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG);
346         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG);
347         forAllLocalListeners(mNotifyActivityUnpinned, msg);
348         msg.sendToTarget();
349     }
350 
351     /**
352      * Notifies all listeners when an attempt was made to start an an activity that is already
353      * running in the pinned stack and the activity was not actually started, but the task is
354      * either brought to the front or a new Intent is delivered to it.
355      */
notifyPinnedActivityRestartAttempt(boolean clearedTask)356     void notifyPinnedActivityRestartAttempt(boolean clearedTask) {
357         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
358         final Message msg =
359                 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG,
360                         clearedTask ? 1 : 0, 0);
361         forAllLocalListeners(mNotifyPinnedActivityRestartAttempt, msg);
362         msg.sendToTarget();
363     }
364 
365     /** Notifies all listeners when the pinned stack animation starts. */
notifyPinnedStackAnimationStarted()366     void notifyPinnedStackAnimationStarted() {
367         mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_STARTED_LISTENERS_MSG);
368         final Message msg =
369                 mHandler.obtainMessage(NOTIFY_PINNED_STACK_ANIMATION_STARTED_LISTENERS_MSG);
370         forAllLocalListeners(mNotifyPinnedStackAnimationStarted, msg);
371         msg.sendToTarget();
372     }
373 
374     /** Notifies all listeners when the pinned stack animation ends. */
notifyPinnedStackAnimationEnded()375     void notifyPinnedStackAnimationEnded() {
376         mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
377         final Message msg =
378                 mHandler.obtainMessage(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
379         forAllLocalListeners(mNotifyPinnedStackAnimationEnded, msg);
380         msg.sendToTarget();
381     }
382 
notifyActivityDismissingDockedStack()383     void notifyActivityDismissingDockedStack() {
384         mHandler.removeMessages(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
385         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG);
386         forAllLocalListeners(mNotifyActivityDismissingDockedStack, msg);
387         msg.sendToTarget();
388     }
389 
notifyActivityForcedResizable(int taskId, int reason, String packageName)390     void notifyActivityForcedResizable(int taskId, int reason, String packageName) {
391         mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
392         final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId, reason,
393                 packageName);
394         forAllLocalListeners(mNotifyActivityForcedResizable, msg);
395         msg.sendToTarget();
396     }
397 
notifyActivityLaunchOnSecondaryDisplayFailed(TaskInfo ti, int requestedDisplayId)398     void notifyActivityLaunchOnSecondaryDisplayFailed(TaskInfo ti, int requestedDisplayId) {
399         mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG);
400         final Message msg = mHandler.obtainMessage(
401                 NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG, requestedDisplayId,
402                 0 /* unused */, ti);
403         forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
404         msg.sendToTarget();
405     }
406 
notifyActivityLaunchOnSecondaryDisplayRerouted(TaskInfo ti, int requestedDisplayId)407     void notifyActivityLaunchOnSecondaryDisplayRerouted(TaskInfo ti, int requestedDisplayId) {
408         mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG);
409         final Message msg = mHandler.obtainMessage(
410                 NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG, requestedDisplayId,
411                 0 /* unused */, ti);
412         forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayRerouted, msg);
413         msg.sendToTarget();
414     }
415 
notifyTaskCreated(int taskId, ComponentName componentName)416     void notifyTaskCreated(int taskId, ComponentName componentName) {
417         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
418                 taskId, 0 /* unused */, componentName);
419         forAllLocalListeners(mNotifyTaskCreated, msg);
420         msg.sendToTarget();
421     }
422 
notifyTaskRemoved(int taskId)423     void notifyTaskRemoved(int taskId) {
424         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVED_LISTENERS_MSG,
425                 taskId, 0 /* unused */);
426         forAllLocalListeners(mNotifyTaskRemoved, msg);
427         msg.sendToTarget();
428     }
429 
notifyTaskMovedToFront(TaskInfo ti)430     void notifyTaskMovedToFront(TaskInfo ti) {
431         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_MOVED_TO_FRONT_LISTENERS_MSG, ti);
432         forAllLocalListeners(mNotifyTaskMovedToFront, msg);
433         msg.sendToTarget();
434     }
435 
notifyTaskDescriptionChanged(TaskInfo taskInfo)436     void notifyTaskDescriptionChanged(TaskInfo taskInfo) {
437         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DESCRIPTION_CHANGED_LISTENERS_MSG,
438                 taskInfo);
439         forAllLocalListeners(mNotifyTaskDescriptionChanged, msg);
440         msg.sendToTarget();
441 
442     }
443 
notifyActivityRequestedOrientationChanged(int taskId, int orientation)444     void notifyActivityRequestedOrientationChanged(int taskId, int orientation) {
445         final Message msg = mHandler.obtainMessage(
446                 NOTIFY_ACTIVITY_REQUESTED_ORIENTATION_CHANGED_LISTENERS, taskId, orientation);
447         forAllLocalListeners(mNotifyActivityRequestedOrientationChanged, msg);
448         msg.sendToTarget();
449     }
450 
451     /**
452      * Notify listeners that the task is about to be finished before its surfaces are removed from
453      * the window manager. This allows interested parties to perform relevant animations before
454      * the window disappears.
455      */
notifyTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo)456     void notifyTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo) {
457         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_REMOVAL_STARTED_LISTENERS, taskInfo);
458         forAllLocalListeners(mNotifyTaskRemovalStarted, msg);
459         msg.sendToTarget();
460     }
461 
462     /**
463      * Notify listeners that the task has been put in a locked state because one or more of the
464      * activities inside it belong to a managed profile user that has been locked.
465      */
notifyTaskProfileLocked(int taskId, int userId)466     void notifyTaskProfileLocked(int taskId, int userId) {
467         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG, taskId,
468                 userId);
469         forAllLocalListeners(mNotifyTaskProfileLocked, msg);
470         msg.sendToTarget();
471     }
472 
473     /**
474      * Notify listeners that the snapshot of a task has changed.
475      */
notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot)476     void notifyTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) {
477         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG,
478                 taskId, 0, snapshot);
479         forAllLocalListeners(mNotifyTaskSnapshotChanged, msg);
480         msg.sendToTarget();
481     }
482 
483     /**
484      * Notify listeners that whether a size compatibility mode activity is using the override
485      * bounds which is not fit its parent.
486      */
notifySizeCompatModeActivityChanged(int displayId, IBinder activityToken)487     void notifySizeCompatModeActivityChanged(int displayId, IBinder activityToken) {
488         final Message msg = mHandler.obtainMessage(NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG,
489                 displayId, 0 /* unused */, activityToken);
490         forAllLocalListeners(mOnSizeCompatModeActivityChanged, msg);
491         msg.sendToTarget();
492     }
493 
494     /**
495      * Notify listeners that an activity received a back press when there are no other activities
496      * in the back stack.
497      */
notifyBackPressedOnTaskRoot(TaskInfo taskInfo)498     void notifyBackPressedOnTaskRoot(TaskInfo taskInfo) {
499         final Message msg = mHandler.obtainMessage(NOTIFY_BACK_PRESSED_ON_TASK_ROOT,
500                 taskInfo);
501         forAllLocalListeners(mNotifyBackPressedOnTaskRoot, msg);
502         msg.sendToTarget();
503     }
504 
505     /**
506      * Notify listeners that contents are drawn for the first time on a single task display.
507      */
notifySingleTaskDisplayDrawn(int displayId)508     void notifySingleTaskDisplayDrawn(int displayId) {
509         final Message msg = mHandler.obtainMessage(NOTIFY_SINGLE_TASK_DISPLAY_DRAWN,
510                 displayId, 0 /* unused */);
511         forAllLocalListeners(mNotifySingleTaskDisplayDrawn, msg);
512         msg.sendToTarget();
513     }
514 
515     /**
516      * Notify listeners that the last task is removed from a single task display.
517      */
notifySingleTaskDisplayEmpty(int displayId)518     void notifySingleTaskDisplayEmpty(int displayId) {
519         final Message msg = mHandler.obtainMessage(
520                 NOTIFY_SINGLE_TASK_DISPLAY_EMPTY,
521                 displayId, 0 /* unused */);
522         forAllLocalListeners(mNotifySingleTaskDisplayEmpty, msg);
523         msg.sendToTarget();
524     }
525 
526     /**
527      * Notify listeners that a task is reparented to another display.
528      */
notifyTaskDisplayChanged(int taskId, int newDisplayId)529     void notifyTaskDisplayChanged(int taskId, int newDisplayId) {
530         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG,
531                 taskId, newDisplayId);
532         forAllLocalListeners(mNotifyTaskStackChanged, msg);
533         msg.sendToTarget();
534     }
535 }
536