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