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