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