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