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