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