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