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