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