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