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