1 /* 2 * Copyright (C) 2016 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.app.Activity.RESULT_CANCELED; 20 import static android.app.ActivityManager.START_ABORTED; 21 import static android.app.ActivityManager.START_CANCELED; 22 import static android.app.ActivityManager.START_CLASS_NOT_FOUND; 23 import static android.app.ActivityManager.START_DELIVERED_TO_TOP; 24 import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED; 25 import static android.app.ActivityManager.START_PERMISSION_DENIED; 26 import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER; 27 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; 28 import static android.app.ActivityManager.START_SUCCESS; 29 import static android.app.ActivityManager.START_TASK_TO_FRONT; 30 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 31 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 32 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 33 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; 34 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; 35 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; 36 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 37 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 38 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 39 import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; 40 import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION; 41 import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP; 42 import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT; 43 import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED; 44 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS; 45 import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; 46 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; 47 import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS; 48 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; 49 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; 50 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK; 51 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; 52 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; 53 import static android.content.pm.ActivityInfo.launchModeToString; 54 import static android.os.Process.INVALID_UID; 55 import static android.view.Display.DEFAULT_DISPLAY; 56 import static android.view.WindowManager.TRANSIT_NONE; 57 import static android.view.WindowManager.TRANSIT_OPEN; 58 import static android.view.WindowManager.TRANSIT_TO_FRONT; 59 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT; 60 61 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; 62 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; 63 import static com.android.server.wm.ActivityRecord.State.RESUMED; 64 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; 65 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; 66 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; 67 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; 68 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS; 69 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS; 70 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING; 71 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 72 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 73 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; 74 import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME; 75 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; 76 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; 77 import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_DEFAULT; 78 import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; 79 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; 80 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY; 81 import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT; 82 import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; 83 import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; 84 import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; 85 import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; 86 import static com.android.server.wm.WindowContainer.POSITION_TOP; 87 88 import android.annotation.NonNull; 89 import android.annotation.Nullable; 90 import android.app.ActivityManager; 91 import android.app.ActivityOptions; 92 import android.app.IApplicationThread; 93 import android.app.PendingIntent; 94 import android.app.ProfilerInfo; 95 import android.app.WaitResult; 96 import android.app.WindowConfiguration; 97 import android.compat.annotation.ChangeId; 98 import android.compat.annotation.EnabledSince; 99 import android.content.IIntentSender; 100 import android.content.Intent; 101 import android.content.IntentSender; 102 import android.content.pm.ActivityInfo; 103 import android.content.pm.ApplicationInfo; 104 import android.content.pm.AuxiliaryResolveInfo; 105 import android.content.pm.PackageManager; 106 import android.content.pm.PackageManagerInternal; 107 import android.content.pm.ResolveInfo; 108 import android.content.pm.UserInfo; 109 import android.content.res.Configuration; 110 import android.os.Binder; 111 import android.os.Build; 112 import android.os.Bundle; 113 import android.os.IBinder; 114 import android.os.RemoteException; 115 import android.os.Trace; 116 import android.os.UserHandle; 117 import android.os.UserManager; 118 import android.service.voice.IVoiceInteractionSession; 119 import android.text.TextUtils; 120 import android.util.Pools.SynchronizedPool; 121 import android.util.Slog; 122 import android.window.RemoteTransition; 123 124 import com.android.internal.annotations.VisibleForTesting; 125 import com.android.internal.app.HeavyWeightSwitcherActivity; 126 import com.android.internal.app.IVoiceInteractor; 127 import com.android.internal.protolog.common.ProtoLog; 128 import com.android.internal.util.FrameworkStatsLog; 129 import com.android.server.am.PendingIntentRecord; 130 import com.android.server.pm.InstantAppResolver; 131 import com.android.server.power.ShutdownCheckPoints; 132 import com.android.server.statusbar.StatusBarManagerInternal; 133 import com.android.server.uri.NeededUriGrants; 134 import com.android.server.wm.ActivityMetricsLogger.LaunchingState; 135 import com.android.server.wm.BackgroundActivityStartController.BalCode; 136 import com.android.server.wm.LaunchParamsController.LaunchParams; 137 import com.android.server.wm.TaskFragment.EmbeddingCheckResult; 138 139 import java.io.PrintWriter; 140 import java.text.DateFormat; 141 import java.util.Date; 142 143 /** 144 * Controller for interpreting how and then launching an activity. 145 * 146 * This class collects all the logic for determining how an intent and flags should be turned into 147 * an activity and associated task and root task. 148 */ 149 class ActivityStarter { 150 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM; 151 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS; 152 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; 153 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; 154 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING; 155 private static final int INVALID_LAUNCH_MODE = -1; 156 157 /** 158 * Feature flag to protect PendingIntent being abused to start background activity. 159 */ 160 @ChangeId 161 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) 162 static final long ENABLE_PENDING_INTENT_BAL_OPTION = 192341120L; 163 164 private final ActivityTaskManagerService mService; 165 private final RootWindowContainer mRootWindowContainer; 166 private final ActivityTaskSupervisor mSupervisor; 167 private final ActivityStartInterceptor mInterceptor; 168 private final ActivityStartController mController; 169 170 // Share state variable among methods when starting an activity. 171 @VisibleForTesting 172 ActivityRecord mStartActivity; 173 private Intent mIntent; 174 private int mCallingUid; 175 private ActivityOptions mOptions; 176 177 // If it is BAL_BLOCK, background activity can only be started in an existing task that contains 178 // an activity with same uid, or if activity starts are enabled in developer options. 179 @BalCode 180 private int mBalCode; 181 182 private int mLaunchMode; 183 private boolean mLaunchTaskBehind; 184 private int mLaunchFlags; 185 186 private LaunchParams mLaunchParams = new LaunchParams(); 187 188 private ActivityRecord mNotTop; 189 private boolean mDoResume; 190 private int mStartFlags; 191 private ActivityRecord mSourceRecord; 192 193 // The task display area to launch the activity onto, barring any strong reason to do otherwise. 194 private TaskDisplayArea mPreferredTaskDisplayArea; 195 private int mPreferredWindowingMode; 196 197 private Task mInTask; 198 private TaskFragment mInTaskFragment; 199 private TaskFragment mAddingToTaskFragment; 200 @VisibleForTesting 201 boolean mAddingToTask; 202 // Activity that was moved to the top of its task in situations where activity-order changes 203 // due to launch flags (eg. REORDER_TO_TOP). 204 @VisibleForTesting 205 ActivityRecord mMovedToTopActivity; 206 207 private Task mSourceRootTask; 208 private Task mTargetRootTask; 209 // The task that the last activity was started into. We currently reset the actual start 210 // activity's task and as a result may not have a reference to the task in all cases 211 private Task mTargetTask; 212 private boolean mIsTaskCleared; 213 private boolean mMovedToFront; 214 private boolean mNoAnimation; 215 private boolean mAvoidMoveToFront; 216 private boolean mFrozeTaskList; 217 private boolean mTransientLaunch; 218 // The task which was above the targetTask before starting this activity. null if the targetTask 219 // was already on top or if the activity is in a new task. 220 private Task mPriorAboveTask; 221 private boolean mDisplayLockAndOccluded; 222 223 // We must track when we deliver the new intent since multiple code paths invoke 224 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used 225 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is 226 // delivered at most once. 227 private boolean mIntentDelivered; 228 229 private IVoiceInteractionSession mVoiceSession; 230 private IVoiceInteractor mVoiceInteractor; 231 232 // Last activity record we attempted to start 233 private ActivityRecord mLastStartActivityRecord; 234 // The result of the last activity we attempted to start. 235 private int mLastStartActivityResult; 236 // Time in milli seconds we attempted to start the last activity. 237 private long mLastStartActivityTimeMs; 238 // The reason we were trying to start the last activity 239 private String mLastStartReason; 240 241 /* 242 * Request details provided through setter methods. Should be reset after {@link #execute()} 243 * to avoid unnecessarily retaining parameters. Note that the request is ignored when 244 * {@link #startResolvedActivity} is invoked directly. 245 */ 246 @VisibleForTesting 247 Request mRequest = new Request(); 248 249 /** 250 * An interface that to provide {@link ActivityStarter} instances to the controller. This is 251 * used by tests to inject their own starter implementations for verification purposes. 252 */ 253 @VisibleForTesting 254 interface Factory { 255 /** 256 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}. 257 */ setController(ActivityStartController controller)258 void setController(ActivityStartController controller); 259 260 /** 261 * Generates an {@link ActivityStarter} that is ready to handle a new start request. 262 * @return an {@link ActivityStarter} 263 */ obtain()264 ActivityStarter obtain(); 265 266 /** 267 * Recycles a starter for reuse. 268 */ recycle(ActivityStarter starter)269 void recycle(ActivityStarter starter); 270 } 271 272 /** 273 * Default implementation of {@link StarterFactory}. 274 */ 275 static class DefaultFactory implements Factory { 276 /** 277 * The maximum count of starters that should be active at one time: 278 * 1. last ran starter (for logging and post activity processing) 279 * 2. current running starter 280 * 3. starter from re-entry in (2) 281 */ 282 private final int MAX_STARTER_COUNT = 3; 283 284 private ActivityStartController mController; 285 private ActivityTaskManagerService mService; 286 private ActivityTaskSupervisor mSupervisor; 287 private ActivityStartInterceptor mInterceptor; 288 289 private SynchronizedPool<ActivityStarter> mStarterPool = 290 new SynchronizedPool<>(MAX_STARTER_COUNT); 291 DefaultFactory(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor)292 DefaultFactory(ActivityTaskManagerService service, 293 ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) { 294 mService = service; 295 mSupervisor = supervisor; 296 mInterceptor = interceptor; 297 } 298 299 @Override setController(ActivityStartController controller)300 public void setController(ActivityStartController controller) { 301 mController = controller; 302 } 303 304 @Override obtain()305 public ActivityStarter obtain() { 306 ActivityStarter starter = mStarterPool.acquire(); 307 308 if (starter == null) { 309 if (mService.mRootWindowContainer == null) { 310 throw new IllegalStateException("Too early to start activity."); 311 } 312 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor); 313 } 314 315 return starter; 316 } 317 318 @Override recycle(ActivityStarter starter)319 public void recycle(ActivityStarter starter) { 320 starter.reset(true /* clearRequest*/); 321 mStarterPool.release(starter); 322 } 323 } 324 325 /** 326 * Container for capturing initial start request details. This information is NOT reset until 327 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same 328 * parameters. 329 * 330 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with 331 * the request object. Note that some member variables are referenced in 332 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after 333 * execution. 334 */ 335 @VisibleForTesting 336 static class Request { 337 private static final int DEFAULT_CALLING_UID = -1; 338 private static final int DEFAULT_CALLING_PID = 0; 339 static final int DEFAULT_REAL_CALLING_UID = -1; 340 static final int DEFAULT_REAL_CALLING_PID = 0; 341 342 IApplicationThread caller; 343 Intent intent; 344 NeededUriGrants intentGrants; 345 // A copy of the original requested intent, in case for ephemeral app launch. 346 Intent ephemeralIntent; 347 String resolvedType; 348 ActivityInfo activityInfo; 349 ResolveInfo resolveInfo; 350 IVoiceInteractionSession voiceSession; 351 IVoiceInteractor voiceInteractor; 352 IBinder resultTo; 353 String resultWho; 354 int requestCode; 355 int callingPid = DEFAULT_CALLING_PID; 356 int callingUid = DEFAULT_CALLING_UID; 357 String callingPackage; 358 @Nullable String callingFeatureId; 359 int realCallingPid = DEFAULT_REAL_CALLING_PID; 360 int realCallingUid = DEFAULT_REAL_CALLING_UID; 361 int startFlags; 362 SafeActivityOptions activityOptions; 363 boolean ignoreTargetSecurity; 364 boolean componentSpecified; 365 boolean avoidMoveToFront; 366 ActivityRecord[] outActivity; 367 Task inTask; 368 TaskFragment inTaskFragment; 369 String reason; 370 ProfilerInfo profilerInfo; 371 Configuration globalConfig; 372 int userId; 373 WaitResult waitResult; 374 int filterCallingUid; 375 PendingIntentRecord originatingPendingIntent; 376 boolean allowBackgroundActivityStart; 377 /** 378 * The error callback token passed in {@link android.window.WindowContainerTransaction} 379 * for TaskFragment operation error handling via 380 * {@link android.window.TaskFragmentOrganizer#onTaskFragmentError(IBinder, Throwable)}. 381 */ 382 @Nullable 383 IBinder errorCallbackToken; 384 385 /** 386 * If set to {@code true}, allows this activity start to look into 387 * {@link PendingRemoteAnimationRegistry} 388 */ 389 boolean allowPendingRemoteAnimationRegistryLookup; 390 391 /** 392 * Ensure constructed request matches reset instance. 393 */ Request()394 Request() { 395 reset(); 396 } 397 398 /** 399 * Sets values back to the initial state, clearing any held references. 400 */ reset()401 void reset() { 402 caller = null; 403 intent = null; 404 intentGrants = null; 405 ephemeralIntent = null; 406 resolvedType = null; 407 activityInfo = null; 408 resolveInfo = null; 409 voiceSession = null; 410 voiceInteractor = null; 411 resultTo = null; 412 resultWho = null; 413 requestCode = 0; 414 callingPid = DEFAULT_CALLING_PID; 415 callingUid = DEFAULT_CALLING_UID; 416 callingPackage = null; 417 callingFeatureId = null; 418 realCallingPid = DEFAULT_REAL_CALLING_PID; 419 realCallingUid = DEFAULT_REAL_CALLING_UID; 420 startFlags = 0; 421 activityOptions = null; 422 ignoreTargetSecurity = false; 423 componentSpecified = false; 424 outActivity = null; 425 inTask = null; 426 inTaskFragment = null; 427 reason = null; 428 profilerInfo = null; 429 globalConfig = null; 430 userId = 0; 431 waitResult = null; 432 avoidMoveToFront = false; 433 allowPendingRemoteAnimationRegistryLookup = true; 434 filterCallingUid = UserHandle.USER_NULL; 435 originatingPendingIntent = null; 436 allowBackgroundActivityStart = false; 437 errorCallbackToken = null; 438 } 439 440 /** 441 * Adopts all values from passed in request. 442 */ set(@onNull Request request)443 void set(@NonNull Request request) { 444 caller = request.caller; 445 intent = request.intent; 446 intentGrants = request.intentGrants; 447 ephemeralIntent = request.ephemeralIntent; 448 resolvedType = request.resolvedType; 449 activityInfo = request.activityInfo; 450 resolveInfo = request.resolveInfo; 451 voiceSession = request.voiceSession; 452 voiceInteractor = request.voiceInteractor; 453 resultTo = request.resultTo; 454 resultWho = request.resultWho; 455 requestCode = request.requestCode; 456 callingPid = request.callingPid; 457 callingUid = request.callingUid; 458 callingPackage = request.callingPackage; 459 callingFeatureId = request.callingFeatureId; 460 realCallingPid = request.realCallingPid; 461 realCallingUid = request.realCallingUid; 462 startFlags = request.startFlags; 463 activityOptions = request.activityOptions; 464 ignoreTargetSecurity = request.ignoreTargetSecurity; 465 componentSpecified = request.componentSpecified; 466 outActivity = request.outActivity; 467 inTask = request.inTask; 468 inTaskFragment = request.inTaskFragment; 469 reason = request.reason; 470 profilerInfo = request.profilerInfo; 471 globalConfig = request.globalConfig; 472 userId = request.userId; 473 waitResult = request.waitResult; 474 avoidMoveToFront = request.avoidMoveToFront; 475 allowPendingRemoteAnimationRegistryLookup 476 = request.allowPendingRemoteAnimationRegistryLookup; 477 filterCallingUid = request.filterCallingUid; 478 originatingPendingIntent = request.originatingPendingIntent; 479 allowBackgroundActivityStart = request.allowBackgroundActivityStart; 480 errorCallbackToken = request.errorCallbackToken; 481 } 482 483 /** 484 * Resolve activity from the given intent for this launch. 485 */ resolveActivity(ActivityTaskSupervisor supervisor)486 void resolveActivity(ActivityTaskSupervisor supervisor) { 487 if (realCallingPid == Request.DEFAULT_REAL_CALLING_PID) { 488 realCallingPid = Binder.getCallingPid(); 489 } 490 if (realCallingUid == Request.DEFAULT_REAL_CALLING_UID) { 491 realCallingUid = Binder.getCallingUid(); 492 } 493 494 if (callingUid >= 0) { 495 callingPid = -1; 496 } else if (caller == null) { 497 callingPid = realCallingPid; 498 callingUid = realCallingUid; 499 } else { 500 callingPid = callingUid = -1; 501 } 502 503 // To determine the set of needed Uri permission grants, we need the 504 // "resolved" calling UID, where we try our best to identify the 505 // actual caller that is starting this activity 506 int resolvedCallingUid = callingUid; 507 if (caller != null) { 508 synchronized (supervisor.mService.mGlobalLock) { 509 final WindowProcessController callerApp = supervisor.mService 510 .getProcessController(caller); 511 if (callerApp != null) { 512 resolvedCallingUid = callerApp.mInfo.uid; 513 } 514 } 515 } 516 517 // Save a copy in case ephemeral needs it 518 ephemeralIntent = new Intent(intent); 519 // Don't modify the client's object! 520 intent = new Intent(intent); 521 if (intent.getComponent() != null 522 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null) 523 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction()) 524 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction()) 525 && supervisor.mService.getPackageManagerInternalLocked() 526 .isInstantAppInstallerComponent(intent.getComponent())) { 527 // Intercept intents targeted directly to the ephemeral installer the ephemeral 528 // installer should never be started with a raw Intent; instead adjust the intent 529 // so it looks like a "normal" instant app launch. 530 intent.setComponent(null /* component */); 531 } 532 533 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId, 534 0 /* matchFlags */, 535 computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid)); 536 if (resolveInfo == null) { 537 final UserInfo userInfo = supervisor.getUserInfo(userId); 538 if (userInfo != null && userInfo.isManagedProfile()) { 539 // Special case for managed profiles, if attempting to launch non-cryto aware 540 // app in a locked managed profile from an unlocked parent allow it to resolve 541 // as user will be sent via confirm credentials to unlock the profile. 542 final UserManager userManager = UserManager.get(supervisor.mService.mContext); 543 boolean profileLockedAndParentUnlockingOrUnlocked = false; 544 final long token = Binder.clearCallingIdentity(); 545 try { 546 final UserInfo parent = userManager.getProfileParent(userId); 547 profileLockedAndParentUnlockingOrUnlocked = (parent != null) 548 && userManager.isUserUnlockingOrUnlocked(parent.id) 549 && !userManager.isUserUnlockingOrUnlocked(userId); 550 } finally { 551 Binder.restoreCallingIdentity(token); 552 } 553 if (profileLockedAndParentUnlockingOrUnlocked) { 554 resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId, 555 PackageManager.MATCH_DIRECT_BOOT_AWARE 556 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 557 computeResolveFilterUid(callingUid, realCallingUid, 558 filterCallingUid)); 559 } 560 } 561 } 562 563 // Collect information about the target of the Intent. 564 activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags, 565 profilerInfo); 566 567 // Carefully collect grants without holding lock 568 if (activityInfo != null) { 569 intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent( 570 intent, resolvedCallingUid, activityInfo.applicationInfo.packageName, 571 UserHandle.getUserId(activityInfo.applicationInfo.uid)); 572 } 573 } 574 } 575 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor)576 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service, 577 ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) { 578 mController = controller; 579 mService = service; 580 mRootWindowContainer = service.mRootWindowContainer; 581 mSupervisor = supervisor; 582 mInterceptor = interceptor; 583 reset(true); 584 } 585 586 /** 587 * Effectively duplicates the starter passed in. All state and request values will be 588 * mirrored. 589 * @param starter 590 */ set(ActivityStarter starter)591 void set(ActivityStarter starter) { 592 mStartActivity = starter.mStartActivity; 593 mIntent = starter.mIntent; 594 mCallingUid = starter.mCallingUid; 595 mOptions = starter.mOptions; 596 mBalCode = starter.mBalCode; 597 598 mLaunchTaskBehind = starter.mLaunchTaskBehind; 599 mLaunchFlags = starter.mLaunchFlags; 600 mLaunchMode = starter.mLaunchMode; 601 602 mLaunchParams.set(starter.mLaunchParams); 603 604 mNotTop = starter.mNotTop; 605 mDoResume = starter.mDoResume; 606 mStartFlags = starter.mStartFlags; 607 mSourceRecord = starter.mSourceRecord; 608 mPreferredTaskDisplayArea = starter.mPreferredTaskDisplayArea; 609 mPreferredWindowingMode = starter.mPreferredWindowingMode; 610 611 mInTask = starter.mInTask; 612 mInTaskFragment = starter.mInTaskFragment; 613 mAddingToTask = starter.mAddingToTask; 614 615 mSourceRootTask = starter.mSourceRootTask; 616 617 mTargetTask = starter.mTargetTask; 618 mTargetRootTask = starter.mTargetRootTask; 619 mIsTaskCleared = starter.mIsTaskCleared; 620 mMovedToFront = starter.mMovedToFront; 621 mNoAnimation = starter.mNoAnimation; 622 mAvoidMoveToFront = starter.mAvoidMoveToFront; 623 mFrozeTaskList = starter.mFrozeTaskList; 624 625 mVoiceSession = starter.mVoiceSession; 626 mVoiceInteractor = starter.mVoiceInteractor; 627 628 mIntentDelivered = starter.mIntentDelivered; 629 mLastStartActivityResult = starter.mLastStartActivityResult; 630 mLastStartActivityTimeMs = starter.mLastStartActivityTimeMs; 631 mLastStartReason = starter.mLastStartReason; 632 633 mRequest.set(starter.mRequest); 634 } 635 relatedToPackage(String packageName)636 boolean relatedToPackage(String packageName) { 637 return (mLastStartActivityRecord != null 638 && packageName.equals(mLastStartActivityRecord.packageName)) 639 || (mStartActivity != null && packageName.equals(mStartActivity.packageName)); 640 } 641 642 /** 643 * Resolve necessary information according the request parameters provided earlier, and execute 644 * the request which begin the journey of starting an activity. 645 * @return The starter result. 646 */ execute()647 int execute() { 648 try { 649 onExecutionStarted(); 650 651 // Refuse possible leaked file descriptors 652 if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) { 653 throw new IllegalArgumentException("File descriptors passed in Intent"); 654 } 655 656 final LaunchingState launchingState; 657 synchronized (mService.mGlobalLock) { 658 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo); 659 final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID 660 ? Binder.getCallingUid() : mRequest.realCallingUid; 661 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching( 662 mRequest.intent, caller, callingUid); 663 } 664 665 // If the caller hasn't already resolved the activity, we're willing 666 // to do so here. If the caller is already holding the WM lock here, 667 // and we need to check dynamic Uri permissions, then we're forced 668 // to assume those permissions are denied to avoid deadlocking. 669 if (mRequest.activityInfo == null) { 670 mRequest.resolveActivity(mSupervisor); 671 } 672 673 // Add checkpoint for this shutdown or reboot attempt, so we can record the original 674 // intent action and package name. 675 if (mRequest.intent != null) { 676 String intentAction = mRequest.intent.getAction(); 677 String callingPackage = mRequest.callingPackage; 678 if (intentAction != null && callingPackage != null 679 && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction) 680 || Intent.ACTION_SHUTDOWN.equals(intentAction) 681 || Intent.ACTION_REBOOT.equals(intentAction))) { 682 ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null); 683 } 684 } 685 686 int res; 687 synchronized (mService.mGlobalLock) { 688 final boolean globalConfigWillChange = mRequest.globalConfig != null 689 && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0; 690 final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); 691 if (rootTask != null) { 692 rootTask.mConfigWillChange = globalConfigWillChange; 693 } 694 ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config " 695 + "will change = %b", globalConfigWillChange); 696 697 final long origId = Binder.clearCallingIdentity(); 698 699 res = resolveToHeavyWeightSwitcherIfNeeded(); 700 if (res != START_SUCCESS) { 701 return res; 702 } 703 res = executeRequest(mRequest); 704 705 Binder.restoreCallingIdentity(origId); 706 707 if (globalConfigWillChange) { 708 // If the caller also wants to switch to a new configuration, do so now. 709 // This allows a clean switch, as we are waiting for the current activity 710 // to pause (so we will not destroy it), and have not yet started the 711 // next activity. 712 mService.mAmInternal.enforceCallingPermission( 713 android.Manifest.permission.CHANGE_CONFIGURATION, 714 "updateConfiguration()"); 715 if (rootTask != null) { 716 rootTask.mConfigWillChange = false; 717 } 718 ProtoLog.v(WM_DEBUG_CONFIGURATION, 719 "Updating to new configuration after starting activity."); 720 721 mService.updateConfigurationLocked(mRequest.globalConfig, null, false); 722 } 723 724 // The original options may have additional info about metrics. The mOptions is not 725 // used here because it may be cleared in setTargetRootTaskIfNeeded. 726 final ActivityOptions originalOptions = mRequest.activityOptions != null 727 ? mRequest.activityOptions.getOriginalOptions() : null; 728 // If the new record is the one that started, a new activity has created. 729 final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord; 730 // Notify ActivityMetricsLogger that the activity has launched. 731 // ActivityMetricsLogger will then wait for the windows to be drawn and populate 732 // WaitResult. 733 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res, 734 newActivityCreated, mLastStartActivityRecord, originalOptions); 735 if (mRequest.waitResult != null) { 736 mRequest.waitResult.result = res; 737 res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord, 738 launchingState); 739 } 740 return getExternalResult(res); 741 } 742 } finally { 743 onExecutionComplete(); 744 } 745 } 746 747 /** 748 * Updates the request to heavy-weight switch if this is a heavy-weight process while there 749 * already have another, different heavy-weight process running. 750 */ resolveToHeavyWeightSwitcherIfNeeded()751 private int resolveToHeavyWeightSwitcherIfNeeded() { 752 if (mRequest.activityInfo == null || !mService.mHasHeavyWeightFeature 753 || (mRequest.activityInfo.applicationInfo.privateFlags 754 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) == 0) { 755 return START_SUCCESS; 756 } 757 758 if (!mRequest.activityInfo.processName.equals( 759 mRequest.activityInfo.applicationInfo.packageName)) { 760 return START_SUCCESS; 761 } 762 763 final WindowProcessController heavy = mService.mHeavyWeightProcess; 764 if (heavy == null || (heavy.mInfo.uid == mRequest.activityInfo.applicationInfo.uid 765 && heavy.mName.equals(mRequest.activityInfo.processName))) { 766 return START_SUCCESS; 767 } 768 769 int appCallingUid = mRequest.callingUid; 770 if (mRequest.caller != null) { 771 WindowProcessController callerApp = mService.getProcessController(mRequest.caller); 772 if (callerApp != null) { 773 appCallingUid = callerApp.mInfo.uid; 774 } else { 775 Slog.w(TAG, "Unable to find app for caller " + mRequest.caller + " (pid=" 776 + mRequest.callingPid + ") when starting: " + mRequest.intent.toString()); 777 SafeActivityOptions.abort(mRequest.activityOptions); 778 return START_PERMISSION_DENIED; 779 } 780 } 781 782 final IIntentSender target = mService.getIntentSenderLocked( 783 ActivityManager.INTENT_SENDER_ACTIVITY, "android" /* packageName */, 784 null /* featureId */, appCallingUid, mRequest.userId, null /* token */, 785 null /* resultWho*/, 0 /* requestCode*/, new Intent[]{mRequest.intent}, 786 new String[]{mRequest.resolvedType}, 787 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT, 788 null /* bOptions */); 789 790 final Intent newIntent = new Intent(); 791 if (mRequest.requestCode >= 0) { 792 // Caller is requesting a result. 793 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 794 } 795 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target)); 796 heavy.updateIntentForHeavyWeightActivity(newIntent); 797 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 798 mRequest.activityInfo.packageName); 799 newIntent.setFlags(mRequest.intent.getFlags()); 800 newIntent.setClassName("android" /* packageName */, 801 HeavyWeightSwitcherActivity.class.getName()); 802 mRequest.intent = newIntent; 803 mRequest.resolvedType = null; 804 mRequest.caller = null; 805 mRequest.callingUid = Binder.getCallingUid(); 806 mRequest.callingPid = Binder.getCallingPid(); 807 mRequest.componentSpecified = true; 808 mRequest.resolveInfo = mSupervisor.resolveIntent(mRequest.intent, null /* resolvedType */, 809 mRequest.userId, 0 /* matchFlags */, 810 computeResolveFilterUid(mRequest.callingUid, mRequest.realCallingUid, 811 mRequest.filterCallingUid)); 812 mRequest.activityInfo = 813 mRequest.resolveInfo != null ? mRequest.resolveInfo.activityInfo : null; 814 if (mRequest.activityInfo != null) { 815 mRequest.activityInfo = mService.mAmInternal.getActivityInfoForUser( 816 mRequest.activityInfo, mRequest.userId); 817 } 818 819 return START_SUCCESS; 820 } 821 822 /** 823 * Wait for activity launch completes. 824 */ waitResultIfNeeded(WaitResult waitResult, ActivityRecord r, LaunchingState launchingState)825 private int waitResultIfNeeded(WaitResult waitResult, ActivityRecord r, 826 LaunchingState launchingState) { 827 final int res = waitResult.result; 828 if (res == START_DELIVERED_TO_TOP 829 || (res == START_TASK_TO_FRONT && r.nowVisible && r.isState(RESUMED))) { 830 // The activity should already be visible, so nothing to wait. 831 waitResult.timeout = false; 832 waitResult.who = r.mActivityComponent; 833 waitResult.totalTime = 0; 834 return res; 835 } 836 mSupervisor.waitActivityVisibleOrLaunched(waitResult, r, launchingState); 837 if (res == START_SUCCESS && waitResult.result == START_TASK_TO_FRONT) { 838 // A trampoline activity is launched and it brings another existing activity to front. 839 return START_TASK_TO_FRONT; 840 } 841 return res; 842 } 843 844 /** 845 * Executing activity start request and starts the journey of starting an activity. Here 846 * begins with performing several preliminary checks. The normally activity launch flow will 847 * go through {@link #startActivityUnchecked} to {@link #startActivityInner}. 848 */ executeRequest(Request request)849 private int executeRequest(Request request) { 850 if (TextUtils.isEmpty(request.reason)) { 851 throw new IllegalArgumentException("Need to specify a reason."); 852 } 853 mLastStartReason = request.reason; 854 mLastStartActivityTimeMs = System.currentTimeMillis(); 855 mLastStartActivityRecord = null; 856 857 final IApplicationThread caller = request.caller; 858 Intent intent = request.intent; 859 NeededUriGrants intentGrants = request.intentGrants; 860 String resolvedType = request.resolvedType; 861 ActivityInfo aInfo = request.activityInfo; 862 ResolveInfo rInfo = request.resolveInfo; 863 final IVoiceInteractionSession voiceSession = request.voiceSession; 864 final IBinder resultTo = request.resultTo; 865 String resultWho = request.resultWho; 866 int requestCode = request.requestCode; 867 int callingPid = request.callingPid; 868 int callingUid = request.callingUid; 869 String callingPackage = request.callingPackage; 870 String callingFeatureId = request.callingFeatureId; 871 final int realCallingPid = request.realCallingPid; 872 final int realCallingUid = request.realCallingUid; 873 final int startFlags = request.startFlags; 874 final SafeActivityOptions options = request.activityOptions; 875 Task inTask = request.inTask; 876 TaskFragment inTaskFragment = request.inTaskFragment; 877 878 int err = ActivityManager.START_SUCCESS; 879 // Pull the optional Ephemeral Installer-only bundle out of the options early. 880 final Bundle verificationBundle = 881 options != null ? options.popAppVerificationBundle() : null; 882 883 WindowProcessController callerApp = null; 884 if (caller != null) { 885 callerApp = mService.getProcessController(caller); 886 if (callerApp != null) { 887 callingPid = callerApp.getPid(); 888 callingUid = callerApp.mInfo.uid; 889 } else { 890 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid 891 + ") when starting: " + intent.toString()); 892 err = START_PERMISSION_DENIED; 893 } 894 } 895 896 final int userId = aInfo != null && aInfo.applicationInfo != null 897 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 898 if (err == ActivityManager.START_SUCCESS) { 899 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) 900 + "} from uid " + callingUid); 901 } 902 903 ActivityRecord sourceRecord = null; 904 ActivityRecord resultRecord = null; 905 if (resultTo != null) { 906 sourceRecord = ActivityRecord.isInAnyTask(resultTo); 907 if (DEBUG_RESULTS) { 908 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord); 909 } 910 if (sourceRecord != null) { 911 if (requestCode >= 0 && !sourceRecord.finishing) { 912 resultRecord = sourceRecord; 913 } 914 } 915 } 916 917 final int launchFlags = intent.getFlags(); 918 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { 919 // Transfer the result target from the source activity to the new one being started, 920 // including any failures. 921 if (requestCode >= 0) { 922 SafeActivityOptions.abort(options); 923 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 924 } 925 resultRecord = sourceRecord.resultTo; 926 if (resultRecord != null && !resultRecord.isInRootTaskLocked()) { 927 resultRecord = null; 928 } 929 resultWho = sourceRecord.resultWho; 930 requestCode = sourceRecord.requestCode; 931 sourceRecord.resultTo = null; 932 if (resultRecord != null) { 933 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); 934 } 935 if (sourceRecord.launchedFromUid == callingUid) { 936 // The new activity is being launched from the same uid as the previous activity 937 // in the flow, and asking to forward its result back to the previous. In this 938 // case the activity is serving as a trampoline between the two, so we also want 939 // to update its launchedFromPackage to be the same as the previous activity. 940 // Note that this is safe, since we know these two packages come from the same 941 // uid; the caller could just as well have supplied that same package name itself 942 // . This specifially deals with the case of an intent picker/chooser being 943 // launched in the app flow to redirect to an activity picked by the user, where 944 // we want the final activity to consider it to have been launched by the 945 // previous app activity. 946 callingPackage = sourceRecord.launchedFromPackage; 947 callingFeatureId = sourceRecord.launchedFromFeatureId; 948 } 949 } 950 951 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 952 // We couldn't find a class that can handle the given Intent. 953 // That's the end of that! 954 err = ActivityManager.START_INTENT_NOT_RESOLVED; 955 } 956 957 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 958 // We couldn't find the specific class specified in the Intent. 959 // Also the end of the line. 960 err = ActivityManager.START_CLASS_NOT_FOUND; 961 } 962 963 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 964 && sourceRecord.getTask().voiceSession != null) { 965 // If this activity is being launched as part of a voice session, we need to ensure 966 // that it is safe to do so. If the upcoming activity will also be part of the voice 967 // session, we can only launch it if it has explicitly said it supports the VOICE 968 // category, or it is a part of the calling app. 969 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 970 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 971 try { 972 intent.addCategory(Intent.CATEGORY_VOICE); 973 if (!mService.getPackageManager().activitySupportsIntent( 974 intent.getComponent(), intent, resolvedType)) { 975 Slog.w(TAG, "Activity being started in current voice task does not support " 976 + "voice: " + intent); 977 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 978 } 979 } catch (RemoteException e) { 980 Slog.w(TAG, "Failure checking voice capabilities", e); 981 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 982 } 983 } 984 } 985 986 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 987 // If the caller is starting a new voice session, just make sure the target 988 // is actually allowing it to run this way. 989 try { 990 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(), 991 intent, resolvedType)) { 992 Slog.w(TAG, 993 "Activity being started in new voice task does not support: " + intent); 994 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 995 } 996 } catch (RemoteException e) { 997 Slog.w(TAG, "Failure checking voice capabilities", e); 998 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 999 } 1000 } 1001 1002 final Task resultRootTask = resultRecord == null 1003 ? null : resultRecord.getRootTask(); 1004 1005 if (err != START_SUCCESS) { 1006 if (resultRecord != null) { 1007 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, 1008 null /* data */, null /* dataGrants */); 1009 } 1010 SafeActivityOptions.abort(options); 1011 return err; 1012 } 1013 1014 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho, 1015 requestCode, callingPid, callingUid, callingPackage, callingFeatureId, 1016 request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, 1017 resultRootTask); 1018 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1019 callingPid, resolvedType, aInfo.applicationInfo); 1020 abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid, 1021 callingPackage); 1022 1023 // Merge the two options bundles, while realCallerOptions takes precedence. 1024 ActivityOptions checkedOptions = options != null 1025 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null; 1026 1027 @BalCode int balCode = BAL_ALLOW_DEFAULT; 1028 if (!abort) { 1029 try { 1030 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, 1031 "shouldAbortBackgroundActivityStart"); 1032 BackgroundActivityStartController balController = 1033 mController.getBackgroundActivityLaunchController(); 1034 balCode = 1035 balController.checkBackgroundActivityStart( 1036 callingUid, 1037 callingPid, 1038 callingPackage, 1039 realCallingUid, 1040 realCallingPid, 1041 callerApp, 1042 request.originatingPendingIntent, 1043 request.allowBackgroundActivityStart, 1044 intent, 1045 checkedOptions); 1046 } finally { 1047 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 1048 } 1049 } 1050 1051 if (request.allowPendingRemoteAnimationRegistryLookup) { 1052 checkedOptions = mService.getActivityStartController() 1053 .getPendingRemoteAnimationRegistry() 1054 .overrideOptionsIfNeeded(callingPackage, checkedOptions); 1055 } 1056 if (mService.mController != null) { 1057 try { 1058 // The Intent we give to the watcher has the extra data stripped off, since it 1059 // can contain private information. 1060 Intent watchIntent = intent.cloneFilter(); 1061 abort |= !mService.mController.activityStarting(watchIntent, 1062 aInfo.applicationInfo.packageName); 1063 } catch (RemoteException e) { 1064 mService.mController = null; 1065 } 1066 } 1067 1068 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, 1069 callingFeatureId); 1070 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment, 1071 callingPid, callingUid, checkedOptions)) { 1072 // activity start was intercepted, e.g. because the target user is currently in quiet 1073 // mode (turn off work) or the target application is suspended 1074 intent = mInterceptor.mIntent; 1075 rInfo = mInterceptor.mRInfo; 1076 aInfo = mInterceptor.mAInfo; 1077 resolvedType = mInterceptor.mResolvedType; 1078 inTask = mInterceptor.mInTask; 1079 callingPid = mInterceptor.mCallingPid; 1080 callingUid = mInterceptor.mCallingUid; 1081 checkedOptions = mInterceptor.mActivityOptions; 1082 1083 // The interception target shouldn't get any permission grants 1084 // intended for the original destination 1085 intentGrants = null; 1086 } 1087 1088 if (abort) { 1089 if (resultRecord != null) { 1090 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, 1091 null /* data */, null /* dataGrants */); 1092 } 1093 // We pretend to the caller that it was really started, but they will just get a 1094 // cancel result. 1095 ActivityOptions.abort(checkedOptions); 1096 return START_ABORTED; 1097 } 1098 1099 // If permissions need a review before any of the app components can run, we 1100 // launch the review activity and pass a pending intent to start the activity 1101 // we are to launching now after the review is completed. 1102 if (aInfo != null) { 1103 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired( 1104 aInfo.packageName, userId)) { 1105 final IIntentSender target = mService.getIntentSenderLocked( 1106 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId, 1107 callingUid, userId, null, null, 0, new Intent[]{intent}, 1108 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT 1109 | PendingIntent.FLAG_ONE_SHOT, null); 1110 1111 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); 1112 1113 int flags = intent.getFlags(); 1114 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; 1115 1116 /* 1117 * Prevent reuse of review activity: Each app needs their own review activity. By 1118 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities 1119 * with the same launch parameters (extras are ignored). Hence to avoid possible 1120 * reuse force a new activity via the MULTIPLE_TASK flag. 1121 * 1122 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used, 1123 * hence no need to add the flag in this case. 1124 */ 1125 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) { 1126 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1127 } 1128 newIntent.setFlags(flags); 1129 1130 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName); 1131 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target)); 1132 if (resultRecord != null) { 1133 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true); 1134 } 1135 intent = newIntent; 1136 1137 // The permissions review target shouldn't get any permission 1138 // grants intended for the original destination 1139 intentGrants = null; 1140 1141 resolvedType = null; 1142 callingUid = realCallingUid; 1143 callingPid = realCallingPid; 1144 1145 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0, 1146 computeResolveFilterUid( 1147 callingUid, realCallingUid, request.filterCallingUid)); 1148 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, 1149 null /*profilerInfo*/); 1150 1151 if (DEBUG_PERMISSIONS_REVIEW) { 1152 final Task focusedRootTask = 1153 mRootWindowContainer.getTopDisplayFocusedRootTask(); 1154 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, 1155 true, false) + "} from uid " + callingUid + " on display " 1156 + (focusedRootTask == null ? DEFAULT_DISPLAY 1157 : focusedRootTask.getDisplayId())); 1158 } 1159 } 1160 } 1161 1162 // If we have an ephemeral app, abort the process of launching the resolved intent. 1163 // Instead, launch the ephemeral installer. Once the installer is finished, it 1164 // starts either the intent we resolved here [on install error] or the ephemeral 1165 // app [on install success]. 1166 if (rInfo != null && rInfo.auxiliaryInfo != null) { 1167 intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent, 1168 callingPackage, callingFeatureId, verificationBundle, resolvedType, userId); 1169 resolvedType = null; 1170 callingUid = realCallingUid; 1171 callingPid = realCallingPid; 1172 1173 // The ephemeral installer shouldn't get any permission grants 1174 // intended for the original destination 1175 intentGrants = null; 1176 1177 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/); 1178 } 1179 // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut 1180 // Pending intent launched from systemui also depends on caller app 1181 if (callerApp == null && realCallingPid > 0) { 1182 final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid); 1183 if (wpc != null) { 1184 callerApp = wpc; 1185 } 1186 } 1187 final ActivityRecord r = new ActivityRecord.Builder(mService) 1188 .setCaller(callerApp) 1189 .setLaunchedFromPid(callingPid) 1190 .setLaunchedFromUid(callingUid) 1191 .setLaunchedFromPackage(callingPackage) 1192 .setLaunchedFromFeature(callingFeatureId) 1193 .setIntent(intent) 1194 .setResolvedType(resolvedType) 1195 .setActivityInfo(aInfo) 1196 .setConfiguration(mService.getGlobalConfiguration()) 1197 .setResultTo(resultRecord) 1198 .setResultWho(resultWho) 1199 .setRequestCode(requestCode) 1200 .setComponentSpecified(request.componentSpecified) 1201 .setRootVoiceInteraction(voiceSession != null) 1202 .setActivityOptions(checkedOptions) 1203 .setSourceRecord(sourceRecord) 1204 .build(); 1205 1206 mLastStartActivityRecord = r; 1207 1208 if (r.appTimeTracker == null && sourceRecord != null) { 1209 // If the caller didn't specify an explicit time tracker, we want to continue 1210 // tracking under any it has. 1211 r.appTimeTracker = sourceRecord.appTimeTracker; 1212 } 1213 1214 // Only allow app switching to be resumed if activity is not a restricted background 1215 // activity and target app is not home process, otherwise any background activity 1216 // started in background task can stop home button protection mode. 1217 // As the targeted app is not a home process and we don't need to wait for the 2nd 1218 // activity to be started to resume app switching, we can just enable app switching 1219 // directly. 1220 WindowProcessController homeProcess = mService.mHomeProcess; 1221 boolean isHomeProcess = homeProcess != null 1222 && aInfo.applicationInfo.uid == homeProcess.mUid; 1223 if (balCode != BAL_BLOCK && !isHomeProcess) { 1224 mService.resumeAppSwitches(); 1225 } 1226 1227 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, 1228 request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, 1229 inTask, inTaskFragment, balCode, intentGrants); 1230 1231 if (request.outActivity != null) { 1232 request.outActivity[0] = mLastStartActivityRecord; 1233 } 1234 1235 return mLastStartActivityResult; 1236 } 1237 1238 /** 1239 * Return true if background activity is really aborted. 1240 * 1241 * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere. 1242 */ handleBackgroundActivityAbort(ActivityRecord r)1243 private boolean handleBackgroundActivityAbort(ActivityRecord r) { 1244 // TODO(b/131747138): Remove toast and refactor related code in R release. 1245 final boolean abort = !mService.isBackgroundActivityStartsEnabled(); 1246 if (!abort) { 1247 return false; 1248 } 1249 final ActivityRecord resultRecord = r.resultTo; 1250 final String resultWho = r.resultWho; 1251 int requestCode = r.requestCode; 1252 if (resultRecord != null) { 1253 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, 1254 null /* data */, null /* dataGrants */); 1255 } 1256 // We pretend to the caller that it was really started to make it backward compatible, but 1257 // they will just get a cancel result. 1258 ActivityOptions.abort(r.getOptions()); 1259 return true; 1260 } 1261 getExternalResult(int result)1262 static int getExternalResult(int result) { 1263 // Aborted results are treated as successes externally, but we must track them internally. 1264 return result != START_ABORTED ? result : START_SUCCESS; 1265 } 1266 1267 /** 1268 * Called when execution is complete. Sets state indicating completion and proceeds with 1269 * recycling if appropriate. 1270 */ onExecutionComplete()1271 private void onExecutionComplete() { 1272 mController.onExecutionComplete(this); 1273 } 1274 onExecutionStarted()1275 private void onExecutionStarted() { 1276 mController.onExecutionStarted(); 1277 } 1278 1279 /** 1280 * Creates a launch intent for the given auxiliary resolution data. 1281 */ createLaunchIntent(@ullable AuxiliaryResolveInfo auxiliaryResponse, Intent originalIntent, String callingPackage, @Nullable String callingFeatureId, Bundle verificationBundle, String resolvedType, int userId)1282 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse, 1283 Intent originalIntent, String callingPackage, @Nullable String callingFeatureId, 1284 Bundle verificationBundle, String resolvedType, int userId) { 1285 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) { 1286 // request phase two resolution 1287 PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked(); 1288 boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId); 1289 packageManager.requestInstantAppResolutionPhaseTwo( 1290 auxiliaryResponse, originalIntent, resolvedType, callingPackage, 1291 callingFeatureId, isRequesterInstantApp, verificationBundle, userId); 1292 } 1293 return InstantAppResolver.buildEphemeralInstallerIntent( 1294 originalIntent, 1295 InstantAppResolver.sanitizeIntent(originalIntent), 1296 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent, 1297 callingPackage, 1298 callingFeatureId, 1299 verificationBundle, 1300 resolvedType, 1301 userId, 1302 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity, 1303 auxiliaryResponse == null ? null : auxiliaryResponse.token, 1304 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo, 1305 auxiliaryResponse == null ? null : auxiliaryResponse.filters); 1306 } 1307 postStartActivityProcessing(ActivityRecord r, int result, Task startedActivityRootTask)1308 void postStartActivityProcessing(ActivityRecord r, int result, 1309 Task startedActivityRootTask) { 1310 if (!ActivityManager.isStartResultSuccessful(result)) { 1311 if (mFrozeTaskList) { 1312 // If we specifically froze the task list as part of starting an activity, then 1313 // reset the frozen list state if it failed to start. This is normally otherwise 1314 // called when the freeze-timeout has elapsed. 1315 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout(); 1316 } 1317 } 1318 if (ActivityManager.isStartResultFatalError(result)) { 1319 return; 1320 } 1321 1322 // We're waiting for an activity launch to finish, but that activity simply 1323 // brought another activity to front. We must also handle the case where the task is already 1324 // in the front as a result of the trampoline activity being in the same task (it will be 1325 // considered focused as the trampoline will be finished). Let them know about this, so 1326 // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}. 1327 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result); 1328 1329 final Task targetTask = r.getTask() != null 1330 ? r.getTask() 1331 : mTargetTask; 1332 if (startedActivityRootTask == null || targetTask == null || !targetTask.isAttached()) { 1333 return; 1334 } 1335 1336 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP) { 1337 // The activity was already running so it wasn't started, but either brought to the 1338 // front or the new intent was delivered to it since it was already in front. Notify 1339 // anyone interested in this piece of information. 1340 final Task rootHomeTask = targetTask.getDisplayArea().getRootHomeTask(); 1341 final boolean homeTaskVisible = rootHomeTask != null 1342 && rootHomeTask.shouldBeVisible(null); 1343 final ActivityRecord top = targetTask.getTopNonFinishingActivity(); 1344 final boolean visible = top != null && top.isVisible(); 1345 mService.getTaskChangeNotificationController().notifyActivityRestartAttempt( 1346 targetTask.getTaskInfo(), homeTaskVisible, mIsTaskCleared, visible); 1347 } 1348 1349 if (ActivityManager.isStartResultSuccessful(result)) { 1350 mInterceptor.onActivityLaunched(targetTask.getTaskInfo(), r); 1351 } 1352 } 1353 1354 /** 1355 * Compute the logical UID based on which the package manager would filter 1356 * app components i.e. based on which the instant app policy would be applied 1357 * because it is the logical calling UID. 1358 * 1359 * @param customCallingUid The UID on whose behalf to make the call. 1360 * @param actualCallingUid The UID actually making the call. 1361 * @param filterCallingUid The UID to be used to filter for instant apps. 1362 * @return The logical UID making the call. 1363 */ computeResolveFilterUid(int customCallingUid, int actualCallingUid, int filterCallingUid)1364 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid, 1365 int filterCallingUid) { 1366 return filterCallingUid != UserHandle.USER_NULL 1367 ? filterCallingUid 1368 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid); 1369 } 1370 1371 /** 1372 * Start an activity while most of preliminary checks has been done and caller has been 1373 * confirmed that holds necessary permissions to do so. 1374 * Here also ensures that the starting activity is removed if the start wasn't successful. 1375 */ startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, @BalCode int balCode, NeededUriGrants intentGrants)1376 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, 1377 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1378 int startFlags, boolean doResume, ActivityOptions options, Task inTask, 1379 TaskFragment inTaskFragment, @BalCode int balCode, 1380 NeededUriGrants intentGrants) { 1381 int result = START_CANCELED; 1382 final Task startedActivityRootTask; 1383 1384 // Create a transition now to record the original intent of actions taken within 1385 // startActivityInner. Otherwise, logic in startActivityInner could start a different 1386 // transition based on a sub-action. 1387 // Only do the create here (and defer requestStart) since startActivityInner might abort. 1388 final TransitionController transitionController = r.mTransitionController; 1389 Transition newTransition = (!transitionController.isCollecting() 1390 && transitionController.getTransitionPlayer() != null) 1391 ? transitionController.createTransition(TRANSIT_OPEN) : null; 1392 RemoteTransition remoteTransition = r.takeRemoteTransition(); 1393 try { 1394 mService.deferWindowLayout(); 1395 transitionController.collect(r); 1396 try { 1397 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner"); 1398 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, 1399 startFlags, doResume, options, inTask, inTaskFragment, balCode, 1400 intentGrants); 1401 } finally { 1402 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 1403 startedActivityRootTask = handleStartResult(r, options, result, newTransition, 1404 remoteTransition); 1405 } 1406 } finally { 1407 mService.continueWindowLayout(); 1408 } 1409 postStartActivityProcessing(r, result, startedActivityRootTask); 1410 1411 return result; 1412 } 1413 1414 /** 1415 * If the start result is success, ensure that the configuration of the started activity matches 1416 * the current display. Otherwise clean up unassociated containers to avoid leakage. 1417 * 1418 * @return the root task where the successful started activity resides. 1419 */ handleStartResult(@onNull ActivityRecord started, ActivityOptions options, int result, Transition newTransition, RemoteTransition remoteTransition)1420 private @Nullable Task handleStartResult(@NonNull ActivityRecord started, 1421 ActivityOptions options, int result, Transition newTransition, 1422 RemoteTransition remoteTransition) { 1423 final boolean userLeaving = mSupervisor.mUserLeaving; 1424 mSupervisor.mUserLeaving = false; 1425 final Task currentRootTask = started.getRootTask(); 1426 final Task startedActivityRootTask = 1427 currentRootTask != null ? currentRootTask : mTargetRootTask; 1428 1429 if (!ActivityManager.isStartResultSuccessful(result) || startedActivityRootTask == null) { 1430 // If we are not able to proceed, disassociate the activity from the task. Leaving an 1431 // activity in an incomplete state can lead to issues, such as performing operations 1432 // without a window container. 1433 if (mStartActivity.getTask() != null) { 1434 mStartActivity.finishIfPossible("startActivity", true /* oomAdj */); 1435 } else if (mStartActivity.getParent() != null) { 1436 mStartActivity.getParent().removeChild(mStartActivity); 1437 } 1438 1439 // Root task should also be detached from display and be removed if it's empty. 1440 if (startedActivityRootTask != null && startedActivityRootTask.isAttached() 1441 && !startedActivityRootTask.hasActivity() 1442 && !startedActivityRootTask.isActivityTypeHome() 1443 && !startedActivityRootTask.mCreatedByOrganizer) { 1444 startedActivityRootTask.removeIfPossible("handleStartResult"); 1445 } 1446 if (newTransition != null) { 1447 newTransition.abort(); 1448 } 1449 return null; 1450 } 1451 1452 // Apply setAlwaysOnTop when starting an activity is successful regardless of creating 1453 // a new Activity or reusing the existing activity. 1454 if (options != null && options.getTaskAlwaysOnTop()) { 1455 startedActivityRootTask.setAlwaysOnTop(true); 1456 } 1457 1458 // If there is no state change (e.g. a resumed activity is reparented to top of 1459 // another display) to trigger a visibility/configuration checking, we have to 1460 // update the configuration for changing to different display. 1461 final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity(); 1462 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) { 1463 mRootWindowContainer.ensureVisibilityAndConfig( 1464 currentTop, currentTop.getDisplayId(), 1465 true /* markFrozenIfConfigChanged */, false /* deferResume */); 1466 } 1467 1468 if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer 1469 .hasVisibleWindowAboveButDoesNotOwnNotificationShade(started.launchedFromUid)) { 1470 // If the UID launching the activity has a visible window on top of the notification 1471 // shade and it's launching an activity that's going to be at the front, we should move 1472 // the shade out of the way so the user can see it. We want to avoid the case where the 1473 // activity is launched on top of a background task which is not moved to the front. 1474 final StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal(); 1475 if (statusBar != null) { 1476 // This results in a async call since the interface is one-way. 1477 statusBar.collapsePanels(); 1478 } 1479 } 1480 1481 // Transition housekeeping. 1482 final TransitionController transitionController = started.mTransitionController; 1483 final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT; 1484 final boolean isTransientLaunch = options != null && options.getTransientLaunch(); 1485 // Start transient launch while keyguard locked and occluded by other app, for this 1486 // condition we would like to play the remote transition without modify any visible state 1487 // for the hierarchy in core, so here will force execute this transition. 1488 final boolean forceTransientTransition = isTransientLaunch && mPriorAboveTask != null 1489 && mDisplayLockAndOccluded; 1490 if (isStarted) { 1491 // The activity is started new rather than just brought forward, so record it as an 1492 // existence change. 1493 transitionController.collectExistenceChange(started); 1494 } else if (result == START_DELIVERED_TO_TOP && newTransition != null 1495 // An activity has changed order/visibility so this isn't just deliver-to-top 1496 && mMovedToTopActivity == null) { 1497 // We just delivered to top, so there isn't an actual transition here. 1498 if (!forceTransientTransition) { 1499 newTransition.abort(); 1500 newTransition = null; 1501 } 1502 } 1503 if (isTransientLaunch) { 1504 if (forceTransientTransition && newTransition != null) { 1505 newTransition.collect(mLastStartActivityRecord); 1506 newTransition.collect(mPriorAboveTask); 1507 } 1508 // `started` isn't guaranteed to be the actual relevant activity, so we must wait 1509 // until after we launched to identify the relevant activity. 1510 transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask); 1511 if (forceTransientTransition && newTransition != null) { 1512 final DisplayContent dc = mLastStartActivityRecord.getDisplayContent(); 1513 // update wallpaper target to TransientHide 1514 dc.mWallpaperController.adjustWallpaperWindows(); 1515 // execute transition because there is no change 1516 newTransition.setReady(dc, true /* ready */); 1517 } 1518 } 1519 if (!userLeaving) { 1520 // no-user-leaving implies not entering PiP. 1521 transitionController.setCanPipOnFinish(false /* canPipOnFinish */); 1522 } 1523 if (newTransition != null) { 1524 transitionController.requestStartTransition(newTransition, 1525 mTargetTask == null ? started.getTask() : mTargetTask, 1526 remoteTransition, null /* displayChange */); 1527 } else if (isStarted) { 1528 // Make the collecting transition wait until this request is ready. 1529 transitionController.setReady(started, false); 1530 } 1531 return startedActivityRootTask; 1532 } 1533 1534 /** 1535 * Start an activity and determine if the activity should be adding to the top of an existing 1536 * task or delivered new intent to an existing activity. Also manipulating the activity task 1537 * onto requested or valid root-task/display. 1538 * 1539 * Note: This method should only be called from {@link #startActivityUnchecked}. 1540 */ 1541 // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner 1542 @VisibleForTesting startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, @BalCode int balCode, NeededUriGrants intentGrants)1543 int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, 1544 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1545 int startFlags, boolean doResume, ActivityOptions options, Task inTask, 1546 TaskFragment inTaskFragment, @BalCode int balCode, 1547 NeededUriGrants intentGrants) { 1548 setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord, 1549 voiceSession, voiceInteractor, balCode); 1550 1551 computeLaunchingTaskFlags(); 1552 mIntent.setFlags(mLaunchFlags); 1553 1554 boolean dreamStopping = false; 1555 1556 for (ActivityRecord stoppingActivity : mSupervisor.mStoppingActivities) { 1557 if (stoppingActivity.getActivityType() 1558 == WindowConfiguration.ACTIVITY_TYPE_DREAM) { 1559 dreamStopping = true; 1560 break; 1561 } 1562 } 1563 1564 // Get top task at beginning because the order may be changed when reusing existing task. 1565 final Task prevTopRootTask = mPreferredTaskDisplayArea.getFocusedRootTask(); 1566 final Task prevTopTask = prevTopRootTask != null ? prevTopRootTask.getTopLeafTask() : null; 1567 final Task reusedTask = getReusableTask(); 1568 1569 // If requested, freeze the task list 1570 if (mOptions != null && mOptions.freezeRecentTasksReordering() 1571 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid) 1572 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) { 1573 mFrozeTaskList = true; 1574 mSupervisor.mRecentTasks.setFreezeTaskListReordering(); 1575 } 1576 1577 // Compute if there is an existing task that should be used for. 1578 final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask(); 1579 final boolean newTask = targetTask == null; 1580 mTargetTask = targetTask; 1581 1582 computeLaunchParams(r, sourceRecord, targetTask); 1583 1584 // Check if starting activity on given task or on a new task is allowed. 1585 int startResult = isAllowedToStart(r, newTask, targetTask); 1586 if (startResult != START_SUCCESS) { 1587 if (r.resultTo != null) { 1588 r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED, 1589 null /* data */, null /* dataGrants */); 1590 } 1591 return startResult; 1592 } 1593 1594 if (targetTask != null) { 1595 mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask()); 1596 } 1597 1598 final ActivityRecord targetTaskTop = newTask 1599 ? null : targetTask.getTopNonFinishingActivity(); 1600 if (targetTaskTop != null) { 1601 // Recycle the target task for this launch. 1602 startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants); 1603 if (startResult != START_SUCCESS) { 1604 return startResult; 1605 } 1606 } else { 1607 mAddingToTask = true; 1608 } 1609 1610 // If the activity being launched is the same as the one currently at the top, then 1611 // we need to check if it should only be launched once. 1612 final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask(); 1613 if (topRootTask != null) { 1614 startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants); 1615 if (startResult != START_SUCCESS) { 1616 return startResult; 1617 } 1618 } 1619 1620 if (mTargetRootTask == null) { 1621 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask, 1622 mOptions); 1623 } 1624 if (newTask) { 1625 final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) 1626 ? mSourceRecord.getTask() : null; 1627 setNewTask(taskToAffiliate); 1628 } else if (mAddingToTask) { 1629 addOrReparentStartingActivity(targetTask, "adding to task"); 1630 } 1631 1632 if (!mAvoidMoveToFront && mDoResume) { 1633 mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask); 1634 if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming() 1635 && !dreamStopping) { 1636 // Launching underneath dream activity (fullscreen, always-on-top). Run the launch- 1637 // -behind transition so the Activity gets created and starts in visible state. 1638 mLaunchTaskBehind = true; 1639 r.mLaunchTaskBehind = true; 1640 } 1641 } 1642 1643 mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, 1644 mStartActivity.getUriPermissionsLocked()); 1645 if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) { 1646 // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs 1647 final PackageManagerInternal pmInternal = 1648 mService.getPackageManagerInternalLocked(); 1649 final int resultToUid = pmInternal.getPackageUid( 1650 mStartActivity.resultTo.info.packageName, 0 /* flags */, 1651 mStartActivity.mUserId); 1652 pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent, 1653 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/, 1654 resultToUid /*visible*/, true /*direct*/); 1655 } 1656 final Task startedTask = mStartActivity.getTask(); 1657 if (newTask) { 1658 EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId); 1659 } 1660 mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask); 1661 1662 mStartActivity.getTaskFragment().clearLastPausedActivity(); 1663 1664 mRootWindowContainer.startPowerModeLaunchIfNeeded( 1665 false /* forceSend */, mStartActivity); 1666 1667 final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded(); 1668 mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch, 1669 mOptions, sourceRecord); 1670 if (mDoResume) { 1671 final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked(); 1672 if (!mTargetRootTask.isTopActivityFocusable() 1673 || (topTaskActivity != null && topTaskActivity.isTaskOverlay() 1674 && mStartActivity != topTaskActivity)) { 1675 // If the activity is not focusable, we can't resume it, but still would like to 1676 // make sure it becomes visible as it starts (this will also trigger entry 1677 // animation). An example of this are PIP activities. 1678 // Also, we don't want to resume activities in a task that currently has an overlay 1679 // as the starting activity just needs to be in the visible paused state until the 1680 // over is removed. 1681 // Passing {@code null} as the start parameter ensures all activities are made 1682 // visible. 1683 mTargetRootTask.ensureActivitiesVisible(null /* starting */, 1684 0 /* configChanges */, !PRESERVE_WINDOWS); 1685 // Go ahead and tell window manager to execute app transition for this activity 1686 // since the app transition will not be triggered through the resume channel. 1687 mTargetRootTask.mDisplayContent.executeAppTransition(); 1688 } else { 1689 // If the target root-task was not previously focusable (previous top running 1690 // activity on that root-task was not visible) then any prior calls to move the 1691 // root-task to the will not update the focused root-task. If starting the new 1692 // activity now allows the task root-task to be focusable, then ensure that we 1693 // now update the focused root-task accordingly. 1694 if (mTargetRootTask.isTopActivityFocusable() 1695 && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) { 1696 mTargetRootTask.moveToFront("startActivityInner"); 1697 } 1698 mRootWindowContainer.resumeFocusedTasksTopActivities( 1699 mTargetRootTask, mStartActivity, mOptions, mTransientLaunch); 1700 } 1701 } 1702 mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask); 1703 1704 // Update the recent tasks list immediately when the activity starts 1705 mSupervisor.mRecentTasks.add(startedTask); 1706 mSupervisor.handleNonResizableTaskIfNeeded(startedTask, 1707 mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask); 1708 1709 // If Activity's launching into PiP, move the mStartActivity immediately to pinned mode. 1710 // Note that mStartActivity and source should be in the same Task at this point. 1711 if (mOptions != null && mOptions.isLaunchIntoPip() 1712 && sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask() 1713 && balCode != BAL_BLOCK) { 1714 mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity, 1715 sourceRecord, "launch-into-pip"); 1716 } 1717 1718 return START_SUCCESS; 1719 } 1720 1721 /** Returns the leaf task where the target activity may be placed. */ computeTargetTask()1722 private Task computeTargetTask() { 1723 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask 1724 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 1725 // A new task should be created instead of using existing one. 1726 return null; 1727 } else if (mSourceRecord != null) { 1728 return mSourceRecord.getTask(); 1729 } else if (mInTask != null) { 1730 // The task is specified from AppTaskImpl, so it may not be attached yet. 1731 if (!mInTask.isAttached()) { 1732 // Attach the task to display area. Ignore the returned root task (though usually 1733 // they are the same) because "target task" should be leaf task. 1734 getOrCreateRootTask(mStartActivity, mLaunchFlags, mInTask, mOptions); 1735 } 1736 return mInTask; 1737 } else { 1738 final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */, 1739 mOptions); 1740 final ActivityRecord top = rootTask.getTopNonFinishingActivity(); 1741 if (top != null) { 1742 return top.getTask(); 1743 } else { 1744 // Remove the root task if no activity in the root task. 1745 rootTask.removeIfPossible("computeTargetTask"); 1746 } 1747 } 1748 return null; 1749 } 1750 computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, Task targetTask)1751 private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, 1752 Task targetTask) { 1753 mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r, 1754 sourceRecord, mOptions, mRequest, PHASE_BOUNDS, mLaunchParams); 1755 mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() 1756 ? mLaunchParams.mPreferredTaskDisplayArea 1757 : mRootWindowContainer.getDefaultTaskDisplayArea(); 1758 mPreferredWindowingMode = mLaunchParams.mWindowingMode; 1759 } 1760 1761 @VisibleForTesting isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask)1762 int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) { 1763 if (r.packageName == null) { 1764 ActivityOptions.abort(mOptions); 1765 return START_CLASS_NOT_FOUND; 1766 } 1767 1768 // Do not start home activity if it cannot be launched on preferred display. We are not 1769 // doing this in ActivityTaskSupervisor#canPlaceEntityOnDisplay because it might 1770 // fallback to launch on other displays. 1771 if (r.isActivityTypeHome()) { 1772 if (!mRootWindowContainer.canStartHomeOnDisplayArea(r.info, mPreferredTaskDisplayArea, 1773 true /* allowInstrumenting */)) { 1774 Slog.w(TAG, "Cannot launch home on display area " + mPreferredTaskDisplayArea); 1775 return START_CANCELED; 1776 } 1777 } 1778 1779 // Do not allow background activity start in new task or in a task that uid is not present. 1780 // Also do not allow pinned window to start single instance activity in background, 1781 // as it will recreate the window and makes it to foreground. 1782 boolean blockBalInTask = (newTask 1783 || !targetTask.isUidPresent(mCallingUid) 1784 || (LAUNCH_SINGLE_INSTANCE == mLaunchMode && targetTask.inPinnedWindowingMode())); 1785 1786 if (mBalCode == BAL_BLOCK && blockBalInTask 1787 && handleBackgroundActivityAbort(r)) { 1788 Slog.e(TAG, "Abort background activity starts from " + mCallingUid); 1789 return START_ABORTED; 1790 } 1791 1792 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still 1793 // needs to be a lock task mode violation since the task gets cleared out and the device 1794 // would otherwise leave the locked task. 1795 final boolean isNewClearTask = 1796 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 1797 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); 1798 if (!newTask) { 1799 if (mService.getLockTaskController().isLockTaskModeViolation(targetTask, 1800 isNewClearTask)) { 1801 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1802 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 1803 } 1804 } else { 1805 if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(r)) { 1806 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1807 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 1808 } 1809 } 1810 1811 // Do not start the activity if target display's DWPC does not allow it. 1812 // We can't return fatal error code here because it will crash the caller of 1813 // startActivity() if they don't catch the exception. We don't expect 3P apps to make 1814 // changes. 1815 if (mPreferredTaskDisplayArea != null) { 1816 final DisplayContent displayContent = mRootWindowContainer.getDisplayContentOrCreate( 1817 mPreferredTaskDisplayArea.getDisplayId()); 1818 if (displayContent != null && displayContent.mDwpcHelper.hasController()) { 1819 final int targetWindowingMode = (targetTask != null) 1820 ? targetTask.getWindowingMode() : displayContent.getWindowingMode(); 1821 final int launchingFromDisplayId = 1822 mSourceRecord != null ? mSourceRecord.getDisplayId() : DEFAULT_DISPLAY; 1823 if (!displayContent.mDwpcHelper 1824 .canActivityBeLaunched(r.info, targetWindowingMode, launchingFromDisplayId, 1825 newTask)) { 1826 Slog.w(TAG, "Abort to launch " + r.info.getComponentName() 1827 + " on display area " + mPreferredTaskDisplayArea); 1828 return START_ABORTED; 1829 } 1830 } 1831 } 1832 1833 // Log activity starts which violate one of the following rules of the 1834 // activity security model (ASM): 1835 // 1. Only the top activity on a task can start activities on that task 1836 // 2. Only the top activity on the top task can create new (top) tasks 1837 // We don't currently block, but these checks may later become blocks 1838 // TODO(b/236234252): Shift to BackgroundActivityStartController once 1839 // class is ready 1840 if (mSourceRecord != null) { 1841 int callerUid = mSourceRecord.getUid(); 1842 ActivityRecord targetTopActivity = 1843 targetTask != null ? targetTask.getTopNonFinishingActivity() : null; 1844 boolean passesAsmChecks = newTask 1845 ? mService.mVisibleActivityProcessTracker.hasResumedActivity(callerUid) 1846 : targetTopActivity != null && targetTopActivity.getUid() == callerUid; 1847 1848 if (!passesAsmChecks) { 1849 Slog.i(TAG, "Launching r: " + r 1850 + " from background: " + mSourceRecord 1851 + ". New task: " + newTask); 1852 boolean newOrEmptyTask = newTask || (targetTopActivity == null); 1853 FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, 1854 /* caller_uid */ 1855 callerUid, 1856 /* caller_activity_class_name */ 1857 mSourceRecord.info.name, 1858 /* target_task_top_activity_uid */ 1859 newOrEmptyTask ? -1 : targetTopActivity.getUid(), 1860 /* target_task_top_activity_class_name */ 1861 newOrEmptyTask ? null : targetTopActivity.info.name, 1862 /* target_task_is_different */ 1863 newTask || !mSourceRecord.getTask().equals(targetTask), 1864 /* target_activity_uid */ 1865 r.getUid(), 1866 /* target_activity_class_name */ 1867 r.info.name, 1868 /* target_intent_action */ 1869 r.intent.getAction(), 1870 /* target_intent_flags */ 1871 r.intent.getFlags() 1872 ); 1873 } 1874 } 1875 1876 return START_SUCCESS; 1877 } 1878 1879 /** 1880 * Returns whether embedding of {@code starting} is allowed. 1881 * 1882 * @param taskFragment the TaskFragment for embedding. 1883 * @param starting the starting activity. 1884 * @param targetTask the target task for launching activity, which could be different from 1885 * the one who hosting the embedding. 1886 */ 1887 @VisibleForTesting 1888 @EmbeddingCheckResult canEmbedActivity(@onNull TaskFragment taskFragment, @NonNull ActivityRecord starting, @NonNull Task targetTask)1889 static int canEmbedActivity(@NonNull TaskFragment taskFragment, 1890 @NonNull ActivityRecord starting, @NonNull Task targetTask) { 1891 final Task hostTask = taskFragment.getTask(); 1892 // Not allowed embedding a separate task or without host task. 1893 if (hostTask == null || targetTask != hostTask) { 1894 return EMBEDDING_DISALLOWED_NEW_TASK; 1895 } 1896 1897 return taskFragment.isAllowedToEmbedActivity(starting); 1898 } 1899 1900 /** 1901 * Prepare the target task to be reused for this launch, which including: 1902 * - Position the target task on valid root task on preferred display. 1903 * - Comply to the specified activity launch flags 1904 * - Determine whether need to add a new activity on top or just brought the task to front. 1905 */ 1906 @VisibleForTesting recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, NeededUriGrants intentGrants)1907 int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, 1908 NeededUriGrants intentGrants) { 1909 // Should not recycle task which is from a different user, just adding the starting 1910 // activity to the task. 1911 if (targetTask.mUserId != mStartActivity.mUserId) { 1912 mTargetRootTask = targetTask.getRootTask(); 1913 mAddingToTask = true; 1914 return START_SUCCESS; 1915 } 1916 1917 if (reusedTask != null) { 1918 if (targetTask.intent == null) { 1919 // This task was started because of movement of the activity based on 1920 // affinity... 1921 // Now that we are actually launching it, we can assign the base intent. 1922 targetTask.setIntent(mStartActivity); 1923 } else { 1924 final boolean taskOnHome = 1925 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0; 1926 if (taskOnHome) { 1927 targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME); 1928 } else { 1929 targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME); 1930 } 1931 } 1932 } 1933 1934 mRootWindowContainer.startPowerModeLaunchIfNeeded(false /* forceSend */, 1935 targetTaskTop); 1936 1937 setTargetRootTaskIfNeeded(targetTaskTop); 1938 1939 // When there is a reused activity and the current result is a trampoline activity, 1940 // set the reused activity as the result. 1941 if (mLastStartActivityRecord != null 1942 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) { 1943 mLastStartActivityRecord = targetTaskTop; 1944 } 1945 1946 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 1947 // We don't need to start a new activity, and the client said not to do anything 1948 // if that is the case, so this is it! And for paranoia, make sure we have 1949 // correctly resumed the top activity. 1950 if (!mMovedToFront && mDoResume) { 1951 ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetRootTask, 1952 targetTaskTop); 1953 mTargetRootTask.moveToFront("intentActivityFound"); 1954 } 1955 resumeTargetRootTaskIfNeeded(); 1956 return START_RETURN_INTENT_TO_CALLER; 1957 } 1958 1959 complyActivityFlags(targetTask, 1960 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants); 1961 1962 if (mAddingToTask) { 1963 return START_SUCCESS; 1964 } 1965 1966 // The reusedActivity could be finishing, for example of starting an activity with 1967 // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, use the top running activity in the 1968 // task instead. 1969 targetTaskTop = targetTaskTop.finishing 1970 ? targetTask.getTopNonFinishingActivity() 1971 : targetTaskTop; 1972 1973 if (mMovedToFront) { 1974 // We moved the task to front, use starting window to hide initial drawn delay. 1975 targetTaskTop.showStartingWindow(true /* taskSwitch */); 1976 } else if (mDoResume) { 1977 // Make sure the root task and its belonging display are moved to topmost. 1978 mTargetRootTask.moveToFront("intentActivityFound"); 1979 } 1980 // We didn't do anything... but it was needed (a.k.a., client don't use that intent!) 1981 // And for paranoia, make sure we have correctly resumed the top activity. 1982 resumeTargetRootTaskIfNeeded(); 1983 1984 // This is moving an existing task to front. But since dream activity has a higher z-order 1985 // to cover normal activities, it needs the awakening event to be dismissed. 1986 if (mService.isDreaming() && targetTaskTop.canTurnScreenOn()) { 1987 targetTaskTop.mTaskSupervisor.wakeUp("recycleTask#turnScreenOnFlag"); 1988 } 1989 1990 mLastStartActivityRecord = targetTaskTop; 1991 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP; 1992 } 1993 1994 /** 1995 * Check if the activity being launched is the same as the one currently at the top and it 1996 * should only be launched once. 1997 */ deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants)1998 private int deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants) { 1999 final ActivityRecord top = topRootTask.topRunningNonDelayedActivityLocked(mNotTop); 2000 final boolean dontStart = top != null 2001 && top.mActivityComponent.equals(mStartActivity.mActivityComponent) 2002 && top.mUserId == mStartActivity.mUserId 2003 && top.attachedToProcess() 2004 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 2005 || LAUNCH_SINGLE_TOP == mLaunchMode) 2006 // This allows home activity to automatically launch on secondary task display area 2007 // when it was added, if home was the top activity on default task display area, 2008 // instead of sending new intent to the home activity on default display area. 2009 && (!top.isActivityTypeHome() || top.getDisplayArea() == mPreferredTaskDisplayArea); 2010 if (!dontStart) { 2011 return START_SUCCESS; 2012 } 2013 2014 // For paranoia, make sure we have correctly resumed the top activity. 2015 top.getTaskFragment().clearLastPausedActivity(); 2016 if (mDoResume) { 2017 mRootWindowContainer.resumeFocusedTasksTopActivities(); 2018 } 2019 ActivityOptions.abort(mOptions); 2020 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 2021 // We don't need to start a new activity, and the client said not to do anything if 2022 // that is the case, so this is it! 2023 return START_RETURN_INTENT_TO_CALLER; 2024 } 2025 2026 if (mStartActivity.resultTo != null) { 2027 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho, 2028 mStartActivity.requestCode, RESULT_CANCELED, 2029 null /* data */, null /* dataGrants */); 2030 mStartActivity.resultTo = null; 2031 } 2032 2033 deliverNewIntent(top, intentGrants); 2034 2035 // Don't use mStartActivity.task to show the toast. We're not starting a new activity but 2036 // reusing 'top'. Fields in mStartActivity may not be fully initialized. 2037 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), 2038 mLaunchParams.mWindowingMode, mPreferredTaskDisplayArea, topRootTask); 2039 2040 return START_DELIVERED_TO_TOP; 2041 } 2042 2043 /** 2044 * Applying the launching flags to the task, which might clear few or all the activities in the 2045 * task. 2046 */ complyActivityFlags(Task targetTask, ActivityRecord reusedActivity, NeededUriGrants intentGrants)2047 private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity, 2048 NeededUriGrants intentGrants) { 2049 ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity(); 2050 final boolean resetTask = 2051 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0; 2052 if (resetTask) { 2053 targetTaskTop = mTargetRootTask.resetTaskIfNeeded(targetTaskTop, mStartActivity); 2054 } 2055 2056 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 2057 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) { 2058 // The caller has requested to completely replace any existing task with its new 2059 // activity. Well that should not be too hard... 2060 // Note: we must persist the {@link Task} first as intentActivity could be 2061 // removed from calling performClearTaskLocked (For example, if it is being brought out 2062 // of history or if it is finished immediately), thus disassociating the task. Keep the 2063 // task-overlay activity because the targetTask will be reused to launch new activity. 2064 targetTask.performClearTaskForReuse(true /* excludingTaskOverlay*/); 2065 targetTask.setIntent(mStartActivity); 2066 mAddingToTask = true; 2067 mIsTaskCleared = true; 2068 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 2069 || isDocumentLaunchesIntoExisting(mLaunchFlags) 2070 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK, 2071 LAUNCH_SINGLE_INSTANCE_PER_TASK)) { 2072 // In this situation we want to remove all activities from the task up to the one 2073 // being started. In most cases this means we are resetting the task to its initial 2074 // state. 2075 int[] finishCount = new int[1]; 2076 final ActivityRecord clearTop = targetTask.performClearTop(mStartActivity, 2077 mLaunchFlags, finishCount); 2078 2079 if (clearTop != null && !clearTop.finishing) { 2080 if (finishCount[0] > 0) { 2081 // Only record if actually moved to top. 2082 mMovedToTopActivity = clearTop; 2083 } 2084 if (clearTop.isRootOfTask()) { 2085 // Activity aliases may mean we use different intents for the top activity, 2086 // so make sure the task now has the identity of the new intent. 2087 clearTop.getTask().setIntent(mStartActivity); 2088 } 2089 deliverNewIntent(clearTop, intentGrants); 2090 } else { 2091 // A special case: we need to start the activity because it is not currently 2092 // running, and the caller has asked to clear the current task to have this 2093 // activity at the top. 2094 mAddingToTask = true; 2095 // Adding the new activity to the same embedded TF of the clear-top activity if 2096 // possible. 2097 if (clearTop != null && clearTop.getTaskFragment() != null 2098 && clearTop.getTaskFragment().isEmbedded()) { 2099 mAddingToTaskFragment = clearTop.getTaskFragment(); 2100 } 2101 if (targetTask.getRootTask() == null) { 2102 // Target root task got cleared when we all activities were removed above. 2103 // Go ahead and reset it. 2104 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, 2105 null /* task */, mOptions); 2106 mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */, 2107 (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0); 2108 } 2109 } 2110 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask 2111 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 2112 // In this case, we are launching an activity in our own task that may 2113 // already be running somewhere in the history, and we want to shuffle it to 2114 // the front of the root task if so. 2115 final ActivityRecord act = 2116 targetTask.findActivityInHistory(mStartActivity.mActivityComponent, 2117 mStartActivity.mUserId); 2118 if (act != null) { 2119 final Task task = act.getTask(); 2120 boolean actuallyMoved = task.moveActivityToFront(act); 2121 if (actuallyMoved) { 2122 // Only record if the activity actually moved. 2123 mMovedToTopActivity = act; 2124 if (mNoAnimation) { 2125 act.mDisplayContent.prepareAppTransition(TRANSIT_NONE); 2126 } else { 2127 act.mDisplayContent.prepareAppTransition(TRANSIT_TO_FRONT); 2128 } 2129 } 2130 act.updateOptionsLocked(mOptions); 2131 deliverNewIntent(act, intentGrants); 2132 act.getTaskFragment().clearLastPausedActivity(); 2133 } else { 2134 mAddingToTask = true; 2135 } 2136 } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) { 2137 if (targetTask == mInTask) { 2138 // In this case we are bringing up an existing activity from a recent task. We 2139 // don't need to add a new activity instance on top. 2140 } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 2141 || LAUNCH_SINGLE_TOP == mLaunchMode) 2142 && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent) 2143 && mStartActivity.resultTo == null) { 2144 // In this case the top activity on the task is the same as the one being launched, 2145 // so we take that as a request to bring the task to the foreground. If the top 2146 // activity in the task is the root activity, deliver this new intent to it if it 2147 // desires. 2148 if (targetTaskTop.isRootOfTask()) { 2149 targetTaskTop.getTask().setIntent(mStartActivity); 2150 } 2151 deliverNewIntent(targetTaskTop, intentGrants); 2152 } else if (!targetTask.isSameIntentFilter(mStartActivity)) { 2153 // In this case we are launching the root activity of the task, but with a 2154 // different intent. We should start a new instance on top. 2155 mAddingToTask = true; 2156 } else if (reusedActivity == null) { 2157 mAddingToTask = true; 2158 } 2159 } else if (!resetTask) { 2160 // In this case an activity is being launched in to an existing task, without 2161 // resetting that task. This is typically the situation of launching an activity 2162 // from a notification or shortcut. We want to place the new activity on top of the 2163 // current task. 2164 mAddingToTask = true; 2165 } else if (!targetTask.rootWasReset) { 2166 // In this case we are launching into an existing task that has not yet been started 2167 // from its front door. The current task has been brought to the front. Ideally, 2168 // we'd probably like to place this new task at the bottom of its root task, but that's 2169 // a little hard to do with the current organization of the code so for now we'll 2170 // just drop it. 2171 targetTask.setIntent(mStartActivity); 2172 } 2173 } 2174 2175 /** 2176 * Resets the {@link ActivityStarter} state. 2177 * @param clearRequest whether the request should be reset to default values. 2178 */ reset(boolean clearRequest)2179 void reset(boolean clearRequest) { 2180 mStartActivity = null; 2181 mIntent = null; 2182 mCallingUid = -1; 2183 mOptions = null; 2184 mBalCode = BAL_ALLOW_DEFAULT; 2185 2186 mLaunchTaskBehind = false; 2187 mLaunchFlags = 0; 2188 mLaunchMode = INVALID_LAUNCH_MODE; 2189 2190 mLaunchParams.reset(); 2191 2192 mNotTop = null; 2193 mDoResume = false; 2194 mStartFlags = 0; 2195 mSourceRecord = null; 2196 mPreferredTaskDisplayArea = null; 2197 mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED; 2198 2199 mInTask = null; 2200 mInTaskFragment = null; 2201 mAddingToTaskFragment = null; 2202 mAddingToTask = false; 2203 2204 mSourceRootTask = null; 2205 2206 mTargetRootTask = null; 2207 mTargetTask = null; 2208 mIsTaskCleared = false; 2209 mMovedToFront = false; 2210 mNoAnimation = false; 2211 mAvoidMoveToFront = false; 2212 mFrozeTaskList = false; 2213 mTransientLaunch = false; 2214 mDisplayLockAndOccluded = false; 2215 2216 mVoiceSession = null; 2217 mVoiceInteractor = null; 2218 2219 mIntentDelivered = false; 2220 2221 if (clearRequest) { 2222 mRequest.reset(); 2223 } 2224 } 2225 setInitialState(ActivityRecord r, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, boolean doResume, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, @BalCode int balCode)2226 private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask, 2227 TaskFragment inTaskFragment, boolean doResume, int startFlags, 2228 ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, 2229 IVoiceInteractor voiceInteractor, @BalCode int balCode) { 2230 reset(false /* clearRequest */); 2231 2232 mStartActivity = r; 2233 mIntent = r.intent; 2234 mOptions = options; 2235 mCallingUid = r.launchedFromUid; 2236 mSourceRecord = sourceRecord; 2237 mSourceRootTask = mSourceRecord != null ? mSourceRecord.getRootTask() : null; 2238 mVoiceSession = voiceSession; 2239 mVoiceInteractor = voiceInteractor; 2240 mBalCode = balCode; 2241 2242 mLaunchParams.reset(); 2243 2244 // Preferred display id is the only state we need for now and it could be updated again 2245 // after we located a reusable task (which might be resided in another display). 2246 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r, 2247 sourceRecord, options, mRequest, PHASE_DISPLAY, mLaunchParams); 2248 mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() 2249 ? mLaunchParams.mPreferredTaskDisplayArea 2250 : mRootWindowContainer.getDefaultTaskDisplayArea(); 2251 mPreferredWindowingMode = mLaunchParams.mWindowingMode; 2252 2253 mLaunchMode = r.launchMode; 2254 2255 mLaunchFlags = adjustLaunchFlagsToDocumentMode( 2256 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode, 2257 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags()); 2258 mLaunchTaskBehind = r.mLaunchTaskBehind 2259 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE) 2260 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0; 2261 2262 if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) { 2263 // Adding NEW_TASK flag for singleInstancePerTask launch mode activity, so that the 2264 // activity won't be launched in source record's task. 2265 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2266 } 2267 2268 sendNewTaskResultRequestIfNeeded(); 2269 2270 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) { 2271 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2272 } 2273 2274 // If we are actually going to launch in to a new task, there are some cases where 2275 // we further want to do multiple task. 2276 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 2277 if (mLaunchTaskBehind 2278 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) { 2279 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK; 2280 } 2281 } 2282 2283 // We'll invoke onUserLeaving before onPause only if the launching 2284 // activity did not explicitly state that this is an automated launch. 2285 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0; 2286 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, 2287 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving); 2288 2289 // If the caller has asked not to resume at this point, we make note 2290 // of this in the record so that we can skip it when trying to find 2291 // the top running activity. 2292 mDoResume = doResume; 2293 if (!doResume || !r.showToCurrentUser() || mLaunchTaskBehind) { 2294 r.delayedResume = true; 2295 mDoResume = false; 2296 } 2297 2298 if (mOptions != null) { 2299 if (mOptions.getLaunchTaskId() != INVALID_TASK_ID && mOptions.getTaskOverlay()) { 2300 r.setTaskOverlay(true); 2301 if (!mOptions.canTaskOverlayResume()) { 2302 final Task task = mRootWindowContainer.anyTaskForId( 2303 mOptions.getLaunchTaskId()); 2304 final ActivityRecord top = task != null 2305 ? task.getTopNonFinishingActivity() : null; 2306 if (top != null && !top.isState(RESUMED)) { 2307 2308 // The caller specifies that we'd like to be avoided to be moved to the 2309 // front, so be it! 2310 mDoResume = false; 2311 mAvoidMoveToFront = true; 2312 } 2313 } 2314 } else if (mOptions.getAvoidMoveToFront()) { 2315 mDoResume = false; 2316 mAvoidMoveToFront = true; 2317 } 2318 mTransientLaunch = mOptions.getTransientLaunch(); 2319 final KeyguardController kc = mSupervisor.getKeyguardController(); 2320 final int displayId = mPreferredTaskDisplayArea.getDisplayId(); 2321 mDisplayLockAndOccluded = kc.isKeyguardLocked(displayId) 2322 && kc.isDisplayOccluded(displayId); 2323 // Recents animation on lock screen, do not resume & move launcher to top. 2324 if (mTransientLaunch && mDisplayLockAndOccluded 2325 && mService.getTransitionController().isShellTransitionsEnabled()) { 2326 mDoResume = false; 2327 mAvoidMoveToFront = true; 2328 } 2329 mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); 2330 2331 if (inTaskFragment == null) { 2332 inTaskFragment = TaskFragment.fromTaskFragmentToken( 2333 mOptions.getLaunchTaskFragmentToken(), mService); 2334 if (inTaskFragment != null && inTaskFragment.isEmbeddedTaskFragmentInPip()) { 2335 // Do not start activity in TaskFragment in a PIP Task. 2336 Slog.w(TAG, "Can not start activity in TaskFragment in PIP: " 2337 + inTaskFragment); 2338 inTaskFragment = null; 2339 } 2340 } 2341 } 2342 2343 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null; 2344 2345 mInTask = inTask; 2346 // In some flows in to this function, we retrieve the task record and hold on to it 2347 // without a lock before calling back in to here... so the task at this point may 2348 // not actually be in recents. Check for that, and if it isn't in recents just 2349 // consider it invalid. 2350 if (inTask != null && !inTask.inRecents) { 2351 Slog.w(TAG, "Starting activity in task not in recents: " + inTask); 2352 mInTask = null; 2353 } 2354 mInTaskFragment = inTaskFragment; 2355 2356 mStartFlags = startFlags; 2357 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched 2358 // is the same as the one making the call... or, as a special case, if we do not know 2359 // the caller then we count the current top activity as the caller. 2360 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 2361 ActivityRecord checkedCaller = sourceRecord; 2362 if (checkedCaller == null) { 2363 Task topFocusedRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); 2364 if (topFocusedRootTask != null) { 2365 checkedCaller = topFocusedRootTask.topRunningNonDelayedActivityLocked(mNotTop); 2366 } 2367 } 2368 if (checkedCaller == null 2369 || !checkedCaller.mActivityComponent.equals(r.mActivityComponent)) { 2370 // Caller is not the same as launcher, so always needed. 2371 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED; 2372 } 2373 } 2374 2375 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; 2376 2377 if (mBalCode == BAL_BLOCK && !mService.isBackgroundActivityStartsEnabled()) { 2378 mAvoidMoveToFront = true; 2379 mDoResume = false; 2380 } 2381 } 2382 sendNewTaskResultRequestIfNeeded()2383 private void sendNewTaskResultRequestIfNeeded() { 2384 if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 2385 // For whatever reason this activity is being launched into a new task... 2386 // yet the caller has requested a result back. Well, that is pretty messed up, 2387 // so instead immediately send back a cancel and let the new task continue launched 2388 // as normal without a dependency on its originator. 2389 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 2390 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho, 2391 mStartActivity.requestCode, RESULT_CANCELED, 2392 null /* data */, null /* dataGrants */); 2393 mStartActivity.resultTo = null; 2394 } 2395 } 2396 computeLaunchingTaskFlags()2397 private void computeLaunchingTaskFlags() { 2398 // If the caller is not coming from another activity, but has given us an explicit task into 2399 // which they would like us to launch the new activity, then let's see about doing that. 2400 if (mSourceRecord == null && mInTask != null && mInTask.getRootTask() != null) { 2401 final Intent baseIntent = mInTask.getBaseIntent(); 2402 final ActivityRecord root = mInTask.getRootActivity(); 2403 if (baseIntent == null) { 2404 ActivityOptions.abort(mOptions); 2405 throw new IllegalArgumentException("Launching into task without base intent: " 2406 + mInTask); 2407 } 2408 2409 // If this task is empty, then we are adding the first activity -- it 2410 // determines the root, and must be launching as a NEW_TASK. 2411 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { 2412 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) { 2413 ActivityOptions.abort(mOptions); 2414 throw new IllegalArgumentException("Trying to launch singleInstance/Task " 2415 + mStartActivity + " into different task " + mInTask); 2416 } 2417 if (root != null) { 2418 ActivityOptions.abort(mOptions); 2419 throw new IllegalArgumentException("Caller with mInTask " + mInTask 2420 + " has root " + root + " but target is singleInstance/Task"); 2421 } 2422 } 2423 2424 // If task is empty, then adopt the interesting intent launch flags in to the 2425 // activity being started. 2426 if (root == null) { 2427 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK 2428 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS; 2429 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest) 2430 | (baseIntent.getFlags() & flagsOfInterest); 2431 mIntent.setFlags(mLaunchFlags); 2432 mInTask.setIntent(mStartActivity); 2433 mAddingToTask = true; 2434 2435 // If the task is not empty and the caller is asking to start it as the root of 2436 // a new task, then we don't actually want to start this on the task. We will 2437 // bring the task to the front, and possibly give it a new intent. 2438 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 2439 mAddingToTask = false; 2440 2441 } else { 2442 mAddingToTask = true; 2443 } 2444 } else { 2445 mInTask = null; 2446 // Launch ResolverActivity in the source task, so that it stays in the task bounds 2447 // when in freeform workspace. 2448 // Also put noDisplay activities in the source task. These by itself can be placed 2449 // in any task/root-task, however it could launch other activities like 2450 // ResolverActivity, and we want those to stay in the original task. 2451 if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay) 2452 && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) { 2453 mAddingToTask = true; 2454 } 2455 } 2456 2457 if (mInTask == null) { 2458 if (mSourceRecord == null) { 2459 // This activity is not being started from another... in this 2460 // case we -always- start a new task. 2461 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) { 2462 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 2463 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent); 2464 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2465 } 2466 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) { 2467 // The original activity who is starting us is running as a single 2468 // instance... this new activity it is starting must go on its 2469 // own task. 2470 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2471 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { 2472 // The activity being started is a single instance... it always 2473 // gets launched into its own task. 2474 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2475 } 2476 } 2477 2478 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0 2479 && ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 || mSourceRecord == null)) { 2480 // ignore the flag if there is no the sourceRecord or without new_task flag 2481 mLaunchFlags &= ~FLAG_ACTIVITY_LAUNCH_ADJACENT; 2482 } 2483 } 2484 2485 /** 2486 * Decide whether the new activity should be inserted into an existing task. Returns null 2487 * if not or an ActivityRecord with the task into which the new activity should be added. 2488 */ getReusableTask()2489 private Task getReusableTask() { 2490 // If a target task is specified, try to reuse that one 2491 if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) { 2492 Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId()); 2493 if (launchTask != null) { 2494 return launchTask; 2495 } 2496 return null; 2497 } 2498 2499 // We may want to try to place the new activity in to an existing task. We always 2500 // do this if the target activity is singleTask or singleInstance; we will also do 2501 // this if NEW_TASK has been requested, and there is not an additional qualifier telling 2502 // us to still place it in a new task: multi task, always doc mode, or being asked to 2503 // launch this as a new task behind the current one. 2504 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 && 2505 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 2506 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK); 2507 // If bring to front is requested, and no result is requested and we have not been given 2508 // an explicit task to launch in to, and we can find a task that was started with this 2509 // same component, then instead of launching bring that one to the front. 2510 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null; 2511 ActivityRecord intentActivity = null; 2512 if (putIntoExistingTask) { 2513 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) { 2514 // There can be one and only one instance of single instance activity in the 2515 // history, and it is always in its own unique task, so we do a special search. 2516 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info, 2517 mStartActivity.isActivityTypeHome()); 2518 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) { 2519 // For the launch adjacent case we only want to put the activity in an existing 2520 // task if the activity already exists in the history. 2521 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info, 2522 !(LAUNCH_SINGLE_TASK == mLaunchMode)); 2523 } else { 2524 // Otherwise find the best task to put the activity in. 2525 intentActivity = 2526 mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea); 2527 } 2528 } 2529 2530 if (intentActivity != null && mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK 2531 && !intentActivity.getTask().getRootActivity().mActivityComponent.equals( 2532 mStartActivity.mActivityComponent)) { 2533 // The task could be selected due to same task affinity. Do not reuse the task while 2534 // starting the singleInstancePerTask activity if it is not the task root activity. 2535 intentActivity = null; 2536 } 2537 2538 if (intentActivity != null 2539 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome()) 2540 && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) { 2541 // Do not reuse home activity on other display areas. 2542 intentActivity = null; 2543 } 2544 2545 return intentActivity != null ? intentActivity.getTask() : null; 2546 } 2547 2548 /** 2549 * Figure out which task and activity to bring to front when we have found an existing matching 2550 * activity record in history. May also clear the task if needed. 2551 * 2552 * @param intentActivity Existing matching activity. 2553 * @return {@link ActivityRecord} brought to front. 2554 */ setTargetRootTaskIfNeeded(ActivityRecord intentActivity)2555 private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) { 2556 intentActivity.getTaskFragment().clearLastPausedActivity(); 2557 Task intentTask = intentActivity.getTask(); 2558 2559 if (mTargetRootTask == null) { 2560 // Update launch target task when it is not indicated. 2561 if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) { 2562 // Inherit the target-root-task from source to ensure trampoline activities will be 2563 // launched into the same root task. 2564 mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask); 2565 } else { 2566 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask, 2567 mOptions); 2568 } 2569 } 2570 2571 // If the matching task is already in the adjacent task of the launch target. Adjust to use 2572 // the adjacent task as its launch target. So the existing task will be launched into the 2573 // closer one and won't be reparent redundantly. 2574 final Task adjacentTargetTask = mTargetRootTask.getAdjacentTaskFragment() != null 2575 ? mTargetRootTask.getAdjacentTaskFragment().asTask() : null; 2576 if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)) { 2577 mTargetRootTask = adjacentTargetTask; 2578 } 2579 2580 // If the target task is not in the front, then we need to bring it to the front... 2581 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have 2582 // the same behavior as if a new instance was being started, which means not bringing it 2583 // to the front if the caller is not itself in the front. 2584 final boolean differentTopTask; 2585 if (mTargetRootTask.getDisplayArea() == mPreferredTaskDisplayArea) { 2586 final Task focusRootTask = mTargetRootTask.mDisplayContent.getFocusedRootTask(); 2587 final ActivityRecord curTop = (focusRootTask == null) 2588 ? null : focusRootTask.topRunningNonDelayedActivityLocked(mNotTop); 2589 final Task topTask = curTop != null ? curTop.getTask() : null; 2590 differentTopTask = topTask != intentTask 2591 || (focusRootTask != null && topTask != focusRootTask.getTopMostTask()); 2592 } else { 2593 // The existing task should always be different from those in other displays. 2594 differentTopTask = true; 2595 } 2596 2597 if (differentTopTask && !mAvoidMoveToFront) { 2598 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 2599 // TODO(b/264487981): Consider using BackgroundActivityStartController to determine 2600 // whether to bring the launching activity to the front. 2601 if (mSourceRecord == null || inTopNonFinishingTask(mSourceRecord)) { 2602 // We really do want to push this one into the user's face, right now. 2603 if (mLaunchTaskBehind && mSourceRecord != null) { 2604 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask()); 2605 } 2606 2607 if (intentActivity.isDescendantOf(mTargetRootTask)) { 2608 // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels 2609 // tasks hierarchies. 2610 if (mTargetRootTask != intentTask 2611 && mTargetRootTask != intentTask.getParent().asTask()) { 2612 intentTask.getParent().positionChildAt(POSITION_TOP, intentTask, 2613 false /* includingParents */); 2614 intentTask = intentTask.getParent().asTaskFragment().getTask(); 2615 } 2616 // If the activity is visible in multi-windowing mode, it may already be on 2617 // the top (visible to user but not the global top), then the result code 2618 // should be START_DELIVERED_TO_TOP instead of START_TASK_TO_FRONT. 2619 final boolean wasTopOfVisibleRootTask = intentActivity.isVisibleRequested() 2620 && intentActivity.inMultiWindowMode() 2621 && intentActivity == mTargetRootTask.topRunningActivity(); 2622 // We only want to move to the front, if we aren't going to launch on a 2623 // different root task. If we launch on a different root task, we will put the 2624 // task on top there. 2625 // Defer resuming the top activity while moving task to top, since the 2626 // current task-top activity may not be the activity that should be resumed. 2627 mTargetRootTask.moveTaskToFront(intentTask, mNoAnimation, mOptions, 2628 mStartActivity.appTimeTracker, DEFER_RESUME, 2629 "bringingFoundTaskToFront"); 2630 mMovedToFront = !wasTopOfVisibleRootTask; 2631 } else if (intentActivity.getWindowingMode() != WINDOWING_MODE_PINNED) { 2632 // Leaves reparenting pinned task operations to task organizer to make sure it 2633 // dismisses pinned task properly. 2634 // TODO(b/199997762): Consider leaving all reparent operation of organized tasks 2635 // to task organizer. 2636 intentTask.reparent(mTargetRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT, 2637 ANIMATE, DEFER_RESUME, "reparentToTargetRootTask"); 2638 mMovedToFront = true; 2639 } 2640 mOptions = null; 2641 } 2642 } 2643 2644 // Update the target's launch cookie and pending remote animation to those specified in the 2645 // options if set. 2646 if (mStartActivity.mLaunchCookie != null) { 2647 intentActivity.mLaunchCookie = mStartActivity.mLaunchCookie; 2648 } 2649 if (mStartActivity.mPendingRemoteAnimation != null) { 2650 intentActivity.mPendingRemoteAnimation = mStartActivity.mPendingRemoteAnimation; 2651 } 2652 2653 // Need to update mTargetRootTask because if task was moved out of it, the original root 2654 // task may be destroyed. 2655 mTargetRootTask = intentActivity.getRootTask(); 2656 mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED, 2657 mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetRootTask); 2658 } 2659 inTopNonFinishingTask(ActivityRecord r)2660 private boolean inTopNonFinishingTask(ActivityRecord r) { 2661 if (r == null || r.getTask() == null) { 2662 return false; 2663 } 2664 2665 final Task rTask = r.getTask(); 2666 final Task parent = rTask.getCreatedByOrganizerTask() != null 2667 ? rTask.getCreatedByOrganizerTask() : r.getRootTask(); 2668 final ActivityRecord topNonFinishingActivity = parent != null 2669 ? parent.getTopNonFinishingActivity() : null; 2670 2671 return topNonFinishingActivity != null && topNonFinishingActivity.getTask() == rTask; 2672 } 2673 resumeTargetRootTaskIfNeeded()2674 private void resumeTargetRootTaskIfNeeded() { 2675 if (mDoResume) { 2676 final ActivityRecord next = mTargetRootTask.topRunningActivity( 2677 true /* focusableOnly */); 2678 if (next != null) { 2679 next.setCurrentLaunchCanTurnScreenOn(true); 2680 } 2681 if (mTargetRootTask.isFocusable()) { 2682 mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, null, 2683 mOptions, mTransientLaunch); 2684 } else { 2685 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 2686 } 2687 } else { 2688 ActivityOptions.abort(mOptions); 2689 } 2690 mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask); 2691 } 2692 setNewTask(Task taskToAffiliate)2693 private void setNewTask(Task taskToAffiliate) { 2694 final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront; 2695 final Task task = mTargetRootTask.reuseOrCreateTask( 2696 mStartActivity.info, mIntent, mVoiceSession, 2697 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions); 2698 task.mTransitionController.collectExistenceChange(task); 2699 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask"); 2700 2701 ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s", 2702 mStartActivity, mStartActivity.getTask()); 2703 2704 if (taskToAffiliate != null) { 2705 mStartActivity.setTaskToAffiliateWith(taskToAffiliate); 2706 } 2707 } 2708 deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants)2709 private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) { 2710 if (mIntentDelivered) { 2711 return; 2712 } 2713 2714 activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask()); 2715 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants, 2716 mStartActivity.launchedFromPackage); 2717 mIntentDelivered = true; 2718 } 2719 2720 /** Places {@link #mStartActivity} in {@code task} or an embedded {@link TaskFragment}. */ addOrReparentStartingActivity(@onNull Task task, String reason)2721 private void addOrReparentStartingActivity(@NonNull Task task, String reason) { 2722 TaskFragment newParent = task; 2723 if (mInTaskFragment != null) { 2724 int embeddingCheckResult = canEmbedActivity(mInTaskFragment, mStartActivity, task); 2725 if (embeddingCheckResult == EMBEDDING_ALLOWED) { 2726 newParent = mInTaskFragment; 2727 } else { 2728 // Start mStartActivity to task instead if it can't be embedded to mInTaskFragment. 2729 sendCanNotEmbedActivityError(mInTaskFragment, embeddingCheckResult); 2730 } 2731 } else { 2732 TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null; 2733 if (candidateTf == null) { 2734 final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */, 2735 false /* includingEmbeddedTask */); 2736 if (top != null) { 2737 candidateTf = top.getTaskFragment(); 2738 } 2739 } 2740 if (candidateTf != null && candidateTf.isEmbedded() 2741 && canEmbedActivity(candidateTf, mStartActivity, task) == EMBEDDING_ALLOWED) { 2742 // Use the embedded TaskFragment of the top activity as the new parent if the 2743 // activity can be embedded. 2744 newParent = candidateTf; 2745 } 2746 } 2747 if (mStartActivity.getTaskFragment() == null 2748 || mStartActivity.getTaskFragment() == newParent) { 2749 newParent.addChild(mStartActivity, POSITION_TOP); 2750 } else { 2751 mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason); 2752 } 2753 } 2754 2755 /** 2756 * Notifies the client side that {@link #mStartActivity} cannot be embedded to 2757 * {@code taskFragment}. 2758 */ sendCanNotEmbedActivityError(TaskFragment taskFragment, @EmbeddingCheckResult int result)2759 private void sendCanNotEmbedActivityError(TaskFragment taskFragment, 2760 @EmbeddingCheckResult int result) { 2761 final String errMsg; 2762 switch(result) { 2763 case EMBEDDING_DISALLOWED_NEW_TASK: { 2764 errMsg = "Cannot embed " + mStartActivity + " that launched on another task" 2765 + ",mLaunchMode=" + launchModeToString(mLaunchMode) 2766 + ",mLaunchFlag=" + Integer.toHexString(mLaunchFlags); 2767 break; 2768 } 2769 case EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION: { 2770 errMsg = "Cannot embed " + mStartActivity 2771 + ". TaskFragment's bounds:" + taskFragment.getBounds() 2772 + ", minimum dimensions:" + mStartActivity.getMinDimensions(); 2773 break; 2774 } 2775 case EMBEDDING_DISALLOWED_UNTRUSTED_HOST: { 2776 errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity; 2777 break; 2778 } 2779 default: 2780 errMsg = "Unhandled embed result:" + result; 2781 } 2782 if (taskFragment.isOrganized()) { 2783 mService.mWindowOrganizerController.sendTaskFragmentOperationFailure( 2784 taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken, 2785 taskFragment, HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT, 2786 new SecurityException(errMsg)); 2787 } else { 2788 // If the taskFragment is not organized, just dump error message as warning logs. 2789 Slog.w(TAG, errMsg); 2790 } 2791 } 2792 adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, boolean launchSingleTask, int launchFlags)2793 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, 2794 boolean launchSingleTask, int launchFlags) { 2795 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 2796 (launchSingleInstance || launchSingleTask)) { 2797 // We have a conflict between the Intent and the Activity manifest, manifest wins. 2798 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 2799 "\"singleInstance\" or \"singleTask\""); 2800 launchFlags &= 2801 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK); 2802 } else { 2803 switch (r.info.documentLaunchMode) { 2804 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 2805 break; 2806 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 2807 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 2808 break; 2809 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 2810 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 2811 break; 2812 case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 2813 if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) { 2814 // Remove MULTIPLE_TASK flag along with NEW_DOCUMENT only if NEW_DOCUMENT 2815 // is set, otherwise we still want to keep the MULTIPLE_TASK flag (if 2816 // any) for singleInstancePerTask that the multiple tasks can be created, 2817 // or a singleInstancePerTask activity is basically the same as a 2818 // singleTask activity when documentLaunchMode set to never. 2819 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 2820 launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT 2821 | FLAG_ACTIVITY_MULTIPLE_TASK); 2822 } 2823 } else { 2824 // TODO(b/184903976): Should FLAG_ACTIVITY_MULTIPLE_TASK always be 2825 // removed for document-never activity? 2826 launchFlags &= 2827 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK); 2828 } 2829 break; 2830 } 2831 } 2832 return launchFlags; 2833 } 2834 getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions)2835 private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, 2836 ActivityOptions aOptions) { 2837 final boolean onTop = 2838 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; 2839 final Task sourceTask = mSourceRecord != null ? mSourceRecord.getTask() : null; 2840 return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, sourceTask, onTop, 2841 mLaunchParams, launchFlags); 2842 } 2843 isLaunchModeOneOf(int mode1, int mode2)2844 private boolean isLaunchModeOneOf(int mode1, int mode2) { 2845 return mode1 == mLaunchMode || mode2 == mLaunchMode; 2846 } 2847 isLaunchModeOneOf(int mode1, int mode2, int mode3)2848 private boolean isLaunchModeOneOf(int mode1, int mode2, int mode3) { 2849 return mode1 == mLaunchMode || mode2 == mLaunchMode || mode3 == mLaunchMode; 2850 } 2851 isDocumentLaunchesIntoExisting(int flags)2852 static boolean isDocumentLaunchesIntoExisting(int flags) { 2853 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 2854 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0; 2855 } 2856 setIntent(Intent intent)2857 ActivityStarter setIntent(Intent intent) { 2858 mRequest.intent = intent; 2859 return this; 2860 } 2861 getIntent()2862 Intent getIntent() { 2863 return mRequest.intent; 2864 } 2865 setIntentGrants(NeededUriGrants intentGrants)2866 ActivityStarter setIntentGrants(NeededUriGrants intentGrants) { 2867 mRequest.intentGrants = intentGrants; 2868 return this; 2869 } 2870 setReason(String reason)2871 ActivityStarter setReason(String reason) { 2872 mRequest.reason = reason; 2873 return this; 2874 } 2875 setCaller(IApplicationThread caller)2876 ActivityStarter setCaller(IApplicationThread caller) { 2877 mRequest.caller = caller; 2878 return this; 2879 } 2880 setResolvedType(String type)2881 ActivityStarter setResolvedType(String type) { 2882 mRequest.resolvedType = type; 2883 return this; 2884 } 2885 setActivityInfo(ActivityInfo info)2886 ActivityStarter setActivityInfo(ActivityInfo info) { 2887 mRequest.activityInfo = info; 2888 return this; 2889 } 2890 setResolveInfo(ResolveInfo info)2891 ActivityStarter setResolveInfo(ResolveInfo info) { 2892 mRequest.resolveInfo = info; 2893 return this; 2894 } 2895 setVoiceSession(IVoiceInteractionSession voiceSession)2896 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) { 2897 mRequest.voiceSession = voiceSession; 2898 return this; 2899 } 2900 setVoiceInteractor(IVoiceInteractor voiceInteractor)2901 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) { 2902 mRequest.voiceInteractor = voiceInteractor; 2903 return this; 2904 } 2905 setResultTo(IBinder resultTo)2906 ActivityStarter setResultTo(IBinder resultTo) { 2907 mRequest.resultTo = resultTo; 2908 return this; 2909 } 2910 setResultWho(String resultWho)2911 ActivityStarter setResultWho(String resultWho) { 2912 mRequest.resultWho = resultWho; 2913 return this; 2914 } 2915 setRequestCode(int requestCode)2916 ActivityStarter setRequestCode(int requestCode) { 2917 mRequest.requestCode = requestCode; 2918 return this; 2919 } 2920 2921 /** 2922 * Sets the pid of the caller who originally started the activity. 2923 * 2924 * Normally, the pid/uid would be the calling pid from the binder call. 2925 * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered 2926 * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid, 2927 * which represents the entity who invoked pending intent via {@link PendingIntent#send}. 2928 */ setCallingPid(int pid)2929 ActivityStarter setCallingPid(int pid) { 2930 mRequest.callingPid = pid; 2931 return this; 2932 } 2933 2934 /** 2935 * Sets the uid of the caller who originally started the activity. 2936 * 2937 * @see #setCallingPid 2938 */ setCallingUid(int uid)2939 ActivityStarter setCallingUid(int uid) { 2940 mRequest.callingUid = uid; 2941 return this; 2942 } 2943 setCallingPackage(String callingPackage)2944 ActivityStarter setCallingPackage(String callingPackage) { 2945 mRequest.callingPackage = callingPackage; 2946 return this; 2947 } 2948 setCallingFeatureId(String callingFeatureId)2949 ActivityStarter setCallingFeatureId(String callingFeatureId) { 2950 mRequest.callingFeatureId = callingFeatureId; 2951 return this; 2952 } 2953 2954 /** 2955 * Sets the pid of the caller who requested to launch the activity. 2956 * 2957 * The pid/uid represents the caller who launches the activity in this request. 2958 * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}: 2959 * the pid/uid will be the caller who called {@link PendingIntent#send()}. 2960 * 2961 * @see #setCallingPid 2962 */ setRealCallingPid(int pid)2963 ActivityStarter setRealCallingPid(int pid) { 2964 mRequest.realCallingPid = pid; 2965 return this; 2966 } 2967 2968 /** 2969 * Sets the uid of the caller who requested to launch the activity. 2970 * 2971 * @see #setRealCallingPid 2972 */ setRealCallingUid(int uid)2973 ActivityStarter setRealCallingUid(int uid) { 2974 mRequest.realCallingUid = uid; 2975 return this; 2976 } 2977 setStartFlags(int startFlags)2978 ActivityStarter setStartFlags(int startFlags) { 2979 mRequest.startFlags = startFlags; 2980 return this; 2981 } 2982 setActivityOptions(SafeActivityOptions options)2983 ActivityStarter setActivityOptions(SafeActivityOptions options) { 2984 mRequest.activityOptions = options; 2985 return this; 2986 } 2987 setActivityOptions(Bundle bOptions)2988 ActivityStarter setActivityOptions(Bundle bOptions) { 2989 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions)); 2990 } 2991 setIgnoreTargetSecurity(boolean ignoreTargetSecurity)2992 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) { 2993 mRequest.ignoreTargetSecurity = ignoreTargetSecurity; 2994 return this; 2995 } 2996 setFilterCallingUid(int filterCallingUid)2997 ActivityStarter setFilterCallingUid(int filterCallingUid) { 2998 mRequest.filterCallingUid = filterCallingUid; 2999 return this; 3000 } 3001 setComponentSpecified(boolean componentSpecified)3002 ActivityStarter setComponentSpecified(boolean componentSpecified) { 3003 mRequest.componentSpecified = componentSpecified; 3004 return this; 3005 } 3006 setOutActivity(ActivityRecord[] outActivity)3007 ActivityStarter setOutActivity(ActivityRecord[] outActivity) { 3008 mRequest.outActivity = outActivity; 3009 return this; 3010 } 3011 setInTask(Task inTask)3012 ActivityStarter setInTask(Task inTask) { 3013 mRequest.inTask = inTask; 3014 return this; 3015 } 3016 setInTaskFragment(TaskFragment taskFragment)3017 ActivityStarter setInTaskFragment(TaskFragment taskFragment) { 3018 mRequest.inTaskFragment = taskFragment; 3019 return this; 3020 } 3021 setWaitResult(WaitResult result)3022 ActivityStarter setWaitResult(WaitResult result) { 3023 mRequest.waitResult = result; 3024 return this; 3025 } 3026 setProfilerInfo(ProfilerInfo info)3027 ActivityStarter setProfilerInfo(ProfilerInfo info) { 3028 mRequest.profilerInfo = info; 3029 return this; 3030 } 3031 setGlobalConfiguration(Configuration config)3032 ActivityStarter setGlobalConfiguration(Configuration config) { 3033 mRequest.globalConfig = config; 3034 return this; 3035 } 3036 setUserId(int userId)3037 ActivityStarter setUserId(int userId) { 3038 mRequest.userId = userId; 3039 return this; 3040 } 3041 setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup)3042 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) { 3043 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup; 3044 return this; 3045 } 3046 setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent)3047 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) { 3048 mRequest.originatingPendingIntent = originatingPendingIntent; 3049 return this; 3050 } 3051 setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart)3052 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) { 3053 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart; 3054 return this; 3055 } 3056 setErrorCallbackToken(@ullable IBinder errorCallbackToken)3057 ActivityStarter setErrorCallbackToken(@Nullable IBinder errorCallbackToken) { 3058 mRequest.errorCallbackToken = errorCallbackToken; 3059 return this; 3060 } 3061 dump(PrintWriter pw, String prefix)3062 void dump(PrintWriter pw, String prefix) { 3063 pw.print(prefix); 3064 pw.print("mCurrentUser="); 3065 pw.println(mRootWindowContainer.mCurrentUser); 3066 pw.print(prefix); 3067 pw.print("mLastStartReason="); 3068 pw.println(mLastStartReason); 3069 pw.print(prefix); 3070 pw.print("mLastStartActivityTimeMs="); 3071 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs))); 3072 pw.print(prefix); 3073 pw.print("mLastStartActivityResult="); 3074 pw.println(mLastStartActivityResult); 3075 if (mLastStartActivityRecord != null) { 3076 pw.print(prefix); 3077 pw.println("mLastStartActivityRecord:"); 3078 mLastStartActivityRecord.dump(pw, prefix + " ", true /* dumpAll */); 3079 } 3080 if (mStartActivity != null) { 3081 pw.print(prefix); 3082 pw.println("mStartActivity:"); 3083 mStartActivity.dump(pw, prefix + " ", true /* dumpAll */); 3084 } 3085 if (mIntent != null) { 3086 pw.print(prefix); 3087 pw.print("mIntent="); 3088 pw.println(mIntent); 3089 } 3090 if (mOptions != null) { 3091 pw.print(prefix); 3092 pw.print("mOptions="); 3093 pw.println(mOptions); 3094 } 3095 pw.print(prefix); 3096 pw.print("mLaunchMode="); 3097 pw.print(launchModeToString(mLaunchMode)); 3098 pw.print(prefix); 3099 pw.print("mLaunchFlags=0x"); 3100 pw.print(Integer.toHexString(mLaunchFlags)); 3101 pw.print(" mDoResume="); 3102 pw.print(mDoResume); 3103 pw.print(" mAddingToTask="); 3104 pw.print(mAddingToTask); 3105 pw.print(" mInTaskFragment="); 3106 pw.println(mInTaskFragment); 3107 } 3108 } 3109