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 { ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, Manifest.permission.CAMERA)253 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, 254 Manifest.permission.CAMERA); ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, Manifest.permission.CAMERA)255 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, 256 Manifest.permission.CAMERA); ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, Manifest.permission.CALL_PHONE)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 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, int _startFlags, ActivityStack _stack, ProcessRecord _callerApp)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 sendErrorResult(String message)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 ActivityStackSupervisor(ActivityManagerService service)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 setRecentTasks(RecentTasks recentTasks)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 */ initPowerManagement()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. getStatusBarService()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 getDevicePolicyManager()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 setWindowManager(WindowManagerService wm)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 notifyActivityDrawnForKeyguard()561 void notifyActivityDrawnForKeyguard() { 562 if (DEBUG_LOCKSCREEN) mService.logLockScreen(""); 563 mWindowManager.notifyActivityDrawnForKeyguard(); 564 } 565 getFocusedStack()566 ActivityStack getFocusedStack() { 567 return mFocusedStack; 568 } 569 getLastStack()570 ActivityStack getLastStack() { 571 return mLastFocusedStack; 572 } 573 isFocusedStack(ActivityStack stack)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. */ isFrontStack(ActivityStack 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} */ setFocusStackUnchecked(String reason, ActivityStack focusCandidate)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 moveHomeStackToFront(String reason)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. */ moveHomeStackTaskToTop(int homeStackTaskType, String reason)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 resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason)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 anyTaskForIdLocked(int id)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 */ anyTaskForIdLocked(int id, boolean restoreFromRecents, int stackId)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 isInAnyStackLocked(IBinder token)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 */ isUserLockedProfile(@serIdInt int userId)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 taskContainsActivityFromUser(TaskRecord task, @UserIdInt int userId)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 setNextTaskIdForUserLocked(int taskId, int userId)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 nextTaskIdForUser(int taskId, int userId)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 getNextTaskIdForUserLocked(int userId)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 resumedAppLocked()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 attachApplicationLocked(ProcessRecord app)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 allResumedActivitiesIdle()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 allResumedActivitiesComplete()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 allResumedActivitiesVisible()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 */ pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait)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 allPausedActivitiesComplete()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 pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean dontWait)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 cancelInitializingActivities()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 reportActivityVisibleLocked(ActivityRecord r)1014 void reportActivityVisibleLocked(ActivityRecord r) { 1015 sendWaitingVisibleReportLocked(r); 1016 } 1017 sendWaitingVisibleReportLocked(ActivityRecord r)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 reportTaskToFrontNoLaunch(ActivityRecord r)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 reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, long thisTime, long totalTime)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 topRunningActivityLocked()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 getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed)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 resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, ProfilerInfo profilerInfo)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 resolveIntent(Intent intent, String resolvedType, int userId)1170 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) { 1171 return resolveIntent(intent, resolvedType, userId, 0); 1172 } 1173 resolveIntent(Intent intent, String resolvedType, int userId, int flags)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 resolveActivity(Intent intent, String resolvedType, int startFlags, ProfilerInfo profilerInfo, int userId)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 realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig)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 startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig)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 checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options)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 getUserInfo(int userId)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 getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity)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 getActionRestrictionForCallingPackage(String action, String callingPackage, int callingPid, int callingUid)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 moveActivityStackToFront(ActivityRecord r, String reason)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 setLaunchSource(int uid)1588 void setLaunchSource(int uid) { 1589 mLaunchingActivity.setWorkSource(new WorkSource(uid)); 1590 } 1591 acquireLaunchWakelock()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 */ checkFinishBootingLocked()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. activityIdleInternalLocked(final IBinder token, boolean fromTimeout, Configuration config)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 handleAppDiedLocked(ProcessRecord app)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 closeSystemDialogsLocked()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 removeUserLocked(int userId)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 */ updateUserStackLocked(int userId, ActivityStack stack)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 */ finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId)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 updatePreviousProcessLocked(ActivityRecord r)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 resumeFocusedStackTopActivityLocked()1822 boolean resumeFocusedStackTopActivityLocked() { 1823 return resumeFocusedStackTopActivityLocked(null, null, null); 1824 } 1825 resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions)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 updateActivityApplicationInfoLocked(ApplicationInfo aInfo)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 finishTopRunningActivityLocked(ProcessRecord app, String reason)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 finishVoiceTask(IVoiceInteractionSession session)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 findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options, String reason, boolean forceNonResizeable)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 canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId)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 getStack(int stackId)1941 ActivityStack getStack(int stackId) { 1942 return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 1943 } 1944 getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop)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 getStacks()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 getHomeActivityToken()1964 IBinder getHomeActivityToken() { 1965 ActivityRecord homeActivity = getHomeActivity(); 1966 if (homeActivity != null) { 1967 return homeActivity.appToken; 1968 } 1969 return null; 1970 } 1971 getHomeActivity()1972 ActivityRecord getHomeActivity() { 1973 return getHomeActivityForUser(mCurrentUser); 1974 } 1975 getHomeActivityForUser(int userId)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 */ isStackDockedInEffect(int stackId)1998 boolean isStackDockedInEffect(int stackId) { 1999 return stackId == DOCKED_STACK_ID || 2000 (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null); 2001 } 2002 createVirtualActivityContainer(ActivityRecord parentActivity, IActivityContainerCallback callback)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 removeChildActivityContainers(ActivityRecord parentActivity)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 deleteActivityContainer(IActivityContainer container)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 resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume)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 deferUpdateBounds(int stackId)2068 void deferUpdateBounds(int stackId) { 2069 final ActivityStack stack = getStack(stackId); 2070 if (stack != null) { 2071 stack.deferUpdateBounds(); 2072 } 2073 } 2074 continueUpdateBounds(int stackId)2075 void continueUpdateBounds(int stackId) { 2076 final ActivityStack stack = getStack(stackId); 2077 if (stack != null) { 2078 stack.continueUpdateBounds(); 2079 } 2080 } 2081 notifyAppTransitionDone()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 resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds)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 moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop)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 */ moveProfileTasksFromFreeformToFullscreenStackLocked(@serIdInt int userId)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 resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows)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 resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows, boolean deferResume)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 resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds)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 resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume)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 createStackOnDisplay(int stackId, int displayId, boolean onTop)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 getNextStackId()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 */ restoreRecentTaskLocked(TaskRecord task, int stackId)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 */ moveTaskToStackUncheckedLocked( TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason)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 moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, String reason, boolean animate)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 moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, String reason, boolean animate, boolean deferResume)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 moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds)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 moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds)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 positionTaskInStackLocked(int taskId, int stackId, int position)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 findTaskLocked(ActivityRecord r)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 findActivityLocked(Intent intent, ActivityInfo info, boolean compareIntentFilters)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 goingToSleepLocked()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 shutdownLocked(int timeout)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 comeOutOfSleepIfNeededLocked()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 activitySleptLocked(ActivityRecord r)2807 void activitySleptLocked(ActivityRecord r) { 2808 mGoingToSleepActivities.remove(r); 2809 checkReadyForSleepLocked(); 2810 } 2811 checkReadyForSleepLocked()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 reportResumedActivityLocked(ActivityRecord r)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 handleAppCrashLocked(ProcessRecord app)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 requestVisibleBehindLocked(ActivityRecord r, boolean visible)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. handleLaunchTaskBehindCompleteLocked(ActivityRecord r)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 scheduleLaunchTaskBehindComplete(IBinder token)2974 void scheduleLaunchTaskBehindComplete(IBinder token) { 2975 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 2976 } 2977 ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, boolean preserveWindows)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 invalidateTaskLayers()2991 void invalidateTaskLayers() { 2992 mTaskLayersChanged = true; 2993 } 2994 rankTaskLayersIfNeeded()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 clearOtherAppTimeTrackers(AppTimeTracker except)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 scheduleDestroyAllActivities(ProcessRecord app, String reason)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 releaseSomeActivitiesLocked(ProcessRecord app, String reason)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 switchUserLocked(int userId, UserState uss)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. */ isCurrentProfileLocked(int userId)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. */ okToShowLocked(ActivityRecord r)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 processStoppingActivitiesLocked(boolean remove)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 boolean waitingVisible = mWaitingVisibleActivities.contains(s); 3143 if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3144 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3145 if (waitingVisible && nowVisible) { 3146 mWaitingVisibleActivities.remove(s); 3147 if (s.finishing) { 3148 // If this activity is finishing, it is sitting on top of 3149 // everyone else but we now know it is no longer needed... 3150 // so get rid of it. Otherwise, we need to go through the 3151 // normal flow and hide it once we determine that it is 3152 // hidden by the activities in front of it. 3153 if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); 3154 mWindowManager.setAppVisibility(s.appToken, false); 3155 waitingVisible = false; 3156 } 3157 } 3158 if ((!waitingVisible || mService.isSleepingOrShuttingDownLocked()) && remove) { 3159 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); 3160 if (stops == null) { 3161 stops = new ArrayList<>(); 3162 } 3163 stops.add(s); 3164 mStoppingActivities.remove(activityNdx); 3165 } 3166 } 3167 3168 return stops; 3169 } 3170 validateTopActivitiesLocked()3171 void validateTopActivitiesLocked() { 3172 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3173 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3174 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3175 final ActivityStack stack = stacks.get(stackNdx); 3176 final ActivityRecord r = stack.topRunningActivityLocked(); 3177 final ActivityState state = r == null ? DESTROYED : r.state; 3178 if (isFocusedStack(stack)) { 3179 if (r == null) Slog.e(TAG, 3180 "validateTop...: null top activity, stack=" + stack); 3181 else { 3182 final ActivityRecord pausing = stack.mPausingActivity; 3183 if (pausing != null && pausing == r) Slog.e(TAG, 3184 "validateTop...: top stack has pausing activity r=" + r 3185 + " state=" + state); 3186 if (state != INITIALIZING && state != RESUMED) Slog.e(TAG, 3187 "validateTop...: activity in front not resumed r=" + r 3188 + " state=" + state); 3189 } 3190 } else { 3191 final ActivityRecord resumed = stack.mResumedActivity; 3192 if (resumed != null && resumed == r) Slog.e(TAG, 3193 "validateTop...: back stack has resumed activity r=" + r 3194 + " state=" + state); 3195 if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG, 3196 "validateTop...: activity in back resumed r=" + r + " state=" + state); 3197 } 3198 } 3199 } 3200 } 3201 lockTaskModeToString()3202 private String lockTaskModeToString() { 3203 switch (mLockTaskModeState) { 3204 case LOCK_TASK_MODE_LOCKED: 3205 return "LOCKED"; 3206 case LOCK_TASK_MODE_PINNED: 3207 return "PINNED"; 3208 case LOCK_TASK_MODE_NONE: 3209 return "NONE"; 3210 default: return "unknown=" + mLockTaskModeState; 3211 } 3212 } 3213 dump(PrintWriter pw, String prefix)3214 public void dump(PrintWriter pw, String prefix) { 3215 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3216 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3217 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3218 pw.print(prefix); 3219 pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); 3220 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3221 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3222 pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); 3223 final SparseArray<String[]> packages = mService.mLockTaskPackages; 3224 if (packages.size() > 0) { 3225 pw.println(" mLockTaskPackages (userId:packages)="); 3226 for (int i = 0; i < packages.size(); ++i) { 3227 pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i)); 3228 pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i))); 3229 } 3230 } 3231 pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks); 3232 } 3233 getDumpActivitiesLocked(String name)3234 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3235 return mFocusedStack.getDumpActivitiesLocked(name); 3236 } 3237 printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, boolean needSep, String prefix)3238 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3239 boolean needSep, String prefix) { 3240 if (activity != null) { 3241 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3242 if (needSep) { 3243 pw.println(); 3244 } 3245 pw.print(prefix); 3246 pw.println(activity); 3247 return true; 3248 } 3249 } 3250 return false; 3251 } 3252 dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage)3253 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3254 boolean dumpClient, String dumpPackage) { 3255 boolean printed = false; 3256 boolean needSep = false; 3257 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3258 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3259 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3260 pw.println(" (activities from top to bottom):"); 3261 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3262 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3263 final ActivityStack stack = stacks.get(stackNdx); 3264 StringBuilder stackHeader = new StringBuilder(128); 3265 stackHeader.append(" Stack #"); 3266 stackHeader.append(stack.mStackId); 3267 stackHeader.append(":"); 3268 stackHeader.append("\n"); 3269 stackHeader.append(" mFullscreen=" + stack.mFullscreen); 3270 stackHeader.append("\n"); 3271 stackHeader.append(" mBounds=" + stack.mBounds); 3272 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3273 needSep, stackHeader.toString()); 3274 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3275 !dumpAll, false, dumpPackage, true, 3276 " Running activities (most recent first):", null); 3277 3278 needSep = printed; 3279 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3280 " mPausingActivity: "); 3281 if (pr) { 3282 printed = true; 3283 needSep = false; 3284 } 3285 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3286 " mResumedActivity: "); 3287 if (pr) { 3288 printed = true; 3289 needSep = false; 3290 } 3291 if (dumpAll) { 3292 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3293 " mLastPausedActivity: "); 3294 if (pr) { 3295 printed = true; 3296 needSep = true; 3297 } 3298 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3299 needSep, " mLastNoHistoryActivity: "); 3300 } 3301 needSep = printed; 3302 } 3303 } 3304 3305 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3306 false, dumpPackage, true, " Activities waiting to finish:", null); 3307 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3308 false, dumpPackage, true, " Activities waiting to stop:", null); 3309 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3310 false, dumpPackage, true, " Activities waiting for another to become visible:", 3311 null); 3312 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3313 false, dumpPackage, true, " Activities waiting to sleep:", null); 3314 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3315 false, dumpPackage, true, " Activities waiting to sleep:", null); 3316 3317 return printed; 3318 } 3319 dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage, boolean needNL, String header1, String header2)3320 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3321 String prefix, String label, boolean complete, boolean brief, boolean client, 3322 String dumpPackage, boolean needNL, String header1, String header2) { 3323 TaskRecord lastTask = null; 3324 String innerPrefix = null; 3325 String[] args = null; 3326 boolean printed = false; 3327 for (int i=list.size()-1; i>=0; i--) { 3328 final ActivityRecord r = list.get(i); 3329 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3330 continue; 3331 } 3332 if (innerPrefix == null) { 3333 innerPrefix = prefix + " "; 3334 args = new String[0]; 3335 } 3336 printed = true; 3337 final boolean full = !brief && (complete || !r.isInHistory()); 3338 if (needNL) { 3339 pw.println(""); 3340 needNL = false; 3341 } 3342 if (header1 != null) { 3343 pw.println(header1); 3344 header1 = null; 3345 } 3346 if (header2 != null) { 3347 pw.println(header2); 3348 header2 = null; 3349 } 3350 if (lastTask != r.task) { 3351 lastTask = r.task; 3352 pw.print(prefix); 3353 pw.print(full ? "* " : " "); 3354 pw.println(lastTask); 3355 if (full) { 3356 lastTask.dump(pw, prefix + " "); 3357 } else if (complete) { 3358 // Complete + brief == give a summary. Isn't that obvious?!? 3359 if (lastTask.intent != null) { 3360 pw.print(prefix); pw.print(" "); 3361 pw.println(lastTask.intent.toInsecureStringWithClip()); 3362 } 3363 } 3364 } 3365 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3366 pw.print(" #"); pw.print(i); pw.print(": "); 3367 pw.println(r); 3368 if (full) { 3369 r.dump(pw, innerPrefix); 3370 } else if (complete) { 3371 // Complete + brief == give a summary. Isn't that obvious?!? 3372 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3373 if (r.app != null) { 3374 pw.print(innerPrefix); pw.println(r.app); 3375 } 3376 } 3377 if (client && r.app != null && r.app.thread != null) { 3378 // flush anything that is already in the PrintWriter since the thread is going 3379 // to write to the file descriptor directly 3380 pw.flush(); 3381 try { 3382 TransferPipe tp = new TransferPipe(); 3383 try { 3384 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3385 r.appToken, innerPrefix, args); 3386 // Short timeout, since blocking here can 3387 // deadlock with the application. 3388 tp.go(fd, 2000); 3389 } finally { 3390 tp.kill(); 3391 } 3392 } catch (IOException e) { 3393 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3394 } catch (RemoteException e) { 3395 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3396 } 3397 needNL = true; 3398 } 3399 } 3400 return printed; 3401 } 3402 scheduleIdleTimeoutLocked(ActivityRecord next)3403 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3404 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3405 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3406 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3407 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3408 } 3409 scheduleIdleLocked()3410 final void scheduleIdleLocked() { 3411 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3412 } 3413 removeTimeoutsForActivityLocked(ActivityRecord r)3414 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3415 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 3416 + Debug.getCallers(4)); 3417 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3418 } 3419 scheduleResumeTopActivities()3420 final void scheduleResumeTopActivities() { 3421 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3422 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3423 } 3424 } 3425 removeSleepTimeouts()3426 void removeSleepTimeouts() { 3427 mSleepTimeout = false; 3428 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3429 } 3430 scheduleSleepTimeout()3431 final void scheduleSleepTimeout() { 3432 removeSleepTimeouts(); 3433 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3434 } 3435 3436 @Override onDisplayAdded(int displayId)3437 public void onDisplayAdded(int displayId) { 3438 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 3439 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3440 } 3441 3442 @Override onDisplayRemoved(int displayId)3443 public void onDisplayRemoved(int displayId) { 3444 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 3445 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3446 } 3447 3448 @Override onDisplayChanged(int displayId)3449 public void onDisplayChanged(int displayId) { 3450 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 3451 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3452 } 3453 handleDisplayAdded(int displayId)3454 private void handleDisplayAdded(int displayId) { 3455 boolean newDisplay; 3456 synchronized (mService) { 3457 newDisplay = mActivityDisplays.get(displayId) == null; 3458 if (newDisplay) { 3459 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3460 if (activityDisplay.mDisplay == null) { 3461 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3462 return; 3463 } 3464 mActivityDisplays.put(displayId, activityDisplay); 3465 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 3466 } 3467 } 3468 if (newDisplay) { 3469 mWindowManager.onDisplayAdded(displayId); 3470 } 3471 } 3472 calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display)3473 private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) { 3474 mDefaultMinSizeOfResizeableTask = 3475 mService.mContext.getResources().getDimensionPixelSize( 3476 com.android.internal.R.dimen.default_minimal_size_resizable_task); 3477 } 3478 handleDisplayRemoved(int displayId)3479 private void handleDisplayRemoved(int displayId) { 3480 synchronized (mService) { 3481 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3482 if (activityDisplay != null) { 3483 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3484 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3485 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3486 } 3487 mActivityDisplays.remove(displayId); 3488 } 3489 } 3490 mWindowManager.onDisplayRemoved(displayId); 3491 } 3492 handleDisplayChanged(int displayId)3493 private void handleDisplayChanged(int displayId) { 3494 synchronized (mService) { 3495 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3496 if (activityDisplay != null) { 3497 // TODO: Update the bounds. 3498 } 3499 } 3500 mWindowManager.onDisplayChanged(displayId); 3501 } 3502 getStackInfoLocked(ActivityStack stack)3503 private StackInfo getStackInfoLocked(ActivityStack stack) { 3504 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 3505 StackInfo info = new StackInfo(); 3506 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3507 info.displayId = Display.DEFAULT_DISPLAY; 3508 info.stackId = stack.mStackId; 3509 info.userId = stack.mCurrentUser; 3510 info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE; 3511 info.position = display != null 3512 ? display.mStacks.indexOf(stack) 3513 : 0; 3514 3515 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3516 final int numTasks = tasks.size(); 3517 int[] taskIds = new int[numTasks]; 3518 String[] taskNames = new String[numTasks]; 3519 Rect[] taskBounds = new Rect[numTasks]; 3520 int[] taskUserIds = new int[numTasks]; 3521 for (int i = 0; i < numTasks; ++i) { 3522 final TaskRecord task = tasks.get(i); 3523 taskIds[i] = task.taskId; 3524 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3525 : task.realActivity != null ? task.realActivity.flattenToString() 3526 : task.getTopActivity() != null ? task.getTopActivity().packageName 3527 : "unknown"; 3528 taskBounds[i] = new Rect(); 3529 mWindowManager.getTaskBounds(task.taskId, taskBounds[i]); 3530 taskUserIds[i] = task.userId; 3531 } 3532 info.taskIds = taskIds; 3533 info.taskNames = taskNames; 3534 info.taskBounds = taskBounds; 3535 info.taskUserIds = taskUserIds; 3536 3537 final ActivityRecord top = stack.topRunningActivityLocked(); 3538 info.topActivity = top != null ? top.intent.getComponent() : null; 3539 return info; 3540 } 3541 getStackInfoLocked(int stackId)3542 StackInfo getStackInfoLocked(int stackId) { 3543 ActivityStack stack = getStack(stackId); 3544 if (stack != null) { 3545 return getStackInfoLocked(stack); 3546 } 3547 return null; 3548 } 3549 getAllStackInfosLocked()3550 ArrayList<StackInfo> getAllStackInfosLocked() { 3551 ArrayList<StackInfo> list = new ArrayList<>(); 3552 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3553 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3554 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3555 list.add(getStackInfoLocked(stacks.get(ndx))); 3556 } 3557 } 3558 return list; 3559 } 3560 getLockedTaskLocked()3561 TaskRecord getLockedTaskLocked() { 3562 final int top = mLockTaskModeTasks.size() - 1; 3563 if (top >= 0) { 3564 return mLockTaskModeTasks.get(top); 3565 } 3566 return null; 3567 } 3568 isLockedTask(TaskRecord task)3569 boolean isLockedTask(TaskRecord task) { 3570 return mLockTaskModeTasks.contains(task); 3571 } 3572 isLastLockedTask(TaskRecord task)3573 boolean isLastLockedTask(TaskRecord task) { 3574 return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task); 3575 } 3576 removeLockedTaskLocked(final TaskRecord task)3577 void removeLockedTaskLocked(final TaskRecord task) { 3578 if (!mLockTaskModeTasks.remove(task)) { 3579 return; 3580 } 3581 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task); 3582 if (mLockTaskModeTasks.isEmpty()) { 3583 // Last one. 3584 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task + 3585 " last task, reverting locktask mode. Callers=" + Debug.getCallers(3)); 3586 final Message lockTaskMsg = Message.obtain(); 3587 lockTaskMsg.arg1 = task.userId; 3588 lockTaskMsg.what = LOCK_TASK_END_MSG; 3589 mHandler.sendMessage(lockTaskMsg); 3590 } 3591 } 3592 handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId)3593 void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) { 3594 handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId, 3595 false /* forceNonResizable */); 3596 } 3597 handleNonResizableTaskIfNeeded( TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable)3598 void handleNonResizableTaskIfNeeded( 3599 TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) { 3600 if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID) 3601 || task.isHomeTask()) { 3602 return; 3603 } 3604 3605 final ActivityRecord topActivity = task.getTopActivity(); 3606 if (!task.canGoInDockedStack() || forceNonResizable) { 3607 // Display a warning toast that we tried to put a non-dockable task in the docked stack. 3608 mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG); 3609 3610 // Dismiss docked stack. If task appeared to be in docked stack but is not resizable - 3611 // we need to move it to top of fullscreen stack, otherwise it will be covered. 3612 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID); 3613 } else if (topActivity != null && topActivity.isNonResizableOrForced() 3614 && !topActivity.noDisplay) { 3615 String packageName = topActivity.appInfo.packageName; 3616 mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0, 3617 packageName).sendToTarget(); 3618 } 3619 } 3620 showLockTaskToast()3621 void showLockTaskToast() { 3622 if (mLockTaskNotify != null) { 3623 mLockTaskNotify.showToast(mLockTaskModeState); 3624 } 3625 } 3626 showLockTaskEscapeMessageLocked(TaskRecord task)3627 void showLockTaskEscapeMessageLocked(TaskRecord task) { 3628 if (mLockTaskModeTasks.contains(task)) { 3629 mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG); 3630 } 3631 } 3632 setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason, boolean andResume)3633 void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason, 3634 boolean andResume) { 3635 if (task == null) { 3636 // Take out of lock task mode if necessary 3637 final TaskRecord lockedTask = getLockedTaskLocked(); 3638 if (lockedTask != null) { 3639 removeLockedTaskLocked(lockedTask); 3640 if (!mLockTaskModeTasks.isEmpty()) { 3641 // There are locked tasks remaining, can only finish this task, not unlock it. 3642 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3643 "setLockTaskModeLocked: Tasks remaining, can't unlock"); 3644 lockedTask.performClearTaskLocked(); 3645 resumeFocusedStackTopActivityLocked(); 3646 return; 3647 } 3648 } 3649 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3650 "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4)); 3651 return; 3652 } 3653 3654 // Should have already been checked, but do it again. 3655 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 3656 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3657 "setLockTaskModeLocked: Can't lock due to auth"); 3658 return; 3659 } 3660 if (isLockTaskModeViolation(task)) { 3661 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 3662 return; 3663 } 3664 3665 if (mLockTaskModeTasks.isEmpty()) { 3666 // First locktask. 3667 final Message lockTaskMsg = Message.obtain(); 3668 lockTaskMsg.obj = task.intent.getComponent().getPackageName(); 3669 lockTaskMsg.arg1 = task.userId; 3670 lockTaskMsg.what = LOCK_TASK_START_MSG; 3671 lockTaskMsg.arg2 = lockTaskModeState; 3672 mHandler.sendMessage(lockTaskMsg); 3673 } 3674 // Add it or move it to the top. 3675 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task + 3676 " Callers=" + Debug.getCallers(4)); 3677 mLockTaskModeTasks.remove(task); 3678 mLockTaskModeTasks.add(task); 3679 3680 if (task.mLockTaskUid == -1) { 3681 task.mLockTaskUid = task.effectiveUid; 3682 } 3683 3684 if (andResume) { 3685 findTaskToMoveToFrontLocked(task, 0, null, reason, 3686 lockTaskModeState != LOCK_TASK_MODE_NONE); 3687 resumeFocusedStackTopActivityLocked(); 3688 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { 3689 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId, 3690 true /* forceNonResizable */); 3691 } 3692 } 3693 isLockTaskModeViolation(TaskRecord task)3694 boolean isLockTaskModeViolation(TaskRecord task) { 3695 return isLockTaskModeViolation(task, false); 3696 } 3697 isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask)3698 boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) { 3699 if (getLockedTaskLocked() == task && !isNewClearTask) { 3700 return false; 3701 } 3702 final int lockTaskAuth = task.mLockTaskAuth; 3703 switch (lockTaskAuth) { 3704 case LOCK_TASK_AUTH_DONT_LOCK: 3705 return !mLockTaskModeTasks.isEmpty(); 3706 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 3707 case LOCK_TASK_AUTH_LAUNCHABLE: 3708 case LOCK_TASK_AUTH_WHITELISTED: 3709 return false; 3710 case LOCK_TASK_AUTH_PINNABLE: 3711 // Pinnable tasks can't be launched on top of locktask tasks. 3712 return !mLockTaskModeTasks.isEmpty(); 3713 default: 3714 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth); 3715 return true; 3716 } 3717 } 3718 onLockTaskPackagesUpdatedLocked()3719 void onLockTaskPackagesUpdatedLocked() { 3720 boolean didSomething = false; 3721 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 3722 final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); 3723 final boolean wasWhitelisted = 3724 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3725 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3726 lockedTask.setLockTaskAuth(); 3727 final boolean isWhitelisted = 3728 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3729 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3730 if (wasWhitelisted && !isWhitelisted) { 3731 // Lost whitelisting authorization. End it now. 3732 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + 3733 lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); 3734 removeLockedTaskLocked(lockedTask); 3735 lockedTask.performClearTaskLocked(); 3736 didSomething = true; 3737 } 3738 } 3739 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3740 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3741 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3742 final ActivityStack stack = stacks.get(stackNdx); 3743 stack.onLockTaskPackagesUpdatedLocked(); 3744 } 3745 } 3746 final ActivityRecord r = topRunningActivityLocked(); 3747 final TaskRecord task = r != null ? r.task : null; 3748 if (mLockTaskModeTasks.isEmpty() && task != null 3749 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 3750 // This task must have just been authorized. 3751 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, 3752 "onLockTaskPackagesUpdated: starting new locktask task=" + task); 3753 setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated", 3754 false); 3755 didSomething = true; 3756 } 3757 if (didSomething) { 3758 resumeFocusedStackTopActivityLocked(); 3759 } 3760 } 3761 getLockTaskModeState()3762 int getLockTaskModeState() { 3763 return mLockTaskModeState; 3764 } 3765 activityRelaunchedLocked(IBinder token)3766 void activityRelaunchedLocked(IBinder token) { 3767 mWindowManager.notifyAppRelaunchingFinished(token); 3768 } 3769 activityRelaunchingLocked(ActivityRecord r)3770 void activityRelaunchingLocked(ActivityRecord r) { 3771 mWindowManager.notifyAppRelaunching(r.appToken); 3772 } 3773 logStackState()3774 void logStackState() { 3775 mActivityMetricsLogger.logWindowState(); 3776 } 3777 scheduleReportMultiWindowModeChanged(TaskRecord task)3778 void scheduleReportMultiWindowModeChanged(TaskRecord task) { 3779 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3780 final ActivityRecord r = task.mActivities.get(i); 3781 if (r.app != null && r.app.thread != null) { 3782 mMultiWindowModeChangedActivities.add(r); 3783 } 3784 } 3785 3786 if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) { 3787 mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG); 3788 } 3789 } 3790 scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack)3791 void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) { 3792 final ActivityStack stack = task.stack; 3793 if (prevStack == null || prevStack == stack 3794 || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) { 3795 return; 3796 } 3797 3798 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3799 final ActivityRecord r = task.mActivities.get(i); 3800 if (r.app != null && r.app.thread != null) { 3801 mPipModeChangedActivities.add(r); 3802 } 3803 } 3804 3805 if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { 3806 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); 3807 } 3808 } 3809 setDockedStackMinimized(boolean minimized)3810 void setDockedStackMinimized(boolean minimized) { 3811 mIsDockMinimized = minimized; 3812 if (minimized) { 3813 // Docked stack is not visible, no need to confirm credentials for its top activity. 3814 return; 3815 } 3816 final ActivityStack dockedStack = getStack(StackId.DOCKED_STACK_ID); 3817 if (dockedStack == null) { 3818 return; 3819 } 3820 final ActivityRecord top = dockedStack.topRunningActivityLocked(); 3821 if (top != null && mService.mUserController.shouldConfirmCredentials(top.userId)) { 3822 mService.mActivityStarter.showConfirmDeviceCredential(top.userId); 3823 } 3824 } 3825 3826 private final class ActivityStackSupervisorHandler extends Handler { 3827 ActivityStackSupervisorHandler(Looper looper)3828 public ActivityStackSupervisorHandler(Looper looper) { 3829 super(looper); 3830 } 3831 activityIdleInternal(ActivityRecord r)3832 void activityIdleInternal(ActivityRecord r) { 3833 synchronized (mService) { 3834 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3835 } 3836 } 3837 3838 @Override handleMessage(Message msg)3839 public void handleMessage(Message msg) { 3840 switch (msg.what) { 3841 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: { 3842 synchronized (mService) { 3843 for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) { 3844 final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i); 3845 r.scheduleMultiWindowModeChanged(); 3846 } 3847 } 3848 } break; 3849 case REPORT_PIP_MODE_CHANGED_MSG: { 3850 synchronized (mService) { 3851 for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) { 3852 final ActivityRecord r = mPipModeChangedActivities.remove(i); 3853 r.schedulePictureInPictureModeChanged(); 3854 } 3855 } 3856 } break; 3857 case IDLE_TIMEOUT_MSG: { 3858 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3859 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3860 if (mService.mDidDexOpt) { 3861 mService.mDidDexOpt = false; 3862 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3863 nmsg.obj = msg.obj; 3864 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3865 return; 3866 } 3867 // We don't at this point know if the activity is fullscreen, 3868 // so we need to be conservative and assume it isn't. 3869 activityIdleInternal((ActivityRecord)msg.obj); 3870 } break; 3871 case IDLE_NOW_MSG: { 3872 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3873 activityIdleInternal((ActivityRecord)msg.obj); 3874 } break; 3875 case RESUME_TOP_ACTIVITY_MSG: { 3876 synchronized (mService) { 3877 resumeFocusedStackTopActivityLocked(); 3878 } 3879 } break; 3880 case SLEEP_TIMEOUT_MSG: { 3881 synchronized (mService) { 3882 if (mService.isSleepingOrShuttingDownLocked()) { 3883 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3884 mSleepTimeout = true; 3885 checkReadyForSleepLocked(); 3886 } 3887 } 3888 } break; 3889 case LAUNCH_TIMEOUT_MSG: { 3890 if (mService.mDidDexOpt) { 3891 mService.mDidDexOpt = false; 3892 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3893 return; 3894 } 3895 synchronized (mService) { 3896 if (mLaunchingActivity.isHeld()) { 3897 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3898 if (VALIDATE_WAKE_LOCK_CALLER 3899 && Binder.getCallingUid() != Process.myUid()) { 3900 throw new IllegalStateException("Calling must be system uid"); 3901 } 3902 mLaunchingActivity.release(); 3903 } 3904 } 3905 } break; 3906 case HANDLE_DISPLAY_ADDED: { 3907 handleDisplayAdded(msg.arg1); 3908 } break; 3909 case HANDLE_DISPLAY_CHANGED: { 3910 handleDisplayChanged(msg.arg1); 3911 } break; 3912 case HANDLE_DISPLAY_REMOVED: { 3913 handleDisplayRemoved(msg.arg1); 3914 } break; 3915 case CONTAINER_CALLBACK_VISIBILITY: { 3916 final ActivityContainer container = (ActivityContainer) msg.obj; 3917 final IActivityContainerCallback callback = container.mCallback; 3918 if (callback != null) { 3919 try { 3920 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3921 } catch (RemoteException e) { 3922 } 3923 } 3924 } break; 3925 case LOCK_TASK_START_MSG: { 3926 // When lock task starts, we disable the status bars. 3927 try { 3928 if (mLockTaskNotify == null) { 3929 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3930 } 3931 mLockTaskNotify.show(true); 3932 mLockTaskModeState = msg.arg2; 3933 if (getStatusBarService() != null) { 3934 int flags = 0; 3935 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 3936 flags = StatusBarManager.DISABLE_MASK 3937 & (~StatusBarManager.DISABLE_BACK); 3938 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 3939 flags = StatusBarManager.DISABLE_MASK 3940 & (~StatusBarManager.DISABLE_BACK) 3941 & (~StatusBarManager.DISABLE_HOME) 3942 & (~StatusBarManager.DISABLE_RECENT); 3943 } 3944 getStatusBarService().disable(flags, mToken, 3945 mService.mContext.getPackageName()); 3946 } 3947 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3948 if (getDevicePolicyManager() != null) { 3949 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3950 (String)msg.obj, msg.arg1); 3951 } 3952 } catch (RemoteException ex) { 3953 throw new RuntimeException(ex); 3954 } 3955 } break; 3956 case LOCK_TASK_END_MSG: { 3957 // When lock task ends, we enable the status bars. 3958 try { 3959 if (getStatusBarService() != null) { 3960 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3961 mService.mContext.getPackageName()); 3962 } 3963 mWindowManager.reenableKeyguard(mToken); 3964 if (getDevicePolicyManager() != null) { 3965 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3966 msg.arg1); 3967 } 3968 if (mLockTaskNotify == null) { 3969 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3970 } 3971 mLockTaskNotify.show(false); 3972 try { 3973 boolean shouldLockKeyguard = Settings.Secure.getInt( 3974 mService.mContext.getContentResolver(), 3975 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; 3976 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) { 3977 mWindowManager.lockNow(null); 3978 mWindowManager.dismissKeyguard(); 3979 new LockPatternUtils(mService.mContext) 3980 .requireCredentialEntry(UserHandle.USER_ALL); 3981 } 3982 } catch (SettingNotFoundException e) { 3983 // No setting, don't lock. 3984 } 3985 } catch (RemoteException ex) { 3986 throw new RuntimeException(ex); 3987 } finally { 3988 mLockTaskModeState = LOCK_TASK_MODE_NONE; 3989 } 3990 } break; 3991 case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: { 3992 if (mLockTaskNotify == null) { 3993 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3994 } 3995 mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED); 3996 } break; 3997 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3998 final ActivityContainer container = (ActivityContainer) msg.obj; 3999 final IActivityContainerCallback callback = container.mCallback; 4000 if (callback != null) { 4001 try { 4002 callback.onAllActivitiesComplete(container.asBinder()); 4003 } catch (RemoteException e) { 4004 } 4005 } 4006 } break; 4007 case LAUNCH_TASK_BEHIND_COMPLETE: { 4008 synchronized (mService) { 4009 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 4010 if (r != null) { 4011 handleLaunchTaskBehindCompleteLocked(r); 4012 } 4013 } 4014 } break; 4015 4016 } 4017 } 4018 } 4019 4020 class ActivityContainer extends android.app.IActivityContainer.Stub { 4021 final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK | 4022 FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 4023 final int mStackId; 4024 IActivityContainerCallback mCallback = null; 4025 final ActivityStack mStack; 4026 ActivityRecord mParentActivity = null; 4027 String mIdString; 4028 4029 boolean mVisible = true; 4030 4031 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 4032 ActivityDisplay mActivityDisplay; 4033 4034 final static int CONTAINER_STATE_HAS_SURFACE = 0; 4035 final static int CONTAINER_STATE_NO_SURFACE = 1; 4036 final static int CONTAINER_STATE_FINISHING = 2; 4037 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 4038 ActivityContainer(int stackId)4039 ActivityContainer(int stackId) { 4040 synchronized (mService) { 4041 mStackId = stackId; 4042 mStack = new ActivityStack(this, mRecentTasks); 4043 mIdString = "ActivtyContainer{" + mStackId + "}"; 4044 if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this); 4045 } 4046 } 4047 attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop)4048 void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) { 4049 if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this 4050 + " to display=" + activityDisplay + " onTop=" + onTop); 4051 mActivityDisplay = activityDisplay; 4052 mStack.attachDisplay(activityDisplay, onTop); 4053 activityDisplay.attachActivities(mStack, onTop); 4054 } 4055 4056 @Override attachToDisplay(int displayId)4057 public void attachToDisplay(int displayId) { 4058 synchronized (mService) { 4059 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 4060 if (activityDisplay == null) { 4061 return; 4062 } 4063 attachToDisplayLocked(activityDisplay, true); 4064 } 4065 } 4066 4067 @Override getDisplayId()4068 public int getDisplayId() { 4069 synchronized (mService) { 4070 if (mActivityDisplay != null) { 4071 return mActivityDisplay.mDisplayId; 4072 } 4073 } 4074 return -1; 4075 } 4076 4077 @Override getStackId()4078 public int getStackId() { 4079 synchronized (mService) { 4080 return mStackId; 4081 } 4082 } 4083 4084 @Override injectEvent(InputEvent event)4085 public boolean injectEvent(InputEvent event) { 4086 final long origId = Binder.clearCallingIdentity(); 4087 try { 4088 synchronized (mService) { 4089 if (mActivityDisplay != null) { 4090 return mInputManagerInternal.injectInputEvent(event, 4091 mActivityDisplay.mDisplayId, 4092 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 4093 } 4094 } 4095 return false; 4096 } finally { 4097 Binder.restoreCallingIdentity(origId); 4098 } 4099 } 4100 4101 @Override release()4102 public void release() { 4103 synchronized (mService) { 4104 if (mContainerState == CONTAINER_STATE_FINISHING) { 4105 return; 4106 } 4107 mContainerState = CONTAINER_STATE_FINISHING; 4108 4109 long origId = Binder.clearCallingIdentity(); 4110 try { 4111 mStack.finishAllActivitiesLocked(false); 4112 mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack); 4113 } finally { 4114 Binder.restoreCallingIdentity(origId); 4115 } 4116 } 4117 } 4118 detachLocked()4119 protected void detachLocked() { 4120 if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display=" 4121 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 4122 if (mActivityDisplay != null) { 4123 mActivityDisplay.detachActivitiesLocked(mStack); 4124 mActivityDisplay = null; 4125 mStack.detachDisplay(); 4126 } 4127 } 4128 4129 @Override startActivity(Intent intent)4130 public final int startActivity(Intent intent) { 4131 return mService.startActivity(intent, this); 4132 } 4133 4134 @Override startActivityIntentSender(IIntentSender intentSender)4135 public final int startActivityIntentSender(IIntentSender intentSender) 4136 throws TransactionTooLargeException { 4137 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 4138 4139 if (!(intentSender instanceof PendingIntentRecord)) { 4140 throw new IllegalArgumentException("Bad PendingIntent object"); 4141 } 4142 4143 final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(), 4144 Binder.getCallingUid(), mCurrentUser, false, 4145 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 4146 4147 final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 4148 checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent, 4149 pendingIntent.key.requestResolvedType); 4150 4151 return pendingIntent.sendInner(0, null, null, null, null, null, null, 0, 4152 FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 4153 } 4154 checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType)4155 void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) { 4156 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 4157 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 4158 throw new SecurityException( 4159 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 4160 } 4161 } 4162 4163 @Override asBinder()4164 public IBinder asBinder() { 4165 return this; 4166 } 4167 4168 @Override setSurface(Surface surface, int width, int height, int density)4169 public void setSurface(Surface surface, int width, int height, int density) { 4170 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 4171 } 4172 getOuter()4173 ActivityStackSupervisor getOuter() { 4174 return ActivityStackSupervisor.this; 4175 } 4176 isAttachedLocked()4177 boolean isAttachedLocked() { 4178 return mActivityDisplay != null; 4179 } 4180 4181 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. setVisible(boolean visible)4182 void setVisible(boolean visible) { 4183 if (mVisible != visible) { 4184 mVisible = visible; 4185 if (mCallback != null) { 4186 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 4187 0 /* unused */, this).sendToTarget(); 4188 } 4189 } 4190 } 4191 setDrawn()4192 void setDrawn() { 4193 } 4194 4195 // You can always start a new task on a regular ActivityStack. isEligibleForNewTasks()4196 boolean isEligibleForNewTasks() { 4197 return true; 4198 } 4199 onTaskListEmptyLocked()4200 void onTaskListEmptyLocked() { 4201 detachLocked(); 4202 deleteActivityContainer(this); 4203 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 4204 } 4205 4206 @Override toString()4207 public String toString() { 4208 return mIdString + (mActivityDisplay == null ? "N" : "A"); 4209 } 4210 } 4211 4212 private class VirtualActivityContainer extends ActivityContainer { 4213 Surface mSurface; 4214 boolean mDrawn = false; 4215 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback)4216 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 4217 super(getNextStackId()); 4218 mParentActivity = parent; 4219 mCallback = callback; 4220 mContainerState = CONTAINER_STATE_NO_SURFACE; 4221 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 4222 } 4223 4224 @Override setSurface(Surface surface, int width, int height, int density)4225 public void setSurface(Surface surface, int width, int height, int density) { 4226 super.setSurface(surface, width, height, density); 4227 4228 synchronized (mService) { 4229 final long origId = Binder.clearCallingIdentity(); 4230 try { 4231 setSurfaceLocked(surface, width, height, density); 4232 } finally { 4233 Binder.restoreCallingIdentity(origId); 4234 } 4235 } 4236 } 4237 setSurfaceLocked(Surface surface, int width, int height, int density)4238 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 4239 if (mContainerState == CONTAINER_STATE_FINISHING) { 4240 return; 4241 } 4242 VirtualActivityDisplay virtualActivityDisplay = 4243 (VirtualActivityDisplay) mActivityDisplay; 4244 if (virtualActivityDisplay == null) { 4245 virtualActivityDisplay = 4246 new VirtualActivityDisplay(width, height, density); 4247 mActivityDisplay = virtualActivityDisplay; 4248 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 4249 attachToDisplayLocked(virtualActivityDisplay, true); 4250 } 4251 4252 if (mSurface != null) { 4253 mSurface.release(); 4254 } 4255 4256 mSurface = surface; 4257 if (surface != null) { 4258 resumeFocusedStackTopActivityLocked(); 4259 } else { 4260 mContainerState = CONTAINER_STATE_NO_SURFACE; 4261 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 4262 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 4263 mStack.startPausingLocked(false, true, null, false); 4264 } 4265 } 4266 4267 setSurfaceIfReadyLocked(); 4268 4269 if (DEBUG_STACK) Slog.d(TAG_STACK, 4270 "setSurface: " + this + " to display=" + virtualActivityDisplay); 4271 } 4272 4273 @Override isAttachedLocked()4274 boolean isAttachedLocked() { 4275 return mSurface != null && super.isAttachedLocked(); 4276 } 4277 4278 @Override setDrawn()4279 void setDrawn() { 4280 synchronized (mService) { 4281 mDrawn = true; 4282 setSurfaceIfReadyLocked(); 4283 } 4284 } 4285 4286 // Never start a new task on an ActivityView if it isn't explicitly specified. 4287 @Override isEligibleForNewTasks()4288 boolean isEligibleForNewTasks() { 4289 return false; 4290 } 4291 setSurfaceIfReadyLocked()4292 private void setSurfaceIfReadyLocked() { 4293 if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 4294 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 4295 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 4296 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 4297 mContainerState = CONTAINER_STATE_HAS_SURFACE; 4298 } 4299 } 4300 } 4301 4302 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 4303 * attached {@link ActivityStack}s */ 4304 class ActivityDisplay { 4305 /** Actual Display this object tracks. */ 4306 int mDisplayId; 4307 Display mDisplay; 4308 DisplayInfo mDisplayInfo = new DisplayInfo(); 4309 4310 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 4311 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 4312 final ArrayList<ActivityStack> mStacks = new ArrayList<>(); 4313 4314 ActivityRecord mVisibleBehindActivity; 4315 ActivityDisplay()4316 ActivityDisplay() { 4317 } 4318 4319 // After instantiation, check that mDisplay is not null before using this. The alternative 4320 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. ActivityDisplay(int displayId)4321 ActivityDisplay(int displayId) { 4322 final Display display = mDisplayManager.getDisplay(displayId); 4323 if (display == null) { 4324 return; 4325 } 4326 init(display); 4327 } 4328 init(Display display)4329 void init(Display display) { 4330 mDisplay = display; 4331 mDisplayId = display.getDisplayId(); 4332 mDisplay.getDisplayInfo(mDisplayInfo); 4333 } 4334 attachActivities(ActivityStack stack, boolean onTop)4335 void attachActivities(ActivityStack stack, boolean onTop) { 4336 if (DEBUG_STACK) Slog.v(TAG_STACK, 4337 "attachActivities: attaching " + stack + " to displayId=" + mDisplayId 4338 + " onTop=" + onTop); 4339 if (onTop) { 4340 mStacks.add(stack); 4341 } else { 4342 mStacks.add(0, stack); 4343 } 4344 } 4345 detachActivitiesLocked(ActivityStack stack)4346 void detachActivitiesLocked(ActivityStack stack) { 4347 if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack 4348 + " from displayId=" + mDisplayId); 4349 mStacks.remove(stack); 4350 } 4351 setVisibleBehindActivity(ActivityRecord r)4352 void setVisibleBehindActivity(ActivityRecord r) { 4353 mVisibleBehindActivity = r; 4354 } 4355 hasVisibleBehindActivity()4356 boolean hasVisibleBehindActivity() { 4357 return mVisibleBehindActivity != null; 4358 } 4359 4360 @Override toString()4361 public String toString() { 4362 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4363 } 4364 } 4365 4366 class VirtualActivityDisplay extends ActivityDisplay { 4367 VirtualDisplay mVirtualDisplay; 4368 VirtualActivityDisplay(int width, int height, int density)4369 VirtualActivityDisplay(int width, int height, int density) { 4370 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 4371 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 4372 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 4373 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 4374 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 4375 4376 init(mVirtualDisplay.getDisplay()); 4377 4378 mWindowManager.handleDisplayAdded(mDisplayId); 4379 } 4380 setSurface(Surface surface)4381 void setSurface(Surface surface) { 4382 if (mVirtualDisplay != null) { 4383 mVirtualDisplay.setSurface(surface); 4384 } 4385 } 4386 4387 @Override detachActivitiesLocked(ActivityStack stack)4388 void detachActivitiesLocked(ActivityStack stack) { 4389 super.detachActivitiesLocked(stack); 4390 if (mVirtualDisplay != null) { 4391 mVirtualDisplay.release(); 4392 mVirtualDisplay = null; 4393 } 4394 } 4395 4396 @Override toString()4397 public String toString() { 4398 return "VirtualActivityDisplay={" + mDisplayId + "}"; 4399 } 4400 } 4401 4402 /** 4403 * Adjust bounds to stay within stack bounds. 4404 * 4405 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way 4406 * that keep them unchanged, but be contained within the stack bounds. 4407 * 4408 * @param bounds Bounds to be adjusted. 4409 * @param stackBounds Bounds within which the other bounds should remain. 4410 */ fitWithinBounds(Rect bounds, Rect stackBounds)4411 private static void fitWithinBounds(Rect bounds, Rect stackBounds) { 4412 if (stackBounds == null || stackBounds.contains(bounds)) { 4413 return; 4414 } 4415 4416 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) { 4417 final int maxRight = stackBounds.right 4418 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER); 4419 int horizontalDiff = stackBounds.left - bounds.left; 4420 if ((horizontalDiff < 0 && bounds.left >= maxRight) 4421 || (bounds.left + horizontalDiff >= maxRight)) { 4422 horizontalDiff = maxRight - bounds.left; 4423 } 4424 bounds.left += horizontalDiff; 4425 bounds.right += horizontalDiff; 4426 } 4427 4428 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) { 4429 final int maxBottom = stackBounds.bottom 4430 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER); 4431 int verticalDiff = stackBounds.top - bounds.top; 4432 if ((verticalDiff < 0 && bounds.top >= maxBottom) 4433 || (bounds.top + verticalDiff >= maxBottom)) { 4434 verticalDiff = maxBottom - bounds.top; 4435 } 4436 bounds.top += verticalDiff; 4437 bounds.bottom += verticalDiff; 4438 } 4439 } 4440 findStackBehind(ActivityStack stack)4441 ActivityStack findStackBehind(ActivityStack stack) { 4442 // TODO(multi-display): We are only looking for stacks on the default display. 4443 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4444 if (display == null) { 4445 return null; 4446 } 4447 final ArrayList<ActivityStack> stacks = display.mStacks; 4448 for (int i = stacks.size() - 1; i >= 0; i--) { 4449 if (stacks.get(i) == stack && i > 0) { 4450 return stacks.get(i - 1); 4451 } 4452 } 4453 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 4454 + " in=" + stacks); 4455 } 4456 4457 /** 4458 * Puts a task into resizing mode during the next app transition. 4459 * 4460 * @param taskId the id of the task to put into resizing mode 4461 */ setResizingDuringAnimation(int taskId)4462 private void setResizingDuringAnimation(int taskId) { 4463 mResizingTasksDuringAnimation.add(taskId); 4464 mWindowManager.setTaskDockedResizing(taskId, true); 4465 } 4466 startActivityFromRecentsInner(int taskId, Bundle bOptions)4467 final int startActivityFromRecentsInner(int taskId, Bundle bOptions) { 4468 final TaskRecord task; 4469 final int callingUid; 4470 final String callingPackage; 4471 final Intent intent; 4472 final int userId; 4473 final ActivityOptions activityOptions = (bOptions != null) 4474 ? new ActivityOptions(bOptions) : null; 4475 final int launchStackId = (activityOptions != null) 4476 ? activityOptions.getLaunchStackId() : INVALID_STACK_ID; 4477 if (launchStackId == HOME_STACK_ID) { 4478 throw new IllegalArgumentException("startActivityFromRecentsInner: Task " 4479 + taskId + " can't be launch in the home stack."); 4480 } 4481 4482 if (launchStackId == DOCKED_STACK_ID) { 4483 mWindowManager.setDockedStackCreateState( 4484 activityOptions.getDockCreateMode(), null /* initialBounds */); 4485 4486 // Defer updating the stack in which recents is until the app transition is done, to 4487 // not run into issues where we still need to draw the task in recents but the 4488 // docked stack is already created. 4489 deferUpdateBounds(HOME_STACK_ID); 4490 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false); 4491 } 4492 4493 task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId); 4494 if (task == null) { 4495 continueUpdateBounds(HOME_STACK_ID); 4496 mWindowManager.executeAppTransition(); 4497 throw new IllegalArgumentException( 4498 "startActivityFromRecentsInner: Task " + taskId + " not found."); 4499 } 4500 4501 // Since we don't have an actual source record here, we assume that the currently focused 4502 // activity was the source. 4503 final ActivityStack focusedStack = getFocusedStack(); 4504 final ActivityRecord sourceRecord = 4505 focusedStack != null ? focusedStack.topActivity() : null; 4506 4507 if (launchStackId != INVALID_STACK_ID) { 4508 if (task.stack.mStackId != launchStackId) { 4509 moveTaskToStackLocked( 4510 taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents", 4511 ANIMATE); 4512 } 4513 } 4514 4515 // If the user must confirm credentials (e.g. when first launching a work app and the 4516 // Work Challenge is present) let startActivityInPackage handle the intercepting. 4517 if (!mService.mUserController.shouldConfirmCredentials(task.userId) 4518 && task.getRootActivity() != null) { 4519 mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */); 4520 mActivityMetricsLogger.notifyActivityLaunching(); 4521 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions); 4522 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT, 4523 task.getTopActivity()); 4524 4525 // If we are launching the task in the docked stack, put it into resizing mode so 4526 // the window renders full-screen with the background filling the void. Also only 4527 // call this at the end to make sure that tasks exists on the window manager side. 4528 if (launchStackId == DOCKED_STACK_ID) { 4529 setResizingDuringAnimation(taskId); 4530 } 4531 4532 mService.mActivityStarter.postStartActivityUncheckedProcessing(task.getTopActivity(), 4533 ActivityManager.START_TASK_TO_FRONT, 4534 sourceRecord != null ? sourceRecord.task.stack.mStackId : INVALID_STACK_ID, 4535 sourceRecord, task.stack); 4536 return ActivityManager.START_TASK_TO_FRONT; 4537 } 4538 callingUid = task.mCallingUid; 4539 callingPackage = task.mCallingPackage; 4540 intent = task.intent; 4541 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 4542 userId = task.userId; 4543 int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null, 4544 null, null, 0, 0, bOptions, userId, null, task); 4545 if (launchStackId == DOCKED_STACK_ID) { 4546 setResizingDuringAnimation(task.taskId); 4547 } 4548 return result; 4549 } 4550 4551 /** 4552 * @return a list of activities which are the top ones in each visible stack. The first 4553 * entry will be the focused activity. 4554 */ getTopVisibleActivities()4555 public List<IBinder> getTopVisibleActivities() { 4556 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4557 if (display == null) { 4558 return Collections.EMPTY_LIST; 4559 } 4560 ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 4561 final ArrayList<ActivityStack> stacks = display.mStacks; 4562 for (int i = stacks.size() - 1; i >= 0; i--) { 4563 ActivityStack stack = stacks.get(i); 4564 if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) { 4565 ActivityRecord top = stack.topActivity(); 4566 if (top != null) { 4567 if (stack == mFocusedStack) { 4568 topActivityTokens.add(0, top.appToken); 4569 } else { 4570 topActivityTokens.add(top.appToken); 4571 } 4572 } 4573 } 4574 } 4575 return topActivityTokens; 4576 } 4577 } 4578