ActivityStarter.java revision 265bd89c3cb6f99d38d2f126a88c12fc6502431c
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, mSourceRecord, mTargetStack); 540 return err; 541 } 542 543 void postStartActivityUncheckedProcessing( 544 ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord, 545 ActivityStack targetStack) { 546 547 if (result < START_SUCCESS) { 548 // If someone asked to have the keyguard dismissed on the next activity start, 549 // but we are not actually doing an activity switch... just dismiss the keyguard now, 550 // because we probably want to see whatever is behind it. 551 mSupervisor.notifyActivityDrawnForKeyguard(); 552 return; 553 } 554 555 int startedActivityStackId = INVALID_STACK_ID; 556 if (r.task != null && r.task.stack != null) { 557 startedActivityStackId = r.task.stack.mStackId; 558 } else if (mTargetStack != null) { 559 startedActivityStackId = targetStack.mStackId; 560 } 561 562 // If we launched the activity from a no display activity that was launched from the home 563 // screen, we also need to start recents to un-minimize the docked stack, since the 564 // noDisplay activity will be finished shortly after. 565 // TODO: We should prevent noDisplay activities from affecting task/stack ordering and 566 // visibility instead of using this flag. 567 final boolean noDisplayActivityOverHome = sourceRecord != null 568 && sourceRecord.noDisplay 569 && sourceRecord.task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE; 570 if (startedActivityStackId == DOCKED_STACK_ID 571 && (prevFocusedStackId == HOME_STACK_ID || noDisplayActivityOverHome)) { 572 final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID); 573 final ActivityRecord topActivityHomeStack = homeStack != null 574 ? homeStack.topRunningActivityLocked() : null; 575 if (topActivityHomeStack == null 576 || topActivityHomeStack.mActivityType != RECENTS_ACTIVITY_TYPE) { 577 // We launch an activity while being in home stack, which means either launcher or 578 // recents into docked stack. We don't want the launched activity to be alone in a 579 // docked stack, so we want to immediately launch recents too. 580 if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch."); 581 mWindowManager.showRecentApps(true /* fromHome */); 582 return; 583 } 584 } 585 586 if (startedActivityStackId == PINNED_STACK_ID 587 && (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP)) { 588 // The activity was already running in the pinned stack so it wasn't started, but either 589 // brought to the front or the new intent was delivered to it since it was already in 590 // front. Notify anyone interested in this piece of information. 591 mService.notifyPinnedActivityRestartAttemptLocked(); 592 return; 593 } 594 } 595 596 void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) { 597 mSupervisor.moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason); 598 startActivityLocked(null /*caller*/, intent, null /*ephemeralIntent*/, 599 null /*resolvedType*/, aInfo, null /*rInfo*/, null /*voiceSession*/, 600 null /*voiceInteractor*/, null /*resultTo*/, null /*resultWho*/, 601 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/, null /*callingPackage*/, 602 0 /*realCallingPid*/, 0 /*realCallingUid*/, 0 /*startFlags*/, null /*options*/, 603 false /*ignoreTargetSecurity*/, false /*componentSpecified*/, null /*outActivity*/, 604 null /*container*/, null /*inTask*/); 605 if (mSupervisor.inResumeTopActivity) { 606 // If we are in resume section already, home activity will be initialized, but not 607 // resumed (to avoid recursive resume) and will stay that way until something pokes it 608 // again. We need to schedule another resume. 609 mSupervisor.scheduleResumeTopActivities(); 610 } 611 } 612 613 void showConfirmDeviceCredential(int userId) { 614 // First, retrieve the stack that we want to resume after credential is confirmed. 615 ActivityStack targetStack; 616 ActivityStack fullscreenStack = 617 mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID); 618 if (fullscreenStack != null && 619 fullscreenStack.getStackVisibilityLocked(null) != ActivityStack.STACK_INVISIBLE) { 620 // Single window case and the case that the docked stack is shown with fullscreen stack. 621 targetStack = fullscreenStack; 622 } else { 623 // The case that the docked stack is shown with recent. 624 targetStack = mSupervisor.getStack(HOME_STACK_ID); 625 } 626 if (targetStack == null) { 627 return; 628 } 629 final KeyguardManager km = (KeyguardManager) mService.mContext 630 .getSystemService(Context.KEYGUARD_SERVICE); 631 final Intent credential = 632 km.createConfirmDeviceCredentialIntent(null, null, userId); 633 // For safety, check null here in case users changed the setting after the checking. 634 if (credential == null) { 635 return; 636 } 637 final ActivityRecord activityRecord = targetStack.topRunningActivityLocked(); 638 if (activityRecord != null) { 639 final IIntentSender target = mService.getIntentSenderLocked( 640 ActivityManager.INTENT_SENDER_ACTIVITY, 641 activityRecord.launchedFromPackage, 642 activityRecord.launchedFromUid, 643 activityRecord.userId, 644 null, null, 0, 645 new Intent[] { activityRecord.intent }, 646 new String[] { activityRecord.resolvedType }, 647 PendingIntent.FLAG_CANCEL_CURRENT | 648 PendingIntent.FLAG_ONE_SHOT | 649 PendingIntent.FLAG_IMMUTABLE, 650 null); 651 credential.putExtra(Intent.EXTRA_INTENT, new IntentSender(target)); 652 // Show confirm credentials activity. 653 startConfirmCredentialIntent(credential); 654 } 655 } 656 657 void startConfirmCredentialIntent(Intent intent) { 658 intent.addFlags(FLAG_ACTIVITY_NEW_TASK | 659 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | 660 FLAG_ACTIVITY_TASK_ON_HOME); 661 final ActivityOptions options = ActivityOptions.makeBasic(); 662 options.setLaunchTaskId(mSupervisor.getHomeActivity().task.taskId); 663 mService.mContext.startActivityAsUser(intent, options.toBundle(), 664 UserHandle.CURRENT); 665 } 666 667 final int startActivityMayWait(IApplicationThread caller, int callingUid, 668 String callingPackage, Intent intent, String resolvedType, 669 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 670 IBinder resultTo, String resultWho, int requestCode, int startFlags, 671 ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config, 672 Bundle bOptions, boolean ignoreTargetSecurity, int userId, 673 IActivityContainer iContainer, TaskRecord inTask) { 674 // Refuse possible leaked file descriptors 675 if (intent != null && intent.hasFileDescriptors()) { 676 throw new IllegalArgumentException("File descriptors passed in Intent"); 677 } 678 mSupervisor.mActivityMetricsLogger.notifyActivityLaunching(); 679 boolean componentSpecified = intent.getComponent() != null; 680 681 // Save a copy in case ephemeral needs it 682 final Intent ephemeralIntent = new Intent(intent); 683 // Don't modify the client's object! 684 intent = new Intent(intent); 685 686 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId); 687 if (rInfo == null) { 688 UserInfo userInfo = mSupervisor.getUserInfo(userId); 689 if (userInfo != null && userInfo.isManagedProfile()) { 690 // Special case for managed profiles, if attempting to launch non-cryto aware 691 // app in a locked managed profile from an unlocked parent allow it to resolve 692 // as user will be sent via confirm credentials to unlock the profile. 693 UserManager userManager = UserManager.get(mService.mContext); 694 boolean profileLockedAndParentUnlockingOrUnlocked = false; 695 long token = Binder.clearCallingIdentity(); 696 try { 697 UserInfo parent = userManager.getProfileParent(userId); 698 profileLockedAndParentUnlockingOrUnlocked = (parent != null) 699 && userManager.isUserUnlockingOrUnlocked(parent.id) 700 && !userManager.isUserUnlockingOrUnlocked(userId); 701 } finally { 702 Binder.restoreCallingIdentity(token); 703 } 704 if (profileLockedAndParentUnlockingOrUnlocked) { 705 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 706 PackageManager.MATCH_DIRECT_BOOT_AWARE 707 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 708 } 709 } 710 } 711 // Collect information about the target of the Intent. 712 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); 713 714 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 715 ActivityStackSupervisor.ActivityContainer container = 716 (ActivityStackSupervisor.ActivityContainer)iContainer; 717 synchronized (mService) { 718 if (container != null && container.mParentActivity != null && 719 container.mParentActivity.state != RESUMED) { 720 // Cannot start a child activity if the parent is not resumed. 721 return ActivityManager.START_CANCELED; 722 } 723 final int realCallingPid = Binder.getCallingPid(); 724 final int realCallingUid = Binder.getCallingUid(); 725 int callingPid; 726 if (callingUid >= 0) { 727 callingPid = -1; 728 } else if (caller == null) { 729 callingPid = realCallingPid; 730 callingUid = realCallingUid; 731 } else { 732 callingPid = callingUid = -1; 733 } 734 735 final ActivityStack stack; 736 if (container == null || container.mStack.isOnHomeDisplay()) { 737 stack = mSupervisor.mFocusedStack; 738 } else { 739 stack = container.mStack; 740 } 741 stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0; 742 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 743 "Starting activity when config will change = " + stack.mConfigWillChange); 744 745 final long origId = Binder.clearCallingIdentity(); 746 747 if (aInfo != null && 748 (aInfo.applicationInfo.privateFlags 749 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { 750 // This may be a heavy-weight process! Check to see if we already 751 // have another, different heavy-weight process running. 752 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { 753 final ProcessRecord heavy = mService.mHeavyWeightProcess; 754 if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid 755 || !heavy.processName.equals(aInfo.processName))) { 756 int appCallingUid = callingUid; 757 if (caller != null) { 758 ProcessRecord callerApp = mService.getRecordForAppLocked(caller); 759 if (callerApp != null) { 760 appCallingUid = callerApp.info.uid; 761 } else { 762 Slog.w(TAG, "Unable to find app for caller " + caller 763 + " (pid=" + callingPid + ") when starting: " 764 + intent.toString()); 765 ActivityOptions.abort(options); 766 return ActivityManager.START_PERMISSION_DENIED; 767 } 768 } 769 770 IIntentSender target = mService.getIntentSenderLocked( 771 ActivityManager.INTENT_SENDER_ACTIVITY, "android", 772 appCallingUid, userId, null, null, 0, new Intent[] { intent }, 773 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT 774 | PendingIntent.FLAG_ONE_SHOT, null); 775 776 Intent newIntent = new Intent(); 777 if (requestCode >= 0) { 778 // Caller is requesting a result. 779 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true); 780 } 781 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, 782 new IntentSender(target)); 783 if (heavy.activities.size() > 0) { 784 ActivityRecord hist = heavy.activities.get(0); 785 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, 786 hist.packageName); 787 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, 788 hist.task.taskId); 789 } 790 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, 791 aInfo.packageName); 792 newIntent.setFlags(intent.getFlags()); 793 newIntent.setClassName("android", 794 HeavyWeightSwitcherActivity.class.getName()); 795 intent = newIntent; 796 resolvedType = null; 797 caller = null; 798 callingUid = Binder.getCallingUid(); 799 callingPid = Binder.getCallingPid(); 800 componentSpecified = true; 801 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId); 802 aInfo = rInfo != null ? rInfo.activityInfo : null; 803 if (aInfo != null) { 804 aInfo = mService.getActivityInfoForUser(aInfo, userId); 805 } 806 } 807 } 808 } 809 810 final ActivityRecord[] outRecord = new ActivityRecord[1]; 811 int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, 812 aInfo, rInfo, voiceSession, voiceInteractor, 813 resultTo, resultWho, requestCode, callingPid, 814 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, 815 options, ignoreTargetSecurity, componentSpecified, outRecord, container, 816 inTask); 817 818 Binder.restoreCallingIdentity(origId); 819 820 if (stack.mConfigWillChange) { 821 // If the caller also wants to switch to a new configuration, 822 // do so now. This allows a clean switch, as we are waiting 823 // for the current activity to pause (so we will not destroy 824 // it), and have not yet started the next activity. 825 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 826 "updateConfiguration()"); 827 stack.mConfigWillChange = false; 828 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 829 "Updating to new configuration after starting activity."); 830 mService.updateConfigurationLocked(config, null, false); 831 } 832 833 if (outResult != null) { 834 outResult.result = res; 835 if (res == ActivityManager.START_SUCCESS) { 836 mSupervisor.mWaitingActivityLaunched.add(outResult); 837 do { 838 try { 839 mService.wait(); 840 } catch (InterruptedException e) { 841 } 842 } while (!outResult.timeout && outResult.who == null); 843 } else if (res == START_TASK_TO_FRONT) { 844 ActivityRecord r = stack.topRunningActivityLocked(); 845 if (r.nowVisible && r.state == RESUMED) { 846 outResult.timeout = false; 847 outResult.who = new ComponentName(r.info.packageName, r.info.name); 848 outResult.totalTime = 0; 849 outResult.thisTime = 0; 850 } else { 851 outResult.thisTime = SystemClock.uptimeMillis(); 852 mSupervisor.mWaitingActivityVisible.add(outResult); 853 do { 854 try { 855 mService.wait(); 856 } catch (InterruptedException e) { 857 } 858 } while (!outResult.timeout && outResult.who == null); 859 } 860 } 861 } 862 863 final ActivityRecord launchedActivity = mReusedActivity != null 864 ? mReusedActivity : outRecord[0]; 865 mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity); 866 return res; 867 } 868 } 869 870 final int startActivities(IApplicationThread caller, int callingUid, String callingPackage, 871 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 872 Bundle bOptions, int userId) { 873 if (intents == null) { 874 throw new NullPointerException("intents is null"); 875 } 876 if (resolvedTypes == null) { 877 throw new NullPointerException("resolvedTypes is null"); 878 } 879 if (intents.length != resolvedTypes.length) { 880 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 881 } 882 883 884 int callingPid; 885 if (callingUid >= 0) { 886 callingPid = -1; 887 } else if (caller == null) { 888 callingPid = Binder.getCallingPid(); 889 callingUid = Binder.getCallingUid(); 890 } else { 891 callingPid = callingUid = -1; 892 } 893 final long origId = Binder.clearCallingIdentity(); 894 try { 895 synchronized (mService) { 896 ActivityRecord[] outActivity = new ActivityRecord[1]; 897 for (int i=0; i<intents.length; i++) { 898 Intent intent = intents[i]; 899 if (intent == null) { 900 continue; 901 } 902 903 // Refuse possible leaked file descriptors 904 if (intent != null && intent.hasFileDescriptors()) { 905 throw new IllegalArgumentException("File descriptors passed in Intent"); 906 } 907 908 boolean componentSpecified = intent.getComponent() != null; 909 910 // Don't modify the client's object! 911 intent = new Intent(intent); 912 913 // Collect information about the target of the Intent. 914 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, 915 null, userId); 916 // TODO: New, check if this is correct 917 aInfo = mService.getActivityInfoForUser(aInfo, userId); 918 919 if (aInfo != null && 920 (aInfo.applicationInfo.privateFlags 921 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { 922 throw new IllegalArgumentException( 923 "FLAG_CANT_SAVE_STATE not supported here"); 924 } 925 926 ActivityOptions options = ActivityOptions.fromBundle( 927 i == intents.length - 1 ? bOptions : null); 928 int res = startActivityLocked(caller, intent, null /*ephemeralIntent*/, 929 resolvedTypes[i], aInfo, null /*rInfo*/, null, null, resultTo, null, -1, 930 callingPid, callingUid, callingPackage, callingPid, callingUid, 0, 931 options, false, componentSpecified, outActivity, null, null); 932 if (res < 0) { 933 return res; 934 } 935 936 resultTo = outActivity[0] != null ? outActivity[0].appToken : null; 937 } 938 } 939 } finally { 940 Binder.restoreCallingIdentity(origId); 941 } 942 943 return START_SUCCESS; 944 } 945 946 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, 947 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 948 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) { 949 950 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, 951 voiceInteractor); 952 953 computeLaunchingTaskFlags(); 954 955 computeSourceStack(); 956 957 mIntent.setFlags(mLaunchFlags); 958 959 mReusedActivity = getReusableIntentActivity(); 960 961 final int preferredLaunchStackId = 962 (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID; 963 964 if (mReusedActivity != null) { 965 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but 966 // still needs to be a lock task mode violation since the task gets cleared out and 967 // the device would otherwise leave the locked task. 968 if (mSupervisor.isLockTaskModeViolation(mReusedActivity.task, 969 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 970 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) { 971 mSupervisor.showLockTaskToast(); 972 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode"); 973 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 974 } 975 976 if (mStartActivity.task == null) { 977 mStartActivity.task = mReusedActivity.task; 978 } 979 if (mReusedActivity.task.intent == null) { 980 // This task was started because of movement of the activity based on affinity... 981 // Now that we are actually launching it, we can assign the base intent. 982 mReusedActivity.task.setIntent(mStartActivity); 983 } 984 985 // This code path leads to delivering a new intent, we want to make sure we schedule it 986 // as the first operation, in case the activity will be resumed as a result of later 987 // operations. 988 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 989 || mLaunchSingleInstance || mLaunchSingleTask) { 990 // In this situation we want to remove all activities from the task up to the one 991 // being started. In most cases this means we are resetting the task to its initial 992 // state. 993 final ActivityRecord top = mReusedActivity.task.performClearTaskForReuseLocked( 994 mStartActivity, mLaunchFlags); 995 if (top != null) { 996 if (top.frontOfTask) { 997 // Activity aliases may mean we use different intents for the top activity, 998 // so make sure the task now has the identity of the new intent. 999 top.task.setIntent(mStartActivity); 1000 } 1001 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task); 1002 top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, 1003 mStartActivity.launchedFromPackage); 1004 } 1005 } 1006 1007 mReusedActivity = setTargetStackAndMoveToFrontIfNeeded(mReusedActivity); 1008 1009 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 1010 // We don't need to start a new activity, and the client said not to do anything 1011 // if that is the case, so this is it! And for paranoia, make sure we have 1012 // correctly resumed the top activity. 1013 resumeTargetStackIfNeeded(); 1014 return START_RETURN_INTENT_TO_CALLER; 1015 } 1016 1017 setTaskFromIntentActivity(mReusedActivity); 1018 1019 if (!mAddingToTask && mReuseTask == null) { 1020 // We didn't do anything... but it was needed (a.k.a., client don't use that 1021 // intent!) And for paranoia, make sure we have correctly resumed the top activity. 1022 resumeTargetStackIfNeeded(); 1023 return START_TASK_TO_FRONT; 1024 } 1025 } 1026 1027 if (mStartActivity.packageName == null) { 1028 if (mStartActivity.resultTo != null && mStartActivity.resultTo.task.stack != null) { 1029 mStartActivity.resultTo.task.stack.sendActivityResultLocked( 1030 -1, mStartActivity.resultTo, mStartActivity.resultWho, 1031 mStartActivity.requestCode, RESULT_CANCELED, null); 1032 } 1033 ActivityOptions.abort(mOptions); 1034 return START_CLASS_NOT_FOUND; 1035 } 1036 1037 // If the activity being launched is the same as the one currently at the top, then 1038 // we need to check if it should only be launched once. 1039 final ActivityStack topStack = mSupervisor.mFocusedStack; 1040 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop); 1041 final boolean dontStart = top != null && mStartActivity.resultTo == null 1042 && top.realActivity.equals(mStartActivity.realActivity) 1043 && top.userId == mStartActivity.userId 1044 && top.app != null && top.app.thread != null 1045 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 1046 || mLaunchSingleTop || mLaunchSingleTask); 1047 if (dontStart) { 1048 ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task); 1049 // For paranoia, make sure we have correctly resumed the top activity. 1050 topStack.mLastPausedActivity = null; 1051 if (mDoResume) { 1052 mSupervisor.resumeFocusedStackTopActivityLocked(); 1053 } 1054 ActivityOptions.abort(mOptions); 1055 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 1056 // We don't need to start a new activity, and the client said not to do 1057 // anything if that is the case, so this is it! 1058 return START_RETURN_INTENT_TO_CALLER; 1059 } 1060 top.deliverNewIntentLocked( 1061 mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); 1062 1063 // Don't use mStartActivity.task to show the toast. We're not starting a new activity 1064 // but reusing 'top'. Fields in mStartActivity may not be fully initialized. 1065 mSupervisor.handleNonResizableTaskIfNeeded( 1066 top.task, preferredLaunchStackId, topStack.mStackId); 1067 1068 return START_DELIVERED_TO_TOP; 1069 } 1070 1071 boolean newTask = false; 1072 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) 1073 ? mSourceRecord.task : null; 1074 1075 // Should this be considered a new task? 1076 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask 1077 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 1078 newTask = true; 1079 setTaskFromReuseOrCreateNewTask(taskToAffiliate); 1080 1081 if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) { 1082 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity); 1083 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 1084 } 1085 if (!mMovedHome) { 1086 updateTaskReturnToType(mStartActivity.task, mLaunchFlags, topStack); 1087 } 1088 } else if (mSourceRecord != null) { 1089 if (mSupervisor.isLockTaskModeViolation(mSourceRecord.task)) { 1090 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity); 1091 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 1092 } 1093 1094 final int result = setTaskFromSourceRecord(); 1095 if (result != START_SUCCESS) { 1096 return result; 1097 } 1098 } else if (mInTask != null) { 1099 // The caller is asking that the new activity be started in an explicit 1100 // task it has provided to us. 1101 if (mSupervisor.isLockTaskModeViolation(mInTask)) { 1102 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity); 1103 return START_RETURN_LOCK_TASK_MODE_VIOLATION; 1104 } 1105 1106 final int result = setTaskFromInTask(); 1107 if (result != START_SUCCESS) { 1108 return result; 1109 } 1110 } else { 1111 // This not being started from an existing activity, and not part of a new task... 1112 // just put it in the top task, though these days this case should never happen. 1113 setTaskToCurrentTopOrCreateNewTask(); 1114 } 1115 1116 mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName, 1117 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId); 1118 1119 if (mSourceRecord != null && mSourceRecord.isRecentsActivity()) { 1120 mStartActivity.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE); 1121 } 1122 if (newTask) { 1123 EventLog.writeEvent( 1124 EventLogTags.AM_CREATE_TASK, mStartActivity.userId, mStartActivity.task.taskId); 1125 } 1126 ActivityStack.logStartActivity( 1127 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.task); 1128 mTargetStack.mLastPausedActivity = null; 1129 mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions); 1130 if (mDoResume) { 1131 if (!mLaunchTaskBehind) { 1132 // TODO(b/26381750): Remove this code after verification that all the decision 1133 // points above moved targetStack to the front which will also set the focus 1134 // activity. 1135 mService.setFocusedActivityLocked(mStartActivity, "startedActivity"); 1136 } 1137 final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked(); 1138 if (!mTargetStack.isFocusable() 1139 || (topTaskActivity != null && topTaskActivity.mTaskOverlay 1140 && mStartActivity != topTaskActivity)) { 1141 // If the activity is not focusable, we can't resume it, but still would like to 1142 // make sure it becomes visible as it starts (this will also trigger entry 1143 // animation). An example of this are PIP activities. 1144 // Also, we don't want to resume activities in a task that currently has an overlay 1145 // as the starting activity just needs to be in the visible paused state until the 1146 // over is removed. 1147 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1148 // Go ahead and tell window manager to execute app transition for this activity 1149 // since the app transition will not be triggered through the resume channel. 1150 mWindowManager.executeAppTransition(); 1151 } else { 1152 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, 1153 mOptions); 1154 } 1155 } else { 1156 mTargetStack.addRecentActivityLocked(mStartActivity); 1157 } 1158 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); 1159 1160 mSupervisor.handleNonResizableTaskIfNeeded( 1161 mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId); 1162 1163 return START_SUCCESS; 1164 } 1165 1166 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask, 1167 boolean doResume, int startFlags, ActivityRecord sourceRecord, 1168 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 1169 reset(); 1170 1171 mStartActivity = r; 1172 mIntent = r.intent; 1173 mOptions = options; 1174 mCallingUid = r.launchedFromUid; 1175 mSourceRecord = sourceRecord; 1176 mVoiceSession = voiceSession; 1177 mVoiceInteractor = voiceInteractor; 1178 1179 mLaunchBounds = getOverrideBounds(r, options, inTask); 1180 1181 mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP; 1182 mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE; 1183 mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK; 1184 mLaunchFlags = adjustLaunchFlagsToDocumentMode( 1185 r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags()); 1186 mLaunchTaskBehind = r.mLaunchTaskBehind 1187 && !mLaunchSingleTask && !mLaunchSingleInstance 1188 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0; 1189 1190 sendNewTaskResultRequestIfNeeded(); 1191 1192 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) { 1193 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 1194 } 1195 1196 // If we are actually going to launch in to a new task, there are some cases where 1197 // we further want to do multiple task. 1198 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 1199 if (mLaunchTaskBehind 1200 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) { 1201 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK; 1202 } 1203 } 1204 1205 // We'll invoke onUserLeaving before onPause only if the launching 1206 // activity did not explicitly state that this is an automated launch. 1207 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0; 1208 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, 1209 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving); 1210 1211 // If the caller has asked not to resume at this point, we make note 1212 // of this in the record so that we can skip it when trying to find 1213 // the top running activity. 1214 mDoResume = doResume; 1215 if (!doResume || !mSupervisor.okToShowLocked(r)) { 1216 r.delayedResume = true; 1217 mDoResume = false; 1218 } 1219 1220 if (mOptions != null && mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) { 1221 r.mTaskOverlay = true; 1222 final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId()); 1223 final ActivityRecord top = task != null ? task.getTopActivity() : null; 1224 if (top != null && !top.visible) { 1225 1226 // The caller specifies that we'd like to be avoided to be moved to the front, so be 1227 // it! 1228 mDoResume = false; 1229 mAvoidMoveToFront = true; 1230 } 1231 } 1232 1233 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; 1234 1235 mInTask = inTask; 1236 // In some flows in to this function, we retrieve the task record and hold on to it 1237 // without a lock before calling back in to here... so the task at this point may 1238 // not actually be in recents. Check for that, and if it isn't in recents just 1239 // consider it invalid. 1240 if (inTask != null && !inTask.inRecents) { 1241 Slog.w(TAG, "Starting activity in task not in recents: " + inTask); 1242 mInTask = null; 1243 } 1244 1245 mStartFlags = startFlags; 1246 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched 1247 // is the same as the one making the call... or, as a special case, if we do not know 1248 // the caller then we count the current top activity as the caller. 1249 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 1250 ActivityRecord checkedCaller = sourceRecord; 1251 if (checkedCaller == null) { 1252 checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked( 1253 mNotTop); 1254 } 1255 if (!checkedCaller.realActivity.equals(r.realActivity)) { 1256 // Caller is not the same as launcher, so always needed. 1257 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED; 1258 } 1259 } 1260 1261 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; 1262 } 1263 1264 private void sendNewTaskResultRequestIfNeeded() { 1265 if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 1266 && mStartActivity.resultTo.task.stack != null) { 1267 // For whatever reason this activity is being launched into a new task... 1268 // yet the caller has requested a result back. Well, that is pretty messed up, 1269 // so instead immediately send back a cancel and let the new task continue launched 1270 // as normal without a dependency on its originator. 1271 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 1272 mStartActivity.resultTo.task.stack.sendActivityResultLocked(-1, mStartActivity.resultTo, 1273 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED, null); 1274 mStartActivity.resultTo = null; 1275 } 1276 } 1277 1278 private void computeLaunchingTaskFlags() { 1279 // If the caller is not coming from another activity, but has given us an explicit task into 1280 // which they would like us to launch the new activity, then let's see about doing that. 1281 if (mSourceRecord == null && mInTask != null && mInTask.stack != null) { 1282 final Intent baseIntent = mInTask.getBaseIntent(); 1283 final ActivityRecord root = mInTask.getRootActivity(); 1284 if (baseIntent == null) { 1285 ActivityOptions.abort(mOptions); 1286 throw new IllegalArgumentException("Launching into task without base intent: " 1287 + mInTask); 1288 } 1289 1290 // If this task is empty, then we are adding the first activity -- it 1291 // determines the root, and must be launching as a NEW_TASK. 1292 if (mLaunchSingleInstance || mLaunchSingleTask) { 1293 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) { 1294 ActivityOptions.abort(mOptions); 1295 throw new IllegalArgumentException("Trying to launch singleInstance/Task " 1296 + mStartActivity + " into different task " + mInTask); 1297 } 1298 if (root != null) { 1299 ActivityOptions.abort(mOptions); 1300 throw new IllegalArgumentException("Caller with mInTask " + mInTask 1301 + " has root " + root + " but target is singleInstance/Task"); 1302 } 1303 } 1304 1305 // If task is empty, then adopt the interesting intent launch flags in to the 1306 // activity being started. 1307 if (root == null) { 1308 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK 1309 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS; 1310 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest) 1311 | (baseIntent.getFlags() & flagsOfInterest); 1312 mIntent.setFlags(mLaunchFlags); 1313 mInTask.setIntent(mStartActivity); 1314 mAddingToTask = true; 1315 1316 // If the task is not empty and the caller is asking to start it as the root of 1317 // a new task, then we don't actually want to start this on the task. We will 1318 // bring the task to the front, and possibly give it a new intent. 1319 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 1320 mAddingToTask = false; 1321 1322 } else { 1323 mAddingToTask = true; 1324 } 1325 1326 mReuseTask = mInTask; 1327 } else { 1328 mInTask = null; 1329 // Launch ResolverActivity in the source task, so that it stays in the task bounds 1330 // when in freeform workspace. 1331 // Also put noDisplay activities in the source task. These by itself can be placed 1332 // in any task/stack, however it could launch other activities like ResolverActivity, 1333 // and we want those to stay in the original task. 1334 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null 1335 && mSourceRecord.isFreeform()) { 1336 mAddingToTask = true; 1337 } 1338 } 1339 1340 if (mInTask == null) { 1341 if (mSourceRecord == null) { 1342 // This activity is not being started from another... in this 1343 // case we -always- start a new task. 1344 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) { 1345 Slog.w(TAG, "startActivity called from non-Activity context; forcing " + 1346 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent); 1347 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 1348 } 1349 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) { 1350 // The original activity who is starting us is running as a single 1351 // instance... this new activity it is starting must go on its 1352 // own task. 1353 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 1354 } else if (mLaunchSingleInstance || mLaunchSingleTask) { 1355 // The activity being started is a single instance... it always 1356 // gets launched into its own task. 1357 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 1358 } 1359 } 1360 } 1361 1362 private void computeSourceStack() { 1363 if (mSourceRecord == null) { 1364 mSourceStack = null; 1365 return; 1366 } 1367 if (!mSourceRecord.finishing) { 1368 mSourceStack = mSourceRecord.task.stack; 1369 return; 1370 } 1371 1372 // If the source is finishing, we can't further count it as our source. This is because the 1373 // task it is associated with may now be empty and on its way out, so we don't want to 1374 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find 1375 // a task for it. But save the task information so it can be used when creating the new task. 1376 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) { 1377 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord 1378 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent); 1379 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; 1380 mNewTaskInfo = mSourceRecord.info; 1381 mNewTaskIntent = mSourceRecord.task.intent; 1382 } 1383 mSourceRecord = null; 1384 mSourceStack = null; 1385 } 1386 1387 /** 1388 * Decide whether the new activity should be inserted into an existing task. Returns null 1389 * if not or an ActivityRecord with the task into which the new activity should be added. 1390 */ 1391 private ActivityRecord getReusableIntentActivity() { 1392 // We may want to try to place the new activity in to an existing task. We always 1393 // do this if the target activity is singleTask or singleInstance; we will also do 1394 // this if NEW_TASK has been requested, and there is not an additional qualifier telling 1395 // us to still place it in a new task: multi task, always doc mode, or being asked to 1396 // launch this as a new task behind the current one. 1397 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 && 1398 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 1399 || mLaunchSingleInstance || mLaunchSingleTask; 1400 // If bring to front is requested, and no result is requested and we have not been given 1401 // an explicit task to launch in to, and we can find a task that was started with this 1402 // same component, then instead of launching bring that one to the front. 1403 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null; 1404 ActivityRecord intentActivity = null; 1405 if (mOptions != null && mOptions.getLaunchTaskId() != -1) { 1406 final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId()); 1407 intentActivity = task != null ? task.getTopActivity() : null; 1408 } else if (putIntoExistingTask) { 1409 if (mLaunchSingleInstance) { 1410 // There can be one and only one instance of single instance activity in the 1411 // history, and it is always in its own unique task, so we do a special search. 1412 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info); 1413 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) { 1414 // For the launch adjacent case we only want to put the activity in an existing 1415 // task if the activity already exists in the history. 1416 intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info); 1417 } else { 1418 // Otherwise find the best task to put the activity in. 1419 intentActivity = mSupervisor.findTaskLocked(mStartActivity); 1420 } 1421 } 1422 return intentActivity; 1423 } 1424 1425 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) { 1426 mTargetStack = intentActivity.task.stack; 1427 mTargetStack.mLastPausedActivity = null; 1428 // If the target task is not in the front, then we need to bring it to the front... 1429 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have 1430 // the same behavior as if a new instance was being started, which means not bringing it 1431 // to the front if the caller is not itself in the front. 1432 final ActivityStack focusStack = mSupervisor.getFocusedStack(); 1433 ActivityRecord curTop = (focusStack == null) 1434 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop); 1435 1436 if (curTop != null 1437 && (curTop.task != intentActivity.task || curTop.task != focusStack.topTask()) 1438 && !mAvoidMoveToFront) { 1439 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 1440 if (mSourceRecord == null || (mSourceStack.topActivity() != null && 1441 mSourceStack.topActivity().task == mSourceRecord.task)) { 1442 // We really do want to push this one into the user's face, right now. 1443 if (mLaunchTaskBehind && mSourceRecord != null) { 1444 intentActivity.setTaskToAffiliateWith(mSourceRecord.task); 1445 } 1446 mMovedHome = true; 1447 1448 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities 1449 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity(). 1450 // So no point resuming any of the activities here, it just wastes one extra 1451 // resuming, plus enter AND exit transitions. 1452 // Here we only want to bring the target stack forward. Transition will be applied 1453 // to the new activity that's started after the old ones are gone. 1454 final boolean willClearTask = 1455 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 1456 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); 1457 if (!willClearTask) { 1458 final ActivityStack launchStack = getLaunchStack( 1459 mStartActivity, mLaunchFlags, mStartActivity.task, mOptions); 1460 if (launchStack == null || launchStack == mTargetStack) { 1461 // We only want to move to the front, if we aren't going to launch on a 1462 // different stack. If we launch on a different stack, we will put the 1463 // task on top there. 1464 mTargetStack.moveTaskToFrontLocked( 1465 intentActivity.task, mNoAnimation, mOptions, 1466 mStartActivity.appTimeTracker, "bringingFoundTaskToFront"); 1467 mMovedToFront = true; 1468 } else if ((launchStack.mStackId == DOCKED_STACK_ID 1469 || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) 1470 && (mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) { 1471 // If we want to launch adjacent and mTargetStack is not the computed 1472 // launch stack - move task to top of computed stack. 1473 mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId, 1474 launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide", 1475 ANIMATE); 1476 mMovedToFront = true; 1477 } 1478 mOptions = null; 1479 } 1480 updateTaskReturnToType(intentActivity.task, mLaunchFlags, focusStack); 1481 } 1482 } 1483 if (!mMovedToFront && mDoResume) { 1484 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack 1485 + " from " + intentActivity); 1486 mTargetStack.moveToFront("intentActivityFound"); 1487 } 1488 1489 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.task, INVALID_STACK_ID, 1490 mTargetStack.mStackId); 1491 1492 // If the caller has requested that the target task be reset, then do so. 1493 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 1494 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity); 1495 } 1496 return intentActivity; 1497 } 1498 1499 private void updateTaskReturnToType( 1500 TaskRecord task, int launchFlags, ActivityStack focusedStack) { 1501 if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) 1502 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { 1503 // Caller wants to appear on home activity. 1504 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1505 return; 1506 } else if (focusedStack == null || focusedStack.mStackId == HOME_STACK_ID) { 1507 // Task will be launched over the home stack, so return home. 1508 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1509 return; 1510 } 1511 1512 // Else we are coming from an application stack so return to an application. 1513 task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); 1514 } 1515 1516 private void setTaskFromIntentActivity(ActivityRecord intentActivity) { 1517 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) 1518 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) { 1519 // The caller has requested to completely replace any existing task with its new 1520 // activity. Well that should not be too hard... 1521 mReuseTask = intentActivity.task; 1522 mReuseTask.performClearTaskLocked(); 1523 mReuseTask.setIntent(mStartActivity); 1524 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 1525 || mLaunchSingleInstance || mLaunchSingleTask) { 1526 ActivityRecord top = intentActivity.task.performClearTaskLocked(mStartActivity, 1527 mLaunchFlags); 1528 if (top == null) { 1529 // A special case: we need to start the activity because it is not currently 1530 // running, and the caller has asked to clear the current task to have this 1531 // activity at the top. 1532 mAddingToTask = true; 1533 // Now pretend like this activity is being started by the top of its task, so it 1534 // is put in the right place. 1535 mSourceRecord = intentActivity; 1536 final TaskRecord task = mSourceRecord.task; 1537 if (task != null && task.stack == null) { 1538 // Target stack got cleared when we all activities were removed above. 1539 // Go ahead and reset it. 1540 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */, 1541 null /* bounds */, mLaunchFlags, mOptions); 1542 mTargetStack.addTask(task, 1543 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked"); 1544 } 1545 } 1546 } else if (mStartActivity.realActivity.equals(intentActivity.task.realActivity)) { 1547 // In this case the top activity on the task is the same as the one being launched, 1548 // so we take that as a request to bring the task to the foreground. If the top 1549 // activity in the task is the root activity, deliver this new intent to it if it 1550 // desires. 1551 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop) 1552 && intentActivity.realActivity.equals(mStartActivity.realActivity)) { 1553 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, 1554 intentActivity.task); 1555 if (intentActivity.frontOfTask) { 1556 intentActivity.task.setIntent(mStartActivity); 1557 } 1558 intentActivity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, 1559 mStartActivity.launchedFromPackage); 1560 } else if (!intentActivity.task.isSameIntentFilter(mStartActivity)) { 1561 // In this case we are launching the root activity of the task, but with a 1562 // different intent. We should start a new instance on top. 1563 mAddingToTask = true; 1564 mSourceRecord = intentActivity; 1565 } 1566 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 1567 // In this case an activity is being launched in to an existing task, without 1568 // resetting that task. This is typically the situation of launching an activity 1569 // from a notification or shortcut. We want to place the new activity on top of the 1570 // current task. 1571 mAddingToTask = true; 1572 mSourceRecord = intentActivity; 1573 } else if (!intentActivity.task.rootWasReset) { 1574 // In this case we are launching into an existing task that has not yet been started 1575 // from its front door. The current task has been brought to the front. Ideally, 1576 // we'd probably like to place this new task at the bottom of its stack, but that's 1577 // a little hard to do with the current organization of the code so for now we'll 1578 // just drop it. 1579 intentActivity.task.setIntent(mStartActivity); 1580 } 1581 } 1582 1583 private void resumeTargetStackIfNeeded() { 1584 if (mDoResume) { 1585 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions); 1586 if (!mMovedToFront) { 1587 // Make sure to notify Keyguard as well if we are not running an app transition 1588 // later. 1589 mSupervisor.notifyActivityDrawnForKeyguard(); 1590 } 1591 } else { 1592 ActivityOptions.abort(mOptions); 1593 } 1594 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); 1595 } 1596 1597 private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) { 1598 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags, 1599 mOptions); 1600 1601 if (mReuseTask == null) { 1602 final TaskRecord task = mTargetStack.createTaskRecord( 1603 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), 1604 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, 1605 mNewTaskIntent != null ? mNewTaskIntent : mIntent, 1606 mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind /* toTop */); 1607 mStartActivity.setTask(task, taskToAffiliate); 1608 if (mLaunchBounds != null) { 1609 final int stackId = mTargetStack.mStackId; 1610 if (StackId.resizeStackWithLaunchBounds(stackId)) { 1611 mService.resizeStack( 1612 stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); 1613 } else { 1614 mStartActivity.task.updateOverrideConfiguration(mLaunchBounds); 1615 } 1616 } 1617 if (DEBUG_TASKS) Slog.v(TAG_TASKS, 1618 "Starting new activity " + 1619 mStartActivity + " in new task " + mStartActivity.task); 1620 } else { 1621 mStartActivity.setTask(mReuseTask, taskToAffiliate); 1622 } 1623 } 1624 1625 private int setTaskFromSourceRecord() { 1626 final TaskRecord sourceTask = mSourceRecord.task; 1627 // We only want to allow changing stack if the target task is not the top one, 1628 // otherwise we would move the launching task to the other side, rather than show 1629 // two side by side. 1630 final boolean moveStackAllowed = sourceTask.stack.topTask() != sourceTask; 1631 if (moveStackAllowed) { 1632 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.task, 1633 mOptions); 1634 } 1635 1636 if (mTargetStack == null) { 1637 mTargetStack = sourceTask.stack; 1638 } else if (mTargetStack != sourceTask.stack) { 1639 mSupervisor.moveTaskToStackLocked(sourceTask.taskId, mTargetStack.mStackId, 1640 ON_TOP, FORCE_FOCUS, "launchToSide", !ANIMATE); 1641 } 1642 if (mDoResume) { 1643 mTargetStack.moveToFront("sourceStackToFront"); 1644 } 1645 final TaskRecord topTask = mTargetStack.topTask(); 1646 if (topTask != sourceTask && !mAvoidMoveToFront) { 1647 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions, 1648 mStartActivity.appTimeTracker, "sourceTaskToFront"); 1649 } 1650 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) { 1651 // In this case, we are adding the activity to an existing task, but the caller has 1652 // asked to clear that task if the activity is already running. 1653 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags); 1654 mKeepCurTransition = true; 1655 if (top != null) { 1656 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task); 1657 top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); 1658 // For paranoia, make sure we have correctly resumed the top activity. 1659 mTargetStack.mLastPausedActivity = null; 1660 if (mDoResume) { 1661 mSupervisor.resumeFocusedStackTopActivityLocked(); 1662 } 1663 ActivityOptions.abort(mOptions); 1664 return START_DELIVERED_TO_TOP; 1665 } 1666 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 1667 // In this case, we are launching an activity in our own task that may already be 1668 // running somewhere in the history, and we want to shuffle it to the front of the 1669 // stack if so. 1670 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity); 1671 if (top != null) { 1672 final TaskRecord task = top.task; 1673 task.moveActivityToFrontLocked(top); 1674 top.updateOptionsLocked(mOptions); 1675 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task); 1676 top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); 1677 mTargetStack.mLastPausedActivity = null; 1678 if (mDoResume) { 1679 mSupervisor.resumeFocusedStackTopActivityLocked(); 1680 } 1681 return START_DELIVERED_TO_TOP; 1682 } 1683 } 1684 1685 // An existing activity is starting this new activity, so we want to keep the new one in 1686 // the same task as the one that is starting it. 1687 mStartActivity.setTask(sourceTask, null); 1688 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity 1689 + " in existing task " + mStartActivity.task + " from source " + mSourceRecord); 1690 return START_SUCCESS; 1691 } 1692 1693 private int setTaskFromInTask() { 1694 if (mLaunchBounds != null) { 1695 mInTask.updateOverrideConfiguration(mLaunchBounds); 1696 int stackId = mInTask.getLaunchStackId(); 1697 if (stackId != mInTask.stack.mStackId) { 1698 final ActivityStack stack = mSupervisor.moveTaskToStackUncheckedLocked( 1699 mInTask, stackId, ON_TOP, !FORCE_FOCUS, "inTaskToFront"); 1700 stackId = stack.mStackId; 1701 } 1702 if (StackId.resizeStackWithLaunchBounds(stackId)) { 1703 mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); 1704 } 1705 } 1706 mTargetStack = mInTask.stack; 1707 mTargetStack.moveTaskToFrontLocked( 1708 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront"); 1709 1710 // Check whether we should actually launch the new activity in to the task, 1711 // or just reuse the current activity on top. 1712 ActivityRecord top = mInTask.getTopActivity(); 1713 if (top != null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId) { 1714 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 1715 || mLaunchSingleTop || mLaunchSingleTask) { 1716 ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task); 1717 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { 1718 // We don't need to start a new activity, and the client said not to do 1719 // anything if that is the case, so this is it! 1720 return START_RETURN_INTENT_TO_CALLER; 1721 } 1722 top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); 1723 return START_DELIVERED_TO_TOP; 1724 } 1725 } 1726 1727 if (!mAddingToTask) { 1728 // We don't actually want to have this activity added to the task, so just 1729 // stop here but still tell the caller that we consumed the intent. 1730 ActivityOptions.abort(mOptions); 1731 return START_TASK_TO_FRONT; 1732 } 1733 1734 mStartActivity.setTask(mInTask, null); 1735 if (DEBUG_TASKS) Slog.v(TAG_TASKS, 1736 "Starting new activity " + mStartActivity + " in explicit task " + mStartActivity.task); 1737 1738 return START_SUCCESS; 1739 } 1740 1741 private void setTaskToCurrentTopOrCreateNewTask() { 1742 mTargetStack = computeStackFocus(mStartActivity, false, null /* bounds */, mLaunchFlags, 1743 mOptions); 1744 if (mDoResume) { 1745 mTargetStack.moveToFront("addingToTopTask"); 1746 } 1747 final ActivityRecord prev = mTargetStack.topActivity(); 1748 final TaskRecord task = (prev != null) ? prev.task : mTargetStack.createTaskRecord( 1749 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), 1750 mStartActivity.info, mIntent, null, null, true); 1751 mStartActivity.setTask(task, null); 1752 mWindowManager.moveTaskToTop(mStartActivity.task.taskId); 1753 if (DEBUG_TASKS) Slog.v(TAG_TASKS, 1754 "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.task); 1755 } 1756 1757 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, 1758 boolean launchSingleTask, int launchFlags) { 1759 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && 1760 (launchSingleInstance || launchSingleTask)) { 1761 // We have a conflict between the Intent and the Activity manifest, manifest wins. 1762 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " + 1763 "\"singleInstance\" or \"singleTask\""); 1764 launchFlags &= 1765 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK); 1766 } else { 1767 switch (r.info.documentLaunchMode) { 1768 case ActivityInfo.DOCUMENT_LAUNCH_NONE: 1769 break; 1770 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING: 1771 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1772 break; 1773 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS: 1774 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 1775 break; 1776 case ActivityInfo.DOCUMENT_LAUNCH_NEVER: 1777 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK; 1778 break; 1779 } 1780 } 1781 return launchFlags; 1782 } 1783 1784 final void doPendingActivityLaunchesLocked(boolean doResume) { 1785 while (!mPendingActivityLaunches.isEmpty()) { 1786 final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0); 1787 final boolean resume = doResume && mPendingActivityLaunches.isEmpty(); 1788 try { 1789 final int result = startActivityUnchecked( 1790 pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null); 1791 postStartActivityUncheckedProcessing( 1792 pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord, 1793 mTargetStack); 1794 } catch (Exception e) { 1795 Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e); 1796 pal.sendErrorResult(e.getMessage()); 1797 } 1798 } 1799 } 1800 1801 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, Rect bounds, 1802 int launchFlags, ActivityOptions aOptions) { 1803 final TaskRecord task = r.task; 1804 if (!(r.isApplicationActivity() || (task != null && task.isApplicationTask()))) { 1805 return mSupervisor.mHomeStack; 1806 } 1807 1808 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions); 1809 if (stack != null) { 1810 return stack; 1811 } 1812 1813 if (task != null && task.stack != null) { 1814 stack = task.stack; 1815 if (stack.isOnHomeDisplay()) { 1816 if (mSupervisor.mFocusedStack != stack) { 1817 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1818 "computeStackFocus: Setting " + "focused stack to r=" + r 1819 + " task=" + task); 1820 } else { 1821 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1822 "computeStackFocus: Focused stack already=" 1823 + mSupervisor.mFocusedStack); 1824 } 1825 } 1826 return stack; 1827 } 1828 1829 final ActivityStackSupervisor.ActivityContainer container = r.mInitialActivityContainer; 1830 if (container != null) { 1831 // The first time put it on the desired stack, after this put on task stack. 1832 r.mInitialActivityContainer = null; 1833 return container.mStack; 1834 } 1835 1836 // The fullscreen stack can contain any task regardless of if the task is resizeable 1837 // or not. So, we let the task go in the fullscreen task if it is the focus stack. 1838 // If the freeform or docked stack has focus, and the activity to be launched is resizeable, 1839 // we can also put it in the focused stack. 1840 final int focusedStackId = mSupervisor.mFocusedStack.mStackId; 1841 final boolean canUseFocusedStack = focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID 1842 || (focusedStackId == DOCKED_STACK_ID && r.canGoInDockedStack()) 1843 || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced()); 1844 if (canUseFocusedStack && (!newTask 1845 || mSupervisor.mFocusedStack.mActivityContainer.isEligibleForNewTasks())) { 1846 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1847 "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack); 1848 return mSupervisor.mFocusedStack; 1849 } 1850 1851 // We first try to put the task in the first dynamic stack. 1852 final ArrayList<ActivityStack> homeDisplayStacks = mSupervisor.mHomeStack.mStacks; 1853 for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { 1854 stack = homeDisplayStacks.get(stackNdx); 1855 if (!ActivityManager.StackId.isStaticStack(stack.mStackId)) { 1856 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, 1857 "computeStackFocus: Setting focused stack=" + stack); 1858 return stack; 1859 } 1860 } 1861 1862 // If there is no suitable dynamic stack then we figure out which static stack to use. 1863 final int stackId = task != null ? task.getLaunchStackId() : 1864 bounds != null ? FREEFORM_WORKSPACE_STACK_ID : 1865 FULLSCREEN_WORKSPACE_STACK_ID; 1866 stack = mSupervisor.getStack(stackId, CREATE_IF_NEEDED, ON_TOP); 1867 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r=" 1868 + r + " stackId=" + stack.mStackId); 1869 return stack; 1870 } 1871 1872 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task, 1873 ActivityOptions aOptions) { 1874 1875 // We are reusing a task, keep the stack! 1876 if (mReuseTask != null) { 1877 return mReuseTask.stack; 1878 } 1879 1880 final int launchStackId = 1881 (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID; 1882 1883 if (isValidLaunchStackId(launchStackId, r)) { 1884 return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP); 1885 } else if (launchStackId == DOCKED_STACK_ID) { 1886 // The preferred launch stack is the docked stack, but it isn't a valid launch stack 1887 // for this activity, so we put the activity in the fullscreen stack. 1888 return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP); 1889 } 1890 1891 if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) { 1892 return null; 1893 } 1894 // Otherwise handle adjacent launch. 1895 1896 // The parent activity doesn't want to launch the activity on top of itself, but 1897 // instead tries to put it onto other side in side-by-side mode. 1898 final ActivityStack parentStack = task != null ? task.stack 1899 : r.mInitialActivityContainer != null ? r.mInitialActivityContainer.mStack 1900 : mSupervisor.mFocusedStack; 1901 1902 if (parentStack != mSupervisor.mFocusedStack) { 1903 // If task's parent stack is not focused - use it during adjacent launch. 1904 return parentStack; 1905 } else { 1906 if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) { 1907 // If task is already on top of focused stack - use it. We don't want to move the 1908 // existing focused task to adjacent stack, just deliver new intent in this case. 1909 return mSupervisor.mFocusedStack; 1910 } 1911 1912 if (parentStack != null && parentStack.mStackId == DOCKED_STACK_ID) { 1913 // If parent was in docked stack, the natural place to launch another activity 1914 // will be fullscreen, so it can appear alongside the docked window. 1915 return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, 1916 ON_TOP); 1917 } else { 1918 // If the parent is not in the docked stack, we check if there is docked window 1919 // and if yes, we will launch into that stack. If not, we just put the new 1920 // activity into parent's stack, because we can't find a better place. 1921 final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID); 1922 if (dockedStack != null 1923 && dockedStack.getStackVisibilityLocked(r) == STACK_INVISIBLE) { 1924 // There is a docked stack, but it isn't visible, so we can't launch into that. 1925 return null; 1926 } else { 1927 return dockedStack; 1928 } 1929 } 1930 } 1931 } 1932 1933 private boolean isValidLaunchStackId(int stackId, ActivityRecord r) { 1934 if (stackId == INVALID_STACK_ID || stackId == HOME_STACK_ID 1935 || !StackId.isStaticStack(stackId)) { 1936 return false; 1937 } 1938 1939 if (stackId != FULLSCREEN_WORKSPACE_STACK_ID 1940 && (!mService.mSupportsMultiWindow || !r.isResizeableOrForced())) { 1941 return false; 1942 } 1943 1944 if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) { 1945 return true; 1946 } 1947 1948 if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) { 1949 return false; 1950 } 1951 1952 final boolean supportsPip = mService.mSupportsPictureInPicture 1953 && (r.supportsPictureInPicture() || mService.mForceResizableActivities); 1954 if (stackId == PINNED_STACK_ID && !supportsPip) { 1955 return false; 1956 } 1957 return true; 1958 } 1959 1960 Rect getOverrideBounds(ActivityRecord r, ActivityOptions options, TaskRecord inTask) { 1961 Rect newBounds = null; 1962 if (options != null && (r.isResizeable() || (inTask != null && inTask.isResizeable()))) { 1963 if (mSupervisor.canUseActivityOptionsLaunchBounds( 1964 options, options.getLaunchStackId())) { 1965 newBounds = TaskRecord.validateBounds(options.getLaunchBounds()); 1966 } 1967 } 1968 return newBounds; 1969 } 1970 1971 void setWindowManager(WindowManagerService wm) { 1972 mWindowManager = wm; 1973 } 1974 1975 void removePendingActivityLaunchesLocked(ActivityStack stack) { 1976 for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) { 1977 PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx); 1978 if (pal.stack == stack) { 1979 mPendingActivityLaunches.remove(palNdx); 1980 } 1981 } 1982 } 1983} 1984