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