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