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