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