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