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