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