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.wm; 18 19 import static android.Manifest.permission.ACTIVITY_EMBEDDING; 20 import static android.Manifest.permission.CAMERA; 21 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 22 import static android.Manifest.permission.START_ANY_ACTIVITY; 23 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; 24 import static android.app.ActivityManager.START_DELIVERED_TO_TOP; 25 import static android.app.ActivityManager.START_FLAG_DEBUG; 26 import static android.app.ActivityManager.START_FLAG_NATIVE_DEBUGGING; 27 import static android.app.ActivityManager.START_FLAG_TRACK_ALLOCATION; 28 import static android.app.ActivityManager.START_TASK_TO_FRONT; 29 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY; 30 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; 31 import static android.app.WaitResult.INVALID_DELAY; 32 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 33 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; 34 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 35 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 36 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 37 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 38 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; 39 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 40 import static android.content.pm.PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY; 41 import static android.content.pm.PackageManager.PERMISSION_DENIED; 42 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 43 import static android.os.PowerManager.PARTIAL_WAKE_LOCK; 44 import static android.os.Process.INVALID_UID; 45 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 46 import static android.view.Display.DEFAULT_DISPLAY; 47 import static android.view.WindowManager.TRANSIT_CLOSE; 48 import static android.view.WindowManager.TRANSIT_TO_FRONT; 49 50 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; 51 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; 52 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; 53 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; 54 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE; 55 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; 56 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK; 57 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; 58 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IDLE; 59 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE; 60 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS; 61 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK; 62 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH; 63 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS; 64 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 65 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 66 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; 67 import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_TASK_MSG; 68 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; 69 import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED; 70 import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE; 71 import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 72 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS; 73 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE; 74 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; 75 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; 76 import static com.android.server.wm.Task.ActivityState.PAUSED; 77 import static com.android.server.wm.Task.ActivityState.PAUSING; 78 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; 79 import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT; 80 import static com.android.server.wm.Task.TAG_CLEANUP; 81 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; 82 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; 83 import static com.android.server.wm.WindowContainer.POSITION_TOP; 84 85 import android.Manifest; 86 import android.annotation.Nullable; 87 import android.app.Activity; 88 import android.app.ActivityManager; 89 import android.app.ActivityManagerInternal; 90 import android.app.ActivityOptions; 91 import android.app.AppOpsManager; 92 import android.app.AppOpsManagerInternal; 93 import android.app.IActivityClientController; 94 import android.app.ProfilerInfo; 95 import android.app.ResultInfo; 96 import android.app.WaitResult; 97 import android.app.servertransaction.ActivityLifecycleItem; 98 import android.app.servertransaction.ClientTransaction; 99 import android.app.servertransaction.LaunchActivityItem; 100 import android.app.servertransaction.PauseActivityItem; 101 import android.app.servertransaction.ResumeActivityItem; 102 import android.content.ComponentName; 103 import android.content.Intent; 104 import android.content.pm.ActivityInfo; 105 import android.content.pm.ApplicationInfo; 106 import android.content.pm.PackageInfo; 107 import android.content.pm.PackageManager; 108 import android.content.pm.PackageManagerInternal; 109 import android.content.pm.ResolveInfo; 110 import android.content.pm.UserInfo; 111 import android.content.res.Configuration; 112 import android.graphics.Rect; 113 import android.hardware.SensorPrivacyManager; 114 import android.hardware.SensorPrivacyManagerInternal; 115 import android.os.Binder; 116 import android.os.Build; 117 import android.os.Bundle; 118 import android.os.Debug; 119 import android.os.Handler; 120 import android.os.IBinder; 121 import android.os.Looper; 122 import android.os.Message; 123 import android.os.PowerManager; 124 import android.os.Process; 125 import android.os.RemoteException; 126 import android.os.SystemClock; 127 import android.os.Trace; 128 import android.os.UserHandle; 129 import android.os.UserManager; 130 import android.os.WorkSource; 131 import android.provider.MediaStore; 132 import android.util.ArrayMap; 133 import android.util.MergedConfiguration; 134 import android.util.Slog; 135 import android.util.SparseArray; 136 import android.util.SparseIntArray; 137 import android.view.Display; 138 139 import com.android.internal.R; 140 import com.android.internal.annotations.GuardedBy; 141 import com.android.internal.annotations.VisibleForTesting; 142 import com.android.internal.content.ReferrerIntent; 143 import com.android.internal.os.TransferPipe; 144 import com.android.internal.protolog.common.ProtoLog; 145 import com.android.internal.util.ArrayUtils; 146 import com.android.internal.util.function.pooled.PooledConsumer; 147 import com.android.internal.util.function.pooled.PooledLambda; 148 import com.android.server.LocalServices; 149 import com.android.server.am.ActivityManagerService; 150 import com.android.server.am.UserState; 151 import com.android.server.wm.ActivityMetricsLogger.LaunchingState; 152 153 import java.io.FileDescriptor; 154 import java.io.IOException; 155 import java.io.PrintWriter; 156 import java.util.ArrayList; 157 import java.util.List; 158 159 // TODO: This class has become a dumping ground. Let's 160 // - Move things relating to the hierarchy to RootWindowContainer 161 // - Move things relating to activity life cycles to maybe a new class called ActivityLifeCycler 162 // - Move interface things to ActivityTaskManagerService. 163 // - All other little things to other files. 164 public class ActivityTaskSupervisor implements RecentTasks.Callbacks { 165 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskSupervisor" : TAG_ATM; 166 private static final String TAG_IDLE = TAG + POSTFIX_IDLE; 167 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; 168 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 169 private static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK; 170 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 171 static final String TAG_TASKS = TAG + POSTFIX_TASKS; 172 173 /** How long we wait until giving up on the last activity telling us it is idle. */ 174 private static final int IDLE_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER; 175 176 /** How long we can hold the sleep wake lock before giving up. */ 177 private static final int SLEEP_TIMEOUT = 5 * 1000 * Build.HW_TIMEOUT_MULTIPLIER; 178 179 // How long we can hold the launch wake lock before giving up. 180 private static final int LAUNCH_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER; 181 182 /** How long we wait until giving up on the activity telling us it released the top state. */ 183 private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500; 184 185 private static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG; 186 private static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_TASK_MSG + 1; 187 private static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_TASK_MSG + 2; 188 private static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 3; 189 private static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 4; 190 private static final int PROCESS_STOPPING_AND_FINISHING_MSG = FIRST_SUPERVISOR_TASK_MSG + 5; 191 private static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_TASK_MSG + 12; 192 private static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 13; 193 private static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_TASK_MSG + 14; 194 private static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_TASK_MSG + 15; 195 private static final int START_HOME_MSG = FIRST_SUPERVISOR_TASK_MSG + 16; 196 private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 17; 197 198 // Used to indicate that windows of activities should be preserved during the resize. 199 static final boolean PRESERVE_WINDOWS = true; 200 201 // Used to indicate if an object (e.g. task) should be moved/created 202 // at the top of its container (e.g. root task). 203 static final boolean ON_TOP = true; 204 205 // Don't execute any calls to resume. 206 static final boolean DEFER_RESUME = true; 207 208 // Used to indicate that a task is removed it should also be removed from recents. 209 static final boolean REMOVE_FROM_RECENTS = true; 210 211 /** True if the docked root task is currently being resized. */ 212 private boolean mDockedRootTaskResizing; 213 214 // Activity actions an app cannot start if it uses a permission which is not granted. 215 private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION = 216 new ArrayMap<>(); 217 218 static { ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, Manifest.permission.CAMERA)219 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, 220 Manifest.permission.CAMERA); ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, Manifest.permission.CAMERA)221 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, 222 Manifest.permission.CAMERA); ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, Manifest.permission.CALL_PHONE)223 ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, 224 Manifest.permission.CALL_PHONE); 225 } 226 227 /** Action restriction: launching the activity is not restricted. */ 228 private static final int ACTIVITY_RESTRICTION_NONE = 0; 229 /** Action restriction: launching the activity is restricted by a permission. */ 230 private static final int ACTIVITY_RESTRICTION_PERMISSION = 1; 231 /** Action restriction: launching the activity is restricted by an app op. */ 232 private static final int ACTIVITY_RESTRICTION_APPOP = 2; 233 234 // For debugging to make sure the caller when acquiring/releasing our 235 // wake lock is the system process. 236 private static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 237 /** The number of distinct task ids that can be assigned to the tasks of a single user */ 238 private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE; 239 240 final ActivityTaskManagerService mService; 241 RootWindowContainer mRootWindowContainer; 242 243 /** The historial list of recent tasks including inactive tasks */ 244 RecentTasks mRecentTasks; 245 246 /** Helper class to abstract out logic for fetching the set of currently running tasks */ 247 private RunningTasks mRunningTasks; 248 249 private final ActivityTaskSupervisorHandler mHandler; 250 final Looper mLooper; 251 252 /** Short cut */ 253 private WindowManagerService mWindowManager; 254 255 private AppOpsManager mAppOpsManager; 256 257 /** Common synchronization logic used to save things to disks. */ 258 PersisterQueue mPersisterQueue; 259 LaunchParamsPersister mLaunchParamsPersister; 260 private LaunchParamsController mLaunchParamsController; 261 262 /** 263 * The processes with changed states that should eventually call 264 * {@link WindowProcessController#computeProcessActivityState}. 265 */ 266 private final ArrayList<WindowProcessController> mActivityStateChangedProcs = new ArrayList<>(); 267 268 /** 269 * Maps the task identifier that activities are currently being started in to the userId of the 270 * task. Each time a new task is created, the entry for the userId of the task is incremented 271 */ 272 private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20); 273 274 /** List of requests waiting for the target activity to be launched or visible. */ 275 private final ArrayList<WaitInfo> mWaitingActivityLaunched = new ArrayList<>(); 276 277 /** List of activities that are ready to be stopped, but waiting for the next activity to 278 * settle down before doing so. */ 279 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>(); 280 281 /** List of activities that are ready to be finished, but waiting for the previous activity to 282 * settle down before doing so. It contains ActivityRecord objects. */ 283 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>(); 284 285 /** 286 * Activities that specify No History must be removed once the user navigates away from them. 287 * If the device goes to sleep with such an activity in the paused state then we save it 288 * here and finish it later if another activity replaces it on wakeup. 289 */ 290 final ArrayList<ActivityRecord> mNoHistoryActivities = new ArrayList<>(); 291 292 /** List of activities whose multi-window mode changed that we need to report to the 293 * application */ 294 private final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>(); 295 296 /** List of activities whose picture-in-picture mode changed that we need to report to the 297 * application */ 298 private final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>(); 299 300 /** 301 * Animations that for the current transition have requested not to 302 * be considered for the transition animation. 303 */ 304 final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>(); 305 306 /** 307 * Cached value of the topmost resumed activity in the system. Updated when new activity is 308 * resumed. 309 */ 310 private ActivityRecord mTopResumedActivity; 311 312 /** 313 * Flag indicating whether we're currently waiting for the previous top activity to handle the 314 * loss of the state and report back before making new activity top resumed. 315 */ 316 private boolean mTopResumedActivityWaitingForPrev; 317 318 /** The target root task bounds for the picture-in-picture mode changed that we need to 319 * report to the application */ 320 private Rect mPipModeChangedTargetRootTaskBounds; 321 322 /** Used on user changes */ 323 final ArrayList<UserState> mStartingUsers = new ArrayList<>(); 324 325 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 326 * is being brought in front of us. */ 327 boolean mUserLeaving = false; 328 329 /** 330 * The system chooser activity which worked as a delegate of 331 * {@link com.android.internal.app.ResolverActivity}. 332 */ 333 private ComponentName mSystemChooserActivity; 334 335 /** 336 * We don't want to allow the device to go to sleep while in the process 337 * of launching an activity. This is primarily to allow alarm intent 338 * receivers to launch an activity and get that to run before the device 339 * goes back to sleep. 340 */ 341 PowerManager.WakeLock mLaunchingActivityWakeLock; 342 343 /** 344 * Set when the system is going to sleep, until we have 345 * successfully paused the current activity and released our wake lock. 346 * At that point the system is allowed to actually sleep. 347 */ 348 PowerManager.WakeLock mGoingToSleepWakeLock; 349 350 /** 351 * Used to keep {@link RootWindowContainer#ensureActivitiesVisible} from being entered 352 * recursively. And only update keyguard states once the nested updates are done. 353 */ 354 private int mVisibilityTransactionDepth; 355 356 private ActivityMetricsLogger mActivityMetricsLogger; 357 358 /** Check if placing task or activity on specified display is allowed. */ canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid, ActivityInfo activityInfo)359 boolean canPlaceEntityOnDisplay(int displayId, int callingPid, int callingUid, 360 ActivityInfo activityInfo) { 361 if (displayId == DEFAULT_DISPLAY) { 362 // No restrictions for the default display. 363 return true; 364 } 365 if (!mService.mSupportsMultiDisplay) { 366 // Can't launch on secondary displays if feature is not supported. 367 return false; 368 } 369 if (!isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, displayId, activityInfo)) { 370 // Can't place activities to a display that has restricted launch rules. 371 // In this case the request should be made by explicitly adding target display id and 372 // by caller with corresponding permissions. See #isCallerAllowedToLaunchOnDisplay(). 373 return false; 374 } 375 return true; 376 } 377 378 /** 379 * Used to keep track whether app visibilities got changed since the last pause. Useful to 380 * determine whether to invoke the task stack change listener after pausing. 381 */ 382 boolean mAppVisibilitiesChangedSinceLastPause; 383 384 private KeyguardController mKeyguardController; 385 386 private PowerManager mPowerManager; 387 private int mDeferResumeCount; 388 389 private boolean mInitialized; 390 ActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper)391 public ActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper) { 392 mService = service; 393 mLooper = looper; 394 mHandler = new ActivityTaskSupervisorHandler(looper); 395 } 396 initialize()397 public void initialize() { 398 if (mInitialized) { 399 return; 400 } 401 402 mInitialized = true; 403 setRunningTasks(new RunningTasks()); 404 405 mActivityMetricsLogger = new ActivityMetricsLogger(this, mHandler.getLooper()); 406 mKeyguardController = new KeyguardController(mService, this); 407 408 mPersisterQueue = new PersisterQueue(); 409 mLaunchParamsPersister = new LaunchParamsPersister(mPersisterQueue, this); 410 mLaunchParamsController = new LaunchParamsController(mService, mLaunchParamsPersister); 411 mLaunchParamsController.registerDefaultModifiers(this); 412 } 413 onSystemReady()414 void onSystemReady() { 415 mLaunchParamsPersister.onSystemReady(); 416 } 417 onUserUnlocked(int userId)418 void onUserUnlocked(int userId) { 419 // Only start persisting when the first user is unlocked. The method call is 420 // idempotent so there is no side effect to call it again when the second user is 421 // unlocked. 422 mPersisterQueue.startPersisting(); 423 mLaunchParamsPersister.onUnlockUser(userId); 424 425 // Need to launch home again for those displays that do not have encryption aware home app. 426 scheduleStartHome("userUnlocked"); 427 } 428 getActivityMetricsLogger()429 public ActivityMetricsLogger getActivityMetricsLogger() { 430 return mActivityMetricsLogger; 431 } 432 getKeyguardController()433 public KeyguardController getKeyguardController() { 434 return mKeyguardController; 435 } 436 getSystemChooserActivity()437 ComponentName getSystemChooserActivity() { 438 if (mSystemChooserActivity == null) { 439 mSystemChooserActivity = ComponentName.unflattenFromString( 440 mService.mContext.getResources().getString(R.string.config_chooserActivity)); 441 } 442 return mSystemChooserActivity; 443 } 444 setRecentTasks(RecentTasks recentTasks)445 void setRecentTasks(RecentTasks recentTasks) { 446 if (mRecentTasks != null) { 447 mRecentTasks.unregisterCallback(this); 448 } 449 mRecentTasks = recentTasks; 450 mRecentTasks.registerCallback(this); 451 } 452 453 @VisibleForTesting setRunningTasks(RunningTasks runningTasks)454 void setRunningTasks(RunningTasks runningTasks) { 455 mRunningTasks = runningTasks; 456 } 457 getRunningTasks()458 RunningTasks getRunningTasks() { 459 return mRunningTasks; 460 } 461 462 /** 463 * At the time when the constructor runs, the power manager has not yet been 464 * initialized. So we initialize our wakelocks afterwards. 465 */ initPowerManagement()466 void initPowerManagement() { 467 mPowerManager = mService.mContext.getSystemService(PowerManager.class); 468 mGoingToSleepWakeLock = mPowerManager 469 .newWakeLock(PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 470 mLaunchingActivityWakeLock = mPowerManager.newWakeLock(PARTIAL_WAKE_LOCK, "*launch*"); 471 mLaunchingActivityWakeLock.setReferenceCounted(false); 472 } 473 setWindowManager(WindowManagerService wm)474 void setWindowManager(WindowManagerService wm) { 475 mWindowManager = wm; 476 getKeyguardController().setWindowManager(wm); 477 } 478 moveRecentsRootTaskToFront(String reason)479 void moveRecentsRootTaskToFront(String reason) { 480 final Task recentsRootTask = mRootWindowContainer.getDefaultTaskDisplayArea() 481 .getRootTask(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS); 482 if (recentsRootTask != null) { 483 recentsRootTask.moveToFront(reason); 484 } 485 } 486 setNextTaskIdForUser(int taskId, int userId)487 void setNextTaskIdForUser(int taskId, int userId) { 488 final int currentTaskId = mCurTaskIdForUser.get(userId, -1); 489 if (taskId > currentTaskId) { 490 mCurTaskIdForUser.put(userId, taskId); 491 } 492 } 493 finishNoHistoryActivitiesIfNeeded(ActivityRecord next)494 void finishNoHistoryActivitiesIfNeeded(ActivityRecord next) { 495 for (int i = mNoHistoryActivities.size() - 1; i >= 0; --i) { 496 final ActivityRecord noHistoryActivity = mNoHistoryActivities.get(i); 497 if (!noHistoryActivity.finishing && noHistoryActivity != next 498 && next.occludesParent() 499 && noHistoryActivity.getDisplayId() == next.getDisplayId()) { 500 ProtoLog.d(WM_DEBUG_STATES, "no-history finish of %s on new resume", 501 noHistoryActivity); 502 noHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */); 503 mNoHistoryActivities.remove(noHistoryActivity); 504 } 505 } 506 } 507 nextTaskIdForUser(int taskId, int userId)508 private static int nextTaskIdForUser(int taskId, int userId) { 509 int nextTaskId = taskId + 1; 510 if (nextTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) { 511 // Wrap around as there will be smaller task ids that are available now. 512 nextTaskId -= MAX_TASK_IDS_PER_USER; 513 } 514 return nextTaskId; 515 } 516 getNextTaskIdForUser()517 int getNextTaskIdForUser() { 518 return getNextTaskIdForUser(mRootWindowContainer.mCurrentUser); 519 } 520 getNextTaskIdForUser(int userId)521 int getNextTaskIdForUser(int userId) { 522 final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER); 523 // for a userId u, a taskId can only be in the range 524 // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER 525 // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on. 526 int candidateTaskId = nextTaskIdForUser(currentTaskId, userId); 527 while (mRecentTasks.containsTaskId(candidateTaskId, userId) 528 || mRootWindowContainer.anyTaskForId( 529 candidateTaskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS) != null) { 530 candidateTaskId = nextTaskIdForUser(candidateTaskId, userId); 531 if (candidateTaskId == currentTaskId) { 532 // Something wrong! 533 // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user 534 throw new IllegalStateException("Cannot get an available task id." 535 + " Reached limit of " + MAX_TASK_IDS_PER_USER 536 + " running tasks per user."); 537 } 538 } 539 mCurTaskIdForUser.put(userId, candidateTaskId); 540 return candidateTaskId; 541 } 542 waitActivityVisibleOrLaunched(WaitResult w, ActivityRecord r, LaunchingState launchingState)543 void waitActivityVisibleOrLaunched(WaitResult w, ActivityRecord r, 544 LaunchingState launchingState) { 545 if (w.result != ActivityManager.START_TASK_TO_FRONT 546 && w.result != ActivityManager.START_SUCCESS) { 547 // Not a result code that can make activity visible or launched. 548 return; 549 } 550 final WaitInfo waitInfo = new WaitInfo(w, r.mActivityComponent, launchingState); 551 mWaitingActivityLaunched.add(waitInfo); 552 do { 553 try { 554 mService.mGlobalLock.wait(); 555 } catch (InterruptedException ignored) { 556 } 557 } while (mWaitingActivityLaunched.contains(waitInfo)); 558 } 559 cleanupActivity(ActivityRecord r)560 void cleanupActivity(ActivityRecord r) { 561 // Make sure this record is no longer in the pending finishes list. 562 // This could happen, for example, if we are trimming activities 563 // down to the max limit while they are still waiting to finish. 564 mFinishingActivities.remove(r); 565 566 stopWaitingForActivityVisible(r); 567 } 568 569 /** There is no valid launch time, just stop waiting. */ stopWaitingForActivityVisible(ActivityRecord r)570 void stopWaitingForActivityVisible(ActivityRecord r) { 571 reportActivityLaunched(false /* timeout */, r, WaitResult.INVALID_DELAY, 572 WaitResult.LAUNCH_STATE_UNKNOWN); 573 } 574 reportActivityLaunched(boolean timeout, ActivityRecord r, long totalTime, @WaitResult.LaunchState int launchState)575 void reportActivityLaunched(boolean timeout, ActivityRecord r, long totalTime, 576 @WaitResult.LaunchState int launchState) { 577 boolean changed = false; 578 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 579 final WaitInfo info = mWaitingActivityLaunched.get(i); 580 if (!info.matches(r)) { 581 continue; 582 } 583 final WaitResult w = info.mResult; 584 w.timeout = timeout; 585 w.who = r.mActivityComponent; 586 w.totalTime = totalTime; 587 w.launchState = launchState; 588 mWaitingActivityLaunched.remove(i); 589 changed = true; 590 } 591 if (changed) { 592 mService.mGlobalLock.notifyAll(); 593 } 594 } 595 reportWaitingActivityLaunchedIfNeeded(ActivityRecord r, int result)596 void reportWaitingActivityLaunchedIfNeeded(ActivityRecord r, int result) { 597 if (mWaitingActivityLaunched.isEmpty()) { 598 return; 599 } 600 601 if (result != START_DELIVERED_TO_TOP && result != START_TASK_TO_FRONT) { 602 return; 603 } 604 605 boolean changed = false; 606 607 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 608 final WaitInfo info = mWaitingActivityLaunched.get(i); 609 if (!info.matches(r)) { 610 continue; 611 } 612 final WaitResult w = info.mResult; 613 w.result = result; 614 if (result == START_DELIVERED_TO_TOP) { 615 // Unlike START_TASK_TO_FRONT, When an intent is delivered to top, there 616 // will be no followup launch signals. Assign the result and launched component. 617 w.who = r.mActivityComponent; 618 mWaitingActivityLaunched.remove(i); 619 changed = true; 620 } 621 } 622 if (changed) { 623 mService.mGlobalLock.notifyAll(); 624 } 625 } 626 resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, ProfilerInfo profilerInfo)627 ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, 628 ProfilerInfo profilerInfo) { 629 final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null; 630 if (aInfo != null) { 631 // Store the found target back into the intent, because now that 632 // we have it we never want to do this again. For example, if the 633 // user navigates back to this point in the history, we should 634 // always restart the exact same activity. 635 intent.setComponent(new ComponentName( 636 aInfo.applicationInfo.packageName, aInfo.name)); 637 638 // Don't debug things in the system process 639 if (!aInfo.processName.equals("system")) { 640 if ((startFlags & (START_FLAG_DEBUG | START_FLAG_NATIVE_DEBUGGING 641 | START_FLAG_TRACK_ALLOCATION)) != 0 || profilerInfo != null) { 642 643 // Mimic an AMS synchronous call by passing a message to AMS and wait for AMS 644 // to notify us that the task has completed. 645 // TODO(b/80414790) look into further untangling for the situation where the 646 // caller is on the same thread as the handler we are posting to. 647 synchronized (mService.mGlobalLock) { 648 // Post message to AMS. 649 final Message msg = PooledLambda.obtainMessage( 650 ActivityManagerInternal::setDebugFlagsForStartingActivity, 651 mService.mAmInternal, aInfo, startFlags, profilerInfo, 652 mService.mGlobalLock); 653 mService.mH.sendMessage(msg); 654 try { 655 mService.mGlobalLock.wait(); 656 } catch (InterruptedException ignore) { 657 658 } 659 } 660 } 661 } 662 final String intentLaunchToken = intent.getLaunchToken(); 663 if (aInfo.launchToken == null && intentLaunchToken != null) { 664 aInfo.launchToken = intentLaunchToken; 665 } 666 } 667 return aInfo; 668 } 669 resolveIntent(Intent intent, String resolvedType, int userId, int flags, int filterCallingUid)670 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags, 671 int filterCallingUid) { 672 try { 673 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "resolveIntent"); 674 int modifiedFlags = flags 675 | PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS; 676 if (intent.isWebIntent() 677 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) { 678 modifiedFlags |= PackageManager.MATCH_INSTANT; 679 } 680 int privateResolveFlags = 0; 681 if (intent.isWebIntent() 682 && (intent.getFlags() & Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER) != 0) { 683 privateResolveFlags |= PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY; 684 } 685 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_REQUIRE_DEFAULT) != 0) { 686 privateResolveFlags |= PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY; 687 } 688 689 // In order to allow cross-profile lookup, we clear the calling identity here. 690 // Note the binder identity won't affect the result, but filterCallingUid will. 691 692 // Cross-user/profile call check are done at the entry points 693 // (e.g. AMS.startActivityAsUser). 694 final long token = Binder.clearCallingIdentity(); 695 try { 696 return mService.getPackageManagerInternalLocked().resolveIntent( 697 intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true, 698 filterCallingUid); 699 } finally { 700 Binder.restoreCallingIdentity(token); 701 } 702 } finally { 703 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 704 } 705 } 706 resolveActivity(Intent intent, String resolvedType, int startFlags, ProfilerInfo profilerInfo, int userId, int filterCallingUid)707 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 708 ProfilerInfo profilerInfo, int userId, int filterCallingUid) { 709 final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId, 0, filterCallingUid); 710 return resolveActivity(intent, rInfo, startFlags, profilerInfo); 711 } 712 realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig)713 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, 714 boolean andResume, boolean checkConfig) throws RemoteException { 715 716 if (!mRootWindowContainer.allPausedActivitiesComplete()) { 717 // While there are activities pausing we skipping starting any new activities until 718 // pauses are complete. NOTE: that we also do this for activities that are starting in 719 // the paused state because they will first be resumed then paused on the client side. 720 ProtoLog.v(WM_DEBUG_STATES, 721 "realStartActivityLocked: Skipping start of r=%s some activities pausing...", 722 r); 723 return false; 724 } 725 726 final Task task = r.getTask(); 727 final Task rootTask = task.getRootTask(); 728 729 beginDeferResume(); 730 // The LaunchActivityItem also contains process configuration, so the configuration change 731 // from WindowProcessController#setProcess can be deferred. The major reason is that if 732 // the activity has FixedRotationAdjustments, it needs to be applied with configuration. 733 // In general, this reduces a binder transaction if process configuration is changed. 734 proc.pauseConfigurationDispatch(); 735 736 try { 737 r.startFreezingScreenLocked(proc, 0); 738 739 // schedule launch ticks to collect information about slow apps. 740 r.startLaunchTickingLocked(); 741 742 r.setProcess(proc); 743 744 // Ensure activity is allowed to be resumed after process has set. 745 if (andResume && !r.canResumeByCompat()) { 746 andResume = false; 747 } 748 749 r.notifyUnknownVisibilityLaunchedForKeyguardTransition(); 750 751 // Have the window manager re-evaluate the orientation of the screen based on the new 752 // activity order. Note that as a result of this, it can call back into the activity 753 // manager with a new orientation. We don't care about that, because the activity is 754 // not currently running so we are just restarting it anyway. 755 if (checkConfig) { 756 // Deferring resume here because we're going to launch new activity shortly. 757 // We don't want to perform a redundant launch of the same record while ensuring 758 // configurations and trying to resume top activity of focused root task. 759 mRootWindowContainer.ensureVisibilityAndConfig(r, r.getDisplayId(), 760 false /* markFrozenIfConfigChanged */, true /* deferResume */); 761 } 762 763 if (mKeyguardController.checkKeyguardVisibility(r) && r.allowMoveToFront()) { 764 // We only set the visibility to true if the activity is not being launched in 765 // background, and is allowed to be visible based on keyguard state. This avoids 766 // setting this into motion in window manager that is later cancelled due to later 767 // calls to ensure visible activities that set visibility back to false. 768 r.setVisibility(true); 769 } 770 771 final int applicationInfoUid = 772 (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1; 773 if ((r.mUserId != proc.mUserId) || (r.info.applicationInfo.uid != applicationInfoUid)) { 774 Slog.wtf(TAG, 775 "User ID for activity changing for " + r 776 + " appInfo.uid=" + r.info.applicationInfo.uid 777 + " info.ai.uid=" + applicationInfoUid 778 + " old=" + r.app + " new=" + proc); 779 } 780 781 // Send the controller to client if the process is the first time to launch activity. 782 // So the client can save binder transactions of getting the controller from activity 783 // task manager service. 784 final IActivityClientController activityClientController = 785 proc.hasEverLaunchedActivity() ? null : mService.mActivityClientController; 786 r.launchCount++; 787 r.lastLaunchTime = SystemClock.uptimeMillis(); 788 proc.setLastActivityLaunchTime(r.lastLaunchTime); 789 790 if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r); 791 792 final LockTaskController lockTaskController = mService.getLockTaskController(); 793 if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE 794 || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV 795 || (task.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED 796 && lockTaskController.getLockTaskModeState() 797 == LOCK_TASK_MODE_LOCKED)) { 798 lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */); 799 } 800 801 try { 802 if (!proc.hasThread()) { 803 throw new RemoteException(); 804 } 805 List<ResultInfo> results = null; 806 List<ReferrerIntent> newIntents = null; 807 if (andResume) { 808 // We don't need to deliver new intents and/or set results if activity is going 809 // to pause immediately after launch. 810 results = r.results; 811 newIntents = r.newIntents; 812 } 813 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 814 "Launching: " + r + " savedState=" + r.getSavedState() 815 + " with results=" + results + " newIntents=" + newIntents 816 + " andResume=" + andResume); 817 EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r), 818 task.mTaskId, r.shortComponentName); 819 if (r.isActivityTypeHome()) { 820 // Home process is the root process of the task. 821 updateHomeProcess(task.getBottomMostActivity().app); 822 } 823 mService.getPackageManagerInternalLocked().notifyPackageUse( 824 r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY); 825 r.forceNewConfig = false; 826 mService.getAppWarningsLocked().onStartActivity(r); 827 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 828 829 // Because we could be starting an Activity in the system process this may not go 830 // across a Binder interface which would create a new Configuration. Consequently 831 // we have to always create a new Configuration here. 832 final Configuration procConfig = proc.prepareConfigurationForLaunchingActivity(); 833 final MergedConfiguration mergedConfiguration = new MergedConfiguration( 834 procConfig, r.getMergedOverrideConfiguration()); 835 r.setLastReportedConfiguration(mergedConfiguration); 836 837 logIfTransactionTooLarge(r.intent, r.getSavedState()); 838 839 840 // Create activity launch transaction. 841 final ClientTransaction clientTransaction = ClientTransaction.obtain( 842 proc.getThread(), r.appToken); 843 844 final boolean isTransitionForward = r.isTransitionForward(); 845 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), 846 System.identityHashCode(r), r.info, 847 // TODO: Have this take the merged configuration instead of separate global 848 // and override configs. 849 mergedConfiguration.getGlobalConfiguration(), 850 mergedConfiguration.getOverrideConfiguration(), r.compat, 851 r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(), 852 r.getSavedState(), r.getPersistentSavedState(), results, newIntents, 853 r.takeOptions(), isTransitionForward, 854 proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController, 855 r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken, 856 r.getLaunchedFromBubble())); 857 858 // Set desired final state. 859 final ActivityLifecycleItem lifecycleItem; 860 if (andResume) { 861 lifecycleItem = ResumeActivityItem.obtain(isTransitionForward); 862 } else { 863 lifecycleItem = PauseActivityItem.obtain(); 864 } 865 clientTransaction.setLifecycleStateRequest(lifecycleItem); 866 867 // Schedule transaction. 868 mService.getLifecycleManager().scheduleTransaction(clientTransaction); 869 870 if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) { 871 // If the seq is increased, there should be something changed (e.g. registered 872 // activity configuration). 873 proc.setLastReportedConfiguration(procConfig); 874 } 875 if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 876 && mService.mHasHeavyWeightFeature) { 877 // This may be a heavy-weight process! Note that the package manager will ensure 878 // that only activity can run in the main process of the .apk, which is the only 879 // thing that will be considered heavy-weight. 880 if (proc.mName.equals(proc.mInfo.packageName)) { 881 if (mService.mHeavyWeightProcess != null 882 && mService.mHeavyWeightProcess != proc) { 883 Slog.w(TAG, "Starting new heavy weight process " + proc 884 + " when already running " 885 + mService.mHeavyWeightProcess); 886 } 887 mService.setHeavyWeightProcess(r); 888 } 889 } 890 891 } catch (RemoteException e) { 892 if (r.launchFailed) { 893 // This is the second time we failed -- finish activity and give up. 894 Slog.e(TAG, "Second failure launching " 895 + r.intent.getComponent().flattenToShortString() + ", giving up", e); 896 proc.appDied("2nd-crash"); 897 r.finishIfPossible("2nd-crash", false /* oomAdj */); 898 return false; 899 } 900 901 // This is the first time we failed -- restart process and 902 // retry. 903 r.launchFailed = true; 904 proc.removeActivity(r, true /* keepAssociation */); 905 throw e; 906 } 907 } finally { 908 endDeferResume(); 909 proc.resumeConfigurationDispatch(); 910 } 911 912 r.launchFailed = false; 913 914 // TODO(lifecycler): Resume or pause requests are done as part of launch transaction, 915 // so updating the state should be done accordingly. 916 if (andResume && readyToResume()) { 917 // As part of the process of launching, ActivityThread also performs 918 // a resume. 919 rootTask.minimalResumeActivityLocked(r); 920 } else { 921 // This activity is not starting in the resumed state... which should look like we asked 922 // it to pause+stop (but remain visible), and it has done so and reported back the 923 // current icicle and other state. 924 ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s " 925 + "(starting in paused state)", r); 926 r.setState(PAUSED, "realStartActivityLocked"); 927 mRootWindowContainer.executeAppTransitionForAllDisplay(); 928 } 929 // Perform OOM scoring after the activity state is set, so the process can be updated with 930 // the latest state. 931 proc.onStartActivity(mService.mTopProcessState, r.info); 932 933 // Launch the new version setup screen if needed. We do this -after- 934 // launching the initial activity (that is, home), so that it can have 935 // a chance to initialize itself while in the background, making the 936 // switch back to it faster and look better. 937 if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) { 938 mService.getActivityStartController().startSetupActivity(); 939 } 940 941 // Update any services we are bound to that might care about whether 942 // their client may have activities. 943 if (r.app != null) { 944 r.app.updateServiceConnectionActivities(); 945 } 946 947 return true; 948 } 949 updateHomeProcess(WindowProcessController app)950 void updateHomeProcess(WindowProcessController app) { 951 if (app != null && mService.mHomeProcess != app) { 952 scheduleStartHome("homeChanged"); 953 mService.mHomeProcess = app; 954 } 955 } 956 scheduleStartHome(String reason)957 private void scheduleStartHome(String reason) { 958 if (!mHandler.hasMessages(START_HOME_MSG)) { 959 mHandler.obtainMessage(START_HOME_MSG, reason).sendToTarget(); 960 } 961 } 962 logIfTransactionTooLarge(Intent intent, Bundle icicle)963 private void logIfTransactionTooLarge(Intent intent, Bundle icicle) { 964 int extrasSize = 0; 965 if (intent != null) { 966 final Bundle extras = intent.getExtras(); 967 if (extras != null) { 968 extrasSize = extras.getSize(); 969 } 970 } 971 int icicleSize = (icicle == null ? 0 : icicle.getSize()); 972 if (extrasSize + icicleSize > 200000) { 973 Slog.e(TAG, "Transaction too large, intent: " + intent + ", extras size: " + extrasSize 974 + ", icicle size: " + icicleSize); 975 } 976 } 977 startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig)978 void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) { 979 // Is this activity's application already running? 980 final WindowProcessController wpc = 981 mService.getProcessController(r.processName, r.info.applicationInfo.uid); 982 983 boolean knownToBeDead = false; 984 if (wpc != null && wpc.hasThread()) { 985 try { 986 realStartActivityLocked(r, wpc, andResume, checkConfig); 987 return; 988 } catch (RemoteException e) { 989 Slog.w(TAG, "Exception when starting activity " 990 + r.intent.getComponent().flattenToShortString(), e); 991 } 992 993 // If a dead object exception was thrown -- fall through to 994 // restart the application. 995 knownToBeDead = true; 996 } 997 998 r.notifyUnknownVisibilityLaunchedForKeyguardTransition(); 999 1000 final boolean isTop = andResume && r.isTopRunningActivity(); 1001 mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity"); 1002 } 1003 checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, @Nullable String callingFeatureId, boolean ignoreTargetSecurity, boolean launchingInTask, WindowProcessController callerApp, ActivityRecord resultRecord, Task resultRootTask)1004 boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho, 1005 int requestCode, int callingPid, int callingUid, String callingPackage, 1006 @Nullable String callingFeatureId, boolean ignoreTargetSecurity, 1007 boolean launchingInTask, WindowProcessController callerApp, ActivityRecord resultRecord, 1008 Task resultRootTask) { 1009 final boolean isCallerRecents = mService.getRecentTasks() != null 1010 && mService.getRecentTasks().isCallerRecents(callingUid); 1011 final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, 1012 callingUid); 1013 if (startAnyPerm == PERMISSION_GRANTED || (isCallerRecents && launchingInTask)) { 1014 // If the caller has START_ANY_ACTIVITY, ignore all checks below. In addition, if the 1015 // caller is the recents component and we are specifically starting an activity in an 1016 // existing task, then also allow the activity to be fully relaunched. 1017 return true; 1018 } 1019 final int componentRestriction = getComponentRestrictionForCallingPackage(aInfo, 1020 callingPackage, callingFeatureId, callingPid, callingUid, ignoreTargetSecurity); 1021 final int actionRestriction = getActionRestrictionForCallingPackage( 1022 intent.getAction(), callingPackage, callingFeatureId, callingPid, callingUid); 1023 if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION 1024 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1025 if (resultRecord != null) { 1026 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, 1027 Activity.RESULT_CANCELED, null /* data */, null /* dataGrants */); 1028 } 1029 final String msg; 1030 if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1031 msg = "Permission Denial: starting " + intent.toString() 1032 + " from " + callerApp + " (pid=" + callingPid 1033 + ", uid=" + callingUid + ")" + " with revoked permission " 1034 + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); 1035 } else if (!aInfo.exported) { 1036 msg = "Permission Denial: starting " + intent.toString() 1037 + " from " + callerApp + " (pid=" + callingPid 1038 + ", uid=" + callingUid + ")" 1039 + " not exported from uid " + aInfo.applicationInfo.uid; 1040 } else { 1041 msg = "Permission Denial: starting " + intent.toString() 1042 + " from " + callerApp + " (pid=" + callingPid 1043 + ", uid=" + callingUid + ")" 1044 + " requires " + aInfo.permission; 1045 } 1046 Slog.w(TAG, msg); 1047 throw new SecurityException(msg); 1048 } 1049 1050 if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) { 1051 final String message = "Appop Denial: starting " + intent.toString() 1052 + " from " + callerApp + " (pid=" + callingPid 1053 + ", uid=" + callingUid + ")" 1054 + " requires " + AppOpsManager.permissionToOp( 1055 ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction())); 1056 Slog.w(TAG, message); 1057 return false; 1058 } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) { 1059 final String message = "Appop Denial: starting " + intent.toString() 1060 + " from " + callerApp + " (pid=" + callingPid 1061 + ", uid=" + callingUid + ")" 1062 + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission); 1063 Slog.w(TAG, message); 1064 return false; 1065 } 1066 1067 return true; 1068 } 1069 1070 /** Check if caller is allowed to launch activities on specified task display area. */ isCallerAllowedToLaunchOnTaskDisplayArea(int callingPid, int callingUid, TaskDisplayArea taskDisplayArea, ActivityInfo aInfo)1071 boolean isCallerAllowedToLaunchOnTaskDisplayArea(int callingPid, int callingUid, 1072 TaskDisplayArea taskDisplayArea, ActivityInfo aInfo) { 1073 return isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, 1074 taskDisplayArea != null ? taskDisplayArea.getDisplayId() : DEFAULT_DISPLAY, aInfo); 1075 } 1076 1077 /** Check if caller is allowed to launch activities on specified display. */ isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, ActivityInfo aInfo)1078 boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, 1079 ActivityInfo aInfo) { 1080 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: displayId=%d callingPid=%d " 1081 + "callingUid=%d", launchDisplayId, callingPid, callingUid); 1082 1083 if (callingPid == -1 && callingUid == -1) { 1084 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: no caller info, skip check"); 1085 return true; 1086 } 1087 1088 final DisplayContent displayContent = 1089 mRootWindowContainer.getDisplayContentOrCreate(launchDisplayId); 1090 if (displayContent == null || displayContent.isRemoved()) { 1091 Slog.w(TAG, "Launch on display check: display not found"); 1092 return false; 1093 } 1094 1095 // Check if the caller has enough privileges to embed activities and launch to private 1096 // displays. 1097 final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid, 1098 callingUid); 1099 if (startAnyPerm == PERMISSION_GRANTED) { 1100 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch any on display"); 1101 return true; 1102 } 1103 1104 // Check if caller is already present on display 1105 final boolean uidPresentOnDisplay = displayContent.isUidPresent(callingUid); 1106 1107 final Display display = displayContent.mDisplay; 1108 if (!display.isTrusted()) { 1109 // Limit launching on untrusted displays because their contents can be read from Surface 1110 // by apps that created them. 1111 if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 1112 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow launch on " 1113 + "virtual display for not-embedded activity."); 1114 return false; 1115 } 1116 // Check if the caller is allowed to embed activities from other apps. 1117 if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid) 1118 == PERMISSION_DENIED && !uidPresentOnDisplay) { 1119 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow activity " 1120 + "embedding without permission."); 1121 return false; 1122 } 1123 } 1124 1125 if (!displayContent.isPrivate()) { 1126 // Anyone can launch on a public display. 1127 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch on public " 1128 + "display"); 1129 return true; 1130 } 1131 1132 // Check if the caller is the owner of the display. 1133 if (display.getOwnerUid() == callingUid) { 1134 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for owner of the" 1135 + " display"); 1136 return true; 1137 } 1138 1139 if (uidPresentOnDisplay) { 1140 ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for caller " 1141 + "present on the display"); 1142 return true; 1143 } 1144 1145 Slog.w(TAG, "Launch on display check: denied"); 1146 return false; 1147 } 1148 getUserInfo(int userId)1149 UserInfo getUserInfo(int userId) { 1150 final long identity = Binder.clearCallingIdentity(); 1151 try { 1152 return UserManager.get(mService.mContext).getUserInfo(userId); 1153 } finally { 1154 Binder.restoreCallingIdentity(identity); 1155 } 1156 } 1157 getAppOpsManager()1158 private AppOpsManager getAppOpsManager() { 1159 if (mAppOpsManager == null) { 1160 mAppOpsManager = mService.mContext.getSystemService(AppOpsManager.class); 1161 } 1162 return mAppOpsManager; 1163 } 1164 getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, String callingPackage, @Nullable String callingFeatureId, int callingPid, int callingUid, boolean ignoreTargetSecurity)1165 private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, 1166 String callingPackage, @Nullable String callingFeatureId, int callingPid, 1167 int callingUid, boolean ignoreTargetSecurity) { 1168 if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, 1169 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) 1170 == PERMISSION_DENIED) { 1171 return ACTIVITY_RESTRICTION_PERMISSION; 1172 } 1173 1174 if (activityInfo.permission == null) { 1175 return ACTIVITY_RESTRICTION_NONE; 1176 } 1177 1178 final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); 1179 if (opCode == AppOpsManager.OP_NONE) { 1180 return ACTIVITY_RESTRICTION_NONE; 1181 } 1182 1183 if (getAppOpsManager().noteOpNoThrow(opCode, callingUid, 1184 callingPackage, callingFeatureId, "") != AppOpsManager.MODE_ALLOWED) { 1185 if (!ignoreTargetSecurity) { 1186 return ACTIVITY_RESTRICTION_APPOP; 1187 } 1188 } 1189 1190 return ACTIVITY_RESTRICTION_NONE; 1191 } 1192 getActionRestrictionForCallingPackage(String action, String callingPackage, @Nullable String callingFeatureId, int callingPid, int callingUid)1193 private int getActionRestrictionForCallingPackage(String action, String callingPackage, 1194 @Nullable String callingFeatureId, int callingPid, int callingUid) { 1195 if (action == null) { 1196 return ACTIVITY_RESTRICTION_NONE; 1197 } 1198 1199 String permission = ACTION_TO_RUNTIME_PERMISSION.get(action); 1200 if (permission == null) { 1201 return ACTIVITY_RESTRICTION_NONE; 1202 } 1203 1204 final PackageInfo packageInfo; 1205 try { 1206 packageInfo = mService.mContext.getPackageManager() 1207 .getPackageInfoAsUser(callingPackage, PackageManager.GET_PERMISSIONS, 1208 UserHandle.getUserId(callingUid)); 1209 } catch (PackageManager.NameNotFoundException e) { 1210 Slog.i(TAG, "Cannot find package info for " + callingPackage); 1211 return ACTIVITY_RESTRICTION_NONE; 1212 } 1213 1214 if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) { 1215 return ACTIVITY_RESTRICTION_NONE; 1216 } 1217 1218 if (mService.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) { 1219 return ACTIVITY_RESTRICTION_PERMISSION; 1220 } 1221 1222 final int opCode = AppOpsManager.permissionToOpCode(permission); 1223 if (opCode == AppOpsManager.OP_NONE) { 1224 return ACTIVITY_RESTRICTION_NONE; 1225 } 1226 1227 if (getAppOpsManager().noteOpNoThrow(opCode, callingUid, 1228 callingPackage, callingFeatureId, "") != AppOpsManager.MODE_ALLOWED) { 1229 if (CAMERA.equals(permission)) { 1230 SensorPrivacyManagerInternal spmi = 1231 LocalServices.getService(SensorPrivacyManagerInternal.class); 1232 1233 final UserHandle user = UserHandle.getUserHandleForUid(callingUid); 1234 final boolean cameraPrivacyEnabled = spmi.isSensorPrivacyEnabled( 1235 user.getIdentifier(), SensorPrivacyManager.Sensors.CAMERA); 1236 if (cameraPrivacyEnabled) { 1237 AppOpsManagerInternal aomi = LocalServices.getService( 1238 AppOpsManagerInternal.class); 1239 int numCameraRestrictions = aomi.getOpRestrictionCount( 1240 AppOpsManager.OP_CAMERA, user, callingPackage, null); 1241 if (numCameraRestrictions == 1) { 1242 // Only restricted by the toggles, do not restrict 1243 return ACTIVITY_RESTRICTION_NONE; 1244 } 1245 } 1246 } 1247 return ACTIVITY_RESTRICTION_APPOP; 1248 } 1249 1250 return ACTIVITY_RESTRICTION_NONE; 1251 } 1252 setLaunchSource(int uid)1253 void setLaunchSource(int uid) { 1254 mLaunchingActivityWakeLock.setWorkSource(new WorkSource(uid)); 1255 } 1256 acquireLaunchWakelock()1257 void acquireLaunchWakelock() { 1258 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1259 throw new IllegalStateException("Calling must be system uid"); 1260 } 1261 mLaunchingActivityWakeLock.acquire(); 1262 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1263 // To be safe, don't allow the wake lock to be held for too long. 1264 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1265 } 1266 } 1267 1268 /** 1269 * Called when all resumed tasks/root-tasks are idle. 1270 * @return the state of mService.mAm.mBooting before this was called. 1271 */ 1272 @GuardedBy("mService") checkFinishBootingLocked()1273 private boolean checkFinishBootingLocked() { 1274 final boolean booting = mService.isBooting(); 1275 boolean enableScreen = false; 1276 mService.setBooting(false); 1277 if (!mService.isBooted()) { 1278 mService.setBooted(true); 1279 enableScreen = true; 1280 } 1281 if (booting || enableScreen) { 1282 mService.postFinishBooting(booting, enableScreen); 1283 } 1284 return booting; 1285 } 1286 activityIdleInternal(ActivityRecord r, boolean fromTimeout, boolean processPausingActivities, Configuration config)1287 void activityIdleInternal(ActivityRecord r, boolean fromTimeout, 1288 boolean processPausingActivities, Configuration config) { 1289 if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + r); 1290 1291 boolean booting = false; 1292 1293 if (r != null) { 1294 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternal: Callers=" 1295 + Debug.getCallers(4)); 1296 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1297 r.finishLaunchTickingLocked(); 1298 if (fromTimeout) { 1299 reportActivityLaunched(fromTimeout, r, INVALID_DELAY, -1 /* launchState */); 1300 } 1301 1302 // This is a hack to semi-deal with a race condition 1303 // in the client where it can be constructed with a 1304 // newer configuration from when we asked it to launch. 1305 // We'll update with whatever configuration it now says 1306 // it used to launch. 1307 if (config != null) { 1308 r.setLastReportedGlobalConfiguration(config); 1309 } 1310 1311 // We are now idle. If someone is waiting for a thumbnail from 1312 // us, we can now deliver. 1313 r.idle = true; 1314 1315 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1316 1317 // Check if able to finish booting when device is booting and all resumed activities 1318 // are idle. 1319 if ((mService.isBooting() && mRootWindowContainer.allResumedActivitiesIdle()) 1320 || fromTimeout) { 1321 booting = checkFinishBootingLocked(); 1322 } 1323 1324 // When activity is idle, we consider the relaunch must be successful, so let's clear 1325 // the flag. 1326 r.mRelaunchReason = RELAUNCH_REASON_NONE; 1327 } 1328 1329 if (mRootWindowContainer.allResumedActivitiesIdle()) { 1330 if (r != null) { 1331 mService.scheduleAppGcsLocked(); 1332 mRecentTasks.onActivityIdle(r); 1333 } 1334 1335 if (mLaunchingActivityWakeLock.isHeld()) { 1336 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1337 if (VALIDATE_WAKE_LOCK_CALLER && 1338 Binder.getCallingUid() != Process.myUid()) { 1339 throw new IllegalStateException("Calling must be system uid"); 1340 } 1341 mLaunchingActivityWakeLock.release(); 1342 } 1343 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 1344 } 1345 1346 // Atomically retrieve all of the other things to do. 1347 processStoppingAndFinishingActivities(r, processPausingActivities, "idle"); 1348 1349 if (!mStartingUsers.isEmpty()) { 1350 final ArrayList<UserState> startingUsers = new ArrayList<>(mStartingUsers); 1351 mStartingUsers.clear(); 1352 1353 if (!booting) { 1354 // Complete user switch. 1355 for (int i = 0; i < startingUsers.size(); i++) { 1356 mService.mAmInternal.finishUserSwitch(startingUsers.get(i)); 1357 } 1358 } 1359 } 1360 1361 mService.mH.post(() -> mService.mAmInternal.trimApplications()); 1362 } 1363 1364 /** This doesn't just find a task, it also moves the task to front. */ findTaskToMoveToFront(Task task, int flags, ActivityOptions options, String reason, boolean forceNonResizeable)1365 void findTaskToMoveToFront(Task task, int flags, ActivityOptions options, String reason, 1366 boolean forceNonResizeable) { 1367 Task currentRootTask = task.getRootTask(); 1368 if (currentRootTask == null) { 1369 Slog.e(TAG, "findTaskToMoveToFront: can't move task=" 1370 + task + " to front. Root task is null"); 1371 return; 1372 } 1373 1374 try { 1375 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 1376 mUserLeaving = true; 1377 } 1378 1379 mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_TO_FRONT, 1380 0 /* flags */, task, options != null ? options.getRemoteTransition() : null); 1381 reason = reason + " findTaskToMoveToFront"; 1382 boolean reparented = false; 1383 if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) { 1384 final Rect bounds = options.getLaunchBounds(); 1385 task.setBounds(bounds); 1386 1387 Task launchRootTask = 1388 mRootWindowContainer.getLaunchRootTask(null, options, task, ON_TOP); 1389 1390 if (launchRootTask != currentRootTask) { 1391 moveHomeRootTaskToFrontIfNeeded(flags, launchRootTask.getDisplayArea(), reason); 1392 task.reparent(launchRootTask, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT, 1393 !ANIMATE, DEFER_RESUME, reason); 1394 currentRootTask = launchRootTask; 1395 reparented = true; 1396 // task.reparent() should already placed the task on top, 1397 // still need moveTaskToFrontLocked() below for any transition settings. 1398 } 1399 if (launchRootTask.shouldResizeRootTaskWithLaunchBounds()) { 1400 launchRootTask.resize(bounds, !PRESERVE_WINDOWS, !DEFER_RESUME); 1401 } else { 1402 // WM resizeTask must be done after the task is moved to the correct stack, 1403 // because Task's setBounds() also updates dim layer's bounds, but that has 1404 // dependency on the root task. 1405 task.resize(false /* relayout */, false /* forced */); 1406 } 1407 } 1408 1409 if (!reparented) { 1410 moveHomeRootTaskToFrontIfNeeded(flags, currentRootTask.getDisplayArea(), reason); 1411 } 1412 1413 final ActivityRecord r = task.getTopNonFinishingActivity(); 1414 currentRootTask.moveTaskToFront(task, false /* noAnimation */, options, 1415 r == null ? null : r.appTimeTracker, reason); 1416 1417 if (DEBUG_ROOT_TASK) Slog.d(TAG_ROOT_TASK, 1418 "findTaskToMoveToFront: moved to front of root task=" + currentRootTask); 1419 1420 handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED, 1421 mRootWindowContainer.getDefaultTaskDisplayArea(), currentRootTask, 1422 forceNonResizeable); 1423 } finally { 1424 mUserLeaving = false; 1425 } 1426 } 1427 moveHomeRootTaskToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea, String reason)1428 private void moveHomeRootTaskToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea, 1429 String reason) { 1430 final Task focusedRootTask = taskDisplayArea.getFocusedRootTask(); 1431 1432 if ((taskDisplayArea.getWindowingMode() == WINDOWING_MODE_FULLSCREEN 1433 && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) 1434 || (focusedRootTask != null && focusedRootTask.isActivityTypeRecents())) { 1435 // We move root home task to front when we are on a fullscreen display area and 1436 // caller has requested the home activity to move with it. Or the previous root task 1437 // is recents. 1438 taskDisplayArea.moveHomeRootTaskToFront(reason); 1439 } 1440 } 1441 canUseActivityOptionsLaunchBounds(ActivityOptions options)1442 boolean canUseActivityOptionsLaunchBounds(ActivityOptions options) { 1443 // We use the launch bounds in the activity options is the device supports freeform 1444 // window management or is launching into the root pinned task. 1445 if (options == null || options.getLaunchBounds() == null) { 1446 return false; 1447 } 1448 return (mService.mSupportsPictureInPicture 1449 && options.getLaunchWindowingMode() == WINDOWING_MODE_PINNED) 1450 || mService.mSupportsFreeformWindowManagement; 1451 } 1452 getLaunchParamsController()1453 LaunchParamsController getLaunchParamsController() { 1454 return mLaunchParamsController; 1455 } 1456 setSplitScreenResizing(boolean resizing)1457 void setSplitScreenResizing(boolean resizing) { 1458 if (resizing == mDockedRootTaskResizing) { 1459 return; 1460 } 1461 1462 mDockedRootTaskResizing = resizing; 1463 mWindowManager.setDockedRootTaskResizing(resizing); 1464 } 1465 removePinnedRootTaskInSurfaceTransaction(Task rootTask)1466 private void removePinnedRootTaskInSurfaceTransaction(Task rootTask) { 1467 /** 1468 * Workaround: Force-stop all the activities in the root pinned task before we reparent them 1469 * to the fullscreen root task. This is to guarantee that when we are removing a root task, 1470 * that the client receives onStop() before new windowing mode is set. 1471 * We do this by detaching the root task from the display so that it will be considered 1472 * invisible when ensureActivitiesVisible() is called, and all of its activities will be 1473 * marked invisible as well and added to the stopping list. After which we process the 1474 * stopping list by handling the idle. 1475 */ 1476 rootTask.cancelAnimation(); 1477 rootTask.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */); 1478 rootTask.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); 1479 activityIdleInternal(null /* idleActivity */, false /* fromTimeout */, 1480 true /* processPausingActivities */, null /* configuration */); 1481 1482 // Reparent all the tasks to the bottom of the display 1483 final DisplayContent toDisplay = 1484 mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY); 1485 1486 mService.deferWindowLayout(); 1487 try { 1488 rootTask.setWindowingMode(WINDOWING_MODE_UNDEFINED); 1489 if (rootTask.getWindowingMode() != WINDOWING_MODE_FREEFORM) { 1490 rootTask.setBounds(null); 1491 } 1492 toDisplay.getDefaultTaskDisplayArea().positionTaskBehindHome(rootTask); 1493 1494 // Follow on the workaround: activities are kept force hidden till the new windowing 1495 // mode is set. 1496 rootTask.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, false /* set */); 1497 mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); 1498 mRootWindowContainer.resumeFocusedTasksTopActivities(); 1499 } finally { 1500 mService.continueWindowLayout(); 1501 } 1502 } 1503 removeRootTaskInSurfaceTransaction(Task rootTask)1504 private void removeRootTaskInSurfaceTransaction(Task rootTask) { 1505 if (rootTask.getWindowingMode() == WINDOWING_MODE_PINNED) { 1506 removePinnedRootTaskInSurfaceTransaction(rootTask); 1507 } else { 1508 final PooledConsumer c = PooledLambda.obtainConsumer( 1509 ActivityTaskSupervisor::processRemoveTask, this, PooledLambda.__(Task.class)); 1510 rootTask.forAllLeafTasks(c, true /* traverseTopToBottom */); 1511 c.recycle(); 1512 } 1513 } 1514 processRemoveTask(Task task)1515 private void processRemoveTask(Task task) { 1516 removeTask(task, true /* killProcess */, REMOVE_FROM_RECENTS, "remove-root-task"); 1517 } 1518 1519 /** 1520 * Removes the root task associated with the given {@param task}. If the {@param task} is the 1521 * pinned task, then its child tasks are not explicitly removed when the root task is 1522 * destroyed, but instead moved back onto the TaskDisplayArea. 1523 */ removeRootTask(Task task)1524 void removeRootTask(Task task) { 1525 mWindowManager.inSurfaceTransaction(() -> removeRootTaskInSurfaceTransaction(task)); 1526 } 1527 1528 /** 1529 * Removes the task with the specified task id. 1530 * 1531 * @param taskId Identifier of the task to be removed. 1532 * @param killProcess Kill any process associated with the task if possible. 1533 * @param removeFromRecents Whether to also remove the task from recents. 1534 * @return Returns true if the given task was found and removed. 1535 */ removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents, String reason)1536 boolean removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents, 1537 String reason) { 1538 final Task task = 1539 mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS); 1540 if (task != null) { 1541 removeTask(task, killProcess, removeFromRecents, reason); 1542 return true; 1543 } 1544 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 1545 return false; 1546 } 1547 removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason)1548 void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) { 1549 if (task.mInRemoveTask) { 1550 // Prevent recursion. 1551 return; 1552 } 1553 if (task.isVisible()) { 1554 mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_CLOSE, task); 1555 } else { 1556 // Removing a non-visible task doesn't require a transition, but if there is one 1557 // collecting, this should be a member just in case. 1558 mService.getTransitionController().collect(task); 1559 } 1560 task.mInRemoveTask = true; 1561 try { 1562 task.performClearTask(reason); 1563 cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents); 1564 mService.getLockTaskController().clearLockedTask(task); 1565 mService.getTaskChangeNotificationController().notifyTaskStackChanged(); 1566 if (task.isPersistable) { 1567 mService.notifyTaskPersisterLocked(null, true); 1568 } 1569 } finally { 1570 task.mInRemoveTask = false; 1571 } 1572 } 1573 cleanUpRemovedTaskLocked(Task task, boolean killProcess, boolean removeFromRecents)1574 void cleanUpRemovedTaskLocked(Task task, boolean killProcess, boolean removeFromRecents) { 1575 if (removeFromRecents) { 1576 mRecentTasks.remove(task); 1577 } 1578 ComponentName component = task.getBaseIntent().getComponent(); 1579 if (component == null) { 1580 Slog.w(TAG, "No component for base intent of task: " + task); 1581 return; 1582 } 1583 1584 // Find any running services associated with this app and stop if needed. 1585 final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::cleanUpServices, 1586 mService.mAmInternal, task.mUserId, component, new Intent(task.getBaseIntent())); 1587 mService.mH.sendMessage(msg); 1588 1589 if (!killProcess) { 1590 return; 1591 } 1592 1593 // Determine if the process(es) for this task should be killed. 1594 final String pkg = component.getPackageName(); 1595 ArrayList<Object> procsToKill = new ArrayList<>(); 1596 ArrayMap<String, SparseArray<WindowProcessController>> pmap = 1597 mService.mProcessNames.getMap(); 1598 for (int i = 0; i < pmap.size(); i++) { 1599 1600 SparseArray<WindowProcessController> uids = pmap.valueAt(i); 1601 for (int j = 0; j < uids.size(); j++) { 1602 WindowProcessController proc = uids.valueAt(j); 1603 if (proc.mUserId != task.mUserId) { 1604 // Don't kill process for a different user. 1605 continue; 1606 } 1607 if (proc == mService.mHomeProcess) { 1608 // Don't kill the home process along with tasks from the same package. 1609 continue; 1610 } 1611 if (!proc.mPkgList.contains(pkg)) { 1612 // Don't kill process that is not associated with this task. 1613 continue; 1614 } 1615 1616 if (!proc.shouldKillProcessForRemovedTask(task)) { 1617 // Don't kill process(es) that has an activity in a different task that is also 1618 // in recents, or has an activity not stopped. 1619 return; 1620 } 1621 1622 if (proc.hasForegroundServices()) { 1623 // Don't kill process(es) with foreground service. 1624 return; 1625 } 1626 1627 // Add process to kill list. 1628 procsToKill.add(proc); 1629 } 1630 } 1631 1632 // Kill the running processes. Post on handle since we don't want to hold the service lock 1633 // while calling into AM. 1634 final Message m = PooledLambda.obtainMessage( 1635 ActivityManagerInternal::killProcessesForRemovedTask, mService.mAmInternal, 1636 procsToKill); 1637 mService.mH.sendMessage(m); 1638 } 1639 1640 /** 1641 * Called to restore the state of the task into the root task that it's supposed to go into. 1642 * 1643 * @param task The recent task to be restored. 1644 * @param aOptions The activity options to use for restoration. 1645 * @param onTop If the root task for the task should be the topmost on the display. 1646 * @return true if the task has been restored successfully. 1647 */ restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop)1648 boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) { 1649 final Task rootTask = 1650 mRootWindowContainer.getLaunchRootTask(null, aOptions, task, onTop); 1651 final WindowContainer parent = task.getParent(); 1652 1653 if (parent == rootTask || task == rootTask) { 1654 // Nothing else to do since it is already restored in the right root task. 1655 return true; 1656 } 1657 1658 if (parent != null) { 1659 // Task has already been restored once. Just re-parent it to the new root task. 1660 task.reparent(rootTask, POSITION_TOP, true /*moveParents*/, "restoreRecentTaskLocked"); 1661 return true; 1662 } 1663 1664 rootTask.addChild(task, onTop, true /* showForAllUsers */); 1665 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 1666 "Added restored task=" + task + " to root task=" + rootTask); 1667 return true; 1668 } 1669 1670 @Override onRecentTaskAdded(Task task)1671 public void onRecentTaskAdded(Task task) { 1672 task.touchActiveTime(); 1673 } 1674 1675 @Override onRecentTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess)1676 public void onRecentTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess) { 1677 if (wasTrimmed) { 1678 // Task was trimmed from the recent tasks list -- remove the active task record as well 1679 // since the user won't really be able to go back to it 1680 removeTaskById(task.mTaskId, killProcess, false /* removeFromRecents */, 1681 "recent-task-trimmed"); 1682 } 1683 task.removedFromRecents(); 1684 } 1685 1686 /** 1687 * Returns the reparent target root task, creating the root task if necessary. This call 1688 * also enforces the various checks on tasks that are going to be reparented from one root 1689 * task to another. 1690 */ 1691 // TODO: Look into changing users to this method to DisplayContent.resolveWindowingMode() getReparentTargetRootTask(Task task, Task rootTask, boolean toTop)1692 Task getReparentTargetRootTask(Task task, Task rootTask, boolean toTop) { 1693 final Task prevRootTask = task.getRootTask(); 1694 final int rootTaskId = rootTask.mTaskId; 1695 final boolean inMultiWindowMode = rootTask.inMultiWindowMode(); 1696 1697 // Check that we aren't reparenting to the same root task that the task is already in 1698 if (prevRootTask != null && prevRootTask.mTaskId == rootTaskId) { 1699 Slog.w(TAG, "Can not reparent to same root task, task=" + task 1700 + " already in rootTaskId=" + rootTaskId); 1701 return prevRootTask; 1702 } 1703 1704 // Ensure that we aren't trying to move into a multi-window root task without multi-window 1705 // support 1706 if (inMultiWindowMode && !mService.mSupportsMultiWindow) { 1707 throw new IllegalArgumentException("Device doesn't support multi-window, can not" 1708 + " reparent task=" + task + " to root-task=" + rootTask); 1709 } 1710 1711 // Ensure that we're not moving a task to a dynamic root task if device doesn't support 1712 // multi-display. 1713 if (rootTask.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) { 1714 throw new IllegalArgumentException("Device doesn't support multi-display, can not" 1715 + " reparent task=" + task + " to rootTaskId=" + rootTaskId); 1716 } 1717 1718 // Ensure that we aren't trying to move into a freeform root task without freeform support 1719 if (rootTask.getWindowingMode() == WINDOWING_MODE_FREEFORM 1720 && !mService.mSupportsFreeformWindowManagement) { 1721 throw new IllegalArgumentException("Device doesn't support freeform, can not reparent" 1722 + " task=" + task); 1723 } 1724 1725 if (rootTask.inPinnedWindowingMode()) { 1726 throw new IllegalArgumentException("No support to reparent to PIP, task=" + task); 1727 } 1728 1729 // Leave the task in its current root task or a fullscreen root task if it isn't 1730 // resizeable and the preferred root task is in multi-window mode. 1731 if (inMultiWindowMode 1732 && !task.supportsMultiWindowInDisplayArea(rootTask.getDisplayArea())) { 1733 Slog.w(TAG, "Can not move unresizeable task=" + task + " to multi-window root task=" 1734 + rootTask + " Moving to a fullscreen root task instead."); 1735 if (prevRootTask != null) { 1736 return prevRootTask; 1737 } 1738 rootTask = rootTask.getDisplayArea().createRootTask( 1739 WINDOWING_MODE_FULLSCREEN, rootTask.getActivityType(), toTop); 1740 } 1741 return rootTask; 1742 } 1743 goingToSleepLocked()1744 void goingToSleepLocked() { 1745 scheduleSleepTimeout(); 1746 if (!mGoingToSleepWakeLock.isHeld()) { 1747 mGoingToSleepWakeLock.acquire(); 1748 if (mLaunchingActivityWakeLock.isHeld()) { 1749 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1750 throw new IllegalStateException("Calling must be system uid"); 1751 } 1752 mLaunchingActivityWakeLock.release(); 1753 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1754 } 1755 } 1756 1757 mRootWindowContainer.applySleepTokens(false /* applyToRootTasks */); 1758 1759 checkReadyForSleepLocked(true /* allowDelay */); 1760 } 1761 shutdownLocked(int timeout)1762 boolean shutdownLocked(int timeout) { 1763 goingToSleepLocked(); 1764 1765 boolean timedout = false; 1766 final long endTime = System.currentTimeMillis() + timeout; 1767 while (true) { 1768 if (!mRootWindowContainer.putTasksToSleep( 1769 true /* allowDelay */, true /* shuttingDown */)) { 1770 long timeRemaining = endTime - System.currentTimeMillis(); 1771 if (timeRemaining > 0) { 1772 try { 1773 mService.mGlobalLock.wait(timeRemaining); 1774 } catch (InterruptedException e) { 1775 } 1776 } else { 1777 Slog.w(TAG, "Activity manager shutdown timed out"); 1778 timedout = true; 1779 break; 1780 } 1781 } else { 1782 break; 1783 } 1784 } 1785 1786 // Force checkReadyForSleep to complete. 1787 checkReadyForSleepLocked(false /* allowDelay */); 1788 1789 return timedout; 1790 } 1791 comeOutOfSleepIfNeededLocked()1792 void comeOutOfSleepIfNeededLocked() { 1793 removeSleepTimeouts(); 1794 if (mGoingToSleepWakeLock.isHeld()) { 1795 mGoingToSleepWakeLock.release(); 1796 } 1797 } 1798 checkReadyForSleepLocked(boolean allowDelay)1799 void checkReadyForSleepLocked(boolean allowDelay) { 1800 if (!mService.isSleepingOrShuttingDownLocked()) { 1801 // Do not care. 1802 return; 1803 } 1804 1805 if (!mRootWindowContainer.putTasksToSleep( 1806 allowDelay, false /* shuttingDown */)) { 1807 return; 1808 } 1809 1810 // End power mode launch before going sleep 1811 mService.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_ALL); 1812 1813 removeSleepTimeouts(); 1814 1815 if (mGoingToSleepWakeLock.isHeld()) { 1816 mGoingToSleepWakeLock.release(); 1817 } 1818 if (mService.mShuttingDown) { 1819 mService.mGlobalLock.notifyAll(); 1820 } 1821 } 1822 reportResumedActivityLocked(ActivityRecord r)1823 boolean reportResumedActivityLocked(ActivityRecord r) { 1824 // A resumed activity cannot be stopping. remove from list 1825 mStoppingActivities.remove(r); 1826 1827 final Task rootTask = r.getRootTask(); 1828 if (rootTask.getDisplayArea().allResumedActivitiesComplete()) { 1829 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 1830 // Make sure activity & window visibility should be identical 1831 // for all displays in this stage. 1832 mRootWindowContainer.executeAppTransitionForAllDisplay(); 1833 return true; 1834 } 1835 return false; 1836 } 1837 1838 // Called when WindowManager has finished animating the launchingBehind activity to the back. handleLaunchTaskBehindCompleteLocked(ActivityRecord r)1839 private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 1840 final Task task = r.getTask(); 1841 final Task rootTask = task.getRootTask(); 1842 1843 mRecentTasks.add(task); 1844 mService.getTaskChangeNotificationController().notifyTaskStackChanged(); 1845 rootTask.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 1846 1847 // When launching tasks behind, update the last active time of the top task after the new 1848 // task has been shown briefly 1849 final ActivityRecord top = rootTask.getTopNonFinishingActivity(); 1850 if (top != null) { 1851 top.getTask().touchActiveTime(); 1852 } 1853 } 1854 scheduleLaunchTaskBehindComplete(IBinder token)1855 void scheduleLaunchTaskBehindComplete(IBinder token) { 1856 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 1857 } 1858 1859 /** Checks whether the userid is a profile of the current user. */ isCurrentProfileLocked(int userId)1860 boolean isCurrentProfileLocked(int userId) { 1861 if (userId == mRootWindowContainer.mCurrentUser) return true; 1862 return mService.mAmInternal.isCurrentProfile(userId); 1863 } 1864 1865 /** 1866 * Processes the activities to be stopped or destroyed. This should be called when the resumed 1867 * activities are idle or drawn. 1868 */ processStoppingAndFinishingActivities(ActivityRecord launchedActivity, boolean processPausingActivities, String reason)1869 private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity, 1870 boolean processPausingActivities, String reason) { 1871 // Stop any activities that are scheduled to do so but have been waiting for the transition 1872 // animation to finish. 1873 ArrayList<ActivityRecord> readyToStopActivities = null; 1874 for (int i = mStoppingActivities.size() - 1; i >= 0; --i) { 1875 final ActivityRecord s = mStoppingActivities.get(i); 1876 final boolean animating = s.isAnimating(TRANSITION | PARENTS, 1877 ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS) 1878 || mService.getTransitionController().inTransition(s); 1879 ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b " 1880 + "finishing=%s", s, s.nowVisible, animating, s.finishing); 1881 if (!animating || mService.mShuttingDown) { 1882 if (!processPausingActivities && s.isState(PAUSING)) { 1883 // Defer processing pausing activities in this iteration and reschedule 1884 // a delayed idle to reprocess it again 1885 removeIdleTimeoutForActivity(launchedActivity); 1886 scheduleIdleTimeout(launchedActivity); 1887 continue; 1888 } 1889 1890 ProtoLog.v(WM_DEBUG_STATES, "Ready to stop: %s", s); 1891 if (readyToStopActivities == null) { 1892 readyToStopActivities = new ArrayList<>(); 1893 } 1894 readyToStopActivities.add(s); 1895 1896 mStoppingActivities.remove(i); 1897 } 1898 } 1899 1900 final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size(); 1901 for (int i = 0; i < numReadyStops; i++) { 1902 final ActivityRecord r = readyToStopActivities.get(i); 1903 if (r.isInHistory()) { 1904 if (r.finishing) { 1905 // TODO(b/137329632): Wait for idle of the right activity, not just any. 1906 r.destroyIfPossible(reason); 1907 } else { 1908 r.stopIfPossible(); 1909 } 1910 } 1911 } 1912 1913 final int numFinishingActivities = mFinishingActivities.size(); 1914 if (numFinishingActivities == 0) { 1915 return; 1916 } 1917 1918 // Finish any activities that are scheduled to do so but have been waiting for the next one 1919 // to start. 1920 final ArrayList<ActivityRecord> finishingActivities = new ArrayList<>(mFinishingActivities); 1921 mFinishingActivities.clear(); 1922 for (int i = 0; i < numFinishingActivities; i++) { 1923 final ActivityRecord r = finishingActivities.get(i); 1924 if (r.isInHistory()) { 1925 r.destroyImmediately("finish-" + reason); 1926 } 1927 } 1928 } 1929 removeHistoryRecords(WindowProcessController app)1930 void removeHistoryRecords(WindowProcessController app) { 1931 removeHistoryRecords(mStoppingActivities, app, "mStoppingActivities"); 1932 removeHistoryRecords(mFinishingActivities, app, "mFinishingActivities"); 1933 } 1934 removeHistoryRecords(ArrayList<ActivityRecord> list, WindowProcessController app, String listName)1935 private void removeHistoryRecords(ArrayList<ActivityRecord> list, WindowProcessController app, 1936 String listName) { 1937 int i = list.size(); 1938 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 1939 "Removing app " + this + " from list " + listName + " with " + i + " entries"); 1940 while (i > 0) { 1941 i--; 1942 ActivityRecord r = list.get(i); 1943 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r); 1944 if (r.app == app) { 1945 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!"); 1946 list.remove(i); 1947 r.removeTimeouts(); 1948 } 1949 } 1950 } 1951 dump(PrintWriter pw, String prefix)1952 public void dump(PrintWriter pw, String prefix) { 1953 pw.println(); 1954 pw.println("ActivityTaskSupervisor state:"); 1955 mRootWindowContainer.dump(pw, prefix, true /* dumpAll */); 1956 getKeyguardController().dump(pw, prefix); 1957 mService.getLockTaskController().dump(pw, prefix); 1958 pw.print(prefix); 1959 pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); 1960 pw.println(prefix + "mUserRootTaskInFront=" + mRootWindowContainer.mUserRootTaskInFront); 1961 pw.println(prefix + "mVisibilityTransactionDepth=" + mVisibilityTransactionDepth); 1962 pw.print(prefix); pw.print("isHomeRecentsComponent="); 1963 pw.println(mRecentTasks.isRecentsComponentHomeActivity(mRootWindowContainer.mCurrentUser)); 1964 if (!mWaitingActivityLaunched.isEmpty()) { 1965 pw.println(prefix + "mWaitingActivityLaunched="); 1966 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 1967 mWaitingActivityLaunched.get(i).dump(pw, prefix + " "); 1968 } 1969 } 1970 pw.println(); 1971 } 1972 printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, boolean needSep, String prefix, Runnable header)1973 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 1974 boolean needSep, String prefix, Runnable header) { 1975 if (activity != null) { 1976 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 1977 if (needSep) { 1978 pw.println(); 1979 } 1980 if (header != null) { 1981 header.run(); 1982 } 1983 pw.print(prefix); 1984 pw.println(activity); 1985 return true; 1986 } 1987 } 1988 return false; 1989 } 1990 dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage, boolean needNL, Runnable header, Task lastTask)1991 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 1992 String prefix, String label, boolean complete, boolean brief, boolean client, 1993 String dumpPackage, boolean needNL, Runnable header, Task lastTask) { 1994 String innerPrefix = null; 1995 String[] args = null; 1996 boolean printed = false; 1997 for (int i=list.size()-1; i>=0; i--) { 1998 final ActivityRecord r = list.get(i); 1999 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 2000 continue; 2001 } 2002 if (innerPrefix == null) { 2003 innerPrefix = prefix + " "; 2004 args = new String[0]; 2005 } 2006 printed = true; 2007 final boolean full = !brief && (complete || !r.isInHistory()); 2008 if (needNL) { 2009 pw.println(""); 2010 needNL = false; 2011 } 2012 if (header != null) { 2013 header.run(); 2014 header = null; 2015 } 2016 if (lastTask != r.getTask()) { 2017 lastTask = r.getTask(); 2018 pw.print(prefix); 2019 pw.print(full ? "* " : " "); 2020 pw.println(lastTask); 2021 if (full) { 2022 lastTask.dump(pw, prefix + " "); 2023 } else if (complete) { 2024 // Complete + brief == give a summary. Isn't that obvious?!? 2025 if (lastTask.intent != null) { 2026 pw.print(prefix); pw.print(" "); 2027 pw.println(lastTask.intent.toInsecureString()); 2028 } 2029 } 2030 } 2031 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 2032 pw.print(" #"); pw.print(i); pw.print(": "); 2033 pw.println(r); 2034 if (full) { 2035 r.dump(pw, innerPrefix, true /* dumpAll */); 2036 } else if (complete) { 2037 // Complete + brief == give a summary. Isn't that obvious?!? 2038 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 2039 if (r.app != null) { 2040 pw.print(innerPrefix); pw.println(r.app); 2041 } 2042 } 2043 if (client && r.attachedToProcess()) { 2044 // flush anything that is already in the PrintWriter since the thread is going 2045 // to write to the file descriptor directly 2046 pw.flush(); 2047 try { 2048 TransferPipe tp = new TransferPipe(); 2049 try { 2050 r.app.getThread().dumpActivity( 2051 tp.getWriteFd(), r.appToken, innerPrefix, args); 2052 // Short timeout, since blocking here can deadlock with the application. 2053 tp.go(fd, 2000); 2054 } finally { 2055 tp.kill(); 2056 } 2057 } catch (IOException e) { 2058 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 2059 } catch (RemoteException e) { 2060 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 2061 } 2062 needNL = true; 2063 } 2064 } 2065 return printed; 2066 } 2067 scheduleIdleTimeout(ActivityRecord next)2068 void scheduleIdleTimeout(ActivityRecord next) { 2069 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdleTimeout: Callers=" + Debug.getCallers(4)); 2070 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 2071 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2072 } 2073 scheduleIdle()2074 final void scheduleIdle() { 2075 if (!mHandler.hasMessages(IDLE_NOW_MSG)) { 2076 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 2077 } 2078 } 2079 2080 /** 2081 * Updates the record of top resumed activity when it changes and handles reporting of the 2082 * state changes to previous and new top activities. It will immediately dispatch top resumed 2083 * state loss message to previous top activity (if haven't done it already). After the previous 2084 * activity releases the top state and reports back, message about acquiring top state will be 2085 * sent to the new top resumed activity. 2086 */ updateTopResumedActivityIfNeeded()2087 void updateTopResumedActivityIfNeeded() { 2088 final ActivityRecord prevTopActivity = mTopResumedActivity; 2089 final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); 2090 if (topRootTask == null || topRootTask.getResumedActivity() == prevTopActivity) { 2091 if (mService.isSleepingLocked()) { 2092 // There won't be a next resumed activity. The top process should still be updated 2093 // according to the current top focused activity. 2094 mService.updateTopApp(null /* topResumedActivity */); 2095 } 2096 return; 2097 } 2098 2099 // Ask previous activity to release the top state. 2100 final boolean prevActivityReceivedTopState = 2101 prevTopActivity != null && !mTopResumedActivityWaitingForPrev; 2102 // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity 2103 // before the prevTopActivity one hasn't reported back yet. So server never sent the top 2104 // resumed state change message to prevTopActivity. 2105 if (prevActivityReceivedTopState 2106 && prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */)) { 2107 scheduleTopResumedStateLossTimeout(prevTopActivity); 2108 mTopResumedActivityWaitingForPrev = true; 2109 } 2110 2111 // Update the current top activity. 2112 mTopResumedActivity = topRootTask.getResumedActivity(); 2113 scheduleTopResumedActivityStateIfNeeded(); 2114 2115 mService.updateTopApp(mTopResumedActivity); 2116 } 2117 2118 /** Schedule top resumed state change if previous top activity already reported back. */ scheduleTopResumedActivityStateIfNeeded()2119 private void scheduleTopResumedActivityStateIfNeeded() { 2120 if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) { 2121 mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */); 2122 } 2123 } 2124 2125 /** 2126 * Limit the time given to the app to report handling of the state loss. 2127 */ scheduleTopResumedStateLossTimeout(ActivityRecord r)2128 private void scheduleTopResumedStateLossTimeout(ActivityRecord r) { 2129 final Message msg = mHandler.obtainMessage(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG); 2130 msg.obj = r; 2131 r.topResumedStateLossTime = SystemClock.uptimeMillis(); 2132 mHandler.sendMessageDelayed(msg, TOP_RESUMED_STATE_LOSS_TIMEOUT); 2133 ProtoLog.v(WM_DEBUG_STATES, "Waiting for top state to be released by %s", r); 2134 } 2135 2136 /** 2137 * Handle a loss of top resumed state by an activity - update internal state and inform next top 2138 * activity if needed. 2139 */ handleTopResumedStateReleased(boolean timeout)2140 void handleTopResumedStateReleased(boolean timeout) { 2141 ProtoLog.v(WM_DEBUG_STATES, "Top resumed state released %s", 2142 (timeout ? "(due to timeout)" : "(transition complete)")); 2143 2144 mHandler.removeMessages(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG); 2145 if (!mTopResumedActivityWaitingForPrev) { 2146 // Top resumed activity state loss already handled. 2147 return; 2148 } 2149 mTopResumedActivityWaitingForPrev = false; 2150 scheduleTopResumedActivityStateIfNeeded(); 2151 } 2152 removeIdleTimeoutForActivity(ActivityRecord r)2153 void removeIdleTimeoutForActivity(ActivityRecord r) { 2154 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 2155 + Debug.getCallers(4)); 2156 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2157 } 2158 scheduleResumeTopActivities()2159 final void scheduleResumeTopActivities() { 2160 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 2161 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2162 } 2163 } 2164 scheduleProcessStoppingAndFinishingActivitiesIfNeeded()2165 void scheduleProcessStoppingAndFinishingActivitiesIfNeeded() { 2166 if (mStoppingActivities.isEmpty() && mFinishingActivities.isEmpty()) { 2167 return; 2168 } 2169 if (mRootWindowContainer.allResumedActivitiesIdle()) { 2170 scheduleIdle(); 2171 return; 2172 } 2173 if (!mHandler.hasMessages(PROCESS_STOPPING_AND_FINISHING_MSG) 2174 && mRootWindowContainer.allResumedActivitiesVisible()) { 2175 mHandler.sendEmptyMessage(PROCESS_STOPPING_AND_FINISHING_MSG); 2176 } 2177 } 2178 removeSleepTimeouts()2179 void removeSleepTimeouts() { 2180 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 2181 } 2182 scheduleSleepTimeout()2183 final void scheduleSleepTimeout() { 2184 removeSleepTimeouts(); 2185 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 2186 } 2187 removeRestartTimeouts(ActivityRecord r)2188 void removeRestartTimeouts(ActivityRecord r) { 2189 mHandler.removeMessages(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r); 2190 } 2191 scheduleRestartTimeout(ActivityRecord r)2192 final void scheduleRestartTimeout(ActivityRecord r) { 2193 removeRestartTimeouts(r); 2194 mHandler.sendMessageDelayed(mHandler.obtainMessage(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r), 2195 WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION); 2196 } 2197 handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask)2198 void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, 2199 TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask) { 2200 handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredTaskDisplayArea, 2201 actualRootTask, false /* forceNonResizable */); 2202 } 2203 handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask, boolean forceNonResizable)2204 void handleNonResizableTaskIfNeeded(Task task, int preferredWindowingMode, 2205 TaskDisplayArea preferredTaskDisplayArea, Task actualRootTask, 2206 boolean forceNonResizable) { 2207 final boolean isSecondaryDisplayPreferred = preferredTaskDisplayArea != null 2208 && preferredTaskDisplayArea.getDisplayId() != DEFAULT_DISPLAY; 2209 final boolean inSplitScreenMode = actualRootTask != null 2210 && actualRootTask.getDisplayArea().isSplitScreenModeActivated(); 2211 if (((!inSplitScreenMode && preferredWindowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) 2212 && !isSecondaryDisplayPreferred) || !task.isActivityTypeStandardOrUndefined()) { 2213 return; 2214 } 2215 2216 // Handle incorrect launch/move to secondary display if needed. 2217 if (isSecondaryDisplayPreferred) { 2218 if (!task.canBeLaunchedOnDisplay(task.getDisplayId())) { 2219 throw new IllegalStateException("Task resolved to incompatible display"); 2220 } 2221 2222 final DisplayContent preferredDisplay = preferredTaskDisplayArea.mDisplayContent; 2223 if (preferredDisplay != task.getDisplayContent()) { 2224 Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplay.mDisplayId); 2225 // Display a warning toast that we failed to put a task on a secondary display. 2226 mService.getTaskChangeNotificationController() 2227 .notifyActivityLaunchOnSecondaryDisplayFailed(task.getTaskInfo(), 2228 preferredDisplay.mDisplayId); 2229 } else if (!forceNonResizable) { 2230 handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY); 2231 } 2232 // The information about not support secondary display should already be notified, we 2233 // don't want to show another message on default display about split-screen. And it may 2234 // be the case that a resizable activity is launched on a non-resizable task. 2235 return; 2236 } 2237 2238 if (!task.supportsSplitScreenWindowingMode() || forceNonResizable) { 2239 if (mService.getTransitionController().getTransitionPlayer() != null) return; 2240 // Dismiss docked root task. If task appeared to be in docked root task but is not 2241 // resizable - we need to move it to top of fullscreen root task, otherwise it will 2242 // be covered. 2243 final TaskDisplayArea taskDisplayArea = task.getDisplayArea(); 2244 if (taskDisplayArea.isSplitScreenModeActivated()) { 2245 // Display a warning toast that we tried to put an app that doesn't support 2246 // split-screen in split-screen. 2247 mService.getTaskChangeNotificationController() 2248 .notifyActivityDismissingDockedRootTask(); 2249 taskDisplayArea.onSplitScreenModeDismissed(task); 2250 taskDisplayArea.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS, 2251 true /* notifyClients */); 2252 } 2253 return; 2254 } 2255 2256 handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN); 2257 } 2258 2259 /** Notifies that the top activity of the task is forced to be resizeable. */ handleForcedResizableTaskIfNeeded(Task task, int reason)2260 private void handleForcedResizableTaskIfNeeded(Task task, int reason) { 2261 final ActivityRecord topActivity = task.getTopNonFinishingActivity(); 2262 if (topActivity == null || topActivity.noDisplay 2263 || !topActivity.canForceResizeNonResizable(task.getWindowingMode())) { 2264 return; 2265 } 2266 mService.getTaskChangeNotificationController().notifyActivityForcedResizable( 2267 task.mTaskId, reason, topActivity.info.applicationInfo.packageName); 2268 } 2269 logRootTaskState()2270 void logRootTaskState() { 2271 mActivityMetricsLogger.logWindowState(); 2272 } 2273 scheduleUpdateMultiWindowMode(Task task)2274 void scheduleUpdateMultiWindowMode(Task task) { 2275 final PooledConsumer c = PooledLambda.obtainConsumer( 2276 ActivityTaskSupervisor::addToMultiWindowModeChangedList, this, 2277 PooledLambda.__(ActivityRecord.class)); 2278 task.forAllActivities(c); 2279 c.recycle(); 2280 2281 if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) { 2282 mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG); 2283 } 2284 } 2285 addToMultiWindowModeChangedList(ActivityRecord r)2286 private void addToMultiWindowModeChangedList(ActivityRecord r) { 2287 if (r.attachedToProcess()) { 2288 mMultiWindowModeChangedActivities.add(r); 2289 } 2290 } 2291 scheduleUpdatePictureInPictureModeIfNeeded(Task task, Task prevRootTask)2292 void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Task prevRootTask) { 2293 final Task rootTask = task.getRootTask(); 2294 if ((prevRootTask == null || (prevRootTask != rootTask 2295 && !prevRootTask.inPinnedWindowingMode() && !rootTask.inPinnedWindowingMode()))) { 2296 return; 2297 } 2298 2299 scheduleUpdatePictureInPictureModeIfNeeded(task, rootTask.getRequestedOverrideBounds()); 2300 } 2301 scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds)2302 void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds) { 2303 final PooledConsumer c = PooledLambda.obtainConsumer( 2304 ActivityTaskSupervisor::addToPipModeChangedList, this, 2305 PooledLambda.__(ActivityRecord.class)); 2306 task.forAllActivities(c); 2307 c.recycle(); 2308 2309 mPipModeChangedTargetRootTaskBounds = targetRootTaskBounds; 2310 2311 if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { 2312 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); 2313 } 2314 } 2315 addToPipModeChangedList(ActivityRecord r)2316 private void addToPipModeChangedList(ActivityRecord r) { 2317 if (!r.attachedToProcess()) return; 2318 2319 mPipModeChangedActivities.add(r); 2320 // If we are scheduling pip change, then remove this activity from multi-window 2321 // change list as the processing of pip change will make sure multi-window changed 2322 // message is processed in the right order relative to pip changed. 2323 mMultiWindowModeChangedActivities.remove(r); 2324 } 2325 wakeUp(String reason)2326 void wakeUp(String reason) { 2327 mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_APPLICATION, 2328 "android.server.am:TURN_ON:" + reason); 2329 } 2330 2331 /** Starts a batch of visibility updates. */ beginActivityVisibilityUpdate()2332 void beginActivityVisibilityUpdate() { 2333 if (mVisibilityTransactionDepth == 0) { 2334 getKeyguardController().updateVisibility(); 2335 } 2336 mVisibilityTransactionDepth++; 2337 } 2338 2339 /** Ends a batch of visibility updates. */ endActivityVisibilityUpdate()2340 void endActivityVisibilityUpdate() { 2341 mVisibilityTransactionDepth--; 2342 if (mVisibilityTransactionDepth == 0) { 2343 computeProcessActivityStateBatch(); 2344 } 2345 } 2346 2347 /** Returns {@code true} if the caller is on the path to update visibility. */ inActivityVisibilityUpdate()2348 boolean inActivityVisibilityUpdate() { 2349 return mVisibilityTransactionDepth > 0; 2350 } 2351 2352 /** 2353 * Called when the state or visibility of an attached activity is changed. 2354 * 2355 * @param wpc The process who owns the activity. 2356 * @param forceBatch Whether to put the changed record to a pending list. If the caller is not 2357 * in the path of visibility update ({@link #inActivityVisibilityUpdate}), it 2358 * must call {@link #computeProcessActivityStateBatch} manually. 2359 */ onProcessActivityStateChanged(WindowProcessController wpc, boolean forceBatch)2360 void onProcessActivityStateChanged(WindowProcessController wpc, boolean forceBatch) { 2361 if (forceBatch || inActivityVisibilityUpdate()) { 2362 if (!mActivityStateChangedProcs.contains(wpc)) { 2363 mActivityStateChangedProcs.add(wpc); 2364 } 2365 return; 2366 } 2367 wpc.computeProcessActivityState(); 2368 } 2369 computeProcessActivityStateBatch()2370 void computeProcessActivityStateBatch() { 2371 if (mActivityStateChangedProcs.isEmpty()) { 2372 return; 2373 } 2374 for (int i = mActivityStateChangedProcs.size() - 1; i >= 0; i--) { 2375 mActivityStateChangedProcs.get(i).computeProcessActivityState(); 2376 } 2377 mActivityStateChangedProcs.clear(); 2378 } 2379 2380 /** 2381 * Begin deferring resume to avoid duplicate resumes in one pass. 2382 */ beginDeferResume()2383 void beginDeferResume() { 2384 mDeferResumeCount++; 2385 } 2386 2387 /** 2388 * End deferring resume and determine if resume can be called. 2389 */ endDeferResume()2390 void endDeferResume() { 2391 mDeferResumeCount--; 2392 } 2393 2394 /** @return True if resume can be called. */ readyToResume()2395 boolean readyToResume() { 2396 return mDeferResumeCount == 0; 2397 } 2398 2399 private final class ActivityTaskSupervisorHandler extends Handler { 2400 ActivityTaskSupervisorHandler(Looper looper)2401 ActivityTaskSupervisorHandler(Looper looper) { 2402 super(looper); 2403 } 2404 2405 @Override handleMessage(Message msg)2406 public void handleMessage(Message msg) { 2407 synchronized (mService.mGlobalLock) { 2408 if (handleMessageInner(msg)) { 2409 return; 2410 } 2411 } 2412 // The cases that some invocations cannot be locked by WM. 2413 switch (msg.what) { 2414 case RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG: { 2415 final ActivityRecord r = (ActivityRecord) msg.obj; 2416 String processName = null; 2417 int uid = 0; 2418 synchronized (mService.mGlobalLock) { 2419 if (r.attachedToProcess() 2420 && r.isState(Task.ActivityState.RESTARTING_PROCESS)) { 2421 processName = r.app.mName; 2422 uid = r.app.mUid; 2423 } 2424 } 2425 if (processName != null) { 2426 mService.mAmInternal.killProcess(processName, uid, 2427 "restartActivityProcessTimeout"); 2428 } 2429 } break; 2430 } 2431 } 2432 activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout)2433 private void activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout) { 2434 activityIdleInternal(idleActivity, fromTimeout, 2435 fromTimeout /* processPausingActivities */, null /* config */); 2436 } 2437 2438 /** 2439 * Handles the message with lock held. 2440 * 2441 * @return {@code true} if the message is handled. 2442 */ handleMessageInner(Message msg)2443 private boolean handleMessageInner(Message msg) { 2444 switch (msg.what) { 2445 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: { 2446 for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) { 2447 final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i); 2448 r.updateMultiWindowMode(); 2449 } 2450 } break; 2451 case REPORT_PIP_MODE_CHANGED_MSG: { 2452 for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) { 2453 final ActivityRecord r = mPipModeChangedActivities.remove(i); 2454 r.updatePictureInPictureMode(mPipModeChangedTargetRootTaskBounds, 2455 false /* forceUpdate */); 2456 } 2457 } break; 2458 case IDLE_TIMEOUT_MSG: { 2459 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 2460 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 2461 // We don't at this point know if the activity is fullscreen, so we need to be 2462 // conservative and assume it isn't. 2463 activityIdleFromMessage((ActivityRecord) msg.obj, true /* fromTimeout */); 2464 } break; 2465 case IDLE_NOW_MSG: { 2466 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 2467 activityIdleFromMessage((ActivityRecord) msg.obj, false /* fromTimeout */); 2468 } break; 2469 case RESUME_TOP_ACTIVITY_MSG: { 2470 mRootWindowContainer.resumeFocusedTasksTopActivities(); 2471 } break; 2472 case SLEEP_TIMEOUT_MSG: { 2473 if (mService.isSleepingOrShuttingDownLocked()) { 2474 Slog.w(TAG, "Sleep timeout! Sleeping now."); 2475 checkReadyForSleepLocked(false /* allowDelay */); 2476 } 2477 } break; 2478 case LAUNCH_TIMEOUT_MSG: { 2479 if (mLaunchingActivityWakeLock.isHeld()) { 2480 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 2481 if (VALIDATE_WAKE_LOCK_CALLER 2482 && Binder.getCallingUid() != Process.myUid()) { 2483 throw new IllegalStateException("Calling must be system uid"); 2484 } 2485 mLaunchingActivityWakeLock.release(); 2486 } 2487 } break; 2488 case PROCESS_STOPPING_AND_FINISHING_MSG: { 2489 processStoppingAndFinishingActivities(null /* launchedActivity */, 2490 false /* processPausingActivities */, "transit"); 2491 } break; 2492 case LAUNCH_TASK_BEHIND_COMPLETE: { 2493 final ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 2494 if (r != null) { 2495 handleLaunchTaskBehindCompleteLocked(r); 2496 } 2497 } break; 2498 case START_HOME_MSG: { 2499 mHandler.removeMessages(START_HOME_MSG); 2500 2501 // Start home activities on displays with no activities. 2502 mRootWindowContainer.startHomeOnEmptyDisplays((String) msg.obj); 2503 } break; 2504 case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: { 2505 final ActivityRecord r = (ActivityRecord) msg.obj; 2506 Slog.w(TAG, "Activity top resumed state loss timeout for " + r); 2507 if (r.hasProcess()) { 2508 mService.logAppTooSlow(r.app, r.topResumedStateLossTime, 2509 "top state loss for " + r); 2510 } 2511 handleTopResumedStateReleased(true /* timeout */); 2512 } break; 2513 default: 2514 return false; 2515 } 2516 return true; 2517 } 2518 } 2519 startActivityFromRecents(int callingPid, int callingUid, int taskId, SafeActivityOptions options)2520 int startActivityFromRecents(int callingPid, int callingUid, int taskId, 2521 SafeActivityOptions options) { 2522 Task task = null; 2523 final String callingPackage; 2524 final String callingFeatureId; 2525 final Intent intent; 2526 final int userId; 2527 int activityType = ACTIVITY_TYPE_UNDEFINED; 2528 int windowingMode = WINDOWING_MODE_UNDEFINED; 2529 final ActivityOptions activityOptions = options != null 2530 ? options.getOptions(this) 2531 : null; 2532 boolean moveHomeTaskForward = true; 2533 if (activityOptions != null) { 2534 activityType = activityOptions.getLaunchActivityType(); 2535 windowingMode = activityOptions.getLaunchWindowingMode(); 2536 if (activityOptions.freezeRecentTasksReordering() 2537 && mRecentTasks.isCallerRecents(callingUid)) { 2538 mRecentTasks.setFreezeTaskListReordering(); 2539 } 2540 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY 2541 || activityOptions.getLaunchRootTask() != null) { 2542 // Don't move home activity forward if we are launching into primary split or there 2543 // is a launch root set. 2544 moveHomeTaskForward = false; 2545 } 2546 } 2547 if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) { 2548 throw new IllegalArgumentException("startActivityFromRecents: Task " 2549 + taskId + " can't be launch in the home/recents root task."); 2550 } 2551 2552 mService.deferWindowLayout(); 2553 try { 2554 task = mRootWindowContainer.anyTaskForId(taskId, 2555 MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, activityOptions, ON_TOP); 2556 if (task == null) { 2557 mWindowManager.executeAppTransition(); 2558 throw new IllegalArgumentException( 2559 "startActivityFromRecents: Task " + taskId + " not found."); 2560 } 2561 2562 if (moveHomeTaskForward) { 2563 // We always want to return to the home activity instead of the recents activity 2564 // from whatever is started from the recents activity, so move the home root task 2565 // forward. 2566 // TODO (b/115289124): Multi-display supports for recents. 2567 mRootWindowContainer.getDefaultTaskDisplayArea().moveHomeRootTaskToFront( 2568 "startActivityFromRecents"); 2569 } 2570 2571 // If the user must confirm credentials (e.g. when first launching a work app and the 2572 // Work Challenge is present) let startActivityInPackage handle the intercepting. 2573 if (!mService.mAmInternal.shouldConfirmCredentials(task.mUserId) 2574 && task.getRootActivity() != null) { 2575 final ActivityRecord targetActivity = task.getTopNonFinishingActivity(); 2576 2577 mRootWindowContainer.startPowerModeLaunchIfNeeded( 2578 true /* forceSend */, targetActivity); 2579 final LaunchingState launchingState = 2580 mActivityMetricsLogger.notifyActivityLaunching(task.intent); 2581 try { 2582 mService.moveTaskToFrontLocked(null /* appThread */, null /* callingPackage */, 2583 task.mTaskId, 0, options); 2584 // Apply options to prevent pendingOptions be taken when scheduling activity 2585 // lifecycle transaction to make sure the override pending app transition will 2586 // be applied immediately. 2587 targetActivity.applyOptionsAnimation(); 2588 } finally { 2589 mActivityMetricsLogger.notifyActivityLaunched(launchingState, 2590 START_TASK_TO_FRONT, false /* newActivityCreated */, targetActivity, 2591 activityOptions); 2592 } 2593 2594 mService.getActivityStartController().postStartActivityProcessingForLastStarter( 2595 task.getTopNonFinishingActivity(), ActivityManager.START_TASK_TO_FRONT, 2596 task.getRootTask()); 2597 2598 // As it doesn't go to ActivityStarter.executeRequest() path, we need to resume 2599 // app switching here also. 2600 mService.resumeAppSwitches(); 2601 2602 return ActivityManager.START_TASK_TO_FRONT; 2603 } 2604 callingPackage = task.mCallingPackage; 2605 callingFeatureId = task.mCallingFeatureId; 2606 intent = task.intent; 2607 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 2608 userId = task.mUserId; 2609 return mService.getActivityStartController().startActivityInPackage(task.mCallingUid, 2610 callingPid, callingUid, callingPackage, callingFeatureId, intent, null, null, 2611 null, 0, 0, options, userId, task, "startActivityFromRecents", 2612 false /* validateIncomingUser */, null /* originatingPendingIntent */, 2613 false /* allowBackgroundActivityStart */); 2614 } finally { 2615 mService.continueWindowLayout(); 2616 } 2617 } 2618 2619 /** 2620 * Internal container to store a match qualifier alongside a WaitResult. 2621 */ 2622 private static class WaitInfo { 2623 final WaitResult mResult; 2624 final ComponentName mTargetComponent; 2625 /** 2626 * The target component may not be the final drawn activity. The launching state is managed 2627 * by {@link ActivityMetricsLogger} that can track consecutive launching sequence. 2628 */ 2629 final LaunchingState mLaunchingState; 2630 WaitInfo(WaitResult result, ComponentName component, LaunchingState launchingState)2631 WaitInfo(WaitResult result, ComponentName component, LaunchingState launchingState) { 2632 mResult = result; 2633 mTargetComponent = component; 2634 mLaunchingState = launchingState; 2635 } 2636 matches(ActivityRecord r)2637 boolean matches(ActivityRecord r) { 2638 return mTargetComponent.equals(r.mActivityComponent) || mLaunchingState.contains(r); 2639 } 2640 dump(PrintWriter pw, String prefix)2641 void dump(PrintWriter pw, String prefix) { 2642 pw.println(prefix + "WaitInfo:"); 2643 pw.println(prefix + " mTargetComponent=" + mTargetComponent); 2644 pw.println(prefix + " mResult="); 2645 mResult.dump(pw, prefix + " "); 2646 } 2647 } 2648 } 2649