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 mLastStartActivityRecord = null; 902 903 final IApplicationThread caller = request.caller; 904 Intent intent = request.intent; 905 NeededUriGrants intentGrants = request.intentGrants; 906 String resolvedType = request.resolvedType; 907 ActivityInfo aInfo = request.activityInfo; 908 ResolveInfo rInfo = request.resolveInfo; 909 final IVoiceInteractionSession voiceSession = request.voiceSession; 910 final IBinder resultTo = request.resultTo; 911 String resultWho = request.resultWho; 912 int requestCode = request.requestCode; 913 int callingPid = request.callingPid; 914 int callingUid = request.callingUid; 915 String callingPackage = request.callingPackage; 916 String callingFeatureId = request.callingFeatureId; 917 final int realCallingPid = request.realCallingPid; 918 final int realCallingUid = request.realCallingUid; 919 final int startFlags = request.startFlags; 920 final SafeActivityOptions options = request.activityOptions; 921 Task inTask = request.inTask; 922 TaskFragment inTaskFragment = request.inTaskFragment; 923 924 int err = ActivityManager.START_SUCCESS; 925 // Pull the optional Ephemeral Installer-only bundle out of the options early. 926 final Bundle verificationBundle = 927 options != null ? options.popAppVerificationBundle() : null; 928 929 WindowProcessController callerApp = null; 930 if (caller != null) { 931 callerApp = mService.getProcessController(caller); 932 if (callerApp != null) { 933 callingPid = callerApp.getPid(); 934 callingUid = callerApp.mInfo.uid; 935 } else { 936 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid 937 + ") when starting: " + intent.toString()); 938 err = START_PERMISSION_DENIED; 939 } 940 } 941 942 final int userId = aInfo != null && aInfo.applicationInfo != null 943 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; 944 final int launchMode = aInfo != null ? aInfo.launchMode : 0; 945 if (err == ActivityManager.START_SUCCESS) { 946 request.logMessage.append("START u").append(userId).append(" {") 947 .append(intent.toShortString(true, true, true, false)) 948 .append("} with ").append(launchModeToString(launchMode)) 949 .append(" from uid ").append(callingUid); 950 if (callingUid != realCallingUid 951 && realCallingUid != Request.DEFAULT_REAL_CALLING_UID) { 952 request.logMessage.append(" (realCallingUid=").append(realCallingUid).append(")"); 953 } 954 } 955 956 ActivityRecord sourceRecord = null; 957 ActivityRecord resultRecord = null; 958 if (resultTo != null) { 959 sourceRecord = ActivityRecord.isInAnyTask(resultTo); 960 if (DEBUG_RESULTS) { 961 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord); 962 } 963 if (sourceRecord != null) { 964 if (requestCode >= 0 && !sourceRecord.finishing) { 965 resultRecord = sourceRecord; 966 } 967 } 968 } 969 970 final int launchFlags = intent.getFlags(); 971 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { 972 // Transfer the result target from the source activity to the new one being started, 973 // including any failures. 974 if (requestCode >= 0) { 975 SafeActivityOptions.abort(options); 976 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; 977 } 978 resultRecord = sourceRecord.resultTo; 979 if (resultRecord != null && !resultRecord.isInRootTaskLocked()) { 980 resultRecord = null; 981 } 982 resultWho = sourceRecord.resultWho; 983 requestCode = sourceRecord.requestCode; 984 sourceRecord.resultTo = null; 985 if (resultRecord != null) { 986 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); 987 } 988 if (sourceRecord.launchedFromUid == callingUid) { 989 // The new activity is being launched from the same uid as the previous activity 990 // in the flow, and asking to forward its result back to the previous. In this 991 // case the activity is serving as a trampoline between the two, so we also want 992 // to update its launchedFromPackage to be the same as the previous activity. 993 // Note that this is safe, since we know these two packages come from the same 994 // uid; the caller could just as well have supplied that same package name itself 995 // . This specifially deals with the case of an intent picker/chooser being 996 // launched in the app flow to redirect to an activity picked by the user, where 997 // we want the final activity to consider it to have been launched by the 998 // previous app activity. 999 callingPackage = sourceRecord.launchedFromPackage; 1000 callingFeatureId = sourceRecord.launchedFromFeatureId; 1001 } 1002 } 1003 1004 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { 1005 // We couldn't find a class that can handle the given Intent. 1006 // That's the end of that! 1007 err = ActivityManager.START_INTENT_NOT_RESOLVED; 1008 } 1009 1010 if (err == ActivityManager.START_SUCCESS && aInfo == null) { 1011 // We couldn't find the specific class specified in the Intent. 1012 // Also the end of the line. 1013 err = ActivityManager.START_CLASS_NOT_FOUND; 1014 } 1015 1016 if (err == ActivityManager.START_SUCCESS && sourceRecord != null 1017 && sourceRecord.getTask().voiceSession != null) { 1018 // If this activity is being launched as part of a voice session, we need to ensure 1019 // that it is safe to do so. If the upcoming activity will also be part of the voice 1020 // session, we can only launch it if it has explicitly said it supports the VOICE 1021 // category, or it is a part of the calling app. 1022 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 1023 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { 1024 try { 1025 intent.addCategory(Intent.CATEGORY_VOICE); 1026 if (!mService.getPackageManager().activitySupportsIntentAsUser( 1027 intent.getComponent(), intent, resolvedType, userId)) { 1028 Slog.w(TAG, "Activity being started in current voice task does not support " 1029 + "voice: " + intent); 1030 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1031 } 1032 } catch (RemoteException e) { 1033 Slog.w(TAG, "Failure checking voice capabilities", e); 1034 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1035 } 1036 } 1037 } 1038 1039 if (err == ActivityManager.START_SUCCESS && voiceSession != null) { 1040 // If the caller is starting a new voice session, just make sure the target 1041 // is actually allowing it to run this way. 1042 try { 1043 if (!mService.getPackageManager().activitySupportsIntentAsUser( 1044 intent.getComponent(), intent, resolvedType, userId)) { 1045 Slog.w(TAG, 1046 "Activity being started in new voice task does not support: " + intent); 1047 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1048 } 1049 } catch (RemoteException e) { 1050 Slog.w(TAG, "Failure checking voice capabilities", e); 1051 err = ActivityManager.START_NOT_VOICE_COMPATIBLE; 1052 } 1053 } 1054 1055 final Task resultRootTask = resultRecord == null 1056 ? null : resultRecord.getRootTask(); 1057 1058 if (err != START_SUCCESS) { 1059 if (resultRecord != null) { 1060 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, 1061 null /* data */, null /* dataGrants */); 1062 } 1063 SafeActivityOptions.abort(options); 1064 return err; 1065 } 1066 1067 boolean abort; 1068 try { 1069 abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho, 1070 requestCode, callingPid, callingUid, callingPackage, callingFeatureId, 1071 request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, 1072 resultRootTask); 1073 } catch (SecurityException e) { 1074 // Return activity not found for the explicit intent if the caller can't see the target 1075 // to prevent the disclosure of package existence. 1076 final Intent originalIntent = request.ephemeralIntent; 1077 if (originalIntent != null && (originalIntent.getComponent() != null 1078 || originalIntent.getPackage() != null)) { 1079 final String targetPackageName = originalIntent.getComponent() != null 1080 ? originalIntent.getComponent().getPackageName() 1081 : originalIntent.getPackage(); 1082 if (mService.getPackageManagerInternalLocked() 1083 .filterAppAccess(targetPackageName, callingUid, userId)) { 1084 if (resultRecord != null) { 1085 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, 1086 RESULT_CANCELED, null /* data */, null /* dataGrants */); 1087 } 1088 SafeActivityOptions.abort(options); 1089 return ActivityManager.START_CLASS_NOT_FOUND; 1090 } 1091 } 1092 throw e; 1093 } 1094 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, 1095 callingPid, resolvedType, aInfo.applicationInfo); 1096 abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid, 1097 callingPackage); 1098 1099 // Merge the two options bundles, while realCallerOptions takes precedence. 1100 ActivityOptions checkedOptions = options != null 1101 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null; 1102 1103 @BalCode int balCode = BAL_ALLOW_DEFAULT; 1104 if (!abort) { 1105 try { 1106 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, 1107 "shouldAbortBackgroundActivityStart"); 1108 BackgroundActivityStartController balController = 1109 mController.getBackgroundActivityLaunchController(); 1110 balCode = 1111 balController.checkBackgroundActivityStart( 1112 callingUid, 1113 callingPid, 1114 callingPackage, 1115 realCallingUid, 1116 realCallingPid, 1117 callerApp, 1118 request.originatingPendingIntent, 1119 request.backgroundStartPrivileges, 1120 intent, 1121 checkedOptions); 1122 if (balCode != BAL_ALLOW_DEFAULT) { 1123 request.logMessage.append(" (").append( 1124 BackgroundActivityStartController.balCodeToString(balCode)) 1125 .append(")"); 1126 } 1127 } finally { 1128 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 1129 } 1130 } 1131 1132 if (request.allowPendingRemoteAnimationRegistryLookup) { 1133 checkedOptions = mService.getActivityStartController() 1134 .getPendingRemoteAnimationRegistry() 1135 .overrideOptionsIfNeeded(callingPackage, checkedOptions); 1136 } 1137 if (mService.mController != null) { 1138 try { 1139 // The Intent we give to the watcher has the extra data stripped off, since it 1140 // can contain private information. 1141 Intent watchIntent = intent.cloneFilter(); 1142 abort |= !mService.mController.activityStarting(watchIntent, 1143 aInfo.applicationInfo.packageName); 1144 } catch (RemoteException e) { 1145 mService.mController = null; 1146 } 1147 } 1148 1149 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, 1150 callingFeatureId); 1151 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment, 1152 callingPid, callingUid, checkedOptions)) { 1153 // activity start was intercepted, e.g. because the target user is currently in quiet 1154 // mode (turn off work) or the target application is suspended 1155 intent = mInterceptor.mIntent; 1156 rInfo = mInterceptor.mRInfo; 1157 aInfo = mInterceptor.mAInfo; 1158 resolvedType = mInterceptor.mResolvedType; 1159 inTask = mInterceptor.mInTask; 1160 callingPid = mInterceptor.mCallingPid; 1161 callingUid = mInterceptor.mCallingUid; 1162 checkedOptions = mInterceptor.mActivityOptions; 1163 1164 // The interception target shouldn't get any permission grants 1165 // intended for the original destination 1166 intentGrants = null; 1167 } 1168 1169 if (abort) { 1170 if (resultRecord != null) { 1171 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, 1172 null /* data */, null /* dataGrants */); 1173 } 1174 // We pretend to the caller that it was really started, but they will just get a 1175 // cancel result. 1176 ActivityOptions.abort(checkedOptions); 1177 return START_ABORTED; 1178 } 1179 1180 // If permissions need a review before any of the app components can run, we 1181 // launch the review activity and pass a pending intent to start the activity 1182 // we are to launching now after the review is completed. 1183 if (aInfo != null) { 1184 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired( 1185 aInfo.packageName, userId)) { 1186 final IIntentSender target = mService.getIntentSenderLocked( 1187 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId, 1188 callingUid, userId, null, null, 0, new Intent[]{intent}, 1189 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT 1190 | PendingIntent.FLAG_ONE_SHOT, null); 1191 1192 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); 1193 1194 int flags = intent.getFlags(); 1195 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; 1196 1197 /* 1198 * Prevent reuse of review activity: Each app needs their own review activity. By 1199 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities 1200 * with the same launch parameters (extras are ignored). Hence to avoid possible 1201 * reuse force a new activity via the MULTIPLE_TASK flag. 1202 * 1203 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used, 1204 * hence no need to add the flag in this case. 1205 */ 1206 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) { 1207 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 1208 } 1209 newIntent.setFlags(flags); 1210 1211 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName); 1212 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target)); 1213 if (resultRecord != null) { 1214 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true); 1215 } 1216 intent = newIntent; 1217 1218 // The permissions review target shouldn't get any permission 1219 // grants intended for the original destination 1220 intentGrants = null; 1221 1222 resolvedType = null; 1223 callingUid = realCallingUid; 1224 callingPid = realCallingPid; 1225 1226 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0, 1227 computeResolveFilterUid( 1228 callingUid, realCallingUid, request.filterCallingUid), 1229 realCallingPid); 1230 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, 1231 null /*profilerInfo*/); 1232 1233 if (DEBUG_PERMISSIONS_REVIEW) { 1234 final Task focusedRootTask = 1235 mRootWindowContainer.getTopDisplayFocusedRootTask(); 1236 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, 1237 true, false) + "} from uid " + callingUid + " on display " 1238 + (focusedRootTask == null ? DEFAULT_DISPLAY 1239 : focusedRootTask.getDisplayId())); 1240 } 1241 } 1242 } 1243 1244 // If we have an ephemeral app, abort the process of launching the resolved intent. 1245 // Instead, launch the ephemeral installer. Once the installer is finished, it 1246 // starts either the intent we resolved here [on install error] or the ephemeral 1247 // app [on install success]. 1248 if (rInfo != null && rInfo.auxiliaryInfo != null) { 1249 intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent, 1250 callingPackage, callingFeatureId, verificationBundle, resolvedType, userId); 1251 resolvedType = null; 1252 callingUid = realCallingUid; 1253 callingPid = realCallingPid; 1254 1255 // The ephemeral installer shouldn't get any permission grants 1256 // intended for the original destination 1257 intentGrants = null; 1258 1259 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/); 1260 } 1261 // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut 1262 // Pending intent launched from systemui also depends on caller app 1263 if (callerApp == null && realCallingPid > 0) { 1264 final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid); 1265 if (wpc != null) { 1266 callerApp = wpc; 1267 } 1268 } 1269 final ActivityRecord r = new ActivityRecord.Builder(mService) 1270 .setCaller(callerApp) 1271 .setLaunchedFromPid(callingPid) 1272 .setLaunchedFromUid(callingUid) 1273 .setLaunchedFromPackage(callingPackage) 1274 .setLaunchedFromFeature(callingFeatureId) 1275 .setIntent(intent) 1276 .setResolvedType(resolvedType) 1277 .setActivityInfo(aInfo) 1278 .setConfiguration(mService.getGlobalConfiguration()) 1279 .setResultTo(resultRecord) 1280 .setResultWho(resultWho) 1281 .setRequestCode(requestCode) 1282 .setComponentSpecified(request.componentSpecified) 1283 .setRootVoiceInteraction(voiceSession != null) 1284 .setActivityOptions(checkedOptions) 1285 .setSourceRecord(sourceRecord) 1286 .build(); 1287 1288 mLastStartActivityRecord = r; 1289 1290 if (r.appTimeTracker == null && sourceRecord != null) { 1291 // If the caller didn't specify an explicit time tracker, we want to continue 1292 // tracking under any it has. 1293 r.appTimeTracker = sourceRecord.appTimeTracker; 1294 } 1295 1296 // Only allow app switching to be resumed if activity is not a restricted background 1297 // activity and target app is not home process, otherwise any background activity 1298 // started in background task can stop home button protection mode. 1299 // As the targeted app is not a home process and we don't need to wait for the 2nd 1300 // activity to be started to resume app switching, we can just enable app switching 1301 // directly. 1302 WindowProcessController homeProcess = mService.mHomeProcess; 1303 boolean isHomeProcess = homeProcess != null 1304 && aInfo.applicationInfo.uid == homeProcess.mUid; 1305 if (balCode != BAL_BLOCK && !isHomeProcess) { 1306 mService.resumeAppSwitches(); 1307 } 1308 1309 mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, 1310 request.voiceInteractor, startFlags, checkedOptions, 1311 inTask, inTaskFragment, balCode, intentGrants, realCallingUid); 1312 1313 if (request.outActivity != null) { 1314 request.outActivity[0] = mLastStartActivityRecord; 1315 } 1316 1317 return mLastStartActivityResult; 1318 } 1319 1320 /** 1321 * Return true if background activity is really aborted. 1322 * 1323 * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere. 1324 */ handleBackgroundActivityAbort(ActivityRecord r)1325 private boolean handleBackgroundActivityAbort(ActivityRecord r) { 1326 // TODO(b/131747138): Remove toast and refactor related code in R release. 1327 final boolean abort = !mService.isBackgroundActivityStartsEnabled(); 1328 if (!abort) { 1329 return false; 1330 } 1331 final ActivityRecord resultRecord = r.resultTo; 1332 final String resultWho = r.resultWho; 1333 int requestCode = r.requestCode; 1334 if (resultRecord != null) { 1335 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED, 1336 null /* data */, null /* dataGrants */); 1337 } 1338 // We pretend to the caller that it was really started to make it backward compatible, but 1339 // they will just get a cancel result. 1340 ActivityOptions.abort(r.getOptions()); 1341 return true; 1342 } 1343 getExternalResult(int result)1344 static int getExternalResult(int result) { 1345 // Aborted results are treated as successes externally, but we must track them internally. 1346 return result != START_ABORTED ? result : START_SUCCESS; 1347 } 1348 1349 /** 1350 * Called when execution is complete. Sets state indicating completion and proceeds with 1351 * recycling if appropriate. 1352 */ onExecutionComplete()1353 private void onExecutionComplete() { 1354 mController.onExecutionComplete(this); 1355 } 1356 onExecutionStarted()1357 private void onExecutionStarted() { 1358 mController.onExecutionStarted(); 1359 } 1360 1361 /** 1362 * Creates a launch intent for the given auxiliary resolution data. 1363 */ createLaunchIntent(@ullable AuxiliaryResolveInfo auxiliaryResponse, Intent originalIntent, String callingPackage, @Nullable String callingFeatureId, Bundle verificationBundle, String resolvedType, int userId)1364 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse, 1365 Intent originalIntent, String callingPackage, @Nullable String callingFeatureId, 1366 Bundle verificationBundle, String resolvedType, int userId) { 1367 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) { 1368 // request phase two resolution 1369 PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked(); 1370 boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId); 1371 packageManager.requestInstantAppResolutionPhaseTwo( 1372 auxiliaryResponse, originalIntent, resolvedType, callingPackage, 1373 callingFeatureId, isRequesterInstantApp, verificationBundle, userId); 1374 } 1375 return InstantAppResolver.buildEphemeralInstallerIntent( 1376 originalIntent, 1377 InstantAppResolver.sanitizeIntent(originalIntent), 1378 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent, 1379 callingPackage, 1380 callingFeatureId, 1381 verificationBundle, 1382 resolvedType, 1383 userId, 1384 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity, 1385 auxiliaryResponse == null ? null : auxiliaryResponse.token, 1386 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo, 1387 auxiliaryResponse == null ? null : auxiliaryResponse.filters); 1388 } 1389 postStartActivityProcessing(ActivityRecord r, int result, Task startedActivityRootTask)1390 void postStartActivityProcessing(ActivityRecord r, int result, 1391 Task startedActivityRootTask) { 1392 if (!ActivityManager.isStartResultSuccessful(result)) { 1393 if (mFrozeTaskList) { 1394 // If we specifically froze the task list as part of starting an activity, then 1395 // reset the frozen list state if it failed to start. This is normally otherwise 1396 // called when the freeze-timeout has elapsed. 1397 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout(); 1398 } 1399 } 1400 if (ActivityManager.isStartResultFatalError(result)) { 1401 return; 1402 } 1403 1404 // We're waiting for an activity launch to finish, but that activity simply 1405 // brought another activity to front. We must also handle the case where the task is already 1406 // in the front as a result of the trampoline activity being in the same task (it will be 1407 // considered focused as the trampoline will be finished). Let them know about this, so 1408 // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}. 1409 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result); 1410 1411 final Task targetTask = r.getTask() != null 1412 ? r.getTask() 1413 : mTargetTask; 1414 if (startedActivityRootTask == null || targetTask == null || !targetTask.isAttached()) { 1415 return; 1416 } 1417 1418 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP) { 1419 // The activity was already running so it wasn't started, but either brought to the 1420 // front or the new intent was delivered to it since it was already in front. Notify 1421 // anyone interested in this piece of information. 1422 final Task rootHomeTask = targetTask.getDisplayArea().getRootHomeTask(); 1423 final boolean homeTaskVisible = rootHomeTask != null 1424 && rootHomeTask.shouldBeVisible(null); 1425 final ActivityRecord top = targetTask.getTopNonFinishingActivity(); 1426 final boolean visible = top != null && top.isVisible(); 1427 mService.getTaskChangeNotificationController().notifyActivityRestartAttempt( 1428 targetTask.getTaskInfo(), homeTaskVisible, mIsTaskCleared, visible); 1429 } 1430 1431 if (ActivityManager.isStartResultSuccessful(result)) { 1432 mInterceptor.onActivityLaunched(targetTask.getTaskInfo(), r); 1433 } 1434 } 1435 1436 /** 1437 * Compute the logical UID based on which the package manager would filter 1438 * app components i.e. based on which the instant app policy would be applied 1439 * because it is the logical calling UID. 1440 * 1441 * @param customCallingUid The UID on whose behalf to make the call. 1442 * @param actualCallingUid The UID actually making the call. 1443 * @param filterCallingUid The UID to be used to filter for instant apps. 1444 * @return The logical UID making the call. 1445 */ computeResolveFilterUid(int customCallingUid, int actualCallingUid, int filterCallingUid)1446 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid, 1447 int filterCallingUid) { 1448 return filterCallingUid != UserHandle.USER_NULL 1449 ? filterCallingUid 1450 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid); 1451 } 1452 1453 /** 1454 * Start an activity while most of preliminary checks has been done and caller has been 1455 * confirmed that holds necessary permissions to do so. 1456 * Here also ensures that the starting activity is removed if the start wasn't successful. 1457 */ 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)1458 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, 1459 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1460 int startFlags, ActivityOptions options, Task inTask, 1461 TaskFragment inTaskFragment, @BalCode int balCode, 1462 NeededUriGrants intentGrants, int realCallingUid) { 1463 int result = START_CANCELED; 1464 final Task startedActivityRootTask; 1465 1466 // Create a transition now to record the original intent of actions taken within 1467 // startActivityInner. Otherwise, logic in startActivityInner could start a different 1468 // transition based on a sub-action. 1469 // Only do the create here (and defer requestStart) since startActivityInner might abort. 1470 final TransitionController transitionController = r.mTransitionController; 1471 Transition newTransition = transitionController.isShellTransitionsEnabled() 1472 ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null; 1473 RemoteTransition remoteTransition = r.takeRemoteTransition(); 1474 try { 1475 mService.deferWindowLayout(); 1476 transitionController.collect(r); 1477 try { 1478 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner"); 1479 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, 1480 startFlags, options, inTask, inTaskFragment, balCode, 1481 intentGrants, realCallingUid); 1482 } finally { 1483 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 1484 startedActivityRootTask = handleStartResult(r, options, result, newTransition, 1485 remoteTransition); 1486 } 1487 } finally { 1488 mService.continueWindowLayout(); 1489 } 1490 postStartActivityProcessing(r, result, startedActivityRootTask); 1491 1492 return result; 1493 } 1494 1495 /** 1496 * If the start result is success, ensure that the configuration of the started activity matches 1497 * the current display. Otherwise clean up unassociated containers to avoid leakage. 1498 * 1499 * @return the root task where the successful started activity resides. 1500 */ handleStartResult(@onNull ActivityRecord started, ActivityOptions options, int result, Transition newTransition, RemoteTransition remoteTransition)1501 private @Nullable Task handleStartResult(@NonNull ActivityRecord started, 1502 ActivityOptions options, int result, Transition newTransition, 1503 RemoteTransition remoteTransition) { 1504 final boolean userLeaving = mSupervisor.mUserLeaving; 1505 mSupervisor.mUserLeaving = false; 1506 final Task currentRootTask = started.getRootTask(); 1507 final Task startedActivityRootTask = 1508 currentRootTask != null ? currentRootTask : mTargetRootTask; 1509 1510 if (!ActivityManager.isStartResultSuccessful(result) || startedActivityRootTask == null) { 1511 // If we are not able to proceed, disassociate the activity from the task. Leaving an 1512 // activity in an incomplete state can lead to issues, such as performing operations 1513 // without a window container. 1514 if (mStartActivity.getTask() != null) { 1515 mStartActivity.finishIfPossible("startActivity", true /* oomAdj */); 1516 } else if (mStartActivity.getParent() != null) { 1517 mStartActivity.getParent().removeChild(mStartActivity); 1518 } 1519 1520 // Root task should also be detached from display and be removed if it's empty. 1521 if (startedActivityRootTask != null && startedActivityRootTask.isAttached() 1522 && !startedActivityRootTask.hasActivity() 1523 && !startedActivityRootTask.isActivityTypeHome() 1524 && !startedActivityRootTask.mCreatedByOrganizer) { 1525 startedActivityRootTask.removeIfPossible("handleStartResult"); 1526 } 1527 if (newTransition != null) { 1528 newTransition.abort(); 1529 } 1530 return null; 1531 } 1532 1533 // Apply setAlwaysOnTop when starting an activity is successful regardless of creating 1534 // a new Activity or reusing the existing activity. 1535 if (options != null && options.getTaskAlwaysOnTop()) { 1536 startedActivityRootTask.setAlwaysOnTop(true); 1537 } 1538 1539 // If there is no state change (e.g. a resumed activity is reparented to top of 1540 // another display) to trigger a visibility/configuration checking, we have to 1541 // update the configuration for changing to different display. 1542 final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity(); 1543 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) { 1544 mRootWindowContainer.ensureVisibilityAndConfig( 1545 currentTop, currentTop.getDisplayId(), 1546 true /* markFrozenIfConfigChanged */, false /* deferResume */); 1547 } 1548 1549 if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer 1550 .hasVisibleWindowAboveButDoesNotOwnNotificationShade(started.launchedFromUid)) { 1551 // If the UID launching the activity has a visible window on top of the notification 1552 // shade and it's launching an activity that's going to be at the front, we should move 1553 // the shade out of the way so the user can see it. We want to avoid the case where the 1554 // activity is launched on top of a background task which is not moved to the front. 1555 final StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal(); 1556 if (statusBar != null) { 1557 // This results in a async call since the interface is one-way. 1558 statusBar.collapsePanels(); 1559 } 1560 } 1561 1562 // Transition housekeeping. 1563 final TransitionController transitionController = started.mTransitionController; 1564 final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT; 1565 final boolean isTransientLaunch = options != null && options.getTransientLaunch(); 1566 // Start transient launch while keyguard locked and occluded by other app, for this 1567 // condition we would like to play the remote transition without modify any visible state 1568 // for the hierarchy in core, so here will force execute this transition. 1569 final boolean forceTransientTransition = isTransientLaunch && mPriorAboveTask != null 1570 && mDisplayLockAndOccluded; 1571 if (isStarted) { 1572 // The activity is started new rather than just brought forward, so record it as an 1573 // existence change. 1574 transitionController.collectExistenceChange(started); 1575 } else if (result == START_DELIVERED_TO_TOP && newTransition != null 1576 // An activity has changed order/visibility or the task is occluded by a transient 1577 // activity, so this isn't just deliver-to-top 1578 && mMovedToTopActivity == null 1579 && !transitionController.isTransientHide(startedActivityRootTask)) { 1580 // We just delivered to top, so there isn't an actual transition here. 1581 if (!forceTransientTransition) { 1582 newTransition.abort(); 1583 newTransition = null; 1584 } 1585 } 1586 if (isTransientLaunch) { 1587 if (forceTransientTransition) { 1588 transitionController.collect(mLastStartActivityRecord); 1589 transitionController.collect(mPriorAboveTask); 1590 } 1591 // `started` isn't guaranteed to be the actual relevant activity, so we must wait 1592 // until after we launched to identify the relevant activity. 1593 transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask); 1594 if (forceTransientTransition) { 1595 final DisplayContent dc = mLastStartActivityRecord.getDisplayContent(); 1596 // update wallpaper target to TransientHide 1597 dc.mWallpaperController.adjustWallpaperWindows(); 1598 // execute transition because there is no change 1599 transitionController.setReady(dc, true /* ready */); 1600 } 1601 } 1602 if (!userLeaving) { 1603 // no-user-leaving implies not entering PiP. 1604 transitionController.setCanPipOnFinish(false /* canPipOnFinish */); 1605 } 1606 if (newTransition != null) { 1607 transitionController.requestStartTransition(newTransition, 1608 mTargetTask == null ? started.getTask() : mTargetTask, 1609 remoteTransition, null /* displayChange */); 1610 } else if (result == START_SUCCESS && mStartActivity.isState(RESUMED)) { 1611 // Do nothing if the activity is started and is resumed directly. 1612 } else if (isStarted) { 1613 // Make the collecting transition wait until this request is ready. 1614 transitionController.setReady(started, false); 1615 } 1616 return startedActivityRootTask; 1617 } 1618 1619 /** 1620 * Start an activity and determine if the activity should be adding to the top of an existing 1621 * task or delivered new intent to an existing activity. Also manipulating the activity task 1622 * onto requested or valid root-task/display. 1623 * 1624 * Note: This method should only be called from {@link #startActivityUnchecked}. 1625 */ 1626 // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner 1627 @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)1628 int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, 1629 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1630 int startFlags, ActivityOptions options, Task inTask, 1631 TaskFragment inTaskFragment, @BalCode int balCode, 1632 NeededUriGrants intentGrants, int realCallingUid) { 1633 setInitialState(r, options, inTask, inTaskFragment, startFlags, sourceRecord, 1634 voiceSession, voiceInteractor, balCode, realCallingUid); 1635 1636 computeLaunchingTaskFlags(); 1637 mIntent.setFlags(mLaunchFlags); 1638 1639 boolean dreamStopping = false; 1640 1641 for (ActivityRecord stoppingActivity : mSupervisor.mStoppingActivities) { 1642 if (stoppingActivity.getActivityType() 1643 == WindowConfiguration.ACTIVITY_TYPE_DREAM) { 1644 dreamStopping = true; 1645 break; 1646 } 1647 } 1648 1649 // Get top task at beginning because the order may be changed when reusing existing task. 1650 final Task prevTopRootTask = mPreferredTaskDisplayArea.getFocusedRootTask(); 1651 final Task prevTopTask = prevTopRootTask != null ? prevTopRootTask.getTopLeafTask() : null; 1652 final Task reusedTask = getReusableTask(); 1653 1654 // If requested, freeze the task list 1655 if (mOptions != null && mOptions.freezeRecentTasksReordering() 1656 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid) 1657 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) { 1658 mFrozeTaskList = true; 1659 mSupervisor.mRecentTasks.setFreezeTaskListReordering(); 1660 } 1661 1662 // Compute if there is an existing task that should be used for. 1663 final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask(); 1664 final boolean newTask = targetTask == null; 1665 mTargetTask = targetTask; 1666 1667 computeLaunchParams(r, sourceRecord, targetTask); 1668 1669 // Check if starting activity on given task or on a new task is allowed. 1670 int startResult = isAllowedToStart(r, newTask, targetTask); 1671 if (startResult != START_SUCCESS) { 1672 if (r.resultTo != null) { 1673 r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED, 1674 null /* data */, null /* dataGrants */); 1675 } 1676 return startResult; 1677 } 1678 1679 if (targetTask != null) { 1680 if (targetTask.getTreeWeight() > MAX_TASK_WEIGHT_FOR_ADDING_ACTIVITY) { 1681 Slog.e(TAG, "Remove " + targetTask + " because it has contained too many" 1682 + " activities or windows (abort starting " + r 1683 + " from uid=" + mCallingUid); 1684 targetTask.removeImmediately("bulky-task"); 1685 return START_ABORTED; 1686 } 1687 // When running transient transition, the transient launch target should keep on top. 1688 // So disallow the transient hide activity to move itself to front, e.g. trampoline. 1689 if (!mAvoidMoveToFront && r.mTransitionController.isTransientHide(targetTask)) { 1690 mAvoidMoveToFront = true; 1691 } 1692 mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask()); 1693 } 1694 1695 final ActivityRecord targetTaskTop = newTask 1696 ? null : targetTask.getTopNonFinishingActivity(); 1697 if (targetTaskTop != null) { 1698 // Removes the existing singleInstance activity in another task (if any) while 1699 // launching a singleInstance activity on sourceRecord's task. 1700 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode && mSourceRecord != null 1701 && targetTask == mSourceRecord.getTask()) { 1702 final ActivityRecord activity = mRootWindowContainer.findActivity(mIntent, 1703 mStartActivity.info, false); 1704 if (activity != null && activity.getTask() != targetTask) { 1705 activity.destroyIfPossible("Removes redundant singleInstance"); 1706 } 1707 } 1708 // Recycle the target task for this launch. 1709 startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants); 1710 if (startResult != START_SUCCESS) { 1711 return startResult; 1712 } 1713 } else { 1714 mAddingToTask = true; 1715 } 1716 1717 // If the activity being launched is the same as the one currently at the top, then 1718 // we need to check if it should only be launched once. 1719 final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask(); 1720 if (topRootTask != null) { 1721 startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants); 1722 if (startResult != START_SUCCESS) { 1723 return startResult; 1724 } 1725 } 1726 1727 if (mTargetRootTask == null) { 1728 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask, 1729 mOptions); 1730 } 1731 if (newTask) { 1732 final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) 1733 ? mSourceRecord.getTask() : null; 1734 setNewTask(taskToAffiliate); 1735 } else if (mAddingToTask) { 1736 addOrReparentStartingActivity(targetTask, "adding to task"); 1737 } 1738 1739 if (!mAvoidMoveToFront && mDoResume) { 1740 mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask); 1741 if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming() 1742 && !dreamStopping) { 1743 // Launching underneath dream activity (fullscreen, always-on-top). Run the launch- 1744 // -behind transition so the Activity gets created and starts in visible state. 1745 mLaunchTaskBehind = true; 1746 r.mLaunchTaskBehind = true; 1747 } 1748 } 1749 1750 mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, 1751 mStartActivity.getUriPermissionsLocked()); 1752 if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) { 1753 // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs 1754 final PackageManagerInternal pmInternal = 1755 mService.getPackageManagerInternalLocked(); 1756 final int resultToUid = pmInternal.getPackageUid( 1757 mStartActivity.resultTo.info.packageName, 0 /* flags */, 1758 mStartActivity.mUserId); 1759 pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent, 1760 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/, 1761 resultToUid /*visible*/, true /*direct*/); 1762 } else if (mStartActivity.mShareIdentity) { 1763 final PackageManagerInternal pmInternal = 1764 mService.getPackageManagerInternalLocked(); 1765 pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent, 1766 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/, 1767 r.launchedFromUid /*visible*/, true /*direct*/); 1768 } 1769 final Task startedTask = mStartActivity.getTask(); 1770 if (newTask) { 1771 EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId, 1772 startedTask.getRootTaskId(), startedTask.getDisplayId()); 1773 } 1774 mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask); 1775 1776 mStartActivity.getTaskFragment().clearLastPausedActivity(); 1777 1778 mRootWindowContainer.startPowerModeLaunchIfNeeded( 1779 false /* forceSend */, mStartActivity); 1780 1781 final boolean isTaskSwitch = startedTask != prevTopTask; 1782 mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch, 1783 mOptions, sourceRecord); 1784 if (mDoResume) { 1785 final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked(); 1786 if (!mTargetRootTask.isTopActivityFocusable() 1787 || (topTaskActivity != null && topTaskActivity.isTaskOverlay() 1788 && mStartActivity != topTaskActivity)) { 1789 // If the activity is not focusable, we can't resume it, but still would like to 1790 // make sure it becomes visible as it starts (this will also trigger entry 1791 // animation). An example of this are PIP activities. 1792 // Also, we don't want to resume activities in a task that currently has an overlay 1793 // as the starting activity just needs to be in the visible paused state until the 1794 // over is removed. 1795 // Passing {@code null} as the start parameter ensures all activities are made 1796 // visible. 1797 mTargetRootTask.ensureActivitiesVisible(null /* starting */, 1798 0 /* configChanges */, !PRESERVE_WINDOWS); 1799 // Go ahead and tell window manager to execute app transition for this activity 1800 // since the app transition will not be triggered through the resume channel. 1801 mTargetRootTask.mDisplayContent.executeAppTransition(); 1802 } else { 1803 // If the target root-task was not previously focusable (previous top running 1804 // activity on that root-task was not visible) then any prior calls to move the 1805 // root-task to the will not update the focused root-task. If starting the new 1806 // activity now allows the task root-task to be focusable, then ensure that we 1807 // now update the focused root-task accordingly. 1808 if (!mAvoidMoveToFront && mTargetRootTask.isTopActivityFocusable() 1809 && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) { 1810 mTargetRootTask.moveToFront("startActivityInner"); 1811 } 1812 mRootWindowContainer.resumeFocusedTasksTopActivities( 1813 mTargetRootTask, mStartActivity, mOptions, mTransientLaunch); 1814 } 1815 } 1816 mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask); 1817 1818 // Update the recent tasks list immediately when the activity starts 1819 mSupervisor.mRecentTasks.add(startedTask); 1820 mSupervisor.handleNonResizableTaskIfNeeded(startedTask, 1821 mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask); 1822 1823 // If Activity's launching into PiP, move the mStartActivity immediately to pinned mode. 1824 // Note that mStartActivity and source should be in the same Task at this point. 1825 if (mOptions != null && mOptions.isLaunchIntoPip() 1826 && sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask() 1827 && balCode != BAL_BLOCK) { 1828 mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity, 1829 sourceRecord, "launch-into-pip"); 1830 } 1831 1832 return START_SUCCESS; 1833 } 1834 1835 /** Returns the leaf task where the target activity may be placed. */ computeTargetTask()1836 private Task computeTargetTask() { 1837 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask 1838 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 1839 // A new task should be created instead of using existing one. 1840 return null; 1841 } else if (mSourceRecord != null) { 1842 return mSourceRecord.getTask(); 1843 } else if (mInTask != null) { 1844 // The task is specified from AppTaskImpl, so it may not be attached yet. 1845 if (!mInTask.isAttached()) { 1846 // Attach the task to display area. Ignore the returned root task (though usually 1847 // they are the same) because "target task" should be leaf task. 1848 getOrCreateRootTask(mStartActivity, mLaunchFlags, mInTask, mOptions); 1849 } 1850 return mInTask; 1851 } else { 1852 final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */, 1853 mOptions); 1854 final ActivityRecord top = rootTask.getTopNonFinishingActivity(); 1855 if (top != null) { 1856 return top.getTask(); 1857 } else { 1858 // Remove the root task if no activity in the root task. 1859 rootTask.removeIfPossible("computeTargetTask"); 1860 } 1861 } 1862 return null; 1863 } 1864 computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, Task targetTask)1865 private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, 1866 Task targetTask) { 1867 mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r, 1868 sourceRecord, mOptions, mRequest, PHASE_BOUNDS, mLaunchParams); 1869 mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() 1870 ? mLaunchParams.mPreferredTaskDisplayArea 1871 : mRootWindowContainer.getDefaultTaskDisplayArea(); 1872 mPreferredWindowingMode = mLaunchParams.mWindowingMode; 1873 } 1874 1875 @VisibleForTesting isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask)1876 int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) { 1877 if (r.packageName == null) { 1878 ActivityOptions.abort(mOptions); 1879 return START_CLASS_NOT_FOUND; 1880 } 1881 1882 // Do not start home activity if it cannot be launched on preferred display. We are not 1883 // doing this in ActivityTaskSupervisor#canPlaceEntityOnDisplay because it might 1884 // fallback to launch on other displays. 1885 if (r.isActivityTypeHome()) { 1886 if (!mRootWindowContainer.canStartHomeOnDisplayArea(r.info, mPreferredTaskDisplayArea, 1887 true /* allowInstrumenting */)) { 1888 Slog.w(TAG, "Cannot launch home on display area " + mPreferredTaskDisplayArea); 1889 return START_CANCELED; 1890 } 1891 } 1892 1893 // Do not allow background activity start in new task or in a task that uid is not present. 1894 // Also do not allow pinned window to start single instance activity in background, 1895 // as it will recreate the window and makes it to foreground. 1896 boolean blockBalInTask = (newTask 1897 || !targetTask.isUidPresent(mCallingUid) 1898 || (LAUNCH_SINGLE_INSTANCE == mLaunchMode && targetTask.inPinnedWindowingMode())); 1899 1900 if (mBalCode == BAL_BLOCK && blockBalInTask 1901 && handleBackgroundActivityAbort(r)) { 1902 Slog.e(TAG, "Abort background activity starts from " + mCallingUid); 1903 return START_ABORTED; 1904 } 1905 1906 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still 1907 // needs to be a lock task mode violation since the task gets cleared out and the device 1908 // would otherwise leave the locked task. 1909 final boolean isNewClearTask = 1910 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 1911 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); 1912 if (!newTask) { 1913 if (mService.getLockTaskController().isLockTaskModeViolation(targetTask, 1914 isNewClearTask)) { 1915 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1916 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 1917 } 1918 } else { 1919 if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(r)) { 1920 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r); 1921 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 1922 } 1923 } 1924 1925 // Do not start the activity if target display's DWPC does not allow it. 1926 // We can't return fatal error code here because it will crash the caller of 1927 // startActivity() if they don't catch the exception. We don't expect 3P apps to make 1928 // changes. 1929 if (mPreferredTaskDisplayArea != null) { 1930 final DisplayContent displayContent = mRootWindowContainer.getDisplayContentOrCreate( 1931 mPreferredTaskDisplayArea.getDisplayId()); 1932 if (displayContent != null) { 1933 final int targetWindowingMode = (targetTask != null) 1934 ? targetTask.getWindowingMode() : displayContent.getWindowingMode(); 1935 final int launchingFromDisplayId = 1936 mSourceRecord != null ? mSourceRecord.getDisplayId() : DEFAULT_DISPLAY; 1937 if (!displayContent.mDwpcHelper 1938 .canActivityBeLaunched(r.info, r.intent, targetWindowingMode, 1939 launchingFromDisplayId, newTask)) { 1940 Slog.w(TAG, "Abort to launch " + r.info.getComponentName() 1941 + " on display area " + mPreferredTaskDisplayArea); 1942 return START_ABORTED; 1943 } 1944 } 1945 } 1946 1947 if (!checkActivitySecurityModel(r, newTask, targetTask)) { 1948 return START_ABORTED; 1949 } 1950 1951 return START_SUCCESS; 1952 } 1953 1954 /** 1955 * TODO(b/263368846): Shift to BackgroundActivityStartController once class is ready 1956 * Log activity starts which violate one of the following rules of the 1957 * activity security model (ASM): 1958 * See go/activity-security for rationale behind the rules. 1959 * 1. Within a task, only an activity matching a top UID of the task can start activities 1960 * 2. Only activities within a foreground task, which match a top UID of the task, can 1961 * create a new task or bring an existing one into the foreground 1962 */ checkActivitySecurityModel(ActivityRecord r, boolean newTask, Task targetTask)1963 private boolean checkActivitySecurityModel(ActivityRecord r, boolean newTask, Task targetTask) { 1964 // BAL Exception allowed in all cases 1965 if (mBalCode == BAL_ALLOW_ALLOWLISTED_UID) { 1966 return true; 1967 } 1968 1969 // Intents with FLAG_ACTIVITY_NEW_TASK will always be considered as creating a new task 1970 // even if the intent is delivered to an existing task. 1971 boolean taskToFront = newTask 1972 || (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == FLAG_ACTIVITY_NEW_TASK; 1973 1974 // BAL exception only allowed for new tasks 1975 if (taskToFront) { 1976 if (mBalCode == BAL_ALLOW_ALLOWLISTED_COMPONENT 1977 || mBalCode == BAL_ALLOW_PERMISSION 1978 || mBalCode == BAL_ALLOW_PENDING_INTENT 1979 || mBalCode == BAL_ALLOW_SAW_PERMISSION 1980 || mBalCode == BAL_ALLOW_VISIBLE_WINDOW) { 1981 return true; 1982 } 1983 } 1984 1985 boolean shouldBlockActivityStart = true; 1986 // Used for logging/toasts. Would we block the start if target sdk was U and feature was 1987 // enabled? 1988 boolean wouldBlockActivityStartIgnoringFlags = true; 1989 1990 if (mSourceRecord != null) { 1991 boolean passesAsmChecks = true; 1992 Task sourceTask = mSourceRecord.getTask(); 1993 1994 // Allow launching into a new task (or a task matching the launched activity's 1995 // affinity) only if the current task is foreground or mutating its own task. 1996 // The latter can happen eg. if caller uses NEW_TASK flag and the activity being 1997 // launched matches affinity of source task. 1998 if (taskToFront) { 1999 passesAsmChecks = sourceTask != null 2000 && (sourceTask.isVisible() || sourceTask == targetTask); 2001 } 2002 2003 if (passesAsmChecks) { 2004 Task taskToCheck = taskToFront ? sourceTask : targetTask; 2005 // first == false means Should Block 2006 // second == false means Would Block disregarding flags 2007 Pair<Boolean, Boolean> pair = ActivityTaskSupervisor 2008 .doesTopActivityMatchingUidExistForAsm(taskToCheck, mSourceRecord.getUid(), 2009 mSourceRecord); 2010 shouldBlockActivityStart = !pair.first; 2011 wouldBlockActivityStartIgnoringFlags = !pair.second; 2012 } 2013 2014 if (!wouldBlockActivityStartIgnoringFlags) { 2015 return true; 2016 } 2017 } 2018 2019 // ASM rules have failed. Log why 2020 ActivityRecord targetTopActivity = targetTask == null ? null 2021 : targetTask.getActivity(ar -> !ar.finishing && !ar.isAlwaysOnTop()); 2022 2023 int action = newTask || mSourceRecord == null 2024 ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK 2025 : (mSourceRecord.getTask().equals(targetTask) 2026 ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_SAME_TASK 2027 : FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_DIFFERENT_TASK); 2028 2029 FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, 2030 /* caller_uid */ 2031 mSourceRecord != null ? mSourceRecord.getUid() : mCallingUid, 2032 /* caller_activity_class_name */ 2033 mSourceRecord != null ? mSourceRecord.info.name : null, 2034 /* target_task_top_activity_uid */ 2035 targetTopActivity != null ? targetTopActivity.getUid() : -1, 2036 /* target_task_top_activity_class_name */ 2037 targetTopActivity != null ? targetTopActivity.info.name : null, 2038 /* target_task_is_different */ 2039 newTask || mSourceRecord == null || targetTask == null 2040 || !targetTask.equals(mSourceRecord.getTask()), 2041 /* target_activity_uid */ 2042 r.getUid(), 2043 /* target_activity_class_name */ 2044 r.info.name, 2045 /* target_intent_action */ 2046 r.intent.getAction(), 2047 /* target_intent_flags */ 2048 mLaunchFlags, 2049 /* action */ 2050 action, 2051 /* version */ 2052 ActivitySecurityModelFeatureFlags.ASM_VERSION, 2053 /* multi_window - we have our source not in the target task, but both are visible */ 2054 targetTask != null && mSourceRecord != null 2055 && !targetTask.equals(mSourceRecord.getTask()) && targetTask.isVisible(), 2056 /* bal_code */ 2057 mBalCode 2058 ); 2059 2060 boolean blockActivityStartAndFeatureEnabled = ActivitySecurityModelFeatureFlags 2061 .shouldRestrictActivitySwitch(mCallingUid) 2062 && shouldBlockActivityStart; 2063 2064 String launchedFromPackageName = r.launchedFromPackage; 2065 if (ActivitySecurityModelFeatureFlags.shouldShowToast(mCallingUid)) { 2066 String toastText = ActivitySecurityModelFeatureFlags.DOC_LINK 2067 + (blockActivityStartAndFeatureEnabled ? " blocked " : " would block ") 2068 + getApplicationLabel(mService.mContext.getPackageManager(), 2069 launchedFromPackageName); 2070 UiThread.getHandler().post(() -> Toast.makeText(mService.mContext, 2071 toastText, Toast.LENGTH_LONG).show()); 2072 2073 logDebugInfoForActivitySecurity("Launch", r, targetTask, targetTopActivity, 2074 blockActivityStartAndFeatureEnabled, /* taskToFront */ taskToFront); 2075 } 2076 2077 if (blockActivityStartAndFeatureEnabled) { 2078 Slog.e(TAG, "[ASM] Abort Launching r: " + r 2079 + " as source: " 2080 + (mSourceRecord != null ? mSourceRecord : launchedFromPackageName) 2081 + " is in background. New task: " + newTask 2082 + ". Top activity: " + targetTopActivity 2083 + ". BAL Code: " + balCodeToString(mBalCode)); 2084 2085 return false; 2086 } 2087 2088 return true; 2089 } 2090 2091 /** Only called when an activity launch may be blocked, which should happen very rarely */ logDebugInfoForActivitySecurity(String action, ActivityRecord r, Task targetTask, ActivityRecord targetTopActivity, boolean blockActivityStartAndFeatureEnabled, boolean taskToFront)2092 private void logDebugInfoForActivitySecurity(String action, ActivityRecord r, Task targetTask, 2093 ActivityRecord targetTopActivity, boolean blockActivityStartAndFeatureEnabled, 2094 boolean taskToFront) { 2095 final String prefix = "[ASM] "; 2096 Function<ActivityRecord, String> recordToString = (ar) -> { 2097 if (ar == null) { 2098 return null; 2099 } 2100 return (ar == mSourceRecord ? " [source]=> " 2101 : ar == targetTopActivity ? " [ top ]=> " 2102 : ar == r ? " [target]=> " 2103 : " => ") 2104 + ar 2105 + " :: visible=" + ar.isVisible() 2106 + ", finishing=" + ar.isFinishing() 2107 + ", alwaysOnTop=" + ar.isAlwaysOnTop() 2108 + ", taskFragment=" + ar.getTaskFragment(); 2109 }; 2110 2111 StringJoiner joiner = new StringJoiner("\n"); 2112 joiner.add(prefix + "------ Activity Security " + action + " Debug Logging Start ------"); 2113 joiner.add(prefix + "Block Enabled: " + blockActivityStartAndFeatureEnabled); 2114 joiner.add(prefix + "ASM Version: " + ActivitySecurityModelFeatureFlags.ASM_VERSION); 2115 2116 boolean targetTaskMatchesSourceTask = targetTask != null 2117 && mSourceRecord != null && mSourceRecord.getTask() == targetTask; 2118 2119 if (mSourceRecord == null) { 2120 joiner.add(prefix + "Source Package: " + r.launchedFromPackage); 2121 String realCallingPackage = mService.mContext.getPackageManager().getNameForUid( 2122 mRealCallingUid); 2123 joiner.add(prefix + "Real Calling Uid Package: " + realCallingPackage); 2124 } else { 2125 joiner.add(prefix + "Source Record: " + recordToString.apply(mSourceRecord)); 2126 if (targetTaskMatchesSourceTask) { 2127 joiner.add(prefix + "Source/Target Task: " + mSourceRecord.getTask()); 2128 joiner.add(prefix + "Source/Target Task Stack: "); 2129 } else { 2130 joiner.add(prefix + "Source Task: " + mSourceRecord.getTask()); 2131 joiner.add(prefix + "Source Task Stack: "); 2132 } 2133 mSourceRecord.getTask().forAllActivities((Consumer<ActivityRecord>) 2134 ar -> joiner.add(prefix + recordToString.apply(ar))); 2135 } 2136 2137 joiner.add(prefix + "Target Task Top: " + recordToString.apply(targetTopActivity)); 2138 if (!targetTaskMatchesSourceTask) { 2139 joiner.add(prefix + "Target Task: " + targetTask); 2140 if (targetTask != null) { 2141 joiner.add(prefix + "Target Task Stack: "); 2142 targetTask.forAllActivities((Consumer<ActivityRecord>) 2143 ar -> joiner.add(prefix + recordToString.apply(ar))); 2144 } 2145 } 2146 2147 joiner.add(prefix + "Target Record: " + recordToString.apply(r)); 2148 joiner.add(prefix + "Intent: " + mIntent); 2149 joiner.add(prefix + "TaskToFront: " + taskToFront); 2150 joiner.add(prefix + "BalCode: " + balCodeToString(mBalCode)); 2151 2152 joiner.add(prefix + "------ Activity Security " + action + " Debug Logging End ------"); 2153 Slog.i(TAG, joiner.toString()); 2154 } 2155 2156 /** 2157 * Returns whether embedding of {@code starting} is allowed. 2158 * 2159 * @param taskFragment the TaskFragment for embedding. 2160 * @param starting the starting activity. 2161 * @param targetTask the target task for launching activity, which could be different from 2162 * the one who hosting the embedding. 2163 */ 2164 @VisibleForTesting 2165 @EmbeddingCheckResult canEmbedActivity(@onNull TaskFragment taskFragment, @NonNull ActivityRecord starting, @NonNull Task targetTask)2166 static int canEmbedActivity(@NonNull TaskFragment taskFragment, 2167 @NonNull ActivityRecord starting, @NonNull Task targetTask) { 2168 final Task hostTask = taskFragment.getTask(); 2169 // Not allowed embedding a separate task or without host task. 2170 if (hostTask == null || targetTask != hostTask) { 2171 return EMBEDDING_DISALLOWED_NEW_TASK; 2172 } 2173 2174 return taskFragment.isAllowedToEmbedActivity(starting); 2175 } 2176 2177 /** 2178 * Prepare the target task to be reused for this launch, which including: 2179 * - Position the target task on valid root task on preferred display. 2180 * - Comply to the specified activity launch flags 2181 * - Determine whether need to add a new activity on top or just brought the task to front. 2182 */ 2183 @VisibleForTesting recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, NeededUriGrants intentGrants)2184 int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, 2185 NeededUriGrants intentGrants) { 2186 // Should not recycle task which is from a different user, just adding the starting 2187 // activity to the task. 2188 if (targetTask.mUserId != mStartActivity.mUserId) { 2189 mTargetRootTask = targetTask.getRootTask(); 2190 mAddingToTask = true; 2191 return START_SUCCESS; 2192 } 2193 2194 if (reusedTask != null) { 2195 if (targetTask.intent == null) { 2196 // This task was started because of movement of the activity based on 2197 // affinity... 2198 // Now that we are actually launching it, we can assign the base intent. 2199 targetTask.setIntent(mStartActivity); 2200 } else { 2201 final boolean taskOnHome = 2202 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0; 2203 if (taskOnHome) { 2204 targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME); 2205 } else { 2206 targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME); 2207 } 2208 } 2209 } 2210 2211 mRootWindowContainer.startPowerModeLaunchIfNeeded(false /* forceSend */, 2212 targetTaskTop); 2213 2214 setTargetRootTaskIfNeeded(targetTaskTop); 2215 2216 // When there is a reused activity and the current result is a trampoline activity, 2217 // set the reused activity as the result. 2218 if (mLastStartActivityRecord != null 2219 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) { 2220 mLastStartActivityRecord = targetTaskTop; 2221 } 2222 2223 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 2224 // We don't need to start a new activity, and the client said not to do anything 2225 // if that is the case, so this is it! And for paranoia, make sure we have 2226 // correctly resumed the top activity. 2227 if (!mMovedToFront && mDoResume) { 2228 ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetRootTask, 2229 targetTaskTop); 2230 mTargetRootTask.moveToFront("intentActivityFound"); 2231 } 2232 resumeTargetRootTaskIfNeeded(); 2233 return START_RETURN_INTENT_TO_CALLER; 2234 } 2235 2236 complyActivityFlags(targetTask, 2237 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants); 2238 2239 if (mAddingToTask) { 2240 clearTopIfNeeded(targetTask, mCallingUid, mRealCallingUid, mStartActivity.getUid(), 2241 mLaunchFlags); 2242 return START_SUCCESS; 2243 } 2244 2245 // The reusedActivity could be finishing, for example of starting an activity with 2246 // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, use the top running activity in the 2247 // task instead. 2248 targetTaskTop = targetTaskTop.finishing 2249 ? targetTask.getTopNonFinishingActivity() 2250 : targetTaskTop; 2251 2252 if (mMovedToFront) { 2253 // We moved the task to front, use starting window to hide initial drawn delay. 2254 targetTaskTop.showStartingWindow(true /* taskSwitch */); 2255 } else if (mDoResume) { 2256 // Make sure the root task and its belonging display are moved to topmost. 2257 mTargetRootTask.moveToFront("intentActivityFound"); 2258 } 2259 // We didn't do anything... but it was needed (a.k.a., client don't use that intent!) 2260 // And for paranoia, make sure we have correctly resumed the top activity. 2261 resumeTargetRootTaskIfNeeded(); 2262 2263 // This is moving an existing task to front. But since dream activity has a higher z-order 2264 // to cover normal activities, it needs the awakening event to be dismissed. 2265 if (mService.isDreaming() && targetTaskTop.canTurnScreenOn()) { 2266 targetTaskTop.mTaskSupervisor.wakeUp("recycleTask#turnScreenOnFlag"); 2267 } 2268 2269 mLastStartActivityRecord = targetTaskTop; 2270 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP; 2271 } 2272 2273 /** 2274 * If the top activity uid does not match the launching or launched activity, and the launch was 2275 * not requested from the top uid, we want to clear out all non matching activities to prevent 2276 * the top activity being sandwiched. 2277 * 2278 * Both creator and sender UID are considered for the launching activity. 2279 */ clearTopIfNeeded(@onNull Task targetTask, int callingUid, int realCallingUid, int startingUid, int launchFlags)2280 private void clearTopIfNeeded(@NonNull Task targetTask, int callingUid, int realCallingUid, 2281 int startingUid, int launchFlags) { 2282 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) != FLAG_ACTIVITY_NEW_TASK 2283 || mBalCode == BAL_ALLOW_ALLOWLISTED_UID) { 2284 // Launch is from the same task, (a top or privileged UID), or is directly privileged. 2285 return; 2286 } 2287 2288 Predicate<ActivityRecord> isLaunchingOrLaunched = ar -> 2289 ar.isUid(startingUid) || ar.isUid(callingUid) || ar.isUid(realCallingUid); 2290 2291 // Return early if we know for sure we won't need to clear any activities by just checking 2292 // the top activity. 2293 ActivityRecord targetTaskTop = targetTask.getTopMostActivity(); 2294 if (targetTaskTop == null || isLaunchingOrLaunched.test(targetTaskTop)) { 2295 return; 2296 } 2297 2298 // Find the first activity which matches a safe UID and is not finishing. Clear everything 2299 // above it 2300 boolean shouldBlockActivityStart = ActivitySecurityModelFeatureFlags 2301 .shouldRestrictActivitySwitch(callingUid); 2302 int[] finishCount = new int[0]; 2303 if (shouldBlockActivityStart) { 2304 ActivityRecord activity = targetTask.getActivity(isLaunchingOrLaunched); 2305 if (activity == null) { 2306 // mStartActivity is not in task, so clear everything 2307 activity = mStartActivity; 2308 } 2309 2310 finishCount = new int[1]; 2311 targetTask.performClearTop(activity, launchFlags, finishCount); 2312 if (finishCount[0] > 0) { 2313 Slog.w(TAG, "Cleared top n: " + finishCount[0] + " activities from task t: " 2314 + targetTask + " not matching top uid: " + callingUid); 2315 } 2316 } 2317 2318 if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid) 2319 && (!shouldBlockActivityStart || finishCount[0] > 0)) { 2320 UiThread.getHandler().post(() -> Toast.makeText(mService.mContext, 2321 (shouldBlockActivityStart 2322 ? "Top activities cleared by " 2323 : "Top activities would be cleared by ") 2324 + ActivitySecurityModelFeatureFlags.DOC_LINK, 2325 Toast.LENGTH_LONG).show()); 2326 2327 logDebugInfoForActivitySecurity("Clear Top", mStartActivity, targetTask, targetTaskTop, 2328 shouldBlockActivityStart, /* taskToFront */ true); 2329 } 2330 } 2331 2332 /** 2333 * Check if the activity being launched is the same as the one currently at the top and it 2334 * should only be launched once. 2335 */ deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants)2336 private int deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants) { 2337 final ActivityRecord top = topRootTask.topRunningNonDelayedActivityLocked(mNotTop); 2338 final boolean dontStart = top != null 2339 && top.mActivityComponent.equals(mStartActivity.mActivityComponent) 2340 && top.mUserId == mStartActivity.mUserId 2341 && top.attachedToProcess() 2342 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 2343 || LAUNCH_SINGLE_TOP == mLaunchMode) 2344 // This allows home activity to automatically launch on secondary task display area 2345 // when it was added, if home was the top activity on default task display area, 2346 // instead of sending new intent to the home activity on default display area. 2347 && (!top.isActivityTypeHome() || top.getDisplayArea() == mPreferredTaskDisplayArea); 2348 if (!dontStart) { 2349 return START_SUCCESS; 2350 } 2351 2352 // For paranoia, make sure we have correctly resumed the top activity. 2353 top.getTaskFragment().clearLastPausedActivity(); 2354 if (mDoResume) { 2355 mRootWindowContainer.resumeFocusedTasksTopActivities(); 2356 } 2357 ActivityOptions.abort(mOptions); 2358 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 2359 // We don't need to start a new activity, and the client said not to do anything if 2360 // that is the case, so this is it! 2361 return START_RETURN_INTENT_TO_CALLER; 2362 } 2363 2364 if (mStartActivity.resultTo != null) { 2365 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho, 2366 mStartActivity.requestCode, RESULT_CANCELED, 2367 null /* data */, null /* dataGrants */); 2368 mStartActivity.resultTo = null; 2369 } 2370 2371 deliverNewIntent(top, intentGrants); 2372 2373 // Don't use mStartActivity.task to show the toast. We're not starting a new activity but 2374 // reusing 'top'. Fields in mStartActivity may not be fully initialized. 2375 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), 2376 mLaunchParams.mWindowingMode, mPreferredTaskDisplayArea, topRootTask); 2377 2378 return START_DELIVERED_TO_TOP; 2379 } 2380 2381 /** 2382 * Applying the launching flags to the task, which might clear few or all the activities in the 2383 * task. 2384 */ complyActivityFlags(Task targetTask, ActivityRecord reusedActivity, NeededUriGrants intentGrants)2385 private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity, 2386 NeededUriGrants intentGrants) { 2387 ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity(); 2388 final boolean resetTask = 2389 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0; 2390 if (resetTask) { 2391 targetTaskTop = mTargetRootTask.resetTaskIfNeeded(targetTaskTop, mStartActivity); 2392 } 2393 2394 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 2395 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) { 2396 // The caller has requested to completely replace any existing task with its new 2397 // activity. Well that should not be too hard... 2398 // Note: we must persist the {@link Task} first as intentActivity could be 2399 // removed from calling performClearTaskLocked (For example, if it is being brought out 2400 // of history or if it is finished immediately), thus disassociating the task. Keep the 2401 // task-overlay activity because the targetTask will be reused to launch new activity. 2402 targetTask.performClearTaskForReuse(true /* excludingTaskOverlay*/); 2403 targetTask.setIntent(mStartActivity); 2404 mAddingToTask = true; 2405 mIsTaskCleared = true; 2406 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 2407 || isDocumentLaunchesIntoExisting(mLaunchFlags) 2408 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK, 2409 LAUNCH_SINGLE_INSTANCE_PER_TASK)) { 2410 // In this situation we want to remove all activities from the task up to the one 2411 // being started. In most cases this means we are resetting the task to its initial 2412 // state. 2413 int[] finishCount = new int[1]; 2414 final ActivityRecord clearTop = targetTask.performClearTop(mStartActivity, 2415 mLaunchFlags, finishCount); 2416 2417 if (clearTop != null && !clearTop.finishing) { 2418 if (finishCount[0] > 0) { 2419 // Only record if actually moved to top. 2420 mMovedToTopActivity = clearTop; 2421 } 2422 if (clearTop.isRootOfTask()) { 2423 // Activity aliases may mean we use different intents for the top activity, 2424 // so make sure the task now has the identity of the new intent. 2425 clearTop.getTask().setIntent(mStartActivity); 2426 } 2427 deliverNewIntent(clearTop, intentGrants); 2428 } else { 2429 // A special case: we need to start the activity because it is not currently 2430 // running, and the caller has asked to clear the current task to have this 2431 // activity at the top. 2432 mAddingToTask = true; 2433 // Adding the new activity to the same embedded TF of the clear-top activity if 2434 // possible. 2435 if (clearTop != null && clearTop.getTaskFragment() != null 2436 && clearTop.getTaskFragment().isEmbedded()) { 2437 mAddingToTaskFragment = clearTop.getTaskFragment(); 2438 } 2439 if (targetTask.getRootTask() == null) { 2440 // Target root task got cleared when we all activities were removed above. 2441 // Go ahead and reset it. 2442 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, 2443 null /* task */, mOptions); 2444 mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */, 2445 (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0); 2446 } 2447 } 2448 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask 2449 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 2450 // In this case, we are launching an activity in our own task that may 2451 // already be running somewhere in the history, and we want to shuffle it to 2452 // the front of the root task if so. 2453 final ActivityRecord act = 2454 targetTask.findActivityInHistory(mStartActivity.mActivityComponent, 2455 mStartActivity.mUserId); 2456 if (act != null) { 2457 final Task task = act.getTask(); 2458 boolean actuallyMoved = task.moveActivityToFront(act); 2459 if (actuallyMoved) { 2460 // Only record if the activity actually moved. 2461 mMovedToTopActivity = act; 2462 if (mNoAnimation) { 2463 act.mDisplayContent.prepareAppTransition(TRANSIT_NONE); 2464 } else { 2465 act.mDisplayContent.prepareAppTransition(TRANSIT_TO_FRONT); 2466 } 2467 } 2468 act.updateOptionsLocked(mOptions); 2469 deliverNewIntent(act, intentGrants); 2470 act.getTaskFragment().clearLastPausedActivity(); 2471 } else { 2472 mAddingToTask = true; 2473 } 2474 } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) { 2475 if (targetTask == mInTask) { 2476 // In this case we are bringing up an existing activity from a recent task. We 2477 // don't need to add a new activity instance on top. 2478 } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 2479 || LAUNCH_SINGLE_TOP == mLaunchMode) 2480 && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent) 2481 && mStartActivity.resultTo == null) { 2482 // In this case the top activity on the task is the same as the one being launched, 2483 // so we take that as a request to bring the task to the foreground. If the top 2484 // activity in the task is the root activity, deliver this new intent to it if it 2485 // desires. 2486 if (targetTaskTop.isRootOfTask()) { 2487 targetTaskTop.getTask().setIntent(mStartActivity); 2488 } 2489 deliverNewIntent(targetTaskTop, intentGrants); 2490 } else if (!targetTask.isSameIntentFilter(mStartActivity)) { 2491 // In this case we are launching the root activity of the task, but with a 2492 // different intent. We should start a new instance on top. 2493 mAddingToTask = true; 2494 } else if (reusedActivity == null) { 2495 mAddingToTask = true; 2496 } 2497 } else if (!resetTask) { 2498 // In this case an activity is being launched in to an existing task, without 2499 // resetting that task. This is typically the situation of launching an activity 2500 // from a notification or shortcut. We want to place the new activity on top of the 2501 // current task. 2502 mAddingToTask = true; 2503 } else if (!targetTask.rootWasReset) { 2504 // In this case we are launching into an existing task that has not yet been started 2505 // from its front door. The current task has been brought to the front. Ideally, 2506 // we'd probably like to place this new task at the bottom of its root task, but that's 2507 // a little hard to do with the current organization of the code so for now we'll 2508 // just drop it. 2509 targetTask.setIntent(mStartActivity); 2510 } 2511 } 2512 2513 /** 2514 * Resets the {@link ActivityStarter} state. 2515 * @param clearRequest whether the request should be reset to default values. 2516 */ reset(boolean clearRequest)2517 void reset(boolean clearRequest) { 2518 mStartActivity = null; 2519 mIntent = null; 2520 mCallingUid = -1; 2521 mRealCallingUid = -1; 2522 mOptions = null; 2523 mBalCode = BAL_ALLOW_DEFAULT; 2524 2525 mLaunchTaskBehind = false; 2526 mLaunchFlags = 0; 2527 mLaunchMode = INVALID_LAUNCH_MODE; 2528 2529 mLaunchParams.reset(); 2530 2531 mNotTop = null; 2532 mDoResume = false; 2533 mStartFlags = 0; 2534 mSourceRecord = null; 2535 mPreferredTaskDisplayArea = null; 2536 mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED; 2537 2538 mInTask = null; 2539 mInTaskFragment = null; 2540 mAddingToTaskFragment = null; 2541 mAddingToTask = false; 2542 2543 mSourceRootTask = null; 2544 2545 mTargetRootTask = null; 2546 mTargetTask = null; 2547 mIsTaskCleared = false; 2548 mMovedToFront = false; 2549 mNoAnimation = false; 2550 mAvoidMoveToFront = false; 2551 mFrozeTaskList = false; 2552 mTransientLaunch = false; 2553 mPriorAboveTask = null; 2554 mDisplayLockAndOccluded = false; 2555 2556 mVoiceSession = null; 2557 mVoiceInteractor = null; 2558 2559 mIntentDelivered = false; 2560 2561 if (clearRequest) { 2562 mRequest.reset(); 2563 } 2564 } 2565 setInitialState(ActivityRecord r, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, @BalCode int balCode, int realCallingUid)2566 private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask, 2567 TaskFragment inTaskFragment, int startFlags, 2568 ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, 2569 IVoiceInteractor voiceInteractor, @BalCode int balCode, int realCallingUid) { 2570 reset(false /* clearRequest */); 2571 2572 mStartActivity = r; 2573 mIntent = r.intent; 2574 mOptions = options; 2575 mCallingUid = r.launchedFromUid; 2576 mRealCallingUid = realCallingUid; 2577 mSourceRecord = sourceRecord; 2578 mSourceRootTask = mSourceRecord != null ? mSourceRecord.getRootTask() : null; 2579 mVoiceSession = voiceSession; 2580 mVoiceInteractor = voiceInteractor; 2581 mBalCode = balCode; 2582 2583 mLaunchParams.reset(); 2584 2585 // Preferred display id is the only state we need for now and it could be updated again 2586 // after we located a reusable task (which might be resided in another display). 2587 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r, 2588 sourceRecord, options, mRequest, PHASE_DISPLAY, mLaunchParams); 2589 mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() 2590 ? mLaunchParams.mPreferredTaskDisplayArea 2591 : mRootWindowContainer.getDefaultTaskDisplayArea(); 2592 mPreferredWindowingMode = mLaunchParams.mWindowingMode; 2593 2594 mLaunchMode = r.launchMode; 2595 2596 mLaunchFlags = adjustLaunchFlagsToDocumentMode( 2597 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode, 2598 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags()); 2599 mLaunchTaskBehind = r.mLaunchTaskBehind 2600 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE) 2601 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0; 2602 2603 if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) { 2604 // Adding NEW_TASK flag for singleInstancePerTask launch mode activity, so that the 2605 // activity won't be launched in source record's task. 2606 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2607 } 2608 2609 if (r.info.requiredDisplayCategory != null && mSourceRecord != null 2610 && !r.info.requiredDisplayCategory.equals( 2611 mSourceRecord.info.requiredDisplayCategory)) { 2612 // Adding NEW_TASK flag for activity with display category attribute if the display 2613 // category of the source record is different, so that the activity won't be launched 2614 // in source record's task. 2615 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2616 } 2617 2618 sendNewTaskResultRequestIfNeeded(); 2619 2620 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) { 2621 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2622 } 2623 2624 // If we are actually going to launch in to a new task, there are some cases where 2625 // we further want to do multiple task. 2626 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 2627 if (mLaunchTaskBehind 2628 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) { 2629 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK; 2630 } 2631 } 2632 2633 // We'll invoke onUserLeaving before onPause only if the launching 2634 // activity did not explicitly state that this is an automated launch. 2635 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0; 2636 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, 2637 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving); 2638 2639 // If the caller has asked not to resume at this point, we make note 2640 // of this in the record so that we can skip it when trying to find 2641 // the top running activity. 2642 if (!r.showToCurrentUser() || mLaunchTaskBehind) { 2643 r.delayedResume = true; 2644 mDoResume = false; 2645 } else { 2646 mDoResume = true; 2647 } 2648 2649 if (mOptions != null) { 2650 if (mOptions.getLaunchTaskId() != INVALID_TASK_ID && mOptions.getTaskOverlay()) { 2651 r.setTaskOverlay(true); 2652 if (!mOptions.canTaskOverlayResume()) { 2653 final Task task = mRootWindowContainer.anyTaskForId( 2654 mOptions.getLaunchTaskId()); 2655 final ActivityRecord top = task != null 2656 ? task.getTopNonFinishingActivity() : null; 2657 if (top != null && !top.isState(RESUMED)) { 2658 2659 // The caller specifies that we'd like to be avoided to be moved to the 2660 // front, so be it! 2661 mDoResume = false; 2662 mAvoidMoveToFront = true; 2663 } 2664 } 2665 } else if (mOptions.getAvoidMoveToFront()) { 2666 mDoResume = false; 2667 mAvoidMoveToFront = true; 2668 } 2669 mTransientLaunch = mOptions.getTransientLaunch(); 2670 final KeyguardController kc = mSupervisor.getKeyguardController(); 2671 final int displayId = mPreferredTaskDisplayArea.getDisplayId(); 2672 mDisplayLockAndOccluded = kc.isKeyguardLocked(displayId) 2673 && kc.isDisplayOccluded(displayId); 2674 // Recents animation on lock screen, do not resume & move launcher to top. 2675 if (mTransientLaunch && mDisplayLockAndOccluded 2676 && mService.getTransitionController().isShellTransitionsEnabled()) { 2677 mDoResume = false; 2678 mAvoidMoveToFront = true; 2679 } 2680 mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); 2681 2682 if (inTaskFragment == null) { 2683 inTaskFragment = TaskFragment.fromTaskFragmentToken( 2684 mOptions.getLaunchTaskFragmentToken(), mService); 2685 if (inTaskFragment != null && inTaskFragment.isEmbeddedTaskFragmentInPip()) { 2686 // Do not start activity in TaskFragment in a PIP Task. 2687 Slog.w(TAG, "Can not start activity in TaskFragment in PIP: " 2688 + inTaskFragment); 2689 inTaskFragment = null; 2690 } 2691 } 2692 } 2693 2694 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null; 2695 2696 mInTask = inTask; 2697 // In some flows in to this function, we retrieve the task record and hold on to it 2698 // without a lock before calling back in to here... so the task at this point may 2699 // not actually be in recents. Check for that, and if it isn't in recents just 2700 // consider it invalid. 2701 if (inTask != null && !inTask.inRecents) { 2702 Slog.w(TAG, "Starting activity in task not in recents: " + inTask); 2703 mInTask = null; 2704 } 2705 // Prevent to start activity in Task with different display category 2706 if (mInTask != null && !mInTask.isSameRequiredDisplayCategory(r.info)) { 2707 Slog.w(TAG, "Starting activity in task with different display category: " 2708 + mInTask); 2709 mInTask = null; 2710 } 2711 mInTaskFragment = inTaskFragment; 2712 2713 mStartFlags = startFlags; 2714 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched 2715 // is the same as the one making the call... or, as a special case, if we do not know 2716 // the caller then we count the current top activity as the caller. 2717 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 2718 ActivityRecord checkedCaller = sourceRecord; 2719 if (checkedCaller == null) { 2720 Task topFocusedRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); 2721 if (topFocusedRootTask != null) { 2722 checkedCaller = topFocusedRootTask.topRunningNonDelayedActivityLocked(mNotTop); 2723 } 2724 } 2725 if (checkedCaller == null 2726 || !checkedCaller.mActivityComponent.equals(r.mActivityComponent)) { 2727 // Caller is not the same as launcher, so always needed. 2728 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED; 2729 } 2730 } 2731 2732 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; 2733 2734 if (mBalCode == BAL_BLOCK && !mService.isBackgroundActivityStartsEnabled()) { 2735 mAvoidMoveToFront = true; 2736 mDoResume = false; 2737 } 2738 } 2739 sendNewTaskResultRequestIfNeeded()2740 private void sendNewTaskResultRequestIfNeeded() { 2741 if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 2742 // For whatever reason this activity is being launched into a new task... 2743 // yet the caller has requested a result back. Well, that is pretty messed up, 2744 // so instead immediately send back a cancel and let the new task continue launched 2745 // as normal without a dependency on its originator. 2746 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 2747 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho, 2748 mStartActivity.requestCode, RESULT_CANCELED, 2749 null /* data */, null /* dataGrants */); 2750 mStartActivity.resultTo = null; 2751 } 2752 } 2753 computeLaunchingTaskFlags()2754 private void computeLaunchingTaskFlags() { 2755 // If the caller is not coming from another activity, but has given us an explicit task into 2756 // which they would like us to launch the new activity, then let's see about doing that. 2757 if (mSourceRecord == null && mInTask != null && mInTask.getRootTask() != null) { 2758 final Intent baseIntent = mInTask.getBaseIntent(); 2759 final ActivityRecord root = mInTask.getRootActivity(); 2760 if (baseIntent == null) { 2761 ActivityOptions.abort(mOptions); 2762 throw new IllegalArgumentException("Launching into task without base intent: " 2763 + mInTask); 2764 } 2765 2766 // If this task is empty, then we are adding the first activity -- it 2767 // determines the root, and must be launching as a NEW_TASK. 2768 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { 2769 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) { 2770 ActivityOptions.abort(mOptions); 2771 throw new IllegalArgumentException("Trying to launch singleInstance/Task " 2772 + mStartActivity + " into different task " + mInTask); 2773 } 2774 if (root != null) { 2775 ActivityOptions.abort(mOptions); 2776 throw new IllegalArgumentException("Caller with mInTask " + mInTask 2777 + " has root " + root + " but target is singleInstance/Task"); 2778 } 2779 } 2780 2781 // If task is empty, then adopt the interesting intent launch flags in to the 2782 // activity being started. 2783 if (root == null) { 2784 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK 2785 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS; 2786 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest) 2787 | (baseIntent.getFlags() & flagsOfInterest); 2788 mIntent.setFlags(mLaunchFlags); 2789 mInTask.setIntent(mStartActivity); 2790 mAddingToTask = true; 2791 2792 // If the task is not empty and the caller is asking to start it as the root of 2793 // a new task, then we don't actually want to start this on the task. We will 2794 // bring the task to the front, and possibly give it a new intent. 2795 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 2796 mAddingToTask = false; 2797 2798 } else { 2799 mAddingToTask = true; 2800 } 2801 } else { 2802 mInTask = null; 2803 // Launch ResolverActivity in the source task, so that it stays in the task bounds 2804 // when in freeform workspace. 2805 // Also put noDisplay activities in the source task. These by itself can be placed 2806 // in any task/root-task, however it could launch other activities like 2807 // ResolverActivity, and we want those to stay in the original task. 2808 if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay) 2809 && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) { 2810 mAddingToTask = true; 2811 } 2812 } 2813 2814 if (mInTask == null) { 2815 if (mSourceRecord == null) { 2816 // This activity is not being started from another... in this 2817 // case we -always- start a new task. 2818 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) { 2819 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 2820 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent); 2821 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2822 } 2823 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) { 2824 // The original activity who is starting us is running as a single 2825 // instance... this new activity it is starting must go on its 2826 // own task. 2827 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2828 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) { 2829 // The activity being started is a single instance... it always 2830 // gets launched into its own task. 2831 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 2832 } 2833 } 2834 2835 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0 2836 && ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 || mSourceRecord == null)) { 2837 // ignore the flag if there is no the sourceRecord or without new_task flag 2838 mLaunchFlags &= ~FLAG_ACTIVITY_LAUNCH_ADJACENT; 2839 } 2840 } 2841 2842 /** 2843 * Decide whether the new activity should be inserted into an existing task. Returns null 2844 * if not or an ActivityRecord with the task into which the new activity should be added. 2845 */ getReusableTask()2846 private Task getReusableTask() { 2847 // If a target task is specified, try to reuse that one 2848 if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) { 2849 Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId()); 2850 if (launchTask != null) { 2851 return launchTask; 2852 } 2853 return null; 2854 } 2855 2856 // We may want to try to place the new activity in to an existing task. We always 2857 // do this if the target activity is singleTask or singleInstance; we will also do 2858 // this if NEW_TASK has been requested, and there is not an additional qualifier telling 2859 // us to still place it in a new task: multi task, always doc mode, or being asked to 2860 // launch this as a new task behind the current one. 2861 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 && 2862 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 2863 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK); 2864 // If bring to front is requested, and no result is requested and we have not been given 2865 // an explicit task to launch in to, and we can find a task that was started with this 2866 // same component, then instead of launching bring that one to the front. 2867 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null; 2868 ActivityRecord intentActivity = null; 2869 if (putIntoExistingTask) { 2870 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) { 2871 // There can be one and only one instance of single instance activity in the 2872 // history, and it is always in its own unique task, so we do a special search. 2873 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info, 2874 mStartActivity.isActivityTypeHome()); 2875 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) { 2876 // For the launch adjacent case we only want to put the activity in an existing 2877 // task if the activity already exists in the history. 2878 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info, 2879 !(LAUNCH_SINGLE_TASK == mLaunchMode)); 2880 } else { 2881 // Otherwise find the best task to put the activity in. 2882 intentActivity = 2883 mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea); 2884 } 2885 } 2886 2887 if (intentActivity != null && mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK 2888 && !intentActivity.getTask().getRootActivity().mActivityComponent.equals( 2889 mStartActivity.mActivityComponent)) { 2890 // The task could be selected due to same task affinity. Do not reuse the task while 2891 // starting the singleInstancePerTask activity if it is not the task root activity. 2892 intentActivity = null; 2893 } 2894 2895 if (intentActivity != null 2896 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome()) 2897 && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) { 2898 // Do not reuse home activity on other display areas. 2899 intentActivity = null; 2900 } 2901 2902 return intentActivity != null ? intentActivity.getTask() : null; 2903 } 2904 2905 /** 2906 * Figure out which task and activity to bring to front when we have found an existing matching 2907 * activity record in history. May also clear the task if needed. 2908 * 2909 * @param intentActivity Existing matching activity. 2910 * @return {@link ActivityRecord} brought to front. 2911 */ setTargetRootTaskIfNeeded(ActivityRecord intentActivity)2912 private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) { 2913 intentActivity.getTaskFragment().clearLastPausedActivity(); 2914 Task intentTask = intentActivity.getTask(); 2915 // The intent task might be reparented while in getOrCreateRootTask, caches the original 2916 // root task to distinguish if it is moving to front or not. 2917 final Task origRootTask = intentTask != null ? intentTask.getRootTask() : null; 2918 2919 if (mTargetRootTask == null) { 2920 // Update launch target task when it is not indicated. 2921 if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) { 2922 // Inherit the target-root-task from source to ensure trampoline activities will be 2923 // launched into the same root task. 2924 mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask); 2925 } else { 2926 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask, 2927 mOptions); 2928 } 2929 } 2930 2931 // If the matching task is already in the adjacent task of the launch target. Adjust to use 2932 // the adjacent task as its launch target. So the existing task will be launched into the 2933 // closer one and won't be reparent redundantly. 2934 final Task adjacentTargetTask = mTargetRootTask.getAdjacentTask(); 2935 if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask) 2936 && intentTask.isOnTop()) { 2937 mTargetRootTask = adjacentTargetTask; 2938 } 2939 2940 // If the target task is not in the front, then we need to bring it to the front... 2941 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have 2942 // the same behavior as if a new instance was being started, which means not bringing it 2943 // to the front if the caller is not itself in the front. 2944 final boolean differentTopTask; 2945 if (mTargetRootTask.getDisplayArea() == mPreferredTaskDisplayArea) { 2946 final Task focusRootTask = mTargetRootTask.mDisplayContent.getFocusedRootTask(); 2947 final ActivityRecord curTop = (focusRootTask == null) 2948 ? null : focusRootTask.topRunningNonDelayedActivityLocked(mNotTop); 2949 final Task topTask = curTop != null ? curTop.getTask() : null; 2950 differentTopTask = topTask != intentTask 2951 || (focusRootTask != null && topTask != focusRootTask.getTopMostTask()) 2952 || (focusRootTask != null && focusRootTask != origRootTask); 2953 } else { 2954 // The existing task should always be different from those in other displays. 2955 differentTopTask = true; 2956 } 2957 2958 if (differentTopTask && !mAvoidMoveToFront) { 2959 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 2960 if (mSourceRecord == null || inTopNonFinishingTask(mSourceRecord)) { 2961 // We really do want to push this one into the user's face, right now. 2962 if (mLaunchTaskBehind && mSourceRecord != null) { 2963 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask()); 2964 } 2965 2966 if (intentActivity.isDescendantOf(mTargetRootTask)) { 2967 // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels 2968 // tasks hierarchies. 2969 if (mTargetRootTask != intentTask 2970 && mTargetRootTask != intentTask.getParent().asTask()) { 2971 intentTask.getParent().positionChildAt(POSITION_TOP, intentTask, 2972 false /* includingParents */); 2973 intentTask = intentTask.getParent().asTaskFragment().getTask(); 2974 } 2975 // If the activity is visible in multi-windowing mode, it may already be on 2976 // the top (visible to user but not the global top), then the result code 2977 // should be START_DELIVERED_TO_TOP instead of START_TASK_TO_FRONT. 2978 final boolean wasTopOfVisibleRootTask = intentActivity.isVisibleRequested() 2979 && intentActivity.inMultiWindowMode() 2980 && intentActivity == mTargetRootTask.topRunningActivity(); 2981 // We only want to move to the front, if we aren't going to launch on a 2982 // different root task. If we launch on a different root task, we will put the 2983 // task on top there. 2984 // Defer resuming the top activity while moving task to top, since the 2985 // current task-top activity may not be the activity that should be resumed. 2986 mTargetRootTask.moveTaskToFront(intentTask, mNoAnimation, mOptions, 2987 mStartActivity.appTimeTracker, DEFER_RESUME, 2988 "bringingFoundTaskToFront"); 2989 mMovedToFront = !wasTopOfVisibleRootTask; 2990 } else if (intentActivity.getWindowingMode() != WINDOWING_MODE_PINNED) { 2991 // Leaves reparenting pinned task operations to task organizer to make sure it 2992 // dismisses pinned task properly. 2993 // TODO(b/199997762): Consider leaving all reparent operation of organized tasks 2994 // to task organizer. 2995 intentTask.reparent(mTargetRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT, 2996 ANIMATE, DEFER_RESUME, "reparentToTargetRootTask"); 2997 mMovedToFront = true; 2998 } 2999 mOptions = null; 3000 } 3001 } 3002 3003 // Update the target's launch cookie and pending remote animation to those specified in the 3004 // options if set. 3005 if (mStartActivity.mLaunchCookie != null) { 3006 intentActivity.mLaunchCookie = mStartActivity.mLaunchCookie; 3007 } 3008 if (mStartActivity.mPendingRemoteAnimation != null) { 3009 intentActivity.mPendingRemoteAnimation = mStartActivity.mPendingRemoteAnimation; 3010 } 3011 3012 // Need to update mTargetRootTask because if task was moved out of it, the original root 3013 // task may be destroyed. 3014 mTargetRootTask = intentActivity.getRootTask(); 3015 mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED, 3016 mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetRootTask); 3017 } 3018 inTopNonFinishingTask(ActivityRecord r)3019 private boolean inTopNonFinishingTask(ActivityRecord r) { 3020 if (r == null || r.getTask() == null) { 3021 return false; 3022 } 3023 3024 final Task rTask = r.getTask(); 3025 final Task parent = rTask.getCreatedByOrganizerTask() != null 3026 ? rTask.getCreatedByOrganizerTask() : r.getRootTask(); 3027 final ActivityRecord topNonFinishingActivity = parent != null 3028 ? parent.getTopNonFinishingActivity() : null; 3029 3030 return topNonFinishingActivity != null && topNonFinishingActivity.getTask() == rTask; 3031 } 3032 resumeTargetRootTaskIfNeeded()3033 private void resumeTargetRootTaskIfNeeded() { 3034 if (mDoResume) { 3035 final ActivityRecord next = mTargetRootTask.topRunningActivity( 3036 true /* focusableOnly */); 3037 if (next != null) { 3038 next.setCurrentLaunchCanTurnScreenOn(true); 3039 } 3040 if (mTargetRootTask.isFocusable()) { 3041 mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, null, 3042 mOptions, mTransientLaunch); 3043 } else { 3044 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 3045 } 3046 } else { 3047 ActivityOptions.abort(mOptions); 3048 } 3049 mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask); 3050 } 3051 setNewTask(Task taskToAffiliate)3052 private void setNewTask(Task taskToAffiliate) { 3053 final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront; 3054 final Task task = mTargetRootTask.reuseOrCreateTask( 3055 mStartActivity.info, mIntent, mVoiceSession, 3056 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions); 3057 task.mTransitionController.collectExistenceChange(task); 3058 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask"); 3059 3060 ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s", 3061 mStartActivity, mStartActivity.getTask()); 3062 3063 if (taskToAffiliate != null) { 3064 mStartActivity.setTaskToAffiliateWith(taskToAffiliate); 3065 } 3066 } 3067 deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants)3068 private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) { 3069 if (mIntentDelivered) { 3070 return; 3071 } 3072 3073 activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask()); 3074 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants, 3075 mStartActivity.launchedFromPackage); 3076 mIntentDelivered = true; 3077 } 3078 3079 /** Places {@link #mStartActivity} in {@code task} or an embedded {@link TaskFragment}. */ addOrReparentStartingActivity(@onNull Task task, String reason)3080 private void addOrReparentStartingActivity(@NonNull Task task, String reason) { 3081 TaskFragment newParent = task; 3082 if (mInTaskFragment != null) { 3083 int embeddingCheckResult = canEmbedActivity(mInTaskFragment, mStartActivity, task); 3084 if (embeddingCheckResult == EMBEDDING_ALLOWED) { 3085 newParent = mInTaskFragment; 3086 mStartActivity.mRequestedLaunchingTaskFragmentToken = 3087 mInTaskFragment.getFragmentToken(); 3088 } else { 3089 // Start mStartActivity to task instead if it can't be embedded to mInTaskFragment. 3090 sendCanNotEmbedActivityError(mInTaskFragment, embeddingCheckResult); 3091 } 3092 } else { 3093 TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null; 3094 if (candidateTf == null) { 3095 final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */); 3096 if (top != null) { 3097 candidateTf = top.getTaskFragment(); 3098 } 3099 } 3100 if (candidateTf != null && candidateTf.isEmbedded() 3101 && canEmbedActivity(candidateTf, mStartActivity, task) == EMBEDDING_ALLOWED) { 3102 // Use the embedded TaskFragment of the top activity as the new parent if the 3103 // activity can be embedded. 3104 newParent = candidateTf; 3105 } 3106 } 3107 if (mStartActivity.getTaskFragment() == null 3108 || mStartActivity.getTaskFragment() == newParent) { 3109 newParent.addChild(mStartActivity, POSITION_TOP); 3110 } else { 3111 mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason); 3112 } 3113 } 3114 3115 /** 3116 * Notifies the client side that {@link #mStartActivity} cannot be embedded to 3117 * {@code taskFragment}. 3118 */ sendCanNotEmbedActivityError(TaskFragment taskFragment, @EmbeddingCheckResult int result)3119 private void sendCanNotEmbedActivityError(TaskFragment taskFragment, 3120 @EmbeddingCheckResult int result) { 3121 final String errMsg; 3122 switch(result) { 3123 case EMBEDDING_DISALLOWED_NEW_TASK: { 3124 errMsg = "Cannot embed " + mStartActivity + " that launched on another task" 3125 + ",mLaunchMode=" + launchModeToString(mLaunchMode) 3126 + ",mLaunchFlag=" + Integer.toHexString(mLaunchFlags); 3127 break; 3128 } 3129 case EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION: { 3130 errMsg = "Cannot embed " + mStartActivity 3131 + ". TaskFragment's bounds:" + taskFragment.getBounds() 3132 + ", minimum dimensions:" + mStartActivity.getMinDimensions(); 3133 break; 3134 } 3135 case EMBEDDING_DISALLOWED_UNTRUSTED_HOST: { 3136 errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity; 3137 break; 3138 } 3139 default: 3140 errMsg = "Unhandled embed result:" + result; 3141 } 3142 if (taskFragment.isOrganized()) { 3143 mService.mWindowOrganizerController.sendTaskFragmentOperationFailure( 3144 taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken, 3145 taskFragment, OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT, 3146 new SecurityException(errMsg)); 3147 } else { 3148 // If the taskFragment is not organized, just dump error message as warning logs. 3149 Slog.w(TAG, errMsg); 3150 } 3151 } 3152 adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, boolean launchSingleTask, int launchFlags)3153 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, 3154 boolean launchSingleTask, int launchFlags) { 3155 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 3156 (launchSingleInstance || launchSingleTask)) { 3157 // We have a conflict between the Intent and the Activity manifest, manifest wins. 3158 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 3159 "\"singleInstance\" or \"singleTask\""); 3160 launchFlags &= 3161 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK); 3162 } else { 3163 switch (r.info.documentLaunchMode) { 3164 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 3165 break; 3166 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 3167 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 3168 break; 3169 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 3170 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 3171 break; 3172 case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 3173 if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) { 3174 // Remove MULTIPLE_TASK flag along with NEW_DOCUMENT only if NEW_DOCUMENT 3175 // is set, otherwise we still want to keep the MULTIPLE_TASK flag (if 3176 // any) for singleInstancePerTask that the multiple tasks can be created, 3177 // or a singleInstancePerTask activity is basically the same as a 3178 // singleTask activity when documentLaunchMode set to never. 3179 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 3180 launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT 3181 | FLAG_ACTIVITY_MULTIPLE_TASK); 3182 } 3183 } else { 3184 // TODO(b/184903976): Should FLAG_ACTIVITY_MULTIPLE_TASK always be 3185 // removed for document-never activity? 3186 launchFlags &= 3187 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK); 3188 } 3189 break; 3190 } 3191 } 3192 return launchFlags; 3193 } 3194 getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions)3195 private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, 3196 ActivityOptions aOptions) { 3197 final boolean onTop = 3198 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; 3199 final Task sourceTask = mSourceRecord != null ? mSourceRecord.getTask() : null; 3200 return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, sourceTask, onTop, 3201 mLaunchParams, launchFlags); 3202 } 3203 isLaunchModeOneOf(int mode1, int mode2)3204 private boolean isLaunchModeOneOf(int mode1, int mode2) { 3205 return mode1 == mLaunchMode || mode2 == mLaunchMode; 3206 } 3207 isLaunchModeOneOf(int mode1, int mode2, int mode3)3208 private boolean isLaunchModeOneOf(int mode1, int mode2, int mode3) { 3209 return mode1 == mLaunchMode || mode2 == mLaunchMode || mode3 == mLaunchMode; 3210 } 3211 isDocumentLaunchesIntoExisting(int flags)3212 static boolean isDocumentLaunchesIntoExisting(int flags) { 3213 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 3214 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0; 3215 } 3216 setIntent(Intent intent)3217 ActivityStarter setIntent(Intent intent) { 3218 mRequest.intent = intent; 3219 return this; 3220 } 3221 getIntent()3222 Intent getIntent() { 3223 return mRequest.intent; 3224 } 3225 setIntentGrants(NeededUriGrants intentGrants)3226 ActivityStarter setIntentGrants(NeededUriGrants intentGrants) { 3227 mRequest.intentGrants = intentGrants; 3228 return this; 3229 } 3230 setReason(String reason)3231 ActivityStarter setReason(String reason) { 3232 mRequest.reason = reason; 3233 return this; 3234 } 3235 setCaller(IApplicationThread caller)3236 ActivityStarter setCaller(IApplicationThread caller) { 3237 mRequest.caller = caller; 3238 return this; 3239 } 3240 setResolvedType(String type)3241 ActivityStarter setResolvedType(String type) { 3242 mRequest.resolvedType = type; 3243 return this; 3244 } 3245 setActivityInfo(ActivityInfo info)3246 ActivityStarter setActivityInfo(ActivityInfo info) { 3247 mRequest.activityInfo = info; 3248 return this; 3249 } 3250 setResolveInfo(ResolveInfo info)3251 ActivityStarter setResolveInfo(ResolveInfo info) { 3252 mRequest.resolveInfo = info; 3253 return this; 3254 } 3255 setVoiceSession(IVoiceInteractionSession voiceSession)3256 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) { 3257 mRequest.voiceSession = voiceSession; 3258 return this; 3259 } 3260 setVoiceInteractor(IVoiceInteractor voiceInteractor)3261 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) { 3262 mRequest.voiceInteractor = voiceInteractor; 3263 return this; 3264 } 3265 setResultTo(IBinder resultTo)3266 ActivityStarter setResultTo(IBinder resultTo) { 3267 mRequest.resultTo = resultTo; 3268 return this; 3269 } 3270 setResultWho(String resultWho)3271 ActivityStarter setResultWho(String resultWho) { 3272 mRequest.resultWho = resultWho; 3273 return this; 3274 } 3275 setRequestCode(int requestCode)3276 ActivityStarter setRequestCode(int requestCode) { 3277 mRequest.requestCode = requestCode; 3278 return this; 3279 } 3280 3281 /** 3282 * Sets the pid of the caller who originally started the activity. 3283 * 3284 * Normally, the pid/uid would be the calling pid from the binder call. 3285 * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered 3286 * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid, 3287 * which represents the entity who invoked pending intent via {@link PendingIntent#send}. 3288 */ setCallingPid(int pid)3289 ActivityStarter setCallingPid(int pid) { 3290 mRequest.callingPid = pid; 3291 return this; 3292 } 3293 3294 /** 3295 * Sets the uid of the caller who originally started the activity. 3296 * 3297 * @see #setCallingPid 3298 */ setCallingUid(int uid)3299 ActivityStarter setCallingUid(int uid) { 3300 mRequest.callingUid = uid; 3301 return this; 3302 } 3303 setCallingPackage(String callingPackage)3304 ActivityStarter setCallingPackage(String callingPackage) { 3305 mRequest.callingPackage = callingPackage; 3306 return this; 3307 } 3308 setCallingFeatureId(String callingFeatureId)3309 ActivityStarter setCallingFeatureId(String callingFeatureId) { 3310 mRequest.callingFeatureId = callingFeatureId; 3311 return this; 3312 } 3313 3314 /** 3315 * Sets the pid of the caller who requested to launch the activity. 3316 * 3317 * The pid/uid represents the caller who launches the activity in this request. 3318 * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}: 3319 * the pid/uid will be the caller who called {@link PendingIntent#send()}. 3320 * 3321 * @see #setCallingPid 3322 */ setRealCallingPid(int pid)3323 ActivityStarter setRealCallingPid(int pid) { 3324 mRequest.realCallingPid = pid; 3325 return this; 3326 } 3327 3328 /** 3329 * Sets the uid of the caller who requested to launch the activity. 3330 * 3331 * @see #setRealCallingPid 3332 */ setRealCallingUid(int uid)3333 ActivityStarter setRealCallingUid(int uid) { 3334 mRequest.realCallingUid = uid; 3335 return this; 3336 } 3337 setStartFlags(int startFlags)3338 ActivityStarter setStartFlags(int startFlags) { 3339 mRequest.startFlags = startFlags; 3340 return this; 3341 } 3342 setActivityOptions(SafeActivityOptions options)3343 ActivityStarter setActivityOptions(SafeActivityOptions options) { 3344 mRequest.activityOptions = options; 3345 return this; 3346 } 3347 setActivityOptions(Bundle bOptions)3348 ActivityStarter setActivityOptions(Bundle bOptions) { 3349 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions)); 3350 } 3351 setIgnoreTargetSecurity(boolean ignoreTargetSecurity)3352 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) { 3353 mRequest.ignoreTargetSecurity = ignoreTargetSecurity; 3354 return this; 3355 } 3356 setFilterCallingUid(int filterCallingUid)3357 ActivityStarter setFilterCallingUid(int filterCallingUid) { 3358 mRequest.filterCallingUid = filterCallingUid; 3359 return this; 3360 } 3361 setComponentSpecified(boolean componentSpecified)3362 ActivityStarter setComponentSpecified(boolean componentSpecified) { 3363 mRequest.componentSpecified = componentSpecified; 3364 return this; 3365 } 3366 setOutActivity(ActivityRecord[] outActivity)3367 ActivityStarter setOutActivity(ActivityRecord[] outActivity) { 3368 mRequest.outActivity = outActivity; 3369 return this; 3370 } 3371 setInTask(Task inTask)3372 ActivityStarter setInTask(Task inTask) { 3373 mRequest.inTask = inTask; 3374 return this; 3375 } 3376 setInTaskFragment(TaskFragment taskFragment)3377 ActivityStarter setInTaskFragment(TaskFragment taskFragment) { 3378 mRequest.inTaskFragment = taskFragment; 3379 return this; 3380 } 3381 setWaitResult(WaitResult result)3382 ActivityStarter setWaitResult(WaitResult result) { 3383 mRequest.waitResult = result; 3384 return this; 3385 } 3386 setProfilerInfo(ProfilerInfo info)3387 ActivityStarter setProfilerInfo(ProfilerInfo info) { 3388 mRequest.profilerInfo = info; 3389 return this; 3390 } 3391 setGlobalConfiguration(Configuration config)3392 ActivityStarter setGlobalConfiguration(Configuration config) { 3393 mRequest.globalConfig = config; 3394 return this; 3395 } 3396 setUserId(int userId)3397 ActivityStarter setUserId(int userId) { 3398 mRequest.userId = userId; 3399 return this; 3400 } 3401 setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup)3402 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) { 3403 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup; 3404 return this; 3405 } 3406 setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent)3407 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) { 3408 mRequest.originatingPendingIntent = originatingPendingIntent; 3409 return this; 3410 } 3411 setBackgroundStartPrivileges( BackgroundStartPrivileges backgroundStartPrivileges)3412 ActivityStarter setBackgroundStartPrivileges( 3413 BackgroundStartPrivileges backgroundStartPrivileges) { 3414 mRequest.backgroundStartPrivileges = backgroundStartPrivileges; 3415 return this; 3416 } 3417 setErrorCallbackToken(@ullable IBinder errorCallbackToken)3418 ActivityStarter setErrorCallbackToken(@Nullable IBinder errorCallbackToken) { 3419 mRequest.errorCallbackToken = errorCallbackToken; 3420 return this; 3421 } 3422 dump(PrintWriter pw, String prefix)3423 void dump(PrintWriter pw, String prefix) { 3424 pw.print(prefix); 3425 pw.print("mCurrentUser="); 3426 pw.println(mRootWindowContainer.mCurrentUser); 3427 pw.print(prefix); 3428 pw.print("mLastStartReason="); 3429 pw.println(mLastStartReason); 3430 pw.print(prefix); 3431 pw.print("mLastStartActivityTimeMs="); 3432 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs))); 3433 pw.print(prefix); 3434 pw.print("mLastStartActivityResult="); 3435 pw.println(mLastStartActivityResult); 3436 if (mLastStartActivityRecord != null) { 3437 pw.print(prefix); 3438 pw.println("mLastStartActivityRecord:"); 3439 mLastStartActivityRecord.dump(pw, prefix + " ", true /* dumpAll */); 3440 } 3441 if (mStartActivity != null) { 3442 pw.print(prefix); 3443 pw.println("mStartActivity:"); 3444 mStartActivity.dump(pw, prefix + " ", true /* dumpAll */); 3445 } 3446 if (mIntent != null) { 3447 pw.print(prefix); 3448 pw.print("mIntent="); 3449 pw.println(mIntent); 3450 } 3451 if (mOptions != null) { 3452 pw.print(prefix); 3453 pw.print("mOptions="); 3454 pw.println(mOptions); 3455 } 3456 pw.print(prefix); 3457 pw.print("mLaunchMode="); 3458 pw.print(launchModeToString(mLaunchMode)); 3459 pw.print(prefix); 3460 pw.print("mLaunchFlags=0x"); 3461 pw.print(Integer.toHexString(mLaunchFlags)); 3462 pw.print(" mDoResume="); 3463 pw.print(mDoResume); 3464 pw.print(" mAddingToTask="); 3465 pw.print(mAddingToTask); 3466 pw.print(" mInTaskFragment="); 3467 pw.println(mInTaskFragment); 3468 } 3469 } 3470