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