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