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