1 /* 2 * Copyright (C) 2013 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.am; 18 19 import static android.Manifest.permission.ACTIVITY_EMBEDDING; 20 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 21 import static android.Manifest.permission.START_ANY_ACTIVITY; 22 import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 23 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; 24 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; 25 import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; 26 import static android.app.ActivityManager.START_TASK_TO_FRONT; 27 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 28 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; 29 import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID; 30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 31 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 32 import static android.app.ActivityManager.StackId.HOME_STACK_ID; 33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 34 import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID; 35 import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 36 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID; 37 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY; 38 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; 39 import static android.content.pm.PackageManager.PERMISSION_DENIED; 40 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 41 import static android.os.Process.SYSTEM_UID; 42 import static android.os.PowerManager.PARTIAL_WAKE_LOCK; 43 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 44 import static android.view.Display.DEFAULT_DISPLAY; 45 import static android.view.Display.FLAG_PRIVATE; 46 import static android.view.Display.INVALID_DISPLAY; 47 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT; 48 import static android.view.Display.TYPE_VIRTUAL; 49 50 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN; 51 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 52 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS; 53 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE; 54 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; 55 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE; 56 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 57 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; 58 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 59 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; 60 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 61 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 62 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS; 63 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE; 64 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; 65 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE; 66 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 67 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; 68 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 69 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES; 70 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 71 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; 72 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 73 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 74 import static com.android.server.am.ActivityManagerService.ANIMATE; 75 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 76 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; 77 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; 78 import static com.android.server.am.ActivityStack.ActivityState.DESTROYED; 79 import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; 80 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING; 81 import static com.android.server.am.ActivityStack.ActivityState.PAUSED; 82 import static com.android.server.am.ActivityStack.ActivityState.PAUSING; 83 import static com.android.server.am.ActivityStack.ActivityState.RESUMED; 84 import static com.android.server.am.ActivityStack.ActivityState.STOPPED; 85 import static com.android.server.am.ActivityStack.ActivityState.STOPPING; 86 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING; 87 import static com.android.server.am.ActivityStack.STACK_INVISIBLE; 88 import static com.android.server.am.ActivityStack.STACK_VISIBLE; 89 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; 90 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; 91 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 92 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; 93 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; 94 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; 95 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; 96 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT; 97 import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS; 98 import static java.lang.Integer.MAX_VALUE; 99 100 import android.Manifest; 101 import android.annotation.IntDef; 102 import android.annotation.NonNull; 103 import android.annotation.UserIdInt; 104 import android.app.Activity; 105 import android.app.ActivityManager; 106 import android.app.ActivityManager.RunningTaskInfo; 107 import android.app.ActivityManager.StackId; 108 import android.app.ActivityManager.StackInfo; 109 import android.app.ActivityManagerInternal.SleepToken; 110 import android.app.ActivityOptions; 111 import android.app.AppOpsManager; 112 import android.app.ProfilerInfo; 113 import android.app.ResultInfo; 114 import android.app.StatusBarManager; 115 import android.app.WaitResult; 116 import android.app.admin.IDevicePolicyManager; 117 import android.content.ComponentName; 118 import android.content.Context; 119 import android.content.Intent; 120 import android.content.pm.ActivityInfo; 121 import android.content.pm.ApplicationInfo; 122 import android.content.pm.PackageInfo; 123 import android.content.pm.PackageManager; 124 import android.content.pm.ResolveInfo; 125 import android.content.pm.UserInfo; 126 import android.content.res.Configuration; 127 import android.graphics.Rect; 128 import android.hardware.display.DisplayManager; 129 import android.hardware.display.DisplayManager.DisplayListener; 130 import android.hardware.display.DisplayManagerInternal; 131 import android.hardware.input.InputManagerInternal; 132 import android.os.Binder; 133 import android.os.Bundle; 134 import android.os.Debug; 135 import android.os.Handler; 136 import android.os.IBinder; 137 import android.os.Looper; 138 import android.os.Message; 139 import android.os.PowerManager; 140 import android.os.Process; 141 import android.os.RemoteException; 142 import android.os.ServiceManager; 143 import android.os.SystemClock; 144 import android.os.Trace; 145 import android.os.UserHandle; 146 import android.os.UserManager; 147 import android.os.WorkSource; 148 import android.provider.MediaStore; 149 import android.provider.Settings; 150 import android.provider.Settings.SettingNotFoundException; 151 import android.service.voice.IVoiceInteractionSession; 152 import android.util.ArrayMap; 153 import android.util.ArraySet; 154 import android.util.EventLog; 155 import android.util.IntArray; 156 import android.util.MergedConfiguration; 157 import android.util.Slog; 158 import android.util.SparseArray; 159 import android.util.SparseIntArray; 160 import android.util.TimeUtils; 161 import android.view.Display; 162 163 import com.android.internal.annotations.VisibleForTesting; 164 import com.android.internal.content.ReferrerIntent; 165 import com.android.internal.logging.MetricsLogger; 166 import com.android.internal.os.TransferPipe; 167 import com.android.internal.statusbar.IStatusBarService; 168 import com.android.internal.util.ArrayUtils; 169 import com.android.internal.widget.LockPatternUtils; 170 import com.android.server.LocalServices; 171 import com.android.server.am.ActivityStack.ActivityState; 172 import com.android.server.wm.PinnedStackWindowController; 173 import com.android.server.wm.WindowManagerService; 174 175 import java.io.FileDescriptor; 176 import java.io.IOException; 177 import java.io.PrintWriter; 178 import java.lang.annotation.Retention; 179 import java.lang.annotation.RetentionPolicy; 180 import java.util.ArrayList; 181 import java.util.Arrays; 182 import java.util.Iterator; 183 import java.util.List; 184 import java.util.Set; 185 186 public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener { 187 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; 188 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; 189 private static final String TAG_IDLE = TAG + POSTFIX_IDLE; 190 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; 191 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; 192 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 193 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 194 private static final String TAG_STACK = TAG + POSTFIX_STACK; 195 private static final String TAG_STATES = TAG + POSTFIX_STATES; 196 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 197 static final String TAG_TASKS = TAG + POSTFIX_TASKS; 198 199 /** How long we wait until giving up on the last activity telling us it is idle. */ 200 static final int IDLE_TIMEOUT = 10 * 1000; 201 202 /** How long we can hold the sleep wake lock before giving up. */ 203 static final int SLEEP_TIMEOUT = 5 * 1000; 204 205 // How long we can hold the launch wake lock before giving up. 206 static final int LAUNCH_TIMEOUT = 10 * 1000; 207 208 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 209 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 210 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 211 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 212 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; 213 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; 214 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; 215 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; 216 static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9; 217 static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10; 218 static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12; 219 static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13; 220 static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14; 221 static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15; 222 223 private static final String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; 224 225 private static final String LOCK_TASK_TAG = "Lock-to-App"; 226 227 // Used to indicate if an object (e.g. stack) that we are trying to get 228 // should be created if it doesn't exist already. 229 static final boolean CREATE_IF_NEEDED = true; 230 231 // Used to indicate that windows of activities should be preserved during the resize. 232 static final boolean PRESERVE_WINDOWS = true; 233 234 // Used to indicate if an object (e.g. task) should be moved/created 235 // at the top of its container (e.g. stack). 236 static final boolean ON_TOP = true; 237 238 // Used to indicate that an objects (e.g. task) removal from its container 239 // (e.g. stack) is due to it moving to another container. 240 static final boolean MOVING = true; 241 242 // Force the focus to change to the stack we are moving a task to.. 243 static final boolean FORCE_FOCUS = true; 244 245 // Don't execute any calls to resume. 246 static final boolean DEFER_RESUME = true; 247 248 // Used to indicate that a task is removed it should also be removed from recents. 249 static final boolean REMOVE_FROM_RECENTS = true; 250 251 // Used to indicate that pausing an activity should occur immediately without waiting for 252 // the activity callback indicating that it has completed pausing 253 static final boolean PAUSE_IMMEDIATELY = true; 254 255 /** 256 * The modes which affect which tasks are returned when calling 257 * {@link ActivityStackSupervisor#anyTaskForIdLocked(int)}. 258 */ 259 @Retention(RetentionPolicy.SOURCE) 260 @IntDef({ 261 MATCH_TASK_IN_STACKS_ONLY, 262 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, 263 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 264 }) 265 public @interface AnyTaskForIdMatchTaskMode {} 266 // Match only tasks in the current stacks 267 static final int MATCH_TASK_IN_STACKS_ONLY = 0; 268 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks 269 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1; 270 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the 271 // provided stack id 272 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2; 273 274 // Activity actions an app cannot start if it uses a permission which is not granted. 275 private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION = 276 new ArrayMap<>(); 277 278 static { 279 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, 280 Manifest.permission.CAMERA); 281 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, 282 Manifest.permission.CAMERA); 283 ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, 284 Manifest.permission.CALL_PHONE); 285 } 286 287 /** Action restriction: launching the activity is not restricted. */ 288 private static final int ACTIVITY_RESTRICTION_NONE = 0; 289 /** Action restriction: launching the activity is restricted by a permission. */ 290 private static final int ACTIVITY_RESTRICTION_PERMISSION = 1; 291 /** Action restriction: launching the activity is restricted by an app op. */ 292 private static final int ACTIVITY_RESTRICTION_APPOP = 2; 293 294 /** Status Bar Service **/ 295 private IBinder mToken = new Binder(); 296 private IStatusBarService mStatusBarService; 297 private IDevicePolicyManager mDevicePolicyManager; 298 299 // For debugging to make sure the caller when acquiring/releasing our 300 // wake lock is the system process. 301 static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 302 /** The number of distinct task ids that can be assigned to the tasks of a single user */ 303 private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE; 304 305 final ActivityManagerService mService; 306 307 private RecentTasks mRecentTasks; 308 309 final ActivityStackSupervisorHandler mHandler; 310 311 /** Short cut */ 312 WindowManagerService mWindowManager; 313 DisplayManager mDisplayManager; 314 315 /** Counter for next free stack ID to use for dynamic activity stacks. */ 316 private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID; 317 318 /** 319 * Maps the task identifier that activities are currently being started in to the userId of the 320 * task. Each time a new task is created, the entry for the userId of the task is incremented 321 */ 322 private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20); 323 324 /** The current user */ 325 int mCurrentUser; 326 327 /** The stack containing the launcher app. Assumed to always be attached to 328 * Display.DEFAULT_DISPLAY. */ 329 ActivityStack mHomeStack; 330 331 /** The stack currently receiving input or launching the next activity. */ 332 ActivityStack mFocusedStack; 333 334 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 335 * been resumed. If stacks are changing position this will hold the old stack until the new 336 * stack becomes resumed after which it will be set to mFocusedStack. */ 337 private ActivityStack mLastFocusedStack; 338 339 /** List of activities that are waiting for a new activity to become visible before completing 340 * whatever operation they are supposed to do. */ 341 // TODO: Remove mActivitiesWaitingForVisibleActivity list and just remove activity from 342 // mStoppingActivities when something else comes up. 343 final ArrayList<ActivityRecord> mActivitiesWaitingForVisibleActivity = new ArrayList<>(); 344 345 /** List of processes waiting to find out when a specific activity becomes visible. */ 346 private final ArrayList<WaitInfo> mWaitingForActivityVisible = new ArrayList<>(); 347 348 /** List of processes waiting to find out about the next launched activity. */ 349 final ArrayList<WaitResult> mWaitingActivityLaunched = new ArrayList<>(); 350 351 /** List of activities that are ready to be stopped, but waiting for the next activity to 352 * settle down before doing so. */ 353 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>(); 354 355 /** List of activities that are ready to be finished, but waiting for the previous activity to 356 * settle down before doing so. It contains ActivityRecord objects. */ 357 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>(); 358 359 /** List of activities that are in the process of going to sleep. */ 360 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>(); 361 362 /** List of activities whose multi-window mode changed that we need to report to the 363 * application */ 364 final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>(); 365 366 /** List of activities whose picture-in-picture mode changed that we need to report to the 367 * application */ 368 final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>(); 369 370 /** The target stack bounds for the picture-in-picture mode changed that we need to report to 371 * the application */ 372 Rect mPipModeChangedTargetStackBounds; 373 374 /** Used on user changes */ 375 final ArrayList<UserState> mStartingUsers = new ArrayList<>(); 376 377 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 378 * is being brought in front of us. */ 379 boolean mUserLeaving = false; 380 381 /** 382 * We don't want to allow the device to go to sleep while in the process 383 * of launching an activity. This is primarily to allow alarm intent 384 * receivers to launch an activity and get that to run before the device 385 * goes back to sleep. 386 */ 387 PowerManager.WakeLock mLaunchingActivity; 388 389 /** 390 * Set when the system is going to sleep, until we have 391 * successfully paused the current activity and released our wake lock. 392 * At that point the system is allowed to actually sleep. 393 */ 394 PowerManager.WakeLock mGoingToSleep; 395 396 /** 397 * A list of tokens that cause the top activity to be put to sleep. 398 * They are used by components that may hide and block interaction with underlying 399 * activities. 400 */ 401 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>(); 402 403 /** Stack id of the front stack when user switched, indexed by userId. */ 404 SparseIntArray mUserStackInFront = new SparseIntArray(2); 405 406 // TODO: Add listener for removal of references. 407 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */ 408 SparseArray<ActivityStack> mStacks = new SparseArray<>(); 409 410 // TODO: There should be an ActivityDisplayController coordinating am/wm interaction. 411 /** Mapping from displayId to display current state */ 412 private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>(); 413 414 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 415 416 private DisplayManagerInternal mDisplayManagerInternal; 417 private InputManagerInternal mInputManagerInternal; 418 419 /** The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks 420 * may be finished until there is only one entry left. If this is empty the system is not 421 * in lockTask mode. */ 422 ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>(); 423 /** Store the current lock task mode. Possible values: 424 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, 425 * {@link ActivityManager#LOCK_TASK_MODE_PINNED} 426 */ 427 private int mLockTaskModeState; 428 /** 429 * Notifies the user when entering/exiting lock-task. 430 */ 431 private LockTaskNotify mLockTaskNotify; 432 433 /** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */ 434 boolean inResumeTopActivity; 435 436 /** 437 * Temporary rect used during docked stack resize calculation so we don't need to create a new 438 * object each time. 439 */ 440 private final Rect tempRect = new Rect(); 441 442 // The default minimal size that will be used if the activity doesn't specify its minimal size. 443 // It will be calculated when the default display gets added. 444 int mDefaultMinSizeOfResizeableTask = -1; 445 446 // Whether tasks have moved and we need to rank the tasks before next OOM scoring 447 private boolean mTaskLayersChanged = true; 448 449 final ActivityMetricsLogger mActivityMetricsLogger; 450 451 private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>(); 452 453 @Override 454 protected int getChildCount() { 455 return mActivityDisplays.size(); 456 } 457 458 @Override 459 protected ActivityDisplay getChildAt(int index) { 460 return mActivityDisplays.valueAt(index); 461 } 462 463 @Override 464 protected ConfigurationContainer getParent() { 465 return null; 466 } 467 468 Configuration getDisplayOverrideConfiguration(int displayId) { 469 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 470 if (activityDisplay == null) { 471 throw new IllegalArgumentException("No display found with id: " + displayId); 472 } 473 474 return activityDisplay.getOverrideConfiguration(); 475 } 476 477 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) { 478 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 479 if (activityDisplay == null) { 480 throw new IllegalArgumentException("No display found with id: " + displayId); 481 } 482 483 activityDisplay.onOverrideConfigurationChanged(overrideConfiguration); 484 } 485 486 /** Check if placing task or activity on specified display is allowed. */ 487 boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable, int callingPid, 488 int callingUid, ActivityInfo activityInfo) { 489 if (displayId == DEFAULT_DISPLAY) { 490 // No restrictions for the default display. 491 return true; 492 } 493 if (!mService.mSupportsMultiDisplay) { 494 // Can't launch on secondary displays if feature is not supported. 495 return false; 496 } 497 if (!resizeable && !displayConfigMatchesGlobal(displayId)) { 498 // Can't apply wrong configuration to non-resizeable activities. 499 return false; 500 } 501 if (!isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, displayId, activityInfo)) { 502 // Can't place activities to a display that has restricted launch rules. 503 // In this case the request should be made by explicitly adding target display id and 504 // by caller with corresponding permissions. See #isCallerAllowedToLaunchOnDisplay(). 505 return false; 506 } 507 return true; 508 } 509 510 /** 511 * Check if configuration of specified display matches current global config. 512 * Used to check if we can put a non-resizeable activity on a secondary display and it will get 513 * the same config as on the default display. 514 * @param displayId Id of the display to check. 515 * @return {@code true} if configuration matches. 516 */ 517 private boolean displayConfigMatchesGlobal(int displayId) { 518 if (displayId == DEFAULT_DISPLAY) { 519 return true; 520 } 521 if (displayId == INVALID_DISPLAY) { 522 return false; 523 } 524 final ActivityDisplay targetDisplay = getActivityDisplayOrCreateLocked(displayId); 525 if (targetDisplay == null) { 526 throw new IllegalArgumentException("No display found with id: " + displayId); 527 } 528 return getConfiguration().equals(targetDisplay.getConfiguration()); 529 } 530 531 static class FindTaskResult { 532 ActivityRecord r; 533 boolean matchedByRootAffinity; 534 } 535 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); 536 537 /** 538 * Temp storage for display ids sorted in focus order. 539 * Maps position to id. Using {@link SparseIntArray} instead of {@link ArrayList} because 540 * it's more efficient, as the number of displays is usually small. 541 */ 542 private SparseIntArray mTmpOrderedDisplayIds = new SparseIntArray(); 543 544 /** 545 * Used to keep track whether app visibilities got changed since the last pause. Useful to 546 * determine whether to invoke the task stack change listener after pausing. 547 */ 548 boolean mAppVisibilitiesChangedSinceLastPause; 549 550 /** 551 * Set of tasks that are in resizing mode during an app transition to fill the "void". 552 */ 553 private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>(); 554 555 556 /** 557 * If set to {@code false} all calls to resize the docked stack {@link #resizeDockedStackLocked} 558 * will be ignored. Useful for the case where the caller is handling resizing of other stack and 559 * moving tasks around and doesn't want dock stack to be resized due to an automatic trigger 560 * like the docked stack going empty. 561 */ 562 private boolean mAllowDockedStackResize = true; 563 564 /** 565 * Is dock currently minimized. 566 */ 567 boolean mIsDockMinimized; 568 569 final KeyguardController mKeyguardController; 570 571 private PowerManager mPowerManager; 572 private int mDeferResumeCount; 573 574 /** 575 * Description of a request to start a new activity, which has been held 576 * due to app switches being disabled. 577 */ 578 static class PendingActivityLaunch { 579 final ActivityRecord r; 580 final ActivityRecord sourceRecord; 581 final int startFlags; 582 final ActivityStack stack; 583 final ProcessRecord callerApp; 584 585 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 586 int _startFlags, ActivityStack _stack, ProcessRecord _callerApp) { 587 r = _r; 588 sourceRecord = _sourceRecord; 589 startFlags = _startFlags; 590 stack = _stack; 591 callerApp = _callerApp; 592 } 593 594 void sendErrorResult(String message) { 595 try { 596 if (callerApp.thread != null) { 597 callerApp.thread.scheduleCrash(message); 598 } 599 } catch (RemoteException e) { 600 Slog.e(TAG, "Exception scheduling crash of failed " 601 + "activity launcher sourceRecord=" + sourceRecord, e); 602 } 603 } 604 } 605 606 public ActivityStackSupervisor(ActivityManagerService service, Looper looper) { 607 mService = service; 608 mHandler = new ActivityStackSupervisorHandler(looper); 609 mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext); 610 mKeyguardController = new KeyguardController(service, this); 611 } 612 613 void setRecentTasks(RecentTasks recentTasks) { 614 mRecentTasks = recentTasks; 615 } 616 617 /** 618 * At the time when the constructor runs, the power manager has not yet been 619 * initialized. So we initialize our wakelocks afterwards. 620 */ 621 void initPowerManagement() { 622 mPowerManager = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); 623 mGoingToSleep = mPowerManager 624 .newWakeLock(PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 625 mLaunchingActivity = mPowerManager.newWakeLock(PARTIAL_WAKE_LOCK, "*launch*"); 626 mLaunchingActivity.setReferenceCounted(false); 627 } 628 629 // This function returns a IStatusBarService. The value is from ServiceManager. 630 // getService and is cached. 631 private IStatusBarService getStatusBarService() { 632 synchronized (mService) { 633 if (mStatusBarService == null) { 634 mStatusBarService = IStatusBarService.Stub.asInterface( 635 ServiceManager.checkService(Context.STATUS_BAR_SERVICE)); 636 if (mStatusBarService == null) { 637 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE"); 638 } 639 } 640 return mStatusBarService; 641 } 642 } 643 644 private IDevicePolicyManager getDevicePolicyManager() { 645 synchronized (mService) { 646 if (mDevicePolicyManager == null) { 647 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 648 ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE)); 649 if (mDevicePolicyManager == null) { 650 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE"); 651 } 652 } 653 return mDevicePolicyManager; 654 } 655 } 656 657 void setWindowManager(WindowManagerService wm) { 658 synchronized (mService) { 659 mWindowManager = wm; 660 mKeyguardController.setWindowManager(wm); 661 662 mDisplayManager = 663 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); 664 mDisplayManager.registerDisplayListener(this, null); 665 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 666 667 Display[] displays = mDisplayManager.getDisplays(); 668 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { 669 final int displayId = displays[displayNdx].getDisplayId(); 670 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 671 if (activityDisplay.mDisplay == null) { 672 throw new IllegalStateException("Default Display does not exist"); 673 } 674 mActivityDisplays.put(displayId, activityDisplay); 675 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 676 } 677 678 mHomeStack = mFocusedStack = mLastFocusedStack = 679 getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP); 680 681 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 682 } 683 } 684 685 ActivityStack getFocusedStack() { 686 return mFocusedStack; 687 } 688 689 ActivityStack getLastStack() { 690 return mLastFocusedStack; 691 } 692 693 boolean isFocusedStack(ActivityStack stack) { 694 return stack != null && stack == mFocusedStack; 695 } 696 697 /** The top most stack on its display. */ 698 boolean isFrontStackOnDisplay(ActivityStack stack) { 699 return isFrontOfStackList(stack, stack.getDisplay().mStacks); 700 } 701 702 private boolean isFrontOfStackList(ActivityStack stack, List<ActivityStack> stackList) { 703 return stack == stackList.get((stackList.size() - 1)); 704 } 705 706 /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */ 707 void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) { 708 if (!focusCandidate.isFocusable()) { 709 // The focus candidate isn't focusable. Move focus to the top stack that is focusable. 710 focusCandidate = getNextFocusableStackLocked(focusCandidate); 711 } 712 713 if (focusCandidate != mFocusedStack) { 714 mLastFocusedStack = mFocusedStack; 715 mFocusedStack = focusCandidate; 716 717 EventLogTags.writeAmFocusedStack( 718 mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(), 719 mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason); 720 } 721 722 final ActivityRecord r = topRunningActivityLocked(); 723 if (mService.mBooting || !mService.mBooted) { 724 if (r != null && r.idle) { 725 checkFinishBootingLocked(); 726 } 727 } 728 } 729 730 void moveHomeStackToFront(String reason) { 731 mHomeStack.moveToFront(reason); 732 } 733 734 void moveRecentsStackToFront(String reason) { 735 final ActivityStack recentsStack = getStack(RECENTS_STACK_ID); 736 if (recentsStack != null) { 737 recentsStack.moveToFront(reason); 738 } 739 } 740 741 /** Returns true if the focus activity was adjusted to the home stack top activity. */ 742 boolean moveHomeStackTaskToTop(String reason) { 743 mHomeStack.moveHomeStackTaskToTop(); 744 745 final ActivityRecord top = getHomeActivity(); 746 if (top == null) { 747 return false; 748 } 749 moveFocusableActivityStackToFrontLocked(top, reason); 750 return true; 751 } 752 753 boolean resumeHomeStackTask(ActivityRecord prev, String reason) { 754 if (!mService.mBooting && !mService.mBooted) { 755 // Not ready yet! 756 return false; 757 } 758 759 if (prev != null) { 760 prev.getTask().setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); 761 } 762 763 mHomeStack.moveHomeStackTaskToTop(); 764 ActivityRecord r = getHomeActivity(); 765 final String myReason = reason + " resumeHomeStackTask"; 766 767 // Only resume home activity if isn't finishing. 768 if (r != null && !r.finishing) { 769 moveFocusableActivityStackToFrontLocked(r, myReason); 770 return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null); 771 } 772 return mService.startHomeActivityLocked(mCurrentUser, myReason); 773 } 774 775 TaskRecord anyTaskForIdLocked(int id) { 776 return anyTaskForIdLocked(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, 777 INVALID_STACK_ID); 778 } 779 780 /** 781 * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise. 782 * @param id Id of the task we would like returned. 783 * @param matchMode The mode to match the given task id in. 784 * @param stackId The stack to restore the task to (default launch stack will be used if 785 * stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}). Only 786 * valid if the matchMode is 787 * {@link #MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE}. 788 */ 789 TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode, int stackId) { 790 // If there is a stack id set, ensure that we are attempting to actually restore a task 791 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && 792 stackId != INVALID_STACK_ID) { 793 throw new IllegalArgumentException("Should not specify stackId for non-restore lookup"); 794 } 795 796 int numDisplays = mActivityDisplays.size(); 797 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 798 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 799 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 800 ActivityStack stack = stacks.get(stackNdx); 801 final TaskRecord task = stack.taskForIdLocked(id); 802 if (task != null) { 803 return task; 804 } 805 } 806 } 807 808 // If we are matching stack tasks only, return now 809 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) { 810 return null; 811 } 812 813 // Otherwise, check the recent tasks and return if we find it there and we are not restoring 814 // the task from recents 815 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents"); 816 final TaskRecord task = mRecentTasks.taskForIdLocked(id); 817 818 if (task == null) { 819 if (DEBUG_RECENTS) { 820 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents"); 821 } 822 823 return null; 824 } 825 826 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) { 827 return task; 828 } 829 830 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 831 if (!restoreRecentTaskLocked(task, stackId)) { 832 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, 833 "Couldn't restore task id=" + id + " found in recents"); 834 return null; 835 } 836 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents"); 837 return task; 838 } 839 840 ActivityRecord isInAnyStackLocked(IBinder token) { 841 int numDisplays = mActivityDisplays.size(); 842 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 843 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 844 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 845 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token); 846 if (r != null) { 847 return r; 848 } 849 } 850 } 851 return null; 852 } 853 854 /** 855 * Detects whether we should show a lock screen in front of this task for a locked user. 856 * <p> 857 * We'll do this if either of the following holds: 858 * <ul> 859 * <li>The top activity explicitly belongs to {@param userId}.</li> 860 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li> 861 * </ul> 862 * 863 * @return {@code true} if the top activity looks like it belongs to {@param userId}. 864 */ 865 private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) { 866 // To handle the case that work app is in the task but just is not the top one. 867 final ActivityRecord activityRecord = task.getTopActivity(); 868 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null); 869 870 return (activityRecord != null && activityRecord.userId == userId) 871 || (resultTo != null && resultTo.userId == userId); 872 } 873 874 /** 875 * Find all visible task stacks containing {@param userId} and intercept them with an activity 876 * to block out the contents and possibly start a credential-confirming intent. 877 * 878 * @param userId user handle for the locked managed profile. 879 */ 880 void lockAllProfileTasks(@UserIdInt int userId) { 881 mWindowManager.deferSurfaceLayout(); 882 try { 883 final List<ActivityStack> stacks = getStacks(); 884 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; stackNdx--) { 885 final List<TaskRecord> tasks = stacks.get(stackNdx).getAllTasks(); 886 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) { 887 final TaskRecord task = tasks.get(taskNdx); 888 889 // Check the task for a top activity belonging to userId, or returning a result 890 // to an activity belonging to userId. Example case: a document picker for 891 // personal files, opened by a work app, should still get locked. 892 if (taskTopActivityIsUser(task, userId)) { 893 mService.mTaskChangeNotificationController.notifyTaskProfileLocked( 894 task.taskId, userId); 895 } 896 } 897 } 898 } finally { 899 mWindowManager.continueSurfaceLayout(); 900 } 901 } 902 903 void setNextTaskIdForUserLocked(int taskId, int userId) { 904 final int currentTaskId = mCurTaskIdForUser.get(userId, -1); 905 if (taskId > currentTaskId) { 906 mCurTaskIdForUser.put(userId, taskId); 907 } 908 } 909 910 static int nextTaskIdForUser(int taskId, int userId) { 911 int nextTaskId = taskId + 1; 912 if (nextTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) { 913 // Wrap around as there will be smaller task ids that are available now. 914 nextTaskId -= MAX_TASK_IDS_PER_USER; 915 } 916 return nextTaskId; 917 } 918 919 int getNextTaskIdForUserLocked(int userId) { 920 final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER); 921 // for a userId u, a taskId can only be in the range 922 // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER 923 // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on. 924 int candidateTaskId = nextTaskIdForUser(currentTaskId, userId); 925 while (mRecentTasks.taskIdTakenForUserLocked(candidateTaskId, userId) 926 || anyTaskForIdLocked(candidateTaskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, 927 INVALID_STACK_ID) != null) { 928 candidateTaskId = nextTaskIdForUser(candidateTaskId, userId); 929 if (candidateTaskId == currentTaskId) { 930 // Something wrong! 931 // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user 932 throw new IllegalStateException("Cannot get an available task id." 933 + " Reached limit of " + MAX_TASK_IDS_PER_USER 934 + " running tasks per user."); 935 } 936 } 937 mCurTaskIdForUser.put(userId, candidateTaskId); 938 return candidateTaskId; 939 } 940 941 ActivityRecord getResumedActivityLocked() { 942 ActivityStack stack = mFocusedStack; 943 if (stack == null) { 944 return null; 945 } 946 ActivityRecord resumedActivity = stack.mResumedActivity; 947 if (resumedActivity == null || resumedActivity.app == null) { 948 resumedActivity = stack.mPausingActivity; 949 if (resumedActivity == null || resumedActivity.app == null) { 950 resumedActivity = stack.topRunningActivityLocked(); 951 } 952 } 953 return resumedActivity; 954 } 955 956 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { 957 final String processName = app.processName; 958 boolean didSomething = false; 959 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 960 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 961 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 962 final ActivityStack stack = stacks.get(stackNdx); 963 if (!isFocusedStack(stack)) { 964 continue; 965 } 966 stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); 967 final ActivityRecord top = stack.topRunningActivityLocked(); 968 final int size = mTmpActivityList.size(); 969 for (int i = 0; i < size; i++) { 970 final ActivityRecord activity = mTmpActivityList.get(i); 971 if (activity.app == null && app.uid == activity.info.applicationInfo.uid 972 && processName.equals(activity.processName)) { 973 try { 974 if (realStartActivityLocked(activity, app, 975 top == activity /* andResume */, true /* checkConfig */)) { 976 didSomething = true; 977 } 978 } catch (RemoteException e) { 979 Slog.w(TAG, "Exception in new application when starting activity " 980 + top.intent.getComponent().flattenToShortString(), e); 981 throw e; 982 } 983 } 984 } 985 } 986 } 987 if (!didSomething) { 988 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 989 } 990 return didSomething; 991 } 992 993 boolean allResumedActivitiesIdle() { 994 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 995 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 996 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 997 final ActivityStack stack = stacks.get(stackNdx); 998 if (!isFocusedStack(stack) || stack.numActivities() == 0) { 999 continue; 1000 } 1001 final ActivityRecord resumedActivity = stack.mResumedActivity; 1002 if (resumedActivity == null || !resumedActivity.idle) { 1003 if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack=" 1004 + stack.mStackId + " " + resumedActivity + " not idle"); 1005 return false; 1006 } 1007 } 1008 } 1009 // Send launch end powerhint when idle 1010 mService.mActivityStarter.sendPowerHintForLaunchEndIfNeeded(); 1011 return true; 1012 } 1013 1014 boolean allResumedActivitiesComplete() { 1015 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1016 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1017 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1018 final ActivityStack stack = stacks.get(stackNdx); 1019 if (isFocusedStack(stack)) { 1020 final ActivityRecord r = stack.mResumedActivity; 1021 if (r != null && r.state != RESUMED) { 1022 return false; 1023 } 1024 } 1025 } 1026 } 1027 // TODO: Not sure if this should check if all Paused are complete too. 1028 if (DEBUG_STACK) Slog.d(TAG_STACK, 1029 "allResumedActivitiesComplete: mLastFocusedStack changing from=" + 1030 mLastFocusedStack + " to=" + mFocusedStack); 1031 mLastFocusedStack = mFocusedStack; 1032 return true; 1033 } 1034 1035 boolean allResumedActivitiesVisible() { 1036 boolean foundResumed = false; 1037 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1038 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1039 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1040 final ActivityStack stack = stacks.get(stackNdx); 1041 final ActivityRecord r = stack.mResumedActivity; 1042 if (r != null) { 1043 if (!r.nowVisible || mActivitiesWaitingForVisibleActivity.contains(r)) { 1044 return false; 1045 } 1046 foundResumed = true; 1047 } 1048 } 1049 } 1050 return foundResumed; 1051 } 1052 1053 /** 1054 * Pause all activities in either all of the stacks or just the back stacks. 1055 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). 1056 * @param resuming The resuming activity. 1057 * @param dontWait The resuming activity isn't going to wait for all activities to be paused 1058 * before resuming. 1059 * @return true if any activity was paused as a result of this call. 1060 */ 1061 boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) { 1062 boolean someActivityPaused = false; 1063 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1064 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1065 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1066 final ActivityStack stack = stacks.get(stackNdx); 1067 if (!isFocusedStack(stack) && stack.mResumedActivity != null) { 1068 if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack + 1069 " mResumedActivity=" + stack.mResumedActivity); 1070 someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, 1071 dontWait); 1072 } 1073 } 1074 } 1075 return someActivityPaused; 1076 } 1077 1078 boolean allPausedActivitiesComplete() { 1079 boolean pausing = true; 1080 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1081 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1082 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1083 final ActivityStack stack = stacks.get(stackNdx); 1084 final ActivityRecord r = stack.mPausingActivity; 1085 if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) { 1086 if (DEBUG_STATES) { 1087 Slog.d(TAG_STATES, 1088 "allPausedActivitiesComplete: r=" + r + " state=" + r.state); 1089 pausing = false; 1090 } else { 1091 return false; 1092 } 1093 } 1094 } 1095 } 1096 return pausing; 1097 } 1098 1099 void cancelInitializingActivities() { 1100 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1101 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1102 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1103 stacks.get(stackNdx).cancelInitializingActivities(); 1104 } 1105 } 1106 } 1107 1108 void waitActivityVisible(ComponentName name, WaitResult result) { 1109 final WaitInfo waitInfo = new WaitInfo(name, result); 1110 mWaitingForActivityVisible.add(waitInfo); 1111 } 1112 1113 void cleanupActivity(ActivityRecord r) { 1114 // Make sure this record is no longer in the pending finishes list. 1115 // This could happen, for example, if we are trimming activities 1116 // down to the max limit while they are still waiting to finish. 1117 mFinishingActivities.remove(r); 1118 mActivitiesWaitingForVisibleActivity.remove(r); 1119 1120 for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) { 1121 if (mWaitingForActivityVisible.get(i).matches(r.realActivity)) { 1122 mWaitingForActivityVisible.remove(i); 1123 } 1124 } 1125 } 1126 1127 void reportActivityVisibleLocked(ActivityRecord r) { 1128 sendWaitingVisibleReportLocked(r); 1129 } 1130 1131 void sendWaitingVisibleReportLocked(ActivityRecord r) { 1132 boolean changed = false; 1133 for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) { 1134 final WaitInfo w = mWaitingForActivityVisible.get(i); 1135 if (w.matches(r.realActivity)) { 1136 final WaitResult result = w.getResult(); 1137 changed = true; 1138 result.timeout = false; 1139 result.who = w.getComponent(); 1140 result.totalTime = SystemClock.uptimeMillis() - result.thisTime; 1141 result.thisTime = result.totalTime; 1142 mWaitingForActivityVisible.remove(w); 1143 } 1144 } 1145 if (changed) { 1146 mService.notifyAll(); 1147 } 1148 } 1149 1150 void reportTaskToFrontNoLaunch(ActivityRecord r) { 1151 boolean changed = false; 1152 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 1153 WaitResult w = mWaitingActivityLaunched.remove(i); 1154 if (w.who == null) { 1155 changed = true; 1156 // Set result to START_TASK_TO_FRONT so that startActivityMayWait() knows that 1157 // the starting activity ends up moving another activity to front, and it should 1158 // wait for this new activity to become visible instead. 1159 // Do not modify other fields. 1160 w.result = START_TASK_TO_FRONT; 1161 } 1162 } 1163 if (changed) { 1164 mService.notifyAll(); 1165 } 1166 } 1167 1168 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 1169 long thisTime, long totalTime) { 1170 boolean changed = false; 1171 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 1172 WaitResult w = mWaitingActivityLaunched.remove(i); 1173 if (w.who == null) { 1174 changed = true; 1175 w.timeout = timeout; 1176 if (r != null) { 1177 w.who = new ComponentName(r.info.packageName, r.info.name); 1178 } 1179 w.thisTime = thisTime; 1180 w.totalTime = totalTime; 1181 // Do not modify w.result. 1182 } 1183 } 1184 if (changed) { 1185 mService.notifyAll(); 1186 } 1187 } 1188 1189 ActivityRecord topRunningActivityLocked() { 1190 final ActivityStack focusedStack = mFocusedStack; 1191 ActivityRecord r = focusedStack.topRunningActivityLocked(); 1192 if (r != null) { 1193 return r; 1194 } 1195 1196 // Look in other non-focused and non-home stacks. 1197 mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds); 1198 1199 for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) { 1200 final int displayId = mTmpOrderedDisplayIds.get(i); 1201 final List<ActivityStack> stacks = mActivityDisplays.get(displayId).mStacks; 1202 if (stacks == null) { 1203 continue; 1204 } 1205 for (int j = stacks.size() - 1; j >= 0; --j) { 1206 final ActivityStack stack = stacks.get(j); 1207 if (stack != focusedStack && isFrontStackOnDisplay(stack) && stack.isFocusable()) { 1208 r = stack.topRunningActivityLocked(); 1209 if (r != null) { 1210 return r; 1211 } 1212 } 1213 } 1214 } 1215 return null; 1216 } 1217 1218 void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) { 1219 // Gather all of the running tasks for each stack into runningTaskLists. 1220 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = 1221 new ArrayList<ArrayList<RunningTaskInfo>>(); 1222 final int numDisplays = mActivityDisplays.size(); 1223 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 1224 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1225 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1226 final ActivityStack stack = stacks.get(stackNdx); 1227 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>(); 1228 runningTaskLists.add(stackTaskList); 1229 stack.getTasksLocked(stackTaskList, callingUid, allowed); 1230 } 1231 } 1232 1233 // The lists are already sorted from most recent to oldest. Just pull the most recent off 1234 // each list and add it to list. Stop when all lists are empty or maxNum reached. 1235 while (maxNum > 0) { 1236 long mostRecentActiveTime = Long.MIN_VALUE; 1237 ArrayList<RunningTaskInfo> selectedStackList = null; 1238 final int numTaskLists = runningTaskLists.size(); 1239 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) { 1240 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx); 1241 if (!stackTaskList.isEmpty()) { 1242 final long lastActiveTime = stackTaskList.get(0).lastActiveTime; 1243 if (lastActiveTime > mostRecentActiveTime) { 1244 mostRecentActiveTime = lastActiveTime; 1245 selectedStackList = stackTaskList; 1246 } 1247 } 1248 } 1249 if (selectedStackList != null) { 1250 list.add(selectedStackList.remove(0)); 1251 --maxNum; 1252 } else { 1253 break; 1254 } 1255 } 1256 } 1257 1258 ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, 1259 ProfilerInfo profilerInfo) { 1260 final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null; 1261 if (aInfo != null) { 1262 // Store the found target back into the intent, because now that 1263 // we have it we never want to do this again. For example, if the 1264 // user navigates back to this point in the history, we should 1265 // always restart the exact same activity. 1266 intent.setComponent(new ComponentName( 1267 aInfo.applicationInfo.packageName, aInfo.name)); 1268 1269 // Don't debug things in the system process 1270 if (!aInfo.processName.equals("system")) { 1271 if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) { 1272 mService.setDebugApp(aInfo.processName, true, false); 1273 } 1274 1275 if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) { 1276 mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName); 1277 } 1278 1279 if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) { 1280 mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName); 1281 } 1282 1283 if (profilerInfo != null) { 1284 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo); 1285 } 1286 } 1287 final String intentLaunchToken = intent.getLaunchToken(); 1288 if (aInfo.launchToken == null && intentLaunchToken != null) { 1289 aInfo.launchToken = intentLaunchToken; 1290 } 1291 } 1292 return aInfo; 1293 } 1294 1295 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) { 1296 return resolveIntent(intent, resolvedType, userId, 0); 1297 } 1298 1299 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) { 1300 synchronized (mService) { 1301 return mService.getPackageManagerInternalLocked().resolveIntent(intent, resolvedType, 1302 PackageManager.MATCH_INSTANT | PackageManager.MATCH_DEFAULT_ONLY | flags 1303 | ActivityManagerService.STOCK_PM_FLAGS, userId); 1304 } 1305 } 1306 1307 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 1308 ProfilerInfo profilerInfo, int userId) { 1309 final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId); 1310 return resolveActivity(intent, rInfo, startFlags, profilerInfo); 1311 } 1312 1313 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, 1314 boolean andResume, boolean checkConfig) throws RemoteException { 1315 1316 if (!allPausedActivitiesComplete()) { 1317 // While there are activities pausing we skipping starting any new activities until 1318 // pauses are complete. NOTE: that we also do this for activities that are starting in 1319 // the paused state because they will first be resumed then paused on the client side. 1320 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, 1321 "realStartActivityLocked: Skipping start of r=" + r 1322 + " some activities pausing..."); 1323 return false; 1324 } 1325 1326 final TaskRecord task = r.getTask(); 1327 final ActivityStack stack = task.getStack(); 1328 1329 beginDeferResume(); 1330 1331 try { 1332 r.startFreezingScreenLocked(app, 0); 1333 1334 // schedule launch ticks to collect information about slow apps. 1335 r.startLaunchTickingLocked(); 1336 1337 r.app = app; 1338 1339 if (mKeyguardController.isKeyguardLocked()) { 1340 r.notifyUnknownVisibilityLaunched(); 1341 } 1342 1343 // Have the window manager re-evaluate the orientation of the screen based on the new 1344 // activity order. Note that as a result of this, it can call back into the activity 1345 // manager with a new orientation. We don't care about that, because the activity is 1346 // not currently running so we are just restarting it anyway. 1347 if (checkConfig) { 1348 final int displayId = r.getDisplayId(); 1349 final Configuration config = mWindowManager.updateOrientationFromAppTokens( 1350 getDisplayOverrideConfiguration(displayId), 1351 r.mayFreezeScreenLocked(app) ? r.appToken : null, displayId); 1352 // Deferring resume here because we're going to launch new activity shortly. 1353 // We don't want to perform a redundant launch of the same record while ensuring 1354 // configurations and trying to resume top activity of focused stack. 1355 mService.updateDisplayOverrideConfigurationLocked(config, r, true /* deferResume */, 1356 displayId); 1357 } 1358 1359 if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */, 1360 true /* isTop */)) { 1361 // We only set the visibility to true if the activity is allowed to be visible 1362 // based on 1363 // keyguard state. This avoids setting this into motion in window manager that is 1364 // later cancelled due to later calls to ensure visible activities that set 1365 // visibility back to false. 1366 r.setVisibility(true); 1367 } 1368 1369 final int applicationInfoUid = 1370 (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1; 1371 if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) { 1372 Slog.wtf(TAG, 1373 "User ID for activity changing for " + r 1374 + " appInfo.uid=" + r.appInfo.uid 1375 + " info.ai.uid=" + applicationInfoUid 1376 + " old=" + r.app + " new=" + app); 1377 } 1378 1379 app.waitingToKill = null; 1380 r.launchCount++; 1381 r.lastLaunchTime = SystemClock.uptimeMillis(); 1382 1383 if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r); 1384 1385 int idx = app.activities.indexOf(r); 1386 if (idx < 0) { 1387 app.activities.add(r); 1388 } 1389 mService.updateLruProcessLocked(app, true, null); 1390 mService.updateOomAdjLocked(); 1391 1392 if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || 1393 task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) { 1394 setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", 1395 false); 1396 } 1397 1398 try { 1399 if (app.thread == null) { 1400 throw new RemoteException(); 1401 } 1402 List<ResultInfo> results = null; 1403 List<ReferrerIntent> newIntents = null; 1404 if (andResume) { 1405 // We don't need to deliver new intents and/or set results if activity is going 1406 // to pause immediately after launch. 1407 results = r.results; 1408 newIntents = r.newIntents; 1409 } 1410 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 1411 "Launching: " + r + " icicle=" + r.icicle + " with results=" + results 1412 + " newIntents=" + newIntents + " andResume=" + andResume); 1413 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId, 1414 System.identityHashCode(r), task.taskId, r.shortComponentName); 1415 if (r.isHomeActivity()) { 1416 // Home process is the root process of the task. 1417 mService.mHomeProcess = task.mActivities.get(0).app; 1418 } 1419 mService.notifyPackageUse(r.intent.getComponent().getPackageName(), 1420 PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY); 1421 r.sleeping = false; 1422 r.forceNewConfig = false; 1423 mService.showUnsupportedZoomDialogIfNeededLocked(r); 1424 mService.showAskCompatModeDialogLocked(r); 1425 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 1426 ProfilerInfo profilerInfo = null; 1427 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 1428 if (mService.mProfileProc == null || mService.mProfileProc == app) { 1429 mService.mProfileProc = app; 1430 ProfilerInfo profilerInfoSvc = mService.mProfilerInfo; 1431 if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) { 1432 if (profilerInfoSvc.profileFd != null) { 1433 try { 1434 profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup(); 1435 } catch (IOException e) { 1436 profilerInfoSvc.closeFd(); 1437 } 1438 } 1439 1440 profilerInfo = new ProfilerInfo(profilerInfoSvc); 1441 } 1442 } 1443 } 1444 1445 app.hasShownUi = true; 1446 app.pendingUiClean = true; 1447 app.forceProcessStateUpTo(mService.mTopProcessState); 1448 // Because we could be starting an Activity in the system process this may not go 1449 // across a Binder interface which would create a new Configuration. Consequently 1450 // we have to always create a new Configuration here. 1451 1452 final MergedConfiguration mergedConfiguration = new MergedConfiguration( 1453 mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration()); 1454 r.setLastReportedConfiguration(mergedConfiguration); 1455 1456 logIfTransactionTooLarge(r.intent, r.icicle); 1457 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1458 System.identityHashCode(r), r.info, 1459 // TODO: Have this take the merged configuration instead of separate global 1460 // and override configs. 1461 mergedConfiguration.getGlobalConfiguration(), 1462 mergedConfiguration.getOverrideConfiguration(), r.compat, 1463 r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, 1464 r.persistentState, results, newIntents, !andResume, 1465 mService.isNextTransitionForward(), profilerInfo); 1466 1467 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { 1468 // This may be a heavy-weight process! Note that the package 1469 // manager will ensure that only activity can run in the main 1470 // process of the .apk, which is the only thing that will be 1471 // considered heavy-weight. 1472 if (app.processName.equals(app.info.packageName)) { 1473 if (mService.mHeavyWeightProcess != null 1474 && mService.mHeavyWeightProcess != app) { 1475 Slog.w(TAG, "Starting new heavy weight process " + app 1476 + " when already running " 1477 + mService.mHeavyWeightProcess); 1478 } 1479 mService.mHeavyWeightProcess = app; 1480 Message msg = mService.mHandler.obtainMessage( 1481 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1482 msg.obj = r; 1483 mService.mHandler.sendMessage(msg); 1484 } 1485 } 1486 1487 } catch (RemoteException e) { 1488 if (r.launchFailed) { 1489 // This is the second time we failed -- finish activity 1490 // and give up. 1491 Slog.e(TAG, "Second failure launching " 1492 + r.intent.getComponent().flattenToShortString() 1493 + ", giving up", e); 1494 mService.appDiedLocked(app); 1495 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1496 "2nd-crash", false); 1497 return false; 1498 } 1499 1500 // This is the first time we failed -- restart process and 1501 // retry. 1502 r.launchFailed = true; 1503 app.activities.remove(r); 1504 throw e; 1505 } 1506 } finally { 1507 endDeferResume(); 1508 } 1509 1510 r.launchFailed = false; 1511 if (stack.updateLRUListLocked(r)) { 1512 Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); 1513 } 1514 1515 if (andResume && readyToResume()) { 1516 // As part of the process of launching, ActivityThread also performs 1517 // a resume. 1518 stack.minimalResumeActivityLocked(r); 1519 } else { 1520 // This activity is not starting in the resumed state... which should look like we asked 1521 // it to pause+stop (but remain visible), and it has done so and reported back the 1522 // current icicle and other state. 1523 if (DEBUG_STATES) Slog.v(TAG_STATES, 1524 "Moving to PAUSED: " + r + " (starting in paused state)"); 1525 r.state = PAUSED; 1526 } 1527 1528 // Launch the new version setup screen if needed. We do this -after- 1529 // launching the initial activity (that is, home), so that it can have 1530 // a chance to initialize itself while in the background, making the 1531 // switch back to it faster and look better. 1532 if (isFocusedStack(stack)) { 1533 mService.startSetupActivityLocked(); 1534 } 1535 1536 // Update any services we are bound to that might care about whether 1537 // their client may have activities. 1538 if (r.app != null) { 1539 mService.mServices.updateServiceConnectionActivitiesLocked(r.app); 1540 } 1541 1542 return true; 1543 } 1544 1545 private void logIfTransactionTooLarge(Intent intent, Bundle icicle) { 1546 int extrasSize = 0; 1547 if (intent != null) { 1548 final Bundle extras = intent.getExtras(); 1549 if (extras != null) { 1550 extrasSize = extras.getSize(); 1551 } 1552 } 1553 int icicleSize = (icicle == null ? 0 : icicle.getSize()); 1554 if (extrasSize + icicleSize > 200000) { 1555 Slog.e(TAG, "Transaction too large, intent: " + intent + ", extras size: " + extrasSize 1556 + ", icicle size: " + icicleSize); 1557 } 1558 } 1559 1560 void startSpecificActivityLocked(ActivityRecord r, 1561 boolean andResume, boolean checkConfig) { 1562 // Is this activity's application already running? 1563 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1564 r.info.applicationInfo.uid, true); 1565 1566 r.getStack().setLaunchTime(r); 1567 1568 if (app != null && app.thread != null) { 1569 try { 1570 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1571 || !"android".equals(r.info.packageName)) { 1572 // Don't add this if it is a platform component that is marked 1573 // to run in multiple processes, because this is actually 1574 // part of the framework so doesn't make sense to track as a 1575 // separate apk in the process. 1576 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, 1577 mService.mProcessStats); 1578 } 1579 realStartActivityLocked(r, app, andResume, checkConfig); 1580 return; 1581 } catch (RemoteException e) { 1582 Slog.w(TAG, "Exception when starting activity " 1583 + r.intent.getComponent().flattenToShortString(), e); 1584 } 1585 1586 // If a dead object exception was thrown -- fall through to 1587 // restart the application. 1588 } 1589 1590 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1591 "activity", r.intent.getComponent(), false, false, true); 1592 } 1593 1594 boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, 1595 String resultWho, int requestCode, int callingPid, int callingUid, 1596 String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp, 1597 ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options) { 1598 final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, 1599 callingUid); 1600 if (startAnyPerm == PERMISSION_GRANTED) { 1601 return true; 1602 } 1603 final int componentRestriction = getComponentRestrictionForCallingPackage( 1604 aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity); 1605 final int actionRestriction = getActionRestrictionForCallingPackage( 1606 intent.getAction(), callingPackage, callingPid, callingUid); 1607 if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION 1608 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1609 if (resultRecord != null) { 1610 resultStack.sendActivityResultLocked(-1, 1611 resultRecord, resultWho, requestCode, 1612 Activity.RESULT_CANCELED, null); 1613 } 1614 final String msg; 1615 if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1616 msg = "Permission Denial: starting " + intent.toString() 1617 + " from " + callerApp + " (pid=" + callingPid 1618 + ", uid=" + callingUid + ")" + " with revoked permission " 1619 + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); 1620 } else if (!aInfo.exported) { 1621 msg = "Permission Denial: starting " + intent.toString() 1622 + " from " + callerApp + " (pid=" + callingPid 1623 + ", uid=" + callingUid + ")" 1624 + " not exported from uid " + aInfo.applicationInfo.uid; 1625 } else { 1626 msg = "Permission Denial: starting " + intent.toString() 1627 + " from " + callerApp + " (pid=" + callingPid 1628 + ", uid=" + callingUid + ")" 1629 + " requires " + aInfo.permission; 1630 } 1631 Slog.w(TAG, msg); 1632 throw new SecurityException(msg); 1633 } 1634 1635 if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) { 1636 final String message = "Appop Denial: starting " + intent.toString() 1637 + " from " + callerApp + " (pid=" + callingPid 1638 + ", uid=" + callingUid + ")" 1639 + " requires " + AppOpsManager.permissionToOp( 1640 ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction())); 1641 Slog.w(TAG, message); 1642 return false; 1643 } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) { 1644 final String message = "Appop Denial: starting " + intent.toString() 1645 + " from " + callerApp + " (pid=" + callingPid 1646 + ", uid=" + callingUid + ")" 1647 + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission); 1648 Slog.w(TAG, message); 1649 return false; 1650 } 1651 if (options != null) { 1652 if (options.getLaunchTaskId() != INVALID_STACK_ID) { 1653 final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS, 1654 callingPid, callingUid); 1655 if (startInTaskPerm == PERMISSION_DENIED) { 1656 final String msg = "Permission Denial: starting " + intent.toString() 1657 + " from " + callerApp + " (pid=" + callingPid 1658 + ", uid=" + callingUid + ") with launchTaskId=" 1659 + options.getLaunchTaskId(); 1660 Slog.w(TAG, msg); 1661 throw new SecurityException(msg); 1662 } 1663 } 1664 // Check if someone tries to launch an activity on a private display with a different 1665 // owner. 1666 final int launchDisplayId = options.getLaunchDisplayId(); 1667 if (launchDisplayId != INVALID_DISPLAY && !isCallerAllowedToLaunchOnDisplay(callingPid, 1668 callingUid, launchDisplayId, aInfo)) { 1669 final String msg = "Permission Denial: starting " + intent.toString() 1670 + " from " + callerApp + " (pid=" + callingPid 1671 + ", uid=" + callingUid + ") with launchDisplayId=" 1672 + launchDisplayId; 1673 Slog.w(TAG, msg); 1674 throw new SecurityException(msg); 1675 } 1676 } 1677 1678 return true; 1679 } 1680 1681 /** Check if caller is allowed to launch activities on specified display. */ 1682 boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, 1683 ActivityInfo aInfo) { 1684 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId 1685 + " callingPid=" + callingPid + " callingUid=" + callingUid); 1686 1687 if (callingPid == -1 && callingUid == -1) { 1688 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: no caller info, skip check"); 1689 return true; 1690 } 1691 1692 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(launchDisplayId); 1693 if (activityDisplay == null) { 1694 Slog.w(TAG, "Launch on display check: display not found"); 1695 return false; 1696 } 1697 1698 // Check if the caller has enough privileges to embed activities and launch to private 1699 // displays. 1700 final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid, 1701 callingUid); 1702 if (startAnyPerm == PERMISSION_GRANTED) { 1703 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1704 + " allow launch any on display"); 1705 return true; 1706 } 1707 1708 // Check if caller is already present on display 1709 final boolean uidPresentOnDisplay = activityDisplay.isUidPresent(callingUid); 1710 1711 final int displayOwnerUid = activityDisplay.mDisplay.getOwnerUid(); 1712 if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL && displayOwnerUid != SYSTEM_UID 1713 && displayOwnerUid != aInfo.applicationInfo.uid) { 1714 // Limit launching on virtual displays, because their contents can be read from Surface 1715 // by apps that created them. 1716 if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 1717 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1718 + " disallow launch on virtual display for not-embedded activity."); 1719 return false; 1720 } 1721 // Check if the caller is allowed to embed activities from other apps. 1722 if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid) 1723 == PERMISSION_DENIED && !uidPresentOnDisplay) { 1724 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1725 + " disallow activity embedding without permission."); 1726 return false; 1727 } 1728 } 1729 1730 if (!activityDisplay.isPrivate()) { 1731 // Anyone can launch on a public display. 1732 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1733 + " allow launch on public display"); 1734 return true; 1735 } 1736 1737 // Check if the caller is the owner of the display. 1738 if (displayOwnerUid == callingUid) { 1739 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1740 + " allow launch for owner of the display"); 1741 return true; 1742 } 1743 1744 if (uidPresentOnDisplay) { 1745 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1746 + " allow launch for caller present on the display"); 1747 return true; 1748 } 1749 1750 Slog.w(TAG, "Launch on display check: denied"); 1751 return false; 1752 } 1753 1754 /** Update lists of UIDs that are present on displays and have access to them. */ 1755 void updateUIDsPresentOnDisplay() { 1756 mDisplayAccessUIDs.clear(); 1757 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1758 final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 1759 // Only bother calculating the whitelist for private displays 1760 if (activityDisplay.isPrivate()) { 1761 mDisplayAccessUIDs.append( 1762 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs()); 1763 } 1764 } 1765 // Store updated lists in DisplayManager. Callers from outside of AM should get them there. 1766 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs); 1767 } 1768 1769 UserInfo getUserInfo(int userId) { 1770 final long identity = Binder.clearCallingIdentity(); 1771 try { 1772 return UserManager.get(mService.mContext).getUserInfo(userId); 1773 } finally { 1774 Binder.restoreCallingIdentity(identity); 1775 } 1776 } 1777 1778 private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, 1779 String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { 1780 if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, 1781 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) 1782 == PERMISSION_DENIED) { 1783 return ACTIVITY_RESTRICTION_PERMISSION; 1784 } 1785 1786 if (activityInfo.permission == null) { 1787 return ACTIVITY_RESTRICTION_NONE; 1788 } 1789 1790 final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); 1791 if (opCode == AppOpsManager.OP_NONE) { 1792 return ACTIVITY_RESTRICTION_NONE; 1793 } 1794 1795 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1796 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1797 if (!ignoreTargetSecurity) { 1798 return ACTIVITY_RESTRICTION_APPOP; 1799 } 1800 } 1801 1802 return ACTIVITY_RESTRICTION_NONE; 1803 } 1804 1805 private int getActionRestrictionForCallingPackage(String action, 1806 String callingPackage, int callingPid, int callingUid) { 1807 if (action == null) { 1808 return ACTIVITY_RESTRICTION_NONE; 1809 } 1810 1811 String permission = ACTION_TO_RUNTIME_PERMISSION.get(action); 1812 if (permission == null) { 1813 return ACTIVITY_RESTRICTION_NONE; 1814 } 1815 1816 final PackageInfo packageInfo; 1817 try { 1818 packageInfo = mService.mContext.getPackageManager() 1819 .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS); 1820 } catch (PackageManager.NameNotFoundException e) { 1821 Slog.i(TAG, "Cannot find package info for " + callingPackage); 1822 return ACTIVITY_RESTRICTION_NONE; 1823 } 1824 1825 if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) { 1826 return ACTIVITY_RESTRICTION_NONE; 1827 } 1828 1829 if (mService.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) { 1830 return ACTIVITY_RESTRICTION_PERMISSION; 1831 } 1832 1833 final int opCode = AppOpsManager.permissionToOpCode(permission); 1834 if (opCode == AppOpsManager.OP_NONE) { 1835 return ACTIVITY_RESTRICTION_NONE; 1836 } 1837 1838 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1839 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1840 return ACTIVITY_RESTRICTION_APPOP; 1841 } 1842 1843 return ACTIVITY_RESTRICTION_NONE; 1844 } 1845 1846 void setLaunchSource(int uid) { 1847 mLaunchingActivity.setWorkSource(new WorkSource(uid)); 1848 } 1849 1850 void acquireLaunchWakelock() { 1851 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1852 throw new IllegalStateException("Calling must be system uid"); 1853 } 1854 mLaunchingActivity.acquire(); 1855 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1856 // To be safe, don't allow the wake lock to be held for too long. 1857 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1858 } 1859 } 1860 1861 /** 1862 * Called when the frontmost task is idle. 1863 * @return the state of mService.mBooting before this was called. 1864 */ 1865 private boolean checkFinishBootingLocked() { 1866 final boolean booting = mService.mBooting; 1867 boolean enableScreen = false; 1868 mService.mBooting = false; 1869 if (!mService.mBooted) { 1870 mService.mBooted = true; 1871 enableScreen = true; 1872 } 1873 if (booting || enableScreen) { 1874 mService.postFinishBooting(booting, enableScreen); 1875 } 1876 return booting; 1877 } 1878 1879 // Checked. 1880 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1881 boolean processPausingActivities, Configuration config) { 1882 if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token); 1883 1884 ArrayList<ActivityRecord> finishes = null; 1885 ArrayList<UserState> startingUsers = null; 1886 int NS = 0; 1887 int NF = 0; 1888 boolean booting = false; 1889 boolean activityRemoved = false; 1890 1891 ActivityRecord r = ActivityRecord.forTokenLocked(token); 1892 if (r != null) { 1893 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers=" 1894 + Debug.getCallers(4)); 1895 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1896 r.finishLaunchTickingLocked(); 1897 if (fromTimeout) { 1898 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1899 } 1900 1901 // This is a hack to semi-deal with a race condition 1902 // in the client where it can be constructed with a 1903 // newer configuration from when we asked it to launch. 1904 // We'll update with whatever configuration it now says 1905 // it used to launch. 1906 if (config != null) { 1907 r.setLastReportedGlobalConfiguration(config); 1908 } 1909 1910 // We are now idle. If someone is waiting for a thumbnail from 1911 // us, we can now deliver. 1912 r.idle = true; 1913 1914 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1915 if (isFocusedStack(r.getStack()) || fromTimeout) { 1916 booting = checkFinishBootingLocked(); 1917 } 1918 } 1919 1920 if (allResumedActivitiesIdle()) { 1921 if (r != null) { 1922 mService.scheduleAppGcsLocked(); 1923 } 1924 1925 if (mLaunchingActivity.isHeld()) { 1926 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1927 if (VALIDATE_WAKE_LOCK_CALLER && 1928 Binder.getCallingUid() != Process.myUid()) { 1929 throw new IllegalStateException("Calling must be system uid"); 1930 } 1931 mLaunchingActivity.release(); 1932 } 1933 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1934 } 1935 1936 // Atomically retrieve all of the other things to do. 1937 final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r, 1938 true /* remove */, processPausingActivities); 1939 NS = stops != null ? stops.size() : 0; 1940 if ((NF = mFinishingActivities.size()) > 0) { 1941 finishes = new ArrayList<>(mFinishingActivities); 1942 mFinishingActivities.clear(); 1943 } 1944 1945 if (mStartingUsers.size() > 0) { 1946 startingUsers = new ArrayList<>(mStartingUsers); 1947 mStartingUsers.clear(); 1948 } 1949 1950 // Stop any activities that are scheduled to do so but have been 1951 // waiting for the next one to start. 1952 for (int i = 0; i < NS; i++) { 1953 r = stops.get(i); 1954 final ActivityStack stack = r.getStack(); 1955 if (stack != null) { 1956 if (r.finishing) { 1957 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1958 } else { 1959 stack.stopActivityLocked(r); 1960 } 1961 } 1962 } 1963 1964 // Finish any activities that are scheduled to do so but have been 1965 // waiting for the next one to start. 1966 for (int i = 0; i < NF; i++) { 1967 r = finishes.get(i); 1968 final ActivityStack stack = r.getStack(); 1969 if (stack != null) { 1970 activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle"); 1971 } 1972 } 1973 1974 if (!booting) { 1975 // Complete user switch 1976 if (startingUsers != null) { 1977 for (int i = 0; i < startingUsers.size(); i++) { 1978 mService.mUserController.finishUserSwitch(startingUsers.get(i)); 1979 } 1980 } 1981 } 1982 1983 mService.trimApplications(); 1984 //dump(); 1985 //mWindowManager.dump(); 1986 1987 if (activityRemoved) { 1988 resumeFocusedStackTopActivityLocked(); 1989 } 1990 1991 return r; 1992 } 1993 1994 boolean handleAppDiedLocked(ProcessRecord app) { 1995 boolean hasVisibleActivities = false; 1996 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1997 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1998 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1999 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 2000 } 2001 } 2002 return hasVisibleActivities; 2003 } 2004 2005 void closeSystemDialogsLocked() { 2006 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2007 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2008 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2009 stacks.get(stackNdx).closeSystemDialogsLocked(); 2010 } 2011 } 2012 } 2013 2014 void removeUserLocked(int userId) { 2015 mUserStackInFront.delete(userId); 2016 } 2017 2018 /** 2019 * Update the last used stack id for non-current user (current user's last 2020 * used stack is the focused stack) 2021 */ 2022 void updateUserStackLocked(int userId, ActivityStack stack) { 2023 if (userId != mCurrentUser) { 2024 mUserStackInFront.put(userId, stack != null ? stack.getStackId() : HOME_STACK_ID); 2025 } 2026 } 2027 2028 /** 2029 * @return true if some activity was finished (or would have finished if doit were true). 2030 */ 2031 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, 2032 boolean doit, boolean evenPersistent, int userId) { 2033 boolean didSomething = false; 2034 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2035 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2036 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2037 final ActivityStack stack = stacks.get(stackNdx); 2038 if (stack.finishDisabledPackageActivitiesLocked( 2039 packageName, filterByClasses, doit, evenPersistent, userId)) { 2040 didSomething = true; 2041 } 2042 } 2043 } 2044 return didSomething; 2045 } 2046 2047 void updatePreviousProcessLocked(ActivityRecord r) { 2048 // Now that this process has stopped, we may want to consider 2049 // it to be the previous app to try to keep around in case 2050 // the user wants to return to it. 2051 2052 // First, found out what is currently the foreground app, so that 2053 // we don't blow away the previous app if this activity is being 2054 // hosted by the process that is actually still the foreground. 2055 ProcessRecord fgApp = null; 2056 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2057 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2058 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2059 final ActivityStack stack = stacks.get(stackNdx); 2060 if (isFocusedStack(stack)) { 2061 if (stack.mResumedActivity != null) { 2062 fgApp = stack.mResumedActivity.app; 2063 } else if (stack.mPausingActivity != null) { 2064 fgApp = stack.mPausingActivity.app; 2065 } 2066 break; 2067 } 2068 } 2069 } 2070 2071 // Now set this one as the previous process, only if that really 2072 // makes sense to. 2073 if (r.app != null && fgApp != null && r.app != fgApp 2074 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2075 && r.app != mService.mHomeProcess) { 2076 mService.mPreviousProcess = r.app; 2077 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2078 } 2079 } 2080 2081 boolean resumeFocusedStackTopActivityLocked() { 2082 return resumeFocusedStackTopActivityLocked(null, null, null); 2083 } 2084 2085 boolean resumeFocusedStackTopActivityLocked( 2086 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 2087 2088 if (!readyToResume()) { 2089 return false; 2090 } 2091 2092 if (targetStack != null && isFocusedStack(targetStack)) { 2093 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 2094 } 2095 2096 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); 2097 if (r == null || r.state != RESUMED) { 2098 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); 2099 } else if (r.state == RESUMED) { 2100 // Kick off any lingering app transitions form the MoveTaskToFront operation. 2101 mFocusedStack.executeAppTransition(targetOptions); 2102 } 2103 2104 return false; 2105 } 2106 2107 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) { 2108 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2109 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2110 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2111 stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo); 2112 } 2113 } 2114 } 2115 2116 TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) { 2117 TaskRecord finishedTask = null; 2118 ActivityStack focusedStack = getFocusedStack(); 2119 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2120 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2121 final int numStacks = stacks.size(); 2122 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2123 final ActivityStack stack = stacks.get(stackNdx); 2124 TaskRecord t = stack.finishTopRunningActivityLocked(app, reason); 2125 if (stack == focusedStack || finishedTask == null) { 2126 finishedTask = t; 2127 } 2128 } 2129 } 2130 return finishedTask; 2131 } 2132 2133 void finishVoiceTask(IVoiceInteractionSession session) { 2134 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2135 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2136 final int numStacks = stacks.size(); 2137 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2138 final ActivityStack stack = stacks.get(stackNdx); 2139 stack.finishVoiceTask(session); 2140 } 2141 } 2142 } 2143 2144 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options, 2145 String reason, boolean forceNonResizeable) { 2146 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2147 mUserLeaving = true; 2148 } 2149 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 2150 // Caller wants the home activity moved with it. To accomplish this, 2151 // we'll just indicate that this task returns to the home task. 2152 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2153 } 2154 ActivityStack currentStack = task.getStack(); 2155 if (currentStack == null) { 2156 Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task=" 2157 + task + " to front. Stack is null"); 2158 return; 2159 } 2160 2161 if (task.isResizeable() && options != null) { 2162 int stackId = options.getLaunchStackId(); 2163 if (canUseActivityOptionsLaunchBounds(options, stackId)) { 2164 final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds()); 2165 task.updateOverrideConfiguration(bounds); 2166 if (stackId == INVALID_STACK_ID) { 2167 stackId = task.getLaunchStackId(); 2168 } 2169 if (stackId != currentStack.mStackId) { 2170 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, 2171 DEFER_RESUME, "findTaskToMoveToFrontLocked"); 2172 stackId = currentStack.mStackId; 2173 // moveTaskToStackUncheckedLocked() should already placed the task on top, 2174 // still need moveTaskToFrontLocked() below for any transition settings. 2175 } 2176 if (StackId.resizeStackWithLaunchBounds(stackId)) { 2177 resizeStackLocked(stackId, bounds, 2178 null /* tempTaskBounds */, null /* tempTaskInsetBounds */, 2179 !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME); 2180 } else { 2181 // WM resizeTask must be done after the task is moved to the correct stack, 2182 // because Task's setBounds() also updates dim layer's bounds, but that has 2183 // dependency on the stack. 2184 task.resizeWindowContainer(); 2185 } 2186 } 2187 } 2188 2189 final ActivityRecord r = task.getTopActivity(); 2190 currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options, 2191 r == null ? null : r.appTimeTracker, reason); 2192 2193 if (DEBUG_STACK) Slog.d(TAG_STACK, 2194 "findTaskToMoveToFront: moved to front of stack=" + currentStack); 2195 2196 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, DEFAULT_DISPLAY, 2197 currentStack.mStackId, forceNonResizeable); 2198 } 2199 2200 boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) { 2201 // We use the launch bounds in the activity options is the device supports freeform 2202 // window management or is launching into the pinned stack. 2203 if (options.getLaunchBounds() == null) { 2204 return false; 2205 } 2206 return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID) 2207 || mService.mSupportsFreeformWindowManagement; 2208 } 2209 2210 protected <T extends ActivityStack> T getStack(int stackId) { 2211 return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 2212 } 2213 2214 protected <T extends ActivityStack> T getStack(int stackId, boolean createStaticStackIfNeeded, 2215 boolean createOnTop) { 2216 final ActivityStack stack = mStacks.get(stackId); 2217 if (stack != null) { 2218 return (T) stack; 2219 } 2220 if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) { 2221 return null; 2222 } 2223 if (stackId == DOCKED_STACK_ID) { 2224 // Make sure recents stack exist when creating a dock stack as it normally need to be on 2225 // the other side of the docked stack and we make visibility decisions based on that. 2226 getStack(RECENTS_STACK_ID, CREATE_IF_NEEDED, createOnTop); 2227 } 2228 return (T) createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop); 2229 } 2230 2231 /** 2232 * Get a topmost stack on the display, that is a valid launch stack for specified activity. 2233 * If there is no such stack, new dynamic stack can be created. 2234 * @param displayId Target display. 2235 * @param r Activity that should be launched there. 2236 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. 2237 */ 2238 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r) { 2239 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 2240 if (activityDisplay == null) { 2241 throw new IllegalArgumentException( 2242 "Display with displayId=" + displayId + " not found."); 2243 } 2244 2245 // Return the topmost valid stack on the display. 2246 for (int i = activityDisplay.mStacks.size() - 1; i >= 0; --i) { 2247 final ActivityStack stack = activityDisplay.mStacks.get(i); 2248 if (mService.mActivityStarter.isValidLaunchStackId(stack.mStackId, displayId, r)) { 2249 return stack; 2250 } 2251 } 2252 2253 // If there is no valid stack on the external display - check if new dynamic stack will do. 2254 if (displayId != Display.DEFAULT_DISPLAY) { 2255 final int newDynamicStackId = getNextStackId(); 2256 if (mService.mActivityStarter.isValidLaunchStackId(newDynamicStackId, displayId, r)) { 2257 return createStackOnDisplay(newDynamicStackId, displayId, true /*onTop*/); 2258 } 2259 } 2260 2261 Slog.w(TAG, "getValidLaunchStackOnDisplay: can't launch on displayId " + displayId); 2262 return null; 2263 } 2264 2265 ArrayList<ActivityStack> getStacks() { 2266 ArrayList<ActivityStack> allStacks = new ArrayList<>(); 2267 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2268 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 2269 } 2270 return allStacks; 2271 } 2272 2273 ArrayList<ActivityStack> getStacksOnDefaultDisplay() { 2274 return mActivityDisplays.valueAt(DEFAULT_DISPLAY).mStacks; 2275 } 2276 2277 /** 2278 * Get next focusable stack in the system. This will search across displays and stacks 2279 * in last-focused order for a focusable and visible stack, different from the target stack. 2280 * 2281 * @param currentFocus The stack that previously had focus and thus needs to be ignored when 2282 * searching for next candidate. 2283 * @return Next focusable {@link ActivityStack}, null if not found. 2284 */ 2285 ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus) { 2286 mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds); 2287 2288 for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) { 2289 final int displayId = mTmpOrderedDisplayIds.get(i); 2290 // If a display is registered in WM, it must also be available in AM. 2291 @SuppressWarnings("ConstantConditions") 2292 final List<ActivityStack> stacks = getActivityDisplayOrCreateLocked(displayId).mStacks; 2293 for (int j = stacks.size() - 1; j >= 0; --j) { 2294 final ActivityStack stack = stacks.get(j); 2295 if (stack != currentFocus && stack.isFocusable() 2296 && stack.shouldBeVisible(null) != STACK_INVISIBLE) { 2297 return stack; 2298 } 2299 } 2300 } 2301 2302 return null; 2303 } 2304 2305 /** 2306 * Get next valid stack for launching provided activity in the system. This will search across 2307 * displays and stacks in last-focused order for a focusable and visible stack, except those 2308 * that are on a currently focused display. 2309 * 2310 * @param r The activity that is being launched. 2311 * @param currentFocus The display that previously had focus and thus needs to be ignored when 2312 * searching for the next candidate. 2313 * @return Next valid {@link ActivityStack}, null if not found. 2314 */ 2315 ActivityStack getNextValidLaunchStackLocked(@NonNull ActivityRecord r, int currentFocus) { 2316 mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds); 2317 for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) { 2318 final int displayId = mTmpOrderedDisplayIds.get(i); 2319 if (displayId == currentFocus) { 2320 continue; 2321 } 2322 final ActivityStack stack = getValidLaunchStackOnDisplay(displayId, r); 2323 if (stack != null) { 2324 return stack; 2325 } 2326 } 2327 return null; 2328 } 2329 2330 ActivityRecord getHomeActivity() { 2331 return getHomeActivityForUser(mCurrentUser); 2332 } 2333 2334 ActivityRecord getHomeActivityForUser(int userId) { 2335 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2336 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2337 final TaskRecord task = tasks.get(taskNdx); 2338 if (task.isHomeTask()) { 2339 final ArrayList<ActivityRecord> activities = task.mActivities; 2340 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2341 final ActivityRecord r = activities.get(activityNdx); 2342 if (r.isHomeActivity() 2343 && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) { 2344 return r; 2345 } 2346 } 2347 } 2348 } 2349 return null; 2350 } 2351 2352 /** 2353 * Returns if a stack should be treated as if it's docked. Returns true if the stack is 2354 * the docked stack itself, or if it's side-by-side to the docked stack. 2355 */ 2356 boolean isStackDockedInEffect(int stackId) { 2357 return stackId == DOCKED_STACK_ID || 2358 (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null); 2359 } 2360 2361 void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, 2362 boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) { 2363 if (stackId == DOCKED_STACK_ID) { 2364 resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null, 2365 preserveWindows, deferResume); 2366 return; 2367 } 2368 final ActivityStack stack = getStack(stackId); 2369 if (stack == null) { 2370 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); 2371 return; 2372 } 2373 2374 if (!allowResizeInDockedMode && !StackId.tasksAreFloating(stackId) && 2375 getStack(DOCKED_STACK_ID) != null) { 2376 // If the docked stack exists, don't resize non-floating stacks independently of the 2377 // size computed from the docked stack size (otherwise they will be out of sync) 2378 return; 2379 } 2380 2381 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId); 2382 mWindowManager.deferSurfaceLayout(); 2383 try { 2384 stack.resize(bounds, tempTaskBounds, tempTaskInsetBounds); 2385 if (!deferResume) { 2386 stack.ensureVisibleActivitiesConfigurationLocked( 2387 stack.topRunningActivityLocked(), preserveWindows); 2388 } 2389 } finally { 2390 mWindowManager.continueSurfaceLayout(); 2391 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2392 } 2393 } 2394 2395 void deferUpdateBounds(int stackId) { 2396 final ActivityStack stack = getStack(stackId); 2397 if (stack != null) { 2398 stack.deferUpdateBounds(); 2399 } 2400 } 2401 2402 void continueUpdateBounds(int stackId) { 2403 final ActivityStack stack = getStack(stackId); 2404 if (stack != null) { 2405 stack.continueUpdateBounds(); 2406 } 2407 } 2408 2409 void notifyAppTransitionDone() { 2410 continueUpdateBounds(RECENTS_STACK_ID); 2411 for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) { 2412 final int taskId = mResizingTasksDuringAnimation.valueAt(i); 2413 final TaskRecord task = 2414 anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID); 2415 if (task != null) { 2416 task.setTaskDockedResizing(false); 2417 } 2418 } 2419 mResizingTasksDuringAnimation.clear(); 2420 } 2421 2422 private void moveTasksToFullscreenStackInSurfaceTransaction(int fromStackId, 2423 boolean onTop) { 2424 2425 final ActivityStack stack = getStack(fromStackId); 2426 if (stack == null) { 2427 return; 2428 } 2429 2430 mWindowManager.deferSurfaceLayout(); 2431 try { 2432 if (fromStackId == DOCKED_STACK_ID) { 2433 // We are moving all tasks from the docked stack to the fullscreen stack, 2434 // which is dismissing the docked stack, so resize all other stacks to 2435 // fullscreen here already so we don't end up with resize trashing. 2436 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2437 if (StackId.isResizeableByDockedStack(i)) { 2438 ActivityStack otherStack = getStack(i); 2439 if (otherStack != null) { 2440 resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS, 2441 true /* allowResizeInDockedMode */, DEFER_RESUME); 2442 } 2443 } 2444 } 2445 2446 // Also disable docked stack resizing since we have manually adjusted the 2447 // size of other stacks above and we don't want to trigger a docked stack 2448 // resize when we remove task from it below and it is detached from the 2449 // display because it no longer contains any tasks. 2450 mAllowDockedStackResize = false; 2451 } else if (fromStackId == PINNED_STACK_ID) { 2452 if (onTop) { 2453 // Log if we are expanding the PiP to fullscreen 2454 MetricsLogger.action(mService.mContext, 2455 ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN); 2456 } 2457 } 2458 ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID); 2459 final boolean isFullscreenStackVisible = fullscreenStack != null && 2460 fullscreenStack.shouldBeVisible(null) == STACK_VISIBLE; 2461 // If we are moving from the pinned stack, then the animation takes care of updating 2462 // the picture-in-picture mode. 2463 final boolean schedulePictureInPictureModeChange = (fromStackId == PINNED_STACK_ID); 2464 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2465 final int size = tasks.size(); 2466 if (onTop) { 2467 for (int i = 0; i < size; i++) { 2468 final TaskRecord task = tasks.get(i); 2469 final boolean isTopTask = i == (size - 1); 2470 if (fromStackId == PINNED_STACK_ID) { 2471 // Update the return-to to reflect where the pinned stack task was moved 2472 // from so that we retain the stack that was previously visible if the 2473 // pinned stack is recreated. See moveActivityToPinnedStackLocked(). 2474 task.setTaskToReturnTo(isFullscreenStackVisible && onTop ? 2475 APPLICATION_ACTIVITY_TYPE : HOME_ACTIVITY_TYPE); 2476 } 2477 // Defer resume until all the tasks have been moved to the fullscreen stack 2478 task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, 2479 REPARENT_MOVE_STACK_TO_FRONT, isTopTask /* animate */, DEFER_RESUME, 2480 schedulePictureInPictureModeChange, 2481 "moveTasksToFullscreenStack - onTop"); 2482 } 2483 } else { 2484 for (int i = 0; i < size; i++) { 2485 final TaskRecord task = tasks.get(i); 2486 // Position the tasks in the fullscreen stack in order at the bottom of the 2487 // stack. Also defer resume until all the tasks have been moved to the 2488 // fullscreen stack. 2489 task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, i /* position */, 2490 REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME, 2491 schedulePictureInPictureModeChange, 2492 "moveTasksToFullscreenStack - NOT_onTop"); 2493 } 2494 } 2495 2496 ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); 2497 resumeFocusedStackTopActivityLocked(); 2498 } finally { 2499 mAllowDockedStackResize = true; 2500 mWindowManager.continueSurfaceLayout(); 2501 } 2502 } 2503 2504 void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) { 2505 mWindowManager.inSurfaceTransaction( 2506 () -> moveTasksToFullscreenStackInSurfaceTransaction(fromStackId, onTop)); 2507 } 2508 2509 void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, 2510 Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, 2511 boolean preserveWindows) { 2512 resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds, 2513 tempOtherTaskBounds, tempOtherTaskInsetBounds, preserveWindows, 2514 false /* deferResume */); 2515 } 2516 2517 void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, 2518 Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, 2519 boolean preserveWindows, boolean deferResume) { 2520 2521 if (!mAllowDockedStackResize) { 2522 // Docked stack resize currently disabled. 2523 return; 2524 } 2525 2526 final ActivityStack stack = getStack(DOCKED_STACK_ID); 2527 if (stack == null) { 2528 Slog.w(TAG, "resizeDockedStackLocked: docked stack not found"); 2529 return; 2530 } 2531 2532 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack"); 2533 mWindowManager.deferSurfaceLayout(); 2534 try { 2535 // Don't allow re-entry while resizing. E.g. due to docked stack detaching. 2536 mAllowDockedStackResize = false; 2537 ActivityRecord r = stack.topRunningActivityLocked(); 2538 stack.resize(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds); 2539 2540 // TODO: Checking for isAttached might not be needed as if the user passes in null 2541 // dockedBounds then they want the docked stack to be dismissed. 2542 if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) { 2543 // The dock stack either was dismissed or went fullscreen, which is kinda the same. 2544 // In this case we make all other static stacks fullscreen and move all 2545 // docked stack tasks to the fullscreen stack. 2546 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP); 2547 2548 // stack shouldn't contain anymore activities, so nothing to resume. 2549 r = null; 2550 } else { 2551 // Docked stacks occupy a dedicated region on screen so the size of all other 2552 // static stacks need to be adjusted so they don't overlap with the docked stack. 2553 // We get the bounds to use from window manager which has been adjusted for any 2554 // screen controls and is also the same for all stacks. 2555 final Rect otherTaskRect = new Rect(); 2556 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2557 final ActivityStack current = getStack(i); 2558 if (current != null && StackId.isResizeableByDockedStack(i)) { 2559 current.getStackDockedModeBounds( 2560 tempOtherTaskBounds /* currentTempTaskBounds */, 2561 tempRect /* outStackBounds */, 2562 otherTaskRect /* outTempTaskBounds */, true /* ignoreVisibility */); 2563 2564 resizeStackLocked(i, !tempRect.isEmpty() ? tempRect : null, 2565 !otherTaskRect.isEmpty() ? otherTaskRect : tempOtherTaskBounds, 2566 tempOtherTaskInsetBounds, preserveWindows, 2567 true /* allowResizeInDockedMode */, deferResume); 2568 } 2569 } 2570 } 2571 if (!deferResume) { 2572 stack.ensureVisibleActivitiesConfigurationLocked(r, preserveWindows); 2573 } 2574 } finally { 2575 mAllowDockedStackResize = true; 2576 mWindowManager.continueSurfaceLayout(); 2577 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2578 } 2579 } 2580 2581 void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 2582 final PinnedActivityStack stack = getStack(PINNED_STACK_ID); 2583 if (stack == null) { 2584 Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found"); 2585 return; 2586 } 2587 2588 // It is possible for the bounds animation from the WM to call this but be delayed by 2589 // another AM call that is holding the AMS lock. In such a case, the pinnedBounds may be 2590 // incorrect if AMS.resizeStackWithBoundsFromWindowManager() is already called while waiting 2591 // for the AMS lock to be freed. So check and make sure these bounds are still good. 2592 final PinnedStackWindowController stackController = stack.getWindowContainerController(); 2593 if (stackController.pinnedStackResizeDisallowed()) { 2594 return; 2595 } 2596 2597 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack"); 2598 mWindowManager.deferSurfaceLayout(); 2599 try { 2600 ActivityRecord r = stack.topRunningActivityLocked(); 2601 Rect insetBounds = null; 2602 if (tempPinnedTaskBounds != null) { 2603 // We always use 0,0 as the position for the inset rect because 2604 // if we are getting insets at all in the pinned stack it must mean 2605 // we are headed for fullscreen. 2606 insetBounds = tempRect; 2607 insetBounds.top = 0; 2608 insetBounds.left = 0; 2609 insetBounds.right = tempPinnedTaskBounds.width(); 2610 insetBounds.bottom = tempPinnedTaskBounds.height(); 2611 } 2612 stack.resize(pinnedBounds, tempPinnedTaskBounds, insetBounds); 2613 stack.ensureVisibleActivitiesConfigurationLocked(r, false); 2614 } finally { 2615 mWindowManager.continueSurfaceLayout(); 2616 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2617 } 2618 } 2619 2620 ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) { 2621 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 2622 if (activityDisplay == null) { 2623 return null; 2624 } 2625 return createStack(stackId, activityDisplay, onTop); 2626 2627 } 2628 2629 ActivityStack createStack(int stackId, ActivityDisplay display, boolean onTop) { 2630 switch (stackId) { 2631 case PINNED_STACK_ID: 2632 return new PinnedActivityStack(display, stackId, this, mRecentTasks, onTop); 2633 default: 2634 return new ActivityStack(display, stackId, this, mRecentTasks, onTop); 2635 } 2636 } 2637 2638 void removeStackInSurfaceTransaction(int stackId) { 2639 final ActivityStack stack = getStack(stackId); 2640 if (stack == null) { 2641 return; 2642 } 2643 2644 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2645 if (stack.getStackId() == PINNED_STACK_ID) { 2646 /** 2647 * Workaround: Force-stop all the activities in the pinned stack before we reparent them 2648 * to the fullscreen stack. This is to guarantee that when we are removing a stack, 2649 * that the client receives onStop() before it is reparented. We do this by detaching 2650 * the stack from the display so that it will be considered invisible when 2651 * ensureActivitiesVisibleLocked() is called, and all of its activitys will be marked 2652 * invisible as well and added to the stopping list. After which we process the 2653 * stopping list by handling the idle. 2654 */ 2655 final PinnedActivityStack pinnedStack = (PinnedActivityStack) stack; 2656 pinnedStack.mForceHidden = true; 2657 pinnedStack.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); 2658 pinnedStack.mForceHidden = false; 2659 activityIdleInternalLocked(null, false /* fromTimeout */, 2660 true /* processPausingActivites */, null /* configuration */); 2661 2662 // Move all the tasks to the bottom of the fullscreen stack 2663 moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP); 2664 } else { 2665 for (int i = tasks.size() - 1; i >= 0; i--) { 2666 removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */, 2667 REMOVE_FROM_RECENTS); 2668 } 2669 } 2670 } 2671 2672 /** 2673 * Removes the stack associated with the given {@param stackId}. If the {@param stackId} is the 2674 * pinned stack, then its tasks are not explicitly removed when the stack is destroyed, but 2675 * instead moved back onto the fullscreen stack. 2676 */ 2677 void removeStackLocked(int stackId) { 2678 mWindowManager.inSurfaceTransaction( 2679 () -> removeStackInSurfaceTransaction(stackId)); 2680 } 2681 2682 /** 2683 * See {@link #removeTaskByIdLocked(int, boolean, boolean, boolean)} 2684 */ 2685 boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) { 2686 return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY); 2687 } 2688 2689 /** 2690 * Removes the task with the specified task id. 2691 * 2692 * @param taskId Identifier of the task to be removed. 2693 * @param killProcess Kill any process associated with the task if possible. 2694 * @param removeFromRecents Whether to also remove the task from recents. 2695 * @param pauseImmediately Pauses all task activities immediately without waiting for the 2696 * pause-complete callback from the activity. 2697 * @return Returns true if the given task was found and removed. 2698 */ 2699 boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, 2700 boolean pauseImmediately) { 2701 final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, 2702 INVALID_STACK_ID); 2703 if (tr != null) { 2704 tr.removeTaskActivitiesLocked(pauseImmediately); 2705 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents); 2706 if (tr.isPersistable) { 2707 mService.notifyTaskPersisterLocked(null, true); 2708 } 2709 return true; 2710 } 2711 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 2712 return false; 2713 } 2714 2715 void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents) { 2716 if (removeFromRecents) { 2717 mRecentTasks.remove(tr); 2718 tr.removedFromRecents(); 2719 } 2720 ComponentName component = tr.getBaseIntent().getComponent(); 2721 if (component == null) { 2722 Slog.w(TAG, "No component for base intent of task: " + tr); 2723 return; 2724 } 2725 2726 // Find any running services associated with this app and stop if needed. 2727 mService.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 2728 2729 if (!killProcess) { 2730 return; 2731 } 2732 2733 // Determine if the process(es) for this task should be killed. 2734 final String pkg = component.getPackageName(); 2735 ArrayList<ProcessRecord> procsToKill = new ArrayList<>(); 2736 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mService.mProcessNames.getMap(); 2737 for (int i = 0; i < pmap.size(); i++) { 2738 2739 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 2740 for (int j = 0; j < uids.size(); j++) { 2741 ProcessRecord proc = uids.valueAt(j); 2742 if (proc.userId != tr.userId) { 2743 // Don't kill process for a different user. 2744 continue; 2745 } 2746 if (proc == mService.mHomeProcess) { 2747 // Don't kill the home process along with tasks from the same package. 2748 continue; 2749 } 2750 if (!proc.pkgList.containsKey(pkg)) { 2751 // Don't kill process that is not associated with this task. 2752 continue; 2753 } 2754 2755 for (int k = 0; k < proc.activities.size(); k++) { 2756 TaskRecord otherTask = proc.activities.get(k).getTask(); 2757 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 2758 // Don't kill process(es) that has an activity in a different task that is 2759 // also in recents. 2760 return; 2761 } 2762 } 2763 2764 if (proc.foregroundServices) { 2765 // Don't kill process(es) with foreground service. 2766 return; 2767 } 2768 2769 // Add process to kill list. 2770 procsToKill.add(proc); 2771 } 2772 } 2773 2774 // Kill the running processes. 2775 for (int i = 0; i < procsToKill.size(); i++) { 2776 ProcessRecord pr = procsToKill.get(i); 2777 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND 2778 && pr.curReceivers.isEmpty()) { 2779 pr.kill("remove task", true); 2780 } else { 2781 // We delay killing processes that are not in the background or running a receiver. 2782 pr.waitingToKill = "remove task"; 2783 } 2784 } 2785 } 2786 2787 int getNextStackId() { 2788 while (true) { 2789 if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID 2790 && getStack(mNextFreeStackId) == null) { 2791 break; 2792 } 2793 mNextFreeStackId++; 2794 } 2795 return mNextFreeStackId; 2796 } 2797 2798 /** 2799 * Restores a recent task to a stack 2800 * @param task The recent task to be restored. 2801 * @param stackId The stack to restore the task to (default launch stack will be used 2802 * if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID} 2803 * or is not a static stack). 2804 * @return true if the task has been restored successfully. 2805 */ 2806 boolean restoreRecentTaskLocked(TaskRecord task, int stackId) { 2807 if (!StackId.isStaticStack(stackId)) { 2808 // If stack is not static (or stack id is invalid) - use the default one. 2809 // This means that tasks that were on external displays will be restored on the 2810 // primary display. 2811 stackId = task.getLaunchStackId(); 2812 } else if (stackId == DOCKED_STACK_ID && !task.supportsSplitScreen()) { 2813 // Preferred stack is the docked stack, but the task can't go in the docked stack. 2814 // Put it in the fullscreen stack. 2815 stackId = FULLSCREEN_WORKSPACE_STACK_ID; 2816 } 2817 2818 final ActivityStack currentStack = task.getStack(); 2819 if (currentStack != null) { 2820 // Task has already been restored once. See if we need to do anything more 2821 if (currentStack.mStackId == stackId) { 2822 // Nothing else to do since it is already restored in the right stack. 2823 return true; 2824 } 2825 // Remove current stack association, so we can re-associate the task with the 2826 // right stack below. 2827 currentStack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING); 2828 } 2829 2830 final ActivityStack stack = 2831 getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); 2832 2833 if (stack == null) { 2834 // What does this mean??? Not sure how we would get here... 2835 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2836 "Unable to find/create stack to restore recent task=" + task); 2837 return false; 2838 } 2839 2840 stack.addTask(task, false /* toTop */, "restoreRecentTask"); 2841 // TODO: move call for creation here and other place into Stack.addTask() 2842 task.createWindowContainer(false /* toTop */, true /* showForAllUsers */); 2843 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2844 "Added restored task=" + task + " to stack=" + stack); 2845 final ArrayList<ActivityRecord> activities = task.mActivities; 2846 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2847 activities.get(activityNdx).createWindowContainer(); 2848 } 2849 return true; 2850 } 2851 2852 /** 2853 * Move stack with all its existing content to specified display. 2854 * @param stackId Id of stack to move. 2855 * @param displayId Id of display to move stack to. 2856 * @param onTop Indicates whether container should be place on top or on bottom. 2857 */ 2858 void moveStackToDisplayLocked(int stackId, int displayId, boolean onTop) { 2859 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 2860 if (activityDisplay == null) { 2861 throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId=" 2862 + displayId); 2863 } 2864 final ActivityStack stack = mStacks.get(stackId); 2865 if (stack == null) { 2866 throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown stackId=" 2867 + stackId); 2868 } 2869 2870 final ActivityDisplay currentDisplay = stack.getDisplay(); 2871 if (currentDisplay == null) { 2872 throw new IllegalStateException("moveStackToDisplayLocked: Stack with stack=" + stack 2873 + " is not attached to any display."); 2874 } 2875 2876 if (currentDisplay.mDisplayId == displayId) { 2877 throw new IllegalArgumentException("Trying to move stack=" + stack 2878 + " to its current displayId=" + displayId); 2879 } 2880 2881 stack.reparent(activityDisplay, onTop); 2882 // TODO(multi-display): resize stacks properly if moved from split-screen. 2883 } 2884 2885 /** 2886 * Returns the reparent target stack, creating the stack if necessary. This call also enforces 2887 * the various checks on tasks that are going to be reparented from one stack to another. 2888 */ 2889 ActivityStack getReparentTargetStack(TaskRecord task, int stackId, boolean toTop) { 2890 final ActivityStack prevStack = task.getStack(); 2891 2892 // Check that we aren't reparenting to the same stack that the task is already in 2893 if (prevStack != null && prevStack.mStackId == stackId) { 2894 Slog.w(TAG, "Can not reparent to same stack, task=" + task 2895 + " already in stackId=" + stackId); 2896 return prevStack; 2897 } 2898 2899 // Ensure that we aren't trying to move into a multi-window stack without multi-window 2900 // support 2901 if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) { 2902 throw new IllegalArgumentException("Device doesn't support multi-window, can not" 2903 + " reparent task=" + task + " to stackId=" + stackId); 2904 } 2905 2906 // Ensure that we're not moving a task to a dynamic stack if device doesn't support 2907 // multi-display. 2908 // TODO(multi-display): Support non-dynamic stacks on secondary displays. 2909 if (StackId.isDynamicStack(stackId) && !mService.mSupportsMultiDisplay) { 2910 throw new IllegalArgumentException("Device doesn't support multi-display, can not" 2911 + " reparent task=" + task + " to stackId=" + stackId); 2912 } 2913 2914 // Ensure that we aren't trying to move into a freeform stack without freeform 2915 // support 2916 if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) { 2917 throw new IllegalArgumentException("Device doesn't support freeform, can not reparent" 2918 + " task=" + task); 2919 } 2920 2921 // We don't allow moving a unresizeable task to the docked stack since the docked stack is 2922 // used for split-screen mode and will cause things like the docked divider to show up. We 2923 // instead leave the task in its current stack or move it to the fullscreen stack if it 2924 // isn't currently in a stack. 2925 if (stackId == DOCKED_STACK_ID && !task.isResizeable()) { 2926 stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID; 2927 Slog.w(TAG, "Can not move unresizeable task=" + task + " to docked stack." 2928 + " Moving to stackId=" + stackId + " instead."); 2929 } 2930 2931 // Temporarily disable resizeablility of the task as we don't want it to be resized if, for 2932 // example, a docked stack is created which will lead to the stack we are moving from being 2933 // resized and and its resizeable tasks being resized. 2934 try { 2935 task.mTemporarilyUnresizable = true; 2936 return getStack(stackId, CREATE_IF_NEEDED, toTop); 2937 } finally { 2938 task.mTemporarilyUnresizable = false; 2939 } 2940 } 2941 2942 boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect destBounds) { 2943 final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 2944 if (stack == null) { 2945 throw new IllegalArgumentException( 2946 "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId); 2947 } 2948 2949 final ActivityRecord r = stack.topRunningActivityLocked(); 2950 if (r == null) { 2951 Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity" 2952 + " in stack=" + stack); 2953 return false; 2954 } 2955 2956 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { 2957 Slog.w(TAG, 2958 "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for " 2959 + " r=" + r); 2960 return false; 2961 } 2962 2963 moveActivityToPinnedStackLocked(r, null /* sourceBounds */, 0f /* aspectRatio */, 2964 true /* moveHomeStackToFront */, "moveTopActivityToPinnedStack"); 2965 return true; 2966 } 2967 2968 void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceHintBounds, float aspectRatio, 2969 boolean moveHomeStackToFront, String reason) { 2970 2971 mWindowManager.deferSurfaceLayout(); 2972 2973 // This will clear the pinned stack by moving an existing task to the full screen stack, 2974 // ensuring only one task is present. 2975 moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP); 2976 2977 // Need to make sure the pinned stack exist so we can resize it below... 2978 final PinnedActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP); 2979 2980 try { 2981 final TaskRecord task = r.getTask(); 2982 // Resize the pinned stack to match the current size of the task the activity we are 2983 // going to be moving is currently contained in. We do this to have the right starting 2984 // animation bounds for the pinned stack to the desired bounds the caller wants. 2985 resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */, 2986 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, 2987 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2988 2989 if (task.mActivities.size() == 1) { 2990 // There is only one activity in the task. So, we can just move the task over to 2991 // the stack without re-parenting the activity in a different task. We don't 2992 // move the home stack forward if we are currently entering picture-in-picture 2993 // while pausing because that changes the focused stack and may prevent the new 2994 // starting activity from resuming. 2995 if (moveHomeStackToFront && task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE 2996 && (r.state == RESUMED || !r.supportsEnterPipOnTaskSwitch)) { 2997 // Move the home stack forward if the task we just moved to the pinned stack 2998 // was launched from home so home should be visible behind it. 2999 moveHomeStackToFront(reason); 3000 } 3001 // Defer resume until below, and do not schedule PiP changes until we animate below 3002 task.reparent(PINNED_STACK_ID, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, 3003 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason); 3004 } else { 3005 // There are multiple activities in the task and moving the top activity should 3006 // reveal/leave the other activities in their original task. 3007 3008 // Currently, we don't support reparenting activities across tasks in two different 3009 // stacks, so instead, just create a new task in the same stack, reparent the 3010 // activity into that task, and then reparent the whole task to the new stack. This 3011 // ensures that all the necessary work to migrate states in the old and new stacks 3012 // is also done. 3013 final TaskRecord newTask = task.getStack().createTaskRecord( 3014 getNextTaskIdForUserLocked(r.userId), r.info, r.intent, null, null, true, 3015 r.mActivityType); 3016 r.reparent(newTask, MAX_VALUE, "moveActivityToStack"); 3017 3018 // Defer resume until below, and do not schedule PiP changes until we animate below 3019 newTask.reparent(PINNED_STACK_ID, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, 3020 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason); 3021 } 3022 3023 // Reset the state that indicates it can enter PiP while pausing after we've moved it 3024 // to the pinned stack 3025 r.supportsEnterPipOnTaskSwitch = false; 3026 } finally { 3027 mWindowManager.continueSurfaceLayout(); 3028 } 3029 3030 // Calculate the default bounds (don't use existing stack bounds as we may have just created 3031 // the stack, and schedule the start of the animation into PiP (the bounds animator that 3032 // is triggered by this is posted on another thread) 3033 final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio); 3034 3035 stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */, 3036 true /* fromFullscreen */); 3037 3038 // Update the visibility of all activities after the they have been reparented to the new 3039 // stack. This MUST run after the animation above is scheduled to ensure that the windows 3040 // drawn signal is scheduled after the bounds animation start call on the bounds animator 3041 // thread. 3042 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 3043 resumeFocusedStackTopActivityLocked(); 3044 3045 mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName, r.userId, 3046 r.getTask().taskId); 3047 } 3048 3049 /** Move activity with its stack to front and make the stack focused. */ 3050 boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) { 3051 if (r == null || !r.isFocusable()) { 3052 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, 3053 "moveActivityStackToFront: unfocusable r=" + r); 3054 return false; 3055 } 3056 3057 final TaskRecord task = r.getTask(); 3058 final ActivityStack stack = r.getStack(); 3059 if (stack == null) { 3060 Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: r=" 3061 + r + " task=" + task); 3062 return false; 3063 } 3064 3065 if (stack == mFocusedStack && stack.topRunningActivityLocked() == r) { 3066 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, 3067 "moveActivityStackToFront: already on top, r=" + r); 3068 return false; 3069 } 3070 3071 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, 3072 "moveActivityStackToFront: r=" + r); 3073 3074 stack.moveToFront(reason, task); 3075 return true; 3076 } 3077 3078 ActivityRecord findTaskLocked(ActivityRecord r, int displayId) { 3079 mTmpFindTaskResult.r = null; 3080 mTmpFindTaskResult.matchedByRootAffinity = false; 3081 ActivityRecord affinityMatch = null; 3082 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 3083 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3084 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3085 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3086 final ActivityStack stack = stacks.get(stackNdx); 3087 if (!checkActivityBelongsInStack(r, stack)) { 3088 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " 3089 + stack); 3090 continue; 3091 } 3092 stack.findTaskLocked(r, mTmpFindTaskResult); 3093 // It is possible to have tasks in multiple stacks with the same root affinity, so 3094 // we should keep looking after finding an affinity match to see if there is a 3095 // better match in another stack. Also, task affinity isn't a good enough reason 3096 // to target a display which isn't the source of the intent, so skip any affinity 3097 // matches not on the specified display. 3098 if (mTmpFindTaskResult.r != null) { 3099 if (!mTmpFindTaskResult.matchedByRootAffinity) { 3100 return mTmpFindTaskResult.r; 3101 } else if (mTmpFindTaskResult.r.getDisplayId() == displayId) { 3102 // Note: since the traversing through the stacks is top down, the floating 3103 // tasks should always have lower priority than any affinity-matching tasks 3104 // in the fullscreen stacks 3105 affinityMatch = mTmpFindTaskResult.r; 3106 } 3107 } 3108 } 3109 } 3110 3111 if (DEBUG_TASKS && affinityMatch == null) Slog.d(TAG_TASKS, "No task found"); 3112 return affinityMatch; 3113 } 3114 3115 /** 3116 * Checks that for the given activity {@param r}, its activity type matches the {@param stack} 3117 * type. 3118 */ 3119 private boolean checkActivityBelongsInStack(ActivityRecord r, ActivityStack stack) { 3120 if (r.isHomeActivity()) { 3121 return stack.isHomeStack(); 3122 } else if (r.isRecentsActivity()) { 3123 return stack.isRecentsStack(); 3124 } else if (r.isAssistantActivity()) { 3125 return stack.isAssistantStack(); 3126 } 3127 return true; 3128 } 3129 3130 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info, 3131 boolean compareIntentFilters) { 3132 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3133 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3134 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3135 final ActivityRecord ar = stacks.get(stackNdx) 3136 .findActivityLocked(intent, info, compareIntentFilters); 3137 if (ar != null) { 3138 return ar; 3139 } 3140 } 3141 } 3142 return null; 3143 } 3144 3145 boolean hasAwakeDisplay() { 3146 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3147 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3148 if (!display.shouldSleep()) { 3149 return true; 3150 } 3151 } 3152 return false; 3153 } 3154 3155 void goingToSleepLocked() { 3156 scheduleSleepTimeout(); 3157 if (!mGoingToSleep.isHeld()) { 3158 mGoingToSleep.acquire(); 3159 if (mLaunchingActivity.isHeld()) { 3160 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 3161 throw new IllegalStateException("Calling must be system uid"); 3162 } 3163 mLaunchingActivity.release(); 3164 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 3165 } 3166 } 3167 3168 applySleepTokensLocked(false /* applyToStacks */); 3169 3170 checkReadyForSleepLocked(true /* allowDelay */); 3171 } 3172 3173 void prepareForShutdownLocked() { 3174 for (int i = 0; i < mActivityDisplays.size(); i++) { 3175 createSleepTokenLocked("shutdown", mActivityDisplays.keyAt(i)); 3176 } 3177 } 3178 3179 boolean shutdownLocked(int timeout) { 3180 goingToSleepLocked(); 3181 3182 boolean timedout = false; 3183 final long endTime = System.currentTimeMillis() + timeout; 3184 while (true) { 3185 if (!putStacksToSleepLocked(true /* allowDelay */, true /* shuttingDown */)) { 3186 long timeRemaining = endTime - System.currentTimeMillis(); 3187 if (timeRemaining > 0) { 3188 try { 3189 mService.wait(timeRemaining); 3190 } catch (InterruptedException e) { 3191 } 3192 } else { 3193 Slog.w(TAG, "Activity manager shutdown timed out"); 3194 timedout = true; 3195 break; 3196 } 3197 } else { 3198 break; 3199 } 3200 } 3201 3202 // Force checkReadyForSleep to complete. 3203 checkReadyForSleepLocked(false /* allowDelay */); 3204 3205 return timedout; 3206 } 3207 3208 void comeOutOfSleepIfNeededLocked() { 3209 removeSleepTimeouts(); 3210 if (mGoingToSleep.isHeld()) { 3211 mGoingToSleep.release(); 3212 } 3213 } 3214 3215 void applySleepTokensLocked(boolean applyToStacks) { 3216 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3217 // Set the sleeping state of the display. 3218 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3219 final boolean displayShouldSleep = display.shouldSleep(); 3220 if (displayShouldSleep == display.isSleeping()) { 3221 continue; 3222 } 3223 display.setIsSleeping(displayShouldSleep); 3224 3225 if (!applyToStacks) { 3226 continue; 3227 } 3228 3229 // Set the sleeping state of the stacks on the display. 3230 final ArrayList<ActivityStack> stacks = display.mStacks; 3231 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3232 final ActivityStack stack = stacks.get(stackNdx); 3233 if (displayShouldSleep) { 3234 stack.goToSleepIfPossible(false /* shuttingDown */); 3235 } else { 3236 stack.awakeFromSleepingLocked(); 3237 if (isFocusedStack(stack)) { 3238 resumeFocusedStackTopActivityLocked(); 3239 } 3240 } 3241 } 3242 3243 if (displayShouldSleep || mGoingToSleepActivities.isEmpty()) { 3244 continue; 3245 } 3246 // The display is awake now, so clean up the going to sleep list. 3247 for (Iterator<ActivityRecord> it = mGoingToSleepActivities.iterator(); it.hasNext(); ) { 3248 final ActivityRecord r = it.next(); 3249 if (r.getDisplayId() == display.mDisplayId) { 3250 it.remove(); 3251 } 3252 } 3253 } 3254 } 3255 3256 void activitySleptLocked(ActivityRecord r) { 3257 mGoingToSleepActivities.remove(r); 3258 final ActivityStack s = r.getStack(); 3259 if (s != null) { 3260 s.checkReadyForSleep(); 3261 } else { 3262 checkReadyForSleepLocked(true); 3263 } 3264 } 3265 3266 void checkReadyForSleepLocked(boolean allowDelay) { 3267 if (!mService.isSleepingOrShuttingDownLocked()) { 3268 // Do not care. 3269 return; 3270 } 3271 3272 if (!putStacksToSleepLocked(allowDelay, false /* shuttingDown */)) { 3273 return; 3274 } 3275 3276 // Send launch end powerhint before going sleep 3277 mService.mActivityStarter.sendPowerHintForLaunchEndIfNeeded(); 3278 3279 removeSleepTimeouts(); 3280 3281 if (mGoingToSleep.isHeld()) { 3282 mGoingToSleep.release(); 3283 } 3284 if (mService.mShuttingDown) { 3285 mService.notifyAll(); 3286 } 3287 } 3288 3289 // Tries to put all activity stacks to sleep. Returns true if all stacks were 3290 // successfully put to sleep. 3291 private boolean putStacksToSleepLocked(boolean allowDelay, boolean shuttingDown) { 3292 boolean allSleep = true; 3293 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3294 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3295 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3296 if (allowDelay) { 3297 allSleep &= stacks.get(stackNdx).goToSleepIfPossible(shuttingDown); 3298 } else { 3299 stacks.get(stackNdx).goToSleep(); 3300 } 3301 } 3302 } 3303 return allSleep; 3304 } 3305 3306 boolean reportResumedActivityLocked(ActivityRecord r) { 3307 // A resumed activity cannot be stopping. remove from list 3308 mStoppingActivities.remove(r); 3309 3310 final ActivityStack stack = r.getStack(); 3311 if (isFocusedStack(stack)) { 3312 mService.updateUsageStats(r, true); 3313 } 3314 if (allResumedActivitiesComplete()) { 3315 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 3316 mWindowManager.executeAppTransition(); 3317 return true; 3318 } 3319 return false; 3320 } 3321 3322 void handleAppCrashLocked(ProcessRecord app) { 3323 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3324 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3325 int stackNdx = stacks.size() - 1; 3326 while (stackNdx >= 0) { 3327 stacks.get(stackNdx).handleAppCrashLocked(app); 3328 stackNdx--; 3329 } 3330 } 3331 } 3332 3333 // Called when WindowManager has finished animating the launchingBehind activity to the back. 3334 private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 3335 final TaskRecord task = r.getTask(); 3336 final ActivityStack stack = task.getStack(); 3337 3338 r.mLaunchTaskBehind = false; 3339 task.setLastThumbnailLocked(r.screenshotActivityLocked()); 3340 mRecentTasks.addLocked(task); 3341 mService.mTaskChangeNotificationController.notifyTaskStackChanged(); 3342 r.setVisibility(false); 3343 3344 // When launching tasks behind, update the last active time of the top task after the new 3345 // task has been shown briefly 3346 final ActivityRecord top = stack.topActivity(); 3347 if (top != null) { 3348 top.getTask().touchActiveTime(); 3349 } 3350 } 3351 3352 void scheduleLaunchTaskBehindComplete(IBinder token) { 3353 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 3354 } 3355 3356 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, 3357 boolean preserveWindows) { 3358 mKeyguardController.beginActivityVisibilityUpdate(); 3359 try { 3360 // First the front stacks. In case any are not fullscreen and are in front of home. 3361 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3362 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3363 final int topStackNdx = stacks.size() - 1; 3364 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 3365 final ActivityStack stack = stacks.get(stackNdx); 3366 stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows); 3367 } 3368 } 3369 } finally { 3370 mKeyguardController.endActivityVisibilityUpdate(); 3371 } 3372 } 3373 3374 void addStartingWindowsForVisibleActivities(boolean taskSwitch) { 3375 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3376 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3377 final int topStackNdx = stacks.size() - 1; 3378 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 3379 final ActivityStack stack = stacks.get(stackNdx); 3380 stack.addStartingWindowsForVisibleActivities(taskSwitch); 3381 } 3382 } 3383 } 3384 3385 void invalidateTaskLayers() { 3386 mTaskLayersChanged = true; 3387 } 3388 3389 void rankTaskLayersIfNeeded() { 3390 if (!mTaskLayersChanged) { 3391 return; 3392 } 3393 mTaskLayersChanged = false; 3394 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) { 3395 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3396 int baseLayer = 0; 3397 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3398 baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer); 3399 } 3400 } 3401 } 3402 3403 void clearOtherAppTimeTrackers(AppTimeTracker except) { 3404 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3405 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3406 final int topStackNdx = stacks.size() - 1; 3407 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 3408 final ActivityStack stack = stacks.get(stackNdx); 3409 stack.clearOtherAppTimeTrackers(except); 3410 } 3411 } 3412 } 3413 3414 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 3415 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3416 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3417 final int numStacks = stacks.size(); 3418 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 3419 final ActivityStack stack = stacks.get(stackNdx); 3420 stack.scheduleDestroyActivities(app, reason); 3421 } 3422 } 3423 } 3424 3425 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 3426 // Examine all activities currently running in the process. 3427 TaskRecord firstTask = null; 3428 // Tasks is non-null only if two or more tasks are found. 3429 ArraySet<TaskRecord> tasks = null; 3430 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); 3431 for (int i = 0; i < app.activities.size(); i++) { 3432 ActivityRecord r = app.activities.get(i); 3433 // First, if we find an activity that is in the process of being destroyed, 3434 // then we just aren't going to do anything for now; we want things to settle 3435 // down before we try to prune more activities. 3436 if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) { 3437 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 3438 return; 3439 } 3440 // Don't consider any activies that are currently not in a state where they 3441 // can be destroyed. 3442 if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING 3443 || r.state == PAUSED || r.state == STOPPING) { 3444 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 3445 continue; 3446 } 3447 3448 final TaskRecord task = r.getTask(); 3449 if (task != null) { 3450 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task 3451 + " from " + r); 3452 if (firstTask == null) { 3453 firstTask = task; 3454 } else if (firstTask != task) { 3455 if (tasks == null) { 3456 tasks = new ArraySet<>(); 3457 tasks.add(firstTask); 3458 } 3459 tasks.add(task); 3460 } 3461 } 3462 } 3463 if (tasks == null) { 3464 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); 3465 return; 3466 } 3467 // If we have activities in multiple tasks that are in a position to be destroyed, 3468 // let's iterate through the tasks and release the oldest one. 3469 final int numDisplays = mActivityDisplays.size(); 3470 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 3471 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3472 // Step through all stacks starting from behind, to hit the oldest things first. 3473 for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) { 3474 final ActivityStack stack = stacks.get(stackNdx); 3475 // Try to release activities in this stack; if we manage to, we are done. 3476 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 3477 return; 3478 } 3479 } 3480 } 3481 } 3482 3483 boolean switchUserLocked(int userId, UserState uss) { 3484 final int focusStackId = mFocusedStack.getStackId(); 3485 // We dismiss the docked stack whenever we switch users. 3486 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, focusStackId == DOCKED_STACK_ID); 3487 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will 3488 // also cause all tasks to be moved to the fullscreen stack at a position that is 3489 // appropriate. 3490 removeStackLocked(PINNED_STACK_ID); 3491 3492 mUserStackInFront.put(mCurrentUser, focusStackId); 3493 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 3494 mCurrentUser = userId; 3495 3496 mStartingUsers.add(uss); 3497 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3498 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3499 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3500 final ActivityStack stack = stacks.get(stackNdx); 3501 stack.switchUserLocked(userId); 3502 TaskRecord task = stack.topTask(); 3503 if (task != null) { 3504 stack.positionChildWindowContainerAtTop(task); 3505 } 3506 } 3507 } 3508 3509 ActivityStack stack = getStack(restoreStackId); 3510 if (stack == null) { 3511 stack = mHomeStack; 3512 } 3513 final boolean homeInFront = stack.isHomeStack(); 3514 if (stack.isOnHomeDisplay()) { 3515 stack.moveToFront("switchUserOnHomeDisplay"); 3516 } else { 3517 // Stack was moved to another display while user was swapped out. 3518 resumeHomeStackTask(null, "switchUserOnOtherDisplay"); 3519 } 3520 return homeInFront; 3521 } 3522 3523 /** Checks whether the userid is a profile of the current user. */ 3524 boolean isCurrentProfileLocked(int userId) { 3525 if (userId == mCurrentUser) return true; 3526 return mService.mUserController.isCurrentProfileLocked(userId); 3527 } 3528 3529 /** 3530 * Returns whether a stopping activity is present that should be stopped after visible, rather 3531 * than idle. 3532 * @return {@code true} if such activity is present. {@code false} otherwise. 3533 */ 3534 boolean isStoppingNoHistoryActivity() { 3535 // Activities that are marked as nohistory should be stopped immediately after the resumed 3536 // activity has become visible. 3537 for (ActivityRecord record : mStoppingActivities) { 3538 if (record.isNoHistory()) { 3539 return true; 3540 } 3541 } 3542 3543 return false; 3544 } 3545 3546 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity, 3547 boolean remove, boolean processPausingActivities) { 3548 ArrayList<ActivityRecord> stops = null; 3549 3550 final boolean nowVisible = allResumedActivitiesVisible(); 3551 for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3552 ActivityRecord s = mStoppingActivities.get(activityNdx); 3553 boolean waitingVisible = mActivitiesWaitingForVisibleActivity.contains(s); 3554 if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3555 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3556 if (waitingVisible && nowVisible) { 3557 mActivitiesWaitingForVisibleActivity.remove(s); 3558 waitingVisible = false; 3559 if (s.finishing) { 3560 // If this activity is finishing, it is sitting on top of 3561 // everyone else but we now know it is no longer needed... 3562 // so get rid of it. Otherwise, we need to go through the 3563 // normal flow and hide it once we determine that it is 3564 // hidden by the activities in front of it. 3565 if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); 3566 s.setVisibility(false); 3567 } 3568 } 3569 if (remove) { 3570 final ActivityStack stack = s.getStack(); 3571 final boolean shouldSleepOrShutDown = stack != null 3572 ? stack.shouldSleepOrShutDownActivities() 3573 : mService.isSleepingOrShuttingDownLocked(); 3574 if (!waitingVisible || shouldSleepOrShutDown) { 3575 if (!processPausingActivities && s.state == PAUSING) { 3576 // Defer processing pausing activities in this iteration and reschedule 3577 // a delayed idle to reprocess it again 3578 removeTimeoutsForActivityLocked(idleActivity); 3579 scheduleIdleTimeoutLocked(idleActivity); 3580 continue; 3581 } 3582 3583 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); 3584 if (stops == null) { 3585 stops = new ArrayList<>(); 3586 } 3587 stops.add(s); 3588 mStoppingActivities.remove(activityNdx); 3589 } 3590 } 3591 } 3592 3593 return stops; 3594 } 3595 3596 void validateTopActivitiesLocked() { 3597 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3598 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3599 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3600 final ActivityStack stack = stacks.get(stackNdx); 3601 final ActivityRecord r = stack.topRunningActivityLocked(); 3602 final ActivityState state = r == null ? DESTROYED : r.state; 3603 if (isFocusedStack(stack)) { 3604 if (r == null) Slog.e(TAG, 3605 "validateTop...: null top activity, stack=" + stack); 3606 else { 3607 final ActivityRecord pausing = stack.mPausingActivity; 3608 if (pausing != null && pausing == r) Slog.e(TAG, 3609 "validateTop...: top stack has pausing activity r=" + r 3610 + " state=" + state); 3611 if (state != INITIALIZING && state != RESUMED) Slog.e(TAG, 3612 "validateTop...: activity in front not resumed r=" + r 3613 + " state=" + state); 3614 } 3615 } else { 3616 final ActivityRecord resumed = stack.mResumedActivity; 3617 if (resumed != null && resumed == r) Slog.e(TAG, 3618 "validateTop...: back stack has resumed activity r=" + r 3619 + " state=" + state); 3620 if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG, 3621 "validateTop...: activity in back resumed r=" + r + " state=" + state); 3622 } 3623 } 3624 } 3625 } 3626 3627 private String lockTaskModeToString() { 3628 switch (mLockTaskModeState) { 3629 case LOCK_TASK_MODE_LOCKED: 3630 return "LOCKED"; 3631 case LOCK_TASK_MODE_PINNED: 3632 return "PINNED"; 3633 case LOCK_TASK_MODE_NONE: 3634 return "NONE"; 3635 default: return "unknown=" + mLockTaskModeState; 3636 } 3637 } 3638 3639 public void dump(PrintWriter pw, String prefix) { 3640 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3641 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3642 pw.print(prefix); 3643 pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); 3644 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3645 pw.print(prefix); pw.println("mStacks=" + mStacks); 3646 pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); 3647 final SparseArray<String[]> packages = mService.mLockTaskPackages; 3648 if (packages.size() > 0) { 3649 pw.print(prefix); pw.println("mLockTaskPackages (userId:packages)="); 3650 for (int i = 0; i < packages.size(); ++i) { 3651 pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i)); 3652 pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i))); 3653 } 3654 } 3655 if (!mWaitingForActivityVisible.isEmpty()) { 3656 pw.print(prefix); pw.println("mWaitingForActivityVisible="); 3657 for (int i = 0; i < mWaitingForActivityVisible.size(); ++i) { 3658 pw.print(prefix); pw.print(prefix); mWaitingForActivityVisible.get(i).dump(pw, prefix); 3659 } 3660 } 3661 3662 pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks); 3663 mKeyguardController.dump(pw, prefix); 3664 } 3665 3666 /** 3667 * Dump all connected displays' configurations. 3668 * @param prefix Prefix to apply to each line of the dump. 3669 */ 3670 void dumpDisplayConfigs(PrintWriter pw, String prefix) { 3671 pw.print(prefix); pw.println("Display override configurations:"); 3672 final int displayCount = mActivityDisplays.size(); 3673 for (int i = 0; i < displayCount; i++) { 3674 final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(i); 3675 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": "); 3676 pw.println(activityDisplay.getOverrideConfiguration()); 3677 } 3678 } 3679 3680 /** 3681 * Dumps the activities matching the given {@param name} in the either the focused stack 3682 * or all visible stacks if {@param dumpVisibleStacks} is true. 3683 */ 3684 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name, boolean dumpVisibleStacksOnly, 3685 boolean dumpFocusedStackOnly) { 3686 if (dumpFocusedStackOnly) { 3687 return mFocusedStack.getDumpActivitiesLocked(name); 3688 } else { 3689 ArrayList<ActivityRecord> activities = new ArrayList<>(); 3690 int numDisplays = mActivityDisplays.size(); 3691 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 3692 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3693 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3694 ActivityStack stack = stacks.get(stackNdx); 3695 if (!dumpVisibleStacksOnly || 3696 stack.shouldBeVisible(null) == STACK_VISIBLE) { 3697 activities.addAll(stack.getDumpActivitiesLocked(name)); 3698 } 3699 } 3700 } 3701 return activities; 3702 } 3703 } 3704 3705 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3706 boolean needSep, String prefix) { 3707 if (activity != null) { 3708 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3709 if (needSep) { 3710 pw.println(); 3711 } 3712 pw.print(prefix); 3713 pw.println(activity); 3714 return true; 3715 } 3716 } 3717 return false; 3718 } 3719 3720 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3721 boolean dumpClient, String dumpPackage) { 3722 boolean printed = false; 3723 boolean needSep = false; 3724 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3725 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3726 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3727 pw.println(" (activities from top to bottom):"); 3728 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3729 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3730 final ActivityStack stack = stacks.get(stackNdx); 3731 StringBuilder stackHeader = new StringBuilder(128); 3732 stackHeader.append(" Stack #"); 3733 stackHeader.append(stack.mStackId); 3734 stackHeader.append(":"); 3735 stackHeader.append("\n"); 3736 stackHeader.append(" mFullscreen=" + stack.mFullscreen); 3737 stackHeader.append("\n"); 3738 stackHeader.append(" isSleeping=" + stack.shouldSleepActivities()); 3739 stackHeader.append("\n"); 3740 stackHeader.append(" mBounds=" + stack.mBounds); 3741 3742 final boolean printedStackHeader = stack.dumpActivitiesLocked(fd, pw, dumpAll, 3743 dumpClient, dumpPackage, needSep, stackHeader.toString()); 3744 printed |= printedStackHeader; 3745 if (!printedStackHeader) { 3746 // Ensure we always dump the stack header even if there are no activities 3747 pw.println(); 3748 pw.println(stackHeader); 3749 } 3750 3751 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3752 !dumpAll, false, dumpPackage, true, 3753 " Running activities (most recent first):", null); 3754 3755 needSep = printed; 3756 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3757 " mPausingActivity: "); 3758 if (pr) { 3759 printed = true; 3760 needSep = false; 3761 } 3762 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3763 " mResumedActivity: "); 3764 if (pr) { 3765 printed = true; 3766 needSep = false; 3767 } 3768 if (dumpAll) { 3769 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3770 " mLastPausedActivity: "); 3771 if (pr) { 3772 printed = true; 3773 needSep = true; 3774 } 3775 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3776 needSep, " mLastNoHistoryActivity: "); 3777 } 3778 needSep = printed; 3779 } 3780 } 3781 3782 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3783 false, dumpPackage, true, " Activities waiting to finish:", null); 3784 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3785 false, dumpPackage, true, " Activities waiting to stop:", null); 3786 printed |= dumpHistoryList(fd, pw, mActivitiesWaitingForVisibleActivity, " ", "Wait", 3787 false, !dumpAll, false, dumpPackage, true, 3788 " Activities waiting for another to become visible:", null); 3789 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3790 false, dumpPackage, true, " Activities waiting to sleep:", null); 3791 3792 return printed; 3793 } 3794 3795 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3796 String prefix, String label, boolean complete, boolean brief, boolean client, 3797 String dumpPackage, boolean needNL, String header1, String header2) { 3798 TaskRecord lastTask = null; 3799 String innerPrefix = null; 3800 String[] args = null; 3801 boolean printed = false; 3802 for (int i=list.size()-1; i>=0; i--) { 3803 final ActivityRecord r = list.get(i); 3804 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3805 continue; 3806 } 3807 if (innerPrefix == null) { 3808 innerPrefix = prefix + " "; 3809 args = new String[0]; 3810 } 3811 printed = true; 3812 final boolean full = !brief && (complete || !r.isInHistory()); 3813 if (needNL) { 3814 pw.println(""); 3815 needNL = false; 3816 } 3817 if (header1 != null) { 3818 pw.println(header1); 3819 header1 = null; 3820 } 3821 if (header2 != null) { 3822 pw.println(header2); 3823 header2 = null; 3824 } 3825 if (lastTask != r.getTask()) { 3826 lastTask = r.getTask(); 3827 pw.print(prefix); 3828 pw.print(full ? "* " : " "); 3829 pw.println(lastTask); 3830 if (full) { 3831 lastTask.dump(pw, prefix + " "); 3832 } else if (complete) { 3833 // Complete + brief == give a summary. Isn't that obvious?!? 3834 if (lastTask.intent != null) { 3835 pw.print(prefix); pw.print(" "); 3836 pw.println(lastTask.intent.toInsecureStringWithClip()); 3837 } 3838 } 3839 } 3840 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3841 pw.print(" #"); pw.print(i); pw.print(": "); 3842 pw.println(r); 3843 if (full) { 3844 r.dump(pw, innerPrefix); 3845 } else if (complete) { 3846 // Complete + brief == give a summary. Isn't that obvious?!? 3847 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3848 if (r.app != null) { 3849 pw.print(innerPrefix); pw.println(r.app); 3850 } 3851 } 3852 if (client && r.app != null && r.app.thread != null) { 3853 // flush anything that is already in the PrintWriter since the thread is going 3854 // to write to the file descriptor directly 3855 pw.flush(); 3856 try { 3857 TransferPipe tp = new TransferPipe(); 3858 try { 3859 r.app.thread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args); 3860 // Short timeout, since blocking here can 3861 // deadlock with the application. 3862 tp.go(fd, 2000); 3863 } finally { 3864 tp.kill(); 3865 } 3866 } catch (IOException e) { 3867 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3868 } catch (RemoteException e) { 3869 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3870 } 3871 needNL = true; 3872 } 3873 } 3874 return printed; 3875 } 3876 3877 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3878 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3879 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3880 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3881 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3882 } 3883 3884 final void scheduleIdleLocked() { 3885 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3886 } 3887 3888 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3889 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 3890 + Debug.getCallers(4)); 3891 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3892 } 3893 3894 final void scheduleResumeTopActivities() { 3895 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3896 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3897 } 3898 } 3899 3900 void removeSleepTimeouts() { 3901 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3902 } 3903 3904 final void scheduleSleepTimeout() { 3905 removeSleepTimeouts(); 3906 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3907 } 3908 3909 @Override 3910 public void onDisplayAdded(int displayId) { 3911 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 3912 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3913 } 3914 3915 @Override 3916 public void onDisplayRemoved(int displayId) { 3917 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 3918 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3919 } 3920 3921 @Override 3922 public void onDisplayChanged(int displayId) { 3923 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 3924 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3925 } 3926 3927 private void handleDisplayAdded(int displayId) { 3928 synchronized (mService) { 3929 getActivityDisplayOrCreateLocked(displayId); 3930 } 3931 } 3932 3933 /** Check if display with specified id is added to the list. */ 3934 boolean isDisplayAdded(int displayId) { 3935 return getActivityDisplayOrCreateLocked(displayId) != null; 3936 } 3937 3938 ActivityDisplay getActivityDisplay(int displayId) { 3939 return mActivityDisplays.get(displayId); 3940 } 3941 3942 /** 3943 * Get an existing instance of {@link ActivityDisplay} or create new if there is a 3944 * corresponding record in display manager. 3945 */ 3946 private ActivityDisplay getActivityDisplayOrCreateLocked(int displayId) { 3947 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3948 if (activityDisplay != null) { 3949 return activityDisplay; 3950 } 3951 if (mDisplayManager == null) { 3952 // The system isn't fully initialized yet. 3953 return null; 3954 } 3955 final Display display = mDisplayManager.getDisplay(displayId); 3956 if (display == null) { 3957 // The display is not registered in DisplayManager. 3958 return null; 3959 } 3960 // The display hasn't been added to ActivityManager yet, create a new record now. 3961 activityDisplay = new ActivityDisplay(displayId); 3962 if (activityDisplay.mDisplay == null) { 3963 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3964 return null; 3965 } 3966 mActivityDisplays.put(displayId, activityDisplay); 3967 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 3968 mWindowManager.onDisplayAdded(displayId); 3969 return activityDisplay; 3970 } 3971 3972 private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) { 3973 mDefaultMinSizeOfResizeableTask = 3974 mService.mContext.getResources().getDimensionPixelSize( 3975 com.android.internal.R.dimen.default_minimal_size_resizable_task); 3976 } 3977 3978 private void handleDisplayRemoved(int displayId) { 3979 if (displayId == DEFAULT_DISPLAY) { 3980 throw new IllegalArgumentException("Can't remove the primary display."); 3981 } 3982 3983 synchronized (mService) { 3984 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3985 if (activityDisplay != null) { 3986 final boolean destroyContentOnRemoval 3987 = activityDisplay.shouldDestroyContentOnRemove(); 3988 final ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3989 while (!stacks.isEmpty()) { 3990 final ActivityStack stack = stacks.get(0); 3991 if (destroyContentOnRemoval) { 3992 moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY, 3993 false /* onTop */); 3994 stack.finishAllActivitiesLocked(true /* immediately */); 3995 } else { 3996 // Moving all tasks to fullscreen stack, because it's guaranteed to be 3997 // a valid launch stack for all activities. This way the task history from 3998 // external display will be preserved on primary after move. 3999 moveTasksToFullscreenStackLocked(stack.getStackId(), true /* onTop */); 4000 } 4001 } 4002 4003 releaseSleepTokens(activityDisplay); 4004 4005 mActivityDisplays.remove(displayId); 4006 mWindowManager.onDisplayRemoved(displayId); 4007 } 4008 } 4009 } 4010 4011 private void handleDisplayChanged(int displayId) { 4012 synchronized (mService) { 4013 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 4014 if (activityDisplay != null) { 4015 // The window policy is responsible for stopping activities on the default display 4016 if (displayId != Display.DEFAULT_DISPLAY) { 4017 int displayState = activityDisplay.mDisplay.getState(); 4018 if (displayState == Display.STATE_OFF && activityDisplay.mOffToken == null) { 4019 activityDisplay.mOffToken = 4020 mService.acquireSleepToken("Display-off", displayId); 4021 } else if (displayState == Display.STATE_ON 4022 && activityDisplay.mOffToken != null) { 4023 activityDisplay.mOffToken.release(); 4024 activityDisplay.mOffToken = null; 4025 } 4026 } 4027 // TODO: Update the bounds. 4028 } 4029 mWindowManager.onDisplayChanged(displayId); 4030 } 4031 } 4032 4033 SleepToken createSleepTokenLocked(String tag, int displayId) { 4034 ActivityDisplay display = mActivityDisplays.get(displayId); 4035 if (display == null) { 4036 throw new IllegalArgumentException("Invalid display: " + displayId); 4037 } 4038 4039 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId); 4040 mSleepTokens.add(token); 4041 display.mAllSleepTokens.add(token); 4042 return token; 4043 } 4044 4045 private void removeSleepTokenLocked(SleepTokenImpl token) { 4046 mSleepTokens.remove(token); 4047 4048 ActivityDisplay display = mActivityDisplays.get(token.mDisplayId); 4049 if (display != null) { 4050 display.mAllSleepTokens.remove(token); 4051 if (display.mAllSleepTokens.isEmpty()) { 4052 mService.updateSleepIfNeededLocked(); 4053 } 4054 } 4055 } 4056 4057 private void releaseSleepTokens(ActivityDisplay display) { 4058 if (display.mAllSleepTokens.isEmpty()) { 4059 return; 4060 } 4061 for (SleepTokenImpl token : display.mAllSleepTokens) { 4062 mSleepTokens.remove(token); 4063 } 4064 display.mAllSleepTokens.clear(); 4065 4066 mService.updateSleepIfNeededLocked(); 4067 } 4068 4069 private StackInfo getStackInfoLocked(ActivityStack stack) { 4070 final int displayId = stack.mDisplayId; 4071 final ActivityDisplay display = mActivityDisplays.get(displayId); 4072 StackInfo info = new StackInfo(); 4073 stack.getWindowContainerBounds(info.bounds); 4074 info.displayId = displayId; 4075 info.stackId = stack.mStackId; 4076 info.userId = stack.mCurrentUser; 4077 info.visible = stack.shouldBeVisible(null) == STACK_VISIBLE; 4078 // A stack might be not attached to a display. 4079 info.position = display != null 4080 ? display.mStacks.indexOf(stack) 4081 : 0; 4082 4083 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 4084 final int numTasks = tasks.size(); 4085 int[] taskIds = new int[numTasks]; 4086 String[] taskNames = new String[numTasks]; 4087 Rect[] taskBounds = new Rect[numTasks]; 4088 int[] taskUserIds = new int[numTasks]; 4089 for (int i = 0; i < numTasks; ++i) { 4090 final TaskRecord task = tasks.get(i); 4091 taskIds[i] = task.taskId; 4092 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 4093 : task.realActivity != null ? task.realActivity.flattenToString() 4094 : task.getTopActivity() != null ? task.getTopActivity().packageName 4095 : "unknown"; 4096 taskBounds[i] = new Rect(); 4097 task.getWindowContainerBounds(taskBounds[i]); 4098 taskUserIds[i] = task.userId; 4099 } 4100 info.taskIds = taskIds; 4101 info.taskNames = taskNames; 4102 info.taskBounds = taskBounds; 4103 info.taskUserIds = taskUserIds; 4104 4105 final ActivityRecord top = stack.topRunningActivityLocked(); 4106 info.topActivity = top != null ? top.intent.getComponent() : null; 4107 return info; 4108 } 4109 4110 StackInfo getStackInfoLocked(int stackId) { 4111 ActivityStack stack = getStack(stackId); 4112 if (stack != null) { 4113 return getStackInfoLocked(stack); 4114 } 4115 return null; 4116 } 4117 4118 ArrayList<StackInfo> getAllStackInfosLocked() { 4119 ArrayList<StackInfo> list = new ArrayList<>(); 4120 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 4121 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 4122 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 4123 list.add(getStackInfoLocked(stacks.get(ndx))); 4124 } 4125 } 4126 return list; 4127 } 4128 4129 TaskRecord getLockedTaskLocked() { 4130 final int top = mLockTaskModeTasks.size() - 1; 4131 if (top >= 0) { 4132 return mLockTaskModeTasks.get(top); 4133 } 4134 return null; 4135 } 4136 4137 boolean isLockedTask(TaskRecord task) { 4138 return mLockTaskModeTasks.contains(task); 4139 } 4140 4141 boolean isLastLockedTask(TaskRecord task) { 4142 return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task); 4143 } 4144 4145 void removeLockedTaskLocked(final TaskRecord task) { 4146 if (!mLockTaskModeTasks.remove(task)) { 4147 return; 4148 } 4149 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task); 4150 if (mLockTaskModeTasks.isEmpty()) { 4151 // Last one. 4152 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task + 4153 " last task, reverting locktask mode. Callers=" + Debug.getCallers(3)); 4154 final Message lockTaskMsg = Message.obtain(); 4155 lockTaskMsg.arg1 = task.userId; 4156 lockTaskMsg.what = LOCK_TASK_END_MSG; 4157 mHandler.sendMessage(lockTaskMsg); 4158 } 4159 } 4160 4161 void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, 4162 int preferredDisplayId, int actualStackId) { 4163 handleNonResizableTaskIfNeeded(task, preferredStackId, preferredDisplayId, actualStackId, 4164 false /* forceNonResizable */); 4165 } 4166 4167 private void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, 4168 int preferredDisplayId, int actualStackId, boolean forceNonResizable) { 4169 final boolean isSecondaryDisplayPreferred = 4170 (preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY) 4171 || StackId.isDynamicStack(preferredStackId); 4172 if (((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID) 4173 && !isSecondaryDisplayPreferred) || task.isHomeTask()) { 4174 return; 4175 } 4176 4177 // Handle incorrect launch/move to secondary display if needed. 4178 final boolean launchOnSecondaryDisplayFailed; 4179 if (isSecondaryDisplayPreferred) { 4180 final int actualDisplayId = task.getStack().mDisplayId; 4181 if (!task.canBeLaunchedOnDisplay(actualDisplayId)) { 4182 // The task landed on an inappropriate display somehow, move it to the default 4183 // display. 4184 // TODO(multi-display): Find proper stack for the task on the default display. 4185 mService.moveTaskToStack(task.taskId, FULLSCREEN_WORKSPACE_STACK_ID, 4186 true /* toTop */); 4187 launchOnSecondaryDisplayFailed = true; 4188 } else { 4189 // The task might have landed on a display different from requested. 4190 launchOnSecondaryDisplayFailed = actualDisplayId == DEFAULT_DISPLAY 4191 || (preferredDisplayId != INVALID_DISPLAY 4192 && preferredDisplayId != actualDisplayId); 4193 } 4194 } else { 4195 // The task wasn't requested to be on a secondary display. 4196 launchOnSecondaryDisplayFailed = false; 4197 } 4198 4199 final ActivityRecord topActivity = task.getTopActivity(); 4200 if (launchOnSecondaryDisplayFailed || !task.supportsSplitScreen() || forceNonResizable) { 4201 if (launchOnSecondaryDisplayFailed) { 4202 // Display a warning toast that we tried to put a non-resizeable task on a secondary 4203 // display with config different from global config. 4204 mService.mTaskChangeNotificationController 4205 .notifyActivityLaunchOnSecondaryDisplayFailed(); 4206 } else { 4207 // Display a warning toast that we tried to put a non-dockable task in the docked 4208 // stack. 4209 mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack(); 4210 } 4211 4212 // Dismiss docked stack. If task appeared to be in docked stack but is not resizable - 4213 // we need to move it to top of fullscreen stack, otherwise it will be covered. 4214 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID); 4215 } else if (topActivity != null && topActivity.isNonResizableOrForcedResizable() 4216 && !topActivity.noDisplay) { 4217 final String packageName = topActivity.appInfo.packageName; 4218 final int reason = isSecondaryDisplayPreferred 4219 ? FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY 4220 : FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; 4221 mService.mTaskChangeNotificationController.notifyActivityForcedResizable( 4222 task.taskId, reason, packageName); 4223 } 4224 } 4225 4226 void showLockTaskToast() { 4227 if (mLockTaskNotify != null) { 4228 mLockTaskNotify.showToast(mLockTaskModeState); 4229 } 4230 } 4231 4232 void showLockTaskEscapeMessageLocked(TaskRecord task) { 4233 if (mLockTaskModeTasks.contains(task)) { 4234 mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG); 4235 } 4236 } 4237 4238 void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason, 4239 boolean andResume) { 4240 if (task == null) { 4241 // Take out of lock task mode if necessary 4242 final TaskRecord lockedTask = getLockedTaskLocked(); 4243 if (lockedTask != null) { 4244 removeLockedTaskLocked(lockedTask); 4245 if (!mLockTaskModeTasks.isEmpty()) { 4246 // There are locked tasks remaining, can only finish this task, not unlock it. 4247 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 4248 "setLockTaskModeLocked: Tasks remaining, can't unlock"); 4249 lockedTask.performClearTaskLocked(); 4250 resumeFocusedStackTopActivityLocked(); 4251 return; 4252 } 4253 } 4254 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 4255 "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4)); 4256 return; 4257 } 4258 4259 // Should have already been checked, but do it again. 4260 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 4261 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 4262 "setLockTaskModeLocked: Can't lock due to auth"); 4263 return; 4264 } 4265 if (isLockTaskModeViolation(task)) { 4266 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 4267 return; 4268 } 4269 4270 if (mLockTaskModeTasks.isEmpty()) { 4271 // First locktask. 4272 final Message lockTaskMsg = Message.obtain(); 4273 lockTaskMsg.obj = task.intent.getComponent().getPackageName(); 4274 lockTaskMsg.arg1 = task.userId; 4275 lockTaskMsg.what = LOCK_TASK_START_MSG; 4276 lockTaskMsg.arg2 = lockTaskModeState; 4277 mHandler.sendMessage(lockTaskMsg); 4278 } 4279 // Add it or move it to the top. 4280 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task + 4281 " Callers=" + Debug.getCallers(4)); 4282 mLockTaskModeTasks.remove(task); 4283 mLockTaskModeTasks.add(task); 4284 4285 if (task.mLockTaskUid == -1) { 4286 task.mLockTaskUid = task.effectiveUid; 4287 } 4288 4289 if (andResume) { 4290 findTaskToMoveToFrontLocked(task, 0, null, reason, 4291 lockTaskModeState != LOCK_TASK_MODE_NONE); 4292 resumeFocusedStackTopActivityLocked(); 4293 mWindowManager.executeAppTransition(); 4294 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { 4295 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, DEFAULT_DISPLAY, 4296 task.getStackId(), true /* forceNonResizable */); 4297 } 4298 } 4299 4300 boolean isLockTaskModeViolation(TaskRecord task) { 4301 return isLockTaskModeViolation(task, false); 4302 } 4303 4304 boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) { 4305 if (getLockedTaskLocked() == task && !isNewClearTask) { 4306 return false; 4307 } 4308 final int lockTaskAuth = task.mLockTaskAuth; 4309 switch (lockTaskAuth) { 4310 case LOCK_TASK_AUTH_DONT_LOCK: 4311 return !mLockTaskModeTasks.isEmpty(); 4312 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 4313 case LOCK_TASK_AUTH_LAUNCHABLE: 4314 case LOCK_TASK_AUTH_WHITELISTED: 4315 return false; 4316 case LOCK_TASK_AUTH_PINNABLE: 4317 // Pinnable tasks can't be launched on top of locktask tasks. 4318 return !mLockTaskModeTasks.isEmpty(); 4319 default: 4320 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth); 4321 return true; 4322 } 4323 } 4324 4325 void onLockTaskPackagesUpdatedLocked() { 4326 boolean didSomething = false; 4327 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 4328 final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); 4329 final boolean wasWhitelisted = 4330 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 4331 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 4332 lockedTask.setLockTaskAuth(); 4333 final boolean isWhitelisted = 4334 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 4335 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 4336 if (wasWhitelisted && !isWhitelisted) { 4337 // Lost whitelisting authorization. End it now. 4338 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + 4339 lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); 4340 removeLockedTaskLocked(lockedTask); 4341 lockedTask.performClearTaskLocked(); 4342 didSomething = true; 4343 } 4344 } 4345 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 4346 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 4347 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 4348 final ActivityStack stack = stacks.get(stackNdx); 4349 stack.onLockTaskPackagesUpdatedLocked(); 4350 } 4351 } 4352 final ActivityRecord r = topRunningActivityLocked(); 4353 final TaskRecord task = r != null ? r.getTask() : null; 4354 if (mLockTaskModeTasks.isEmpty() && task != null 4355 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 4356 // This task must have just been authorized. 4357 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, 4358 "onLockTaskPackagesUpdated: starting new locktask task=" + task); 4359 setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated", 4360 false); 4361 didSomething = true; 4362 } 4363 if (didSomething) { 4364 resumeFocusedStackTopActivityLocked(); 4365 } 4366 } 4367 4368 int getLockTaskModeState() { 4369 return mLockTaskModeState; 4370 } 4371 4372 void activityRelaunchedLocked(IBinder token) { 4373 mWindowManager.notifyAppRelaunchingFinished(token); 4374 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 4375 if (r != null) { 4376 if (r.getStack().shouldSleepOrShutDownActivities()) { 4377 r.setSleeping(true, true); 4378 } 4379 } 4380 } 4381 4382 void activityRelaunchingLocked(ActivityRecord r) { 4383 mWindowManager.notifyAppRelaunching(r.appToken); 4384 } 4385 4386 void logStackState() { 4387 mActivityMetricsLogger.logWindowState(); 4388 } 4389 4390 void scheduleUpdateMultiWindowMode(TaskRecord task) { 4391 // If the stack is animating in a way where we will be forcing a multi-mode change at the 4392 // end, then ensure that we defer all in between multi-window mode changes 4393 if (task.getStack().deferScheduleMultiWindowModeChanged()) { 4394 return; 4395 } 4396 4397 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 4398 final ActivityRecord r = task.mActivities.get(i); 4399 if (r.app != null && r.app.thread != null) { 4400 mMultiWindowModeChangedActivities.add(r); 4401 } 4402 } 4403 4404 if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) { 4405 mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG); 4406 } 4407 } 4408 4409 void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, ActivityStack prevStack) { 4410 final ActivityStack stack = task.getStack(); 4411 if (prevStack == null || prevStack == stack 4412 || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) { 4413 return; 4414 } 4415 4416 scheduleUpdatePictureInPictureModeIfNeeded(task, stack.mBounds); 4417 } 4418 4419 void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, Rect targetStackBounds) { 4420 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 4421 final ActivityRecord r = task.mActivities.get(i); 4422 if (r.app != null && r.app.thread != null) { 4423 mPipModeChangedActivities.add(r); 4424 } 4425 } 4426 mPipModeChangedTargetStackBounds = targetStackBounds; 4427 4428 if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { 4429 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); 4430 } 4431 } 4432 4433 void updatePictureInPictureMode(TaskRecord task, Rect targetStackBounds, boolean forceUpdate) { 4434 mHandler.removeMessages(REPORT_PIP_MODE_CHANGED_MSG); 4435 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 4436 final ActivityRecord r = task.mActivities.get(i); 4437 if (r.app != null && r.app.thread != null) { 4438 r.updatePictureInPictureMode(targetStackBounds, forceUpdate); 4439 } 4440 } 4441 } 4442 4443 void setDockedStackMinimized(boolean minimized) { 4444 mIsDockMinimized = minimized; 4445 } 4446 4447 void wakeUp(String reason) { 4448 mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.am:TURN_ON:" + reason); 4449 } 4450 4451 /** 4452 * Begin deferring resume to avoid duplicate resumes in one pass. 4453 */ 4454 private void beginDeferResume() { 4455 mDeferResumeCount++; 4456 } 4457 4458 /** 4459 * End deferring resume and determine if resume can be called. 4460 */ 4461 private void endDeferResume() { 4462 mDeferResumeCount--; 4463 } 4464 4465 /** 4466 * @return True if resume can be called. 4467 */ 4468 private boolean readyToResume() { 4469 return mDeferResumeCount == 0; 4470 } 4471 4472 private final class ActivityStackSupervisorHandler extends Handler { 4473 4474 public ActivityStackSupervisorHandler(Looper looper) { 4475 super(looper); 4476 } 4477 4478 void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) { 4479 synchronized (mService) { 4480 activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */, 4481 processPausingActivities, null); 4482 } 4483 } 4484 4485 @Override 4486 public void handleMessage(Message msg) { 4487 switch (msg.what) { 4488 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: { 4489 synchronized (mService) { 4490 for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) { 4491 final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i); 4492 r.updateMultiWindowMode(); 4493 } 4494 } 4495 } break; 4496 case REPORT_PIP_MODE_CHANGED_MSG: { 4497 synchronized (mService) { 4498 for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) { 4499 final ActivityRecord r = mPipModeChangedActivities.remove(i); 4500 r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds, 4501 false /* forceUpdate */); 4502 } 4503 } 4504 } break; 4505 case IDLE_TIMEOUT_MSG: { 4506 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 4507 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 4508 // We don't at this point know if the activity is fullscreen, 4509 // so we need to be conservative and assume it isn't. 4510 activityIdleInternal((ActivityRecord) msg.obj, 4511 true /* processPausingActivities */); 4512 } break; 4513 case IDLE_NOW_MSG: { 4514 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 4515 activityIdleInternal((ActivityRecord) msg.obj, 4516 false /* processPausingActivities */); 4517 } break; 4518 case RESUME_TOP_ACTIVITY_MSG: { 4519 synchronized (mService) { 4520 resumeFocusedStackTopActivityLocked(); 4521 } 4522 } break; 4523 case SLEEP_TIMEOUT_MSG: { 4524 synchronized (mService) { 4525 if (mService.isSleepingOrShuttingDownLocked()) { 4526 Slog.w(TAG, "Sleep timeout! Sleeping now."); 4527 checkReadyForSleepLocked(false /* allowDelay */); 4528 } 4529 } 4530 } break; 4531 case LAUNCH_TIMEOUT_MSG: { 4532 synchronized (mService) { 4533 if (mLaunchingActivity.isHeld()) { 4534 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 4535 if (VALIDATE_WAKE_LOCK_CALLER 4536 && Binder.getCallingUid() != Process.myUid()) { 4537 throw new IllegalStateException("Calling must be system uid"); 4538 } 4539 mLaunchingActivity.release(); 4540 } 4541 } 4542 } break; 4543 case HANDLE_DISPLAY_ADDED: { 4544 handleDisplayAdded(msg.arg1); 4545 } break; 4546 case HANDLE_DISPLAY_CHANGED: { 4547 handleDisplayChanged(msg.arg1); 4548 } break; 4549 case HANDLE_DISPLAY_REMOVED: { 4550 handleDisplayRemoved(msg.arg1); 4551 } break; 4552 case LOCK_TASK_START_MSG: { 4553 // When lock task starts, we disable the status bars. 4554 try { 4555 if (mLockTaskNotify == null) { 4556 mLockTaskNotify = new LockTaskNotify(mService.mContext); 4557 } 4558 mLockTaskNotify.show(true); 4559 mLockTaskModeState = msg.arg2; 4560 if (getStatusBarService() != null) { 4561 int flags = 0; 4562 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 4563 flags = StatusBarManager.DISABLE_MASK 4564 & (~StatusBarManager.DISABLE_BACK); 4565 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 4566 flags = StatusBarManager.DISABLE_MASK 4567 & (~StatusBarManager.DISABLE_BACK) 4568 & (~StatusBarManager.DISABLE_HOME) 4569 & (~StatusBarManager.DISABLE_RECENT); 4570 } 4571 getStatusBarService().disable(flags, mToken, 4572 mService.mContext.getPackageName()); 4573 } 4574 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 4575 if (getDevicePolicyManager() != null) { 4576 getDevicePolicyManager().notifyLockTaskModeChanged(true, 4577 (String)msg.obj, msg.arg1); 4578 } 4579 } catch (RemoteException ex) { 4580 throw new RuntimeException(ex); 4581 } 4582 } break; 4583 case LOCK_TASK_END_MSG: { 4584 // When lock task ends, we enable the status bars. 4585 try { 4586 if (getStatusBarService() != null) { 4587 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 4588 mService.mContext.getPackageName()); 4589 } 4590 mWindowManager.reenableKeyguard(mToken); 4591 if (getDevicePolicyManager() != null) { 4592 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 4593 msg.arg1); 4594 } 4595 if (mLockTaskNotify == null) { 4596 mLockTaskNotify = new LockTaskNotify(mService.mContext); 4597 } 4598 mLockTaskNotify.show(false); 4599 try { 4600 boolean shouldLockKeyguard = Settings.Secure.getIntForUser( 4601 mService.mContext.getContentResolver(), 4602 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, 4603 UserHandle.USER_CURRENT) != 0; 4604 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) { 4605 mWindowManager.lockNow(null); 4606 mWindowManager.dismissKeyguard(null /* callback */); 4607 new LockPatternUtils(mService.mContext) 4608 .requireCredentialEntry(UserHandle.USER_ALL); 4609 } 4610 } catch (SettingNotFoundException e) { 4611 // No setting, don't lock. 4612 } 4613 } catch (RemoteException ex) { 4614 throw new RuntimeException(ex); 4615 } finally { 4616 mLockTaskModeState = LOCK_TASK_MODE_NONE; 4617 } 4618 } break; 4619 case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: { 4620 if (mLockTaskNotify == null) { 4621 mLockTaskNotify = new LockTaskNotify(mService.mContext); 4622 } 4623 mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED); 4624 } break; 4625 case LAUNCH_TASK_BEHIND_COMPLETE: { 4626 synchronized (mService) { 4627 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 4628 if (r != null) { 4629 handleLaunchTaskBehindCompleteLocked(r); 4630 } 4631 } 4632 } break; 4633 4634 } 4635 } 4636 } 4637 4638 // TODO: Move to its own file. 4639 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 4640 * attached {@link ActivityStack}s */ 4641 class ActivityDisplay extends ConfigurationContainer { 4642 /** Actual Display this object tracks. */ 4643 int mDisplayId; 4644 Display mDisplay; 4645 4646 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 4647 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 4648 final ArrayList<ActivityStack> mStacks = new ArrayList<>(); 4649 4650 /** Array of all UIDs that are present on the display. */ 4651 private IntArray mDisplayAccessUIDs = new IntArray(); 4652 4653 /** All tokens used to put activities on this stack to sleep (including mOffToken) */ 4654 final ArrayList<SleepTokenImpl> mAllSleepTokens = new ArrayList<>(); 4655 /** The token acquired by ActivityStackSupervisor to put stacks on the display to sleep */ 4656 SleepToken mOffToken; 4657 4658 private boolean mSleeping; 4659 4660 @VisibleForTesting 4661 ActivityDisplay() { 4662 mActivityDisplays.put(mDisplayId, this); 4663 } 4664 4665 // After instantiation, check that mDisplay is not null before using this. The alternative 4666 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. 4667 ActivityDisplay(int displayId) { 4668 final Display display = mDisplayManager.getDisplay(displayId); 4669 if (display == null) { 4670 return; 4671 } 4672 init(display); 4673 } 4674 4675 void init(Display display) { 4676 mDisplay = display; 4677 mDisplayId = display.getDisplayId(); 4678 } 4679 4680 void attachStack(ActivityStack stack, int position) { 4681 if (DEBUG_STACK) Slog.v(TAG_STACK, "attachStack: attaching " + stack 4682 + " to displayId=" + mDisplayId + " position=" + position); 4683 mStacks.add(position, stack); 4684 mService.updateSleepIfNeededLocked(); 4685 } 4686 4687 void detachStack(ActivityStack stack) { 4688 if (DEBUG_STACK) Slog.v(TAG_STACK, "detachStack: detaching " + stack 4689 + " from displayId=" + mDisplayId); 4690 mStacks.remove(stack); 4691 mService.updateSleepIfNeededLocked(); 4692 } 4693 4694 @Override 4695 public String toString() { 4696 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4697 } 4698 4699 @Override 4700 protected int getChildCount() { 4701 return mStacks.size(); 4702 } 4703 4704 @Override 4705 protected ConfigurationContainer getChildAt(int index) { 4706 return mStacks.get(index); 4707 } 4708 4709 @Override 4710 protected ConfigurationContainer getParent() { 4711 return ActivityStackSupervisor.this; 4712 } 4713 4714 boolean isPrivate() { 4715 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0; 4716 } 4717 4718 boolean isUidPresent(int uid) { 4719 for (ActivityStack stack : mStacks) { 4720 if (stack.isUidPresent(uid)) { 4721 return true; 4722 } 4723 } 4724 return false; 4725 } 4726 4727 /** Update and get all UIDs that are present on the display and have access to it. */ 4728 private IntArray getPresentUIDs() { 4729 mDisplayAccessUIDs.clear(); 4730 for (ActivityStack stack : mStacks) { 4731 stack.getPresentUIDs(mDisplayAccessUIDs); 4732 } 4733 return mDisplayAccessUIDs; 4734 } 4735 4736 boolean shouldDestroyContentOnRemove() { 4737 return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT; 4738 } 4739 4740 boolean shouldSleep() { 4741 return (mStacks.isEmpty() || !mAllSleepTokens.isEmpty()) 4742 && (mService.mRunningVoice == null); 4743 } 4744 4745 boolean isSleeping() { 4746 return mSleeping; 4747 } 4748 4749 void setIsSleeping(boolean asleep) { 4750 mSleeping = asleep; 4751 } 4752 } 4753 4754 ActivityStack findStackBehind(ActivityStack stack) { 4755 // TODO(multi-display): We are only looking for stacks on the default display. 4756 final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY); 4757 if (display == null) { 4758 return null; 4759 } 4760 final ArrayList<ActivityStack> stacks = display.mStacks; 4761 for (int i = stacks.size() - 1; i >= 0; i--) { 4762 if (stacks.get(i) == stack && i > 0) { 4763 return stacks.get(i - 1); 4764 } 4765 } 4766 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 4767 + " in=" + stacks); 4768 } 4769 4770 /** 4771 * Puts a task into resizing mode during the next app transition. 4772 * 4773 * @param task The task to put into resizing mode 4774 */ 4775 private void setResizingDuringAnimation(TaskRecord task) { 4776 mResizingTasksDuringAnimation.add(task.taskId); 4777 task.setTaskDockedResizing(true); 4778 } 4779 4780 final int startActivityFromRecentsInner(int taskId, Bundle bOptions) { 4781 final TaskRecord task; 4782 final int callingUid; 4783 final String callingPackage; 4784 final Intent intent; 4785 final int userId; 4786 final ActivityOptions activityOptions = (bOptions != null) 4787 ? new ActivityOptions(bOptions) : null; 4788 final int launchStackId = (activityOptions != null) 4789 ? activityOptions.getLaunchStackId() : INVALID_STACK_ID; 4790 if (StackId.isHomeOrRecentsStack(launchStackId)) { 4791 throw new IllegalArgumentException("startActivityFromRecentsInner: Task " 4792 + taskId + " can't be launch in the home/recents stack."); 4793 } 4794 4795 mWindowManager.deferSurfaceLayout(); 4796 try { 4797 if (launchStackId == DOCKED_STACK_ID) { 4798 mWindowManager.setDockedStackCreateState( 4799 activityOptions.getDockCreateMode(), null /* initialBounds */); 4800 4801 // Defer updating the stack in which recents is until the app transition is done, to 4802 // not run into issues where we still need to draw the task in recents but the 4803 // docked stack is already created. 4804 deferUpdateBounds(RECENTS_STACK_ID); 4805 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false); 4806 } 4807 4808 task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, 4809 launchStackId); 4810 if (task == null) { 4811 continueUpdateBounds(RECENTS_STACK_ID); 4812 mWindowManager.executeAppTransition(); 4813 throw new IllegalArgumentException( 4814 "startActivityFromRecentsInner: Task " + taskId + " not found."); 4815 } 4816 4817 // Since we don't have an actual source record here, we assume that the currently 4818 // focused activity was the source. 4819 final ActivityStack focusedStack = getFocusedStack(); 4820 final ActivityRecord sourceRecord = 4821 focusedStack != null ? focusedStack.topActivity() : null; 4822 4823 if (launchStackId != INVALID_STACK_ID) { 4824 if (task.getStackId() != launchStackId) { 4825 task.reparent(launchStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, 4826 DEFER_RESUME, "startActivityFromRecents"); 4827 } 4828 } 4829 4830 // If the user must confirm credentials (e.g. when first launching a work app and the 4831 // Work Challenge is present) let startActivityInPackage handle the intercepting. 4832 if (!mService.mUserController.shouldConfirmCredentials(task.userId) 4833 && task.getRootActivity() != null) { 4834 final ActivityRecord targetActivity = task.getTopActivity(); 4835 4836 mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */, 4837 targetActivity); 4838 mActivityMetricsLogger.notifyActivityLaunching(); 4839 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions, true /* fromRecents */); 4840 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT, 4841 targetActivity); 4842 4843 // If we are launching the task in the docked stack, put it into resizing mode so 4844 // the window renders full-screen with the background filling the void. Also only 4845 // call this at the end to make sure that tasks exists on the window manager side. 4846 if (launchStackId == DOCKED_STACK_ID) { 4847 setResizingDuringAnimation(task); 4848 } 4849 4850 mService.mActivityStarter.postStartActivityProcessing(task.getTopActivity(), 4851 ActivityManager.START_TASK_TO_FRONT, 4852 sourceRecord != null 4853 ? sourceRecord.getTask().getStackId() : INVALID_STACK_ID, 4854 sourceRecord, task.getStack()); 4855 return ActivityManager.START_TASK_TO_FRONT; 4856 } 4857 callingUid = task.mCallingUid; 4858 callingPackage = task.mCallingPackage; 4859 intent = task.intent; 4860 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 4861 userId = task.userId; 4862 int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null, 4863 null, null, 0, 0, bOptions, userId, task, "startActivityFromRecents"); 4864 if (launchStackId == DOCKED_STACK_ID) { 4865 setResizingDuringAnimation(task); 4866 } 4867 return result; 4868 } finally { 4869 mWindowManager.continueSurfaceLayout(); 4870 } 4871 } 4872 4873 /** 4874 * @return a list of activities which are the top ones in each visible stack. The first 4875 * entry will be the focused activity. 4876 */ 4877 List<IBinder> getTopVisibleActivities() { 4878 final ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 4879 // Traverse all displays. 4880 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) { 4881 final ActivityDisplay display = mActivityDisplays.valueAt(i); 4882 // Traverse all stacks on a display. 4883 for (int j = display.mStacks.size() - 1; j >= 0; j--) { 4884 final ActivityStack stack = display.mStacks.get(j); 4885 // Get top activity from a visible stack and add it to the list. 4886 if (stack.shouldBeVisible(null /* starting */) 4887 == ActivityStack.STACK_VISIBLE) { 4888 final ActivityRecord top = stack.topActivity(); 4889 if (top != null) { 4890 if (stack == mFocusedStack) { 4891 topActivityTokens.add(0, top.appToken); 4892 } else { 4893 topActivityTokens.add(top.appToken); 4894 } 4895 } 4896 } 4897 } 4898 } 4899 return topActivityTokens; 4900 } 4901 4902 /** 4903 * Internal container to store a match qualifier alongside a WaitResult. 4904 */ 4905 static class WaitInfo { 4906 private final ComponentName mTargetComponent; 4907 private final WaitResult mResult; 4908 4909 public WaitInfo(ComponentName targetComponent, WaitResult result) { 4910 this.mTargetComponent = targetComponent; 4911 this.mResult = result; 4912 } 4913 4914 public boolean matches(ComponentName targetComponent) { 4915 return mTargetComponent == null || mTargetComponent.equals(targetComponent); 4916 } 4917 4918 public WaitResult getResult() { 4919 return mResult; 4920 } 4921 4922 public ComponentName getComponent() { 4923 return mTargetComponent; 4924 } 4925 4926 public void dump(PrintWriter pw, String prefix) { 4927 pw.println(prefix + "WaitInfo:"); 4928 pw.println(prefix + " mTargetComponent=" + mTargetComponent); 4929 pw.println(prefix + " mResult="); 4930 mResult.dump(pw, prefix); 4931 } 4932 } 4933 4934 private final class SleepTokenImpl extends SleepToken { 4935 private final String mTag; 4936 private final long mAcquireTime; 4937 private final int mDisplayId; 4938 4939 public SleepTokenImpl(String tag, int displayId) { 4940 mTag = tag; 4941 mDisplayId = displayId; 4942 mAcquireTime = SystemClock.uptimeMillis(); 4943 } 4944 4945 @Override 4946 public void release() { 4947 synchronized (mService) { 4948 removeSleepTokenLocked(this); 4949 } 4950 } 4951 4952 @Override 4953 public String toString() { 4954 return "{\"" + mTag + "\", display " + mDisplayId 4955 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}"; 4956 } 4957 } 4958 4959 } 4960