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