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