1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.wm; 18 19 import static android.app.ActivityManager.START_CANCELED; 20 import static android.app.ActivityManager.START_SUCCESS; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; 23 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 24 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 25 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 26 import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL; 27 28 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 29 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 30 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; 31 32 import android.annotation.NonNull; 33 import android.annotation.Nullable; 34 import android.app.ActivityManager; 35 import android.app.ActivityOptions; 36 import android.app.IApplicationThread; 37 import android.content.ComponentName; 38 import android.content.ContentResolver; 39 import android.content.Intent; 40 import android.content.pm.ActivityInfo; 41 import android.content.pm.ApplicationInfo; 42 import android.content.pm.PackageManager; 43 import android.content.pm.ResolveInfo; 44 import android.os.Binder; 45 import android.os.Bundle; 46 import android.os.IBinder; 47 import android.os.UserHandle; 48 import android.provider.Settings; 49 import android.util.Slog; 50 import android.util.SparseArray; 51 import android.view.RemoteAnimationAdapter; 52 import android.view.WindowManager; 53 import android.window.RemoteTransition; 54 55 import com.android.internal.annotations.VisibleForTesting; 56 import com.android.internal.util.ArrayUtils; 57 import com.android.server.am.ActivityManagerService; 58 import com.android.server.am.PendingIntentRecord; 59 import com.android.server.uri.NeededUriGrants; 60 import com.android.server.wm.ActivityStarter.DefaultFactory; 61 import com.android.server.wm.ActivityStarter.Factory; 62 63 import java.io.PrintWriter; 64 import java.util.List; 65 66 /** 67 * Controller for delegating activity launches. 68 * 69 * This class' main objective is to take external activity start requests and prepare them into 70 * a series of discrete activity launches that can be handled by an {@link ActivityStarter}. It is 71 * also responsible for handling logic that happens around an activity launch, but doesn't 72 * necessarily influence the activity start. Examples include power hint management, processing 73 * through the pending activity list, and recording home activity launches. 74 */ 75 public class ActivityStartController { 76 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStartController" : TAG_ATM; 77 78 private static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 1; 79 80 private final ActivityTaskManagerService mService; 81 private final ActivityTaskSupervisor mSupervisor; 82 83 /** Last home activity record we attempted to start. */ 84 private ActivityRecord mLastHomeActivityStartRecord; 85 86 /** Temporary array to capture start activity results */ 87 private ActivityRecord[] tmpOutRecord = new ActivityRecord[1]; 88 89 /** The result of the last home activity we attempted to start. */ 90 private int mLastHomeActivityStartResult; 91 92 private final Factory mFactory; 93 94 private final PendingRemoteAnimationRegistry mPendingRemoteAnimationRegistry; 95 96 boolean mCheckedForSetup = false; 97 98 /** Whether an {@link ActivityStarter} is currently executing (starting an Activity). */ 99 private boolean mInExecution = false; 100 101 private final BackgroundActivityStartController mBalController; 102 103 /** 104 * TODO(b/64750076): Capture information necessary for dump and 105 * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object 106 * around 107 */ 108 private ActivityStarter mLastStarter; 109 ActivityStartController(ActivityTaskManagerService service)110 ActivityStartController(ActivityTaskManagerService service) { 111 this(service, service.mTaskSupervisor, 112 new DefaultFactory(service, service.mTaskSupervisor, 113 new ActivityStartInterceptor(service, service.mTaskSupervisor))); 114 } 115 116 @VisibleForTesting ActivityStartController(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, Factory factory)117 ActivityStartController(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, 118 Factory factory) { 119 mService = service; 120 mSupervisor = supervisor; 121 mFactory = factory; 122 mFactory.setController(this); 123 mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock, 124 service.mH); 125 mBalController = new BackgroundActivityStartController(mService, mSupervisor); 126 } 127 128 /** 129 * @return A starter to configure and execute starting an activity. It is valid until after 130 * {@link ActivityStarter#execute} is invoked. At that point, the starter should be 131 * considered invalid and no longer modified or used. 132 */ obtainStarter(Intent intent, String reason)133 ActivityStarter obtainStarter(Intent intent, String reason) { 134 return mFactory.obtain().setIntent(intent).setReason(reason); 135 } 136 onExecutionStarted()137 void onExecutionStarted() { 138 mInExecution = true; 139 } 140 isInExecution()141 boolean isInExecution() { 142 return mInExecution; 143 } onExecutionComplete(ActivityStarter starter)144 void onExecutionComplete(ActivityStarter starter) { 145 mInExecution = false; 146 if (mLastStarter == null) { 147 mLastStarter = mFactory.obtain(); 148 } 149 150 mLastStarter.set(starter); 151 mFactory.recycle(starter); 152 } 153 154 /** 155 * TODO(b/64750076): usage of this doesn't seem right. We're making decisions based off the 156 * last starter for an arbitrary task record. Re-evaluate whether we can remove. 157 */ postStartActivityProcessingForLastStarter(ActivityRecord r, int result, Task targetRootTask)158 void postStartActivityProcessingForLastStarter(ActivityRecord r, int result, 159 Task targetRootTask) { 160 if (mLastStarter == null) { 161 return; 162 } 163 164 mLastStarter.postStartActivityProcessing(r, result, targetRootTask); 165 } 166 startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, TaskDisplayArea taskDisplayArea)167 void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, 168 TaskDisplayArea taskDisplayArea) { 169 final ActivityOptions options = ActivityOptions.makeBasic(); 170 options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); 171 if (!ActivityRecord.isResolverActivity(aInfo.name)) { 172 // The resolver activity shouldn't be put in root home task because when the 173 // foreground is standard type activity, the resolver activity should be put on the 174 // top of current foreground instead of bring root home task to front. 175 options.setLaunchActivityType(ACTIVITY_TYPE_HOME); 176 } 177 final int displayId = taskDisplayArea.getDisplayId(); 178 options.setLaunchDisplayId(displayId); 179 options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken 180 .toWindowContainerToken()); 181 182 // The home activity will be started later, defer resuming to avoid unnecessary operations 183 // (e.g. start home recursively) when creating root home task. 184 mSupervisor.beginDeferResume(); 185 final Task rootHomeTask; 186 try { 187 // Make sure root home task exists on display area. 188 rootHomeTask = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP); 189 } finally { 190 mSupervisor.endDeferResume(); 191 } 192 193 mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason) 194 .setOutActivity(tmpOutRecord) 195 .setCallingUid(0) 196 .setActivityInfo(aInfo) 197 .setActivityOptions(options.toBundle()) 198 .execute(); 199 mLastHomeActivityStartRecord = tmpOutRecord[0]; 200 if (rootHomeTask.mInResumeTopActivity) { 201 // If we are in resume section already, home activity will be initialized, but not 202 // resumed (to avoid recursive resume) and will stay that way until something pokes it 203 // again. We need to schedule another resume. 204 mSupervisor.scheduleResumeTopActivities(); 205 } 206 } 207 208 /** 209 * Starts the "new version setup screen" if appropriate. 210 */ startSetupActivity()211 void startSetupActivity() { 212 // Only do this once per boot. 213 if (mCheckedForSetup) { 214 return; 215 } 216 217 // We will show this screen if the current one is a different 218 // version than the last one shown, and we are not running in 219 // low-level factory test mode. 220 final ContentResolver resolver = mService.mContext.getContentResolver(); 221 if (mService.mFactoryTest != FACTORY_TEST_LOW_LEVEL 222 && Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 223 mCheckedForSetup = true; 224 225 // See if we should be showing the platform update setup UI. 226 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 227 final List<ResolveInfo> ris = 228 mService.mContext.getPackageManager().queryIntentActivities(intent, 229 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA 230 | ActivityManagerService.STOCK_PM_FLAGS); 231 if (!ris.isEmpty()) { 232 final ResolveInfo ri = ris.get(0); 233 String vers = ri.activityInfo.metaData != null 234 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 235 : null; 236 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 237 vers = ri.activityInfo.applicationInfo.metaData.getString( 238 Intent.METADATA_SETUP_VERSION); 239 } 240 String lastVers = Settings.Secure.getString( 241 resolver, Settings.Secure.LAST_SETUP_SHOWN); 242 if (vers != null && !vers.equals(lastVers)) { 243 intent.setFlags(FLAG_ACTIVITY_NEW_TASK); 244 intent.setComponent(new ComponentName( 245 ri.activityInfo.packageName, ri.activityInfo.name)); 246 obtainStarter(intent, "startSetupActivity") 247 .setCallingUid(0) 248 .setActivityInfo(ri.activityInfo) 249 .execute(); 250 } 251 } 252 } 253 } 254 255 /** 256 * If {@code validateIncomingUser} is true, check {@code targetUserId} against the real calling 257 * user ID inferred from {@code realCallingUid}, then return the resolved user-id, taking into 258 * account "current user", etc. 259 * 260 * If {@code validateIncomingUser} is false, it skips the above check, but instead 261 * ensures {@code targetUserId} is a real user ID and not a special user ID such as 262 * {@link android.os.UserHandle#USER_ALL}, etc. 263 */ checkTargetUser(int targetUserId, boolean validateIncomingUser, int realCallingPid, int realCallingUid, String reason)264 int checkTargetUser(int targetUserId, boolean validateIncomingUser, 265 int realCallingPid, int realCallingUid, String reason) { 266 if (validateIncomingUser) { 267 return mService.handleIncomingUser( 268 realCallingPid, realCallingUid, targetUserId, reason); 269 } else { 270 mService.mAmInternal.ensureNotSpecialUser(targetUserId); 271 return targetUserId; 272 } 273 } 274 startActivityInPackage(int uid, int realCallingPid, int realCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, SafeActivityOptions options, int userId, Task inTask, String reason, boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)275 final int startActivityInPackage(int uid, int realCallingPid, int realCallingUid, 276 String callingPackage, @Nullable String callingFeatureId, Intent intent, 277 String resolvedType, IBinder resultTo, String resultWho, int requestCode, 278 int startFlags, SafeActivityOptions options, int userId, Task inTask, String reason, 279 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, 280 boolean allowBackgroundActivityStart) { 281 282 userId = checkTargetUser(userId, validateIncomingUser, realCallingPid, realCallingUid, 283 reason); 284 285 // TODO: Switch to user app stacks here. 286 return obtainStarter(intent, reason) 287 .setCallingUid(uid) 288 .setRealCallingPid(realCallingPid) 289 .setRealCallingUid(realCallingUid) 290 .setCallingPackage(callingPackage) 291 .setCallingFeatureId(callingFeatureId) 292 .setResolvedType(resolvedType) 293 .setResultTo(resultTo) 294 .setResultWho(resultWho) 295 .setRequestCode(requestCode) 296 .setStartFlags(startFlags) 297 .setActivityOptions(options) 298 .setUserId(userId) 299 .setInTask(inTask) 300 .setOriginatingPendingIntent(originatingPendingIntent) 301 .setAllowBackgroundActivityStart(allowBackgroundActivityStart) 302 .execute(); 303 } 304 305 /** 306 * Start intents as a package. 307 * 308 * @param uid Make a call as if this UID did. 309 * @param callingPackage Make a call as if this package did. 310 * @param callingFeatureId Make a call as if this feature in the package did. 311 * @param intents Intents to start. 312 * @param userId Start the intents on this user. 313 * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID. 314 * @param originatingPendingIntent PendingIntentRecord that originated this activity start or 315 * null if not originated by PendingIntent 316 */ startActivitiesInPackage(int uid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)317 final int startActivitiesInPackage(int uid, String callingPackage, 318 @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, 319 IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser, 320 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) { 321 return startActivitiesInPackage(uid, 0 /* realCallingPid */, -1 /* realCallingUid */, 322 callingPackage, callingFeatureId, intents, resolvedTypes, resultTo, options, userId, 323 validateIncomingUser, originatingPendingIntent, allowBackgroundActivityStart); 324 } 325 326 /** 327 * Start intents as a package. 328 * 329 * @param uid Make a call as if this UID did. 330 * @param realCallingPid PID of the real caller. 331 * @param realCallingUid UID of the real caller. 332 * @param callingPackage Make a call as if this package did. 333 * @param intents Intents to start. 334 * @param userId Start the intents on this user. 335 * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID. 336 * @param originatingPendingIntent PendingIntentRecord that originated this activity start or 337 * null if not originated by PendingIntent 338 */ startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)339 final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid, 340 String callingPackage, @Nullable String callingFeatureId, Intent[] intents, 341 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, 342 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, 343 boolean allowBackgroundActivityStart) { 344 345 final String reason = "startActivityInPackage"; 346 347 userId = checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), 348 Binder.getCallingUid(), reason); 349 350 // TODO: Switch to user app stacks here. 351 return startActivities(null, uid, realCallingPid, realCallingUid, callingPackage, 352 callingFeatureId, intents, resolvedTypes, resultTo, options, userId, reason, 353 originatingPendingIntent, allowBackgroundActivityStart); 354 } 355 startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid, int incomingRealCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, String reason, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)356 int startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid, 357 int incomingRealCallingUid, String callingPackage, @Nullable String callingFeatureId, 358 Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, 359 int userId, String reason, PendingIntentRecord originatingPendingIntent, 360 boolean allowBackgroundActivityStart) { 361 if (intents == null) { 362 throw new NullPointerException("intents is null"); 363 } 364 if (resolvedTypes == null) { 365 throw new NullPointerException("resolvedTypes is null"); 366 } 367 if (intents.length != resolvedTypes.length) { 368 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 369 } 370 371 final int realCallingPid = incomingRealCallingPid != 0 372 ? incomingRealCallingPid 373 : Binder.getCallingPid(); 374 final int realCallingUid = incomingRealCallingUid != -1 375 ? incomingRealCallingUid 376 : Binder.getCallingUid(); 377 378 int callingPid; 379 if (callingUid >= 0) { 380 callingPid = -1; 381 } else if (caller == null) { 382 callingPid = realCallingPid; 383 callingUid = realCallingUid; 384 } else { 385 callingPid = callingUid = -1; 386 } 387 final int filterCallingUid = ActivityStarter.computeResolveFilterUid( 388 callingUid, realCallingUid, UserHandle.USER_NULL); 389 final SparseArray<String> startingUidPkgs = new SparseArray<>(); 390 final long origId = Binder.clearCallingIdentity(); 391 392 SafeActivityOptions bottomOptions = null; 393 if (options != null) { 394 // To ensure the first N-1 activities (N == total # of activities) are also launched 395 // into the correct display and root task, use a copy of the passed-in options (keeping 396 // only display-related and launch-root-task information) for these activities. 397 bottomOptions = options.selectiveCloneLaunchOptions(); 398 } 399 try { 400 intents = ArrayUtils.filterNotNull(intents, Intent[]::new); 401 final ActivityStarter[] starters = new ActivityStarter[intents.length]; 402 // Do not hold WM global lock on this loop because when resolving intent, it may 403 // potentially acquire activity manager lock that leads to deadlock. 404 for (int i = 0; i < intents.length; i++) { 405 Intent intent = intents[i]; 406 NeededUriGrants intentGrants = null; 407 408 // Refuse possible leaked file descriptors. 409 if (intent.hasFileDescriptors()) { 410 throw new IllegalArgumentException("File descriptors passed in Intent"); 411 } 412 413 // Get the flag earlier because the intent may be modified in resolveActivity below. 414 final boolean componentSpecified = intent.getComponent() != null; 415 // Don't modify the client's object! 416 intent = new Intent(intent); 417 418 // Collect information about the target of the Intent. 419 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 420 0 /* startFlags */, null /* profilerInfo */, userId, filterCallingUid); 421 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId); 422 423 if (aInfo != null) { 424 try { 425 // Carefully collect grants without holding lock 426 intentGrants = mSupervisor.mService.mUgmInternal 427 .checkGrantUriPermissionFromIntent(intent, filterCallingUid, 428 aInfo.applicationInfo.packageName, 429 UserHandle.getUserId(aInfo.applicationInfo.uid)); 430 } catch (SecurityException e) { 431 Slog.d(TAG, "Not allowed to start activity since no uri permission."); 432 return START_CANCELED; 433 } 434 435 if ((aInfo.applicationInfo.privateFlags 436 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { 437 throw new IllegalArgumentException( 438 "FLAG_CANT_SAVE_STATE not supported here"); 439 } 440 startingUidPkgs.put(aInfo.applicationInfo.uid, 441 aInfo.applicationInfo.packageName); 442 } 443 444 final boolean top = i == intents.length - 1; 445 final SafeActivityOptions checkedOptions = top 446 ? options 447 : bottomOptions; 448 starters[i] = obtainStarter(intent, reason) 449 .setIntentGrants(intentGrants) 450 .setCaller(caller) 451 .setResolvedType(resolvedTypes[i]) 452 .setActivityInfo(aInfo) 453 .setRequestCode(-1) 454 .setCallingPid(callingPid) 455 .setCallingUid(callingUid) 456 .setCallingPackage(callingPackage) 457 .setCallingFeatureId(callingFeatureId) 458 .setRealCallingPid(realCallingPid) 459 .setRealCallingUid(realCallingUid) 460 .setActivityOptions(checkedOptions) 461 .setComponentSpecified(componentSpecified) 462 463 // Top activity decides on animation being run, so we allow only for the 464 // top one as otherwise an activity below might consume it. 465 .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/) 466 .setOriginatingPendingIntent(originatingPendingIntent) 467 .setAllowBackgroundActivityStart(allowBackgroundActivityStart); 468 } 469 // Log if the activities to be started have different uids. 470 if (startingUidPkgs.size() > 1) { 471 final StringBuilder sb = new StringBuilder("startActivities: different apps ["); 472 final int size = startingUidPkgs.size(); 473 for (int i = 0; i < size; i++) { 474 sb.append(startingUidPkgs.valueAt(i)).append(i == size - 1 ? "]" : ", "); 475 } 476 sb.append(" from ").append(callingPackage); 477 Slog.wtf(TAG, sb.toString()); 478 } 479 480 final IBinder sourceResultTo = resultTo; 481 final ActivityRecord[] outActivity = new ActivityRecord[1]; 482 // Lock the loop to ensure the activities launched in a sequence. 483 synchronized (mService.mGlobalLock) { 484 mService.deferWindowLayout(); 485 // To avoid creating multiple starting window when creating starting multiples 486 // activities, we defer the creation of the starting window once all start request 487 // are processed 488 mService.mWindowManager.mStartingSurfaceController.beginDeferAddStartingWindow(); 489 try { 490 for (int i = 0; i < starters.length; i++) { 491 final int startResult = starters[i].setResultTo(resultTo) 492 .setOutActivity(outActivity).execute(); 493 if (startResult < START_SUCCESS) { 494 // Abort by error result and recycle unused starters. 495 for (int j = i + 1; j < starters.length; j++) { 496 mFactory.recycle(starters[j]); 497 } 498 return startResult; 499 } 500 final ActivityRecord started = outActivity[0]; 501 if (started != null && started.getUid() == filterCallingUid) { 502 // Only the started activity which has the same uid as the source caller 503 // can be the caller of next activity. 504 resultTo = started.token; 505 } else { 506 resultTo = sourceResultTo; 507 // Different apps not adjacent to the caller are forced to be new task. 508 if (i < starters.length - 1) { 509 starters[i + 1].getIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 510 } 511 } 512 } 513 } finally { 514 mService.mWindowManager.mStartingSurfaceController.endDeferAddStartingWindow( 515 options != null ? options.getOriginalOptions() : null); 516 mService.continueWindowLayout(); 517 } 518 } 519 } finally { 520 Binder.restoreCallingIdentity(origId); 521 } 522 523 return START_SUCCESS; 524 } 525 526 /** 527 * Starts an activity in the TaskFragment. 528 * @param taskFragment TaskFragment {@link TaskFragment} to start the activity in. 529 * @param activityIntent intent to start the activity. 530 * @param activityOptions ActivityOptions to start the activity with. 531 * @param resultTo the caller activity 532 * @param callingUid the caller uid 533 * @param callingPid the caller pid 534 * @return the start result. 535 */ startActivityInTaskFragment(@onNull TaskFragment taskFragment, @NonNull Intent activityIntent, @Nullable Bundle activityOptions, @Nullable IBinder resultTo, int callingUid, int callingPid, @Nullable IBinder errorCallbackToken)536 int startActivityInTaskFragment(@NonNull TaskFragment taskFragment, 537 @NonNull Intent activityIntent, @Nullable Bundle activityOptions, 538 @Nullable IBinder resultTo, int callingUid, int callingPid, 539 @Nullable IBinder errorCallbackToken) { 540 final ActivityRecord caller = 541 resultTo != null ? ActivityRecord.forTokenLocked(resultTo) : null; 542 return obtainStarter(activityIntent, "startActivityInTaskFragment") 543 .setActivityOptions(activityOptions) 544 .setInTaskFragment(taskFragment) 545 .setResultTo(resultTo) 546 .setRequestCode(-1) 547 .setCallingUid(callingUid) 548 .setCallingPid(callingPid) 549 .setRealCallingUid(callingUid) 550 .setRealCallingPid(callingPid) 551 .setUserId(caller != null ? caller.mUserId : mService.getCurrentUserId()) 552 .setErrorCallbackToken(errorCallbackToken) 553 .execute(); 554 } 555 startExistingRecentsIfPossible(Intent intent, ActivityOptions options)556 boolean startExistingRecentsIfPossible(Intent intent, ActivityOptions options) { 557 final int activityType = mService.getRecentTasks().getRecentsComponent() 558 .equals(intent.getComponent()) ? ACTIVITY_TYPE_RECENTS : ACTIVITY_TYPE_HOME; 559 final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea() 560 .getRootTask(WINDOWING_MODE_UNDEFINED, activityType); 561 if (rootTask == null) return false; 562 final RemoteTransition remote = options.getRemoteTransition(); 563 final ActivityRecord r = rootTask.topRunningActivity(); 564 if (r == null || r.isVisibleRequested() || !r.attachedToProcess() || remote == null 565 || !r.mActivityComponent.equals(intent.getComponent()) 566 // Recents keeps invisible while device is locked. 567 || r.mDisplayContent.isKeyguardLocked()) { 568 return false; 569 } 570 mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r); 571 final ActivityMetricsLogger.LaunchingState launchingState = 572 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent); 573 final Transition transition = new Transition(WindowManager.TRANSIT_TO_FRONT, 574 0 /* flags */, r.mTransitionController, mService.mWindowManager.mSyncEngine); 575 if (r.mTransitionController.isCollecting()) { 576 // Special case: we are entering recents while an existing transition is running. In 577 // this case, we know it's safe to "defer" the activity launch, so lets do so now so 578 // that it can get its own transition and thus update launcher correctly. 579 mService.mWindowManager.mSyncEngine.queueSyncSet( 580 () -> { 581 if (r.isAttached()) { 582 r.mTransitionController.moveToCollecting(transition); 583 } 584 }, 585 () -> { 586 if (r.isAttached() && transition.isCollecting()) { 587 startExistingRecentsIfPossibleInner(options, r, rootTask, 588 launchingState, remote, transition); 589 } 590 }); 591 } else { 592 r.mTransitionController.moveToCollecting(transition); 593 startExistingRecentsIfPossibleInner(options, r, rootTask, launchingState, remote, 594 transition); 595 } 596 return true; 597 } 598 startExistingRecentsIfPossibleInner(ActivityOptions options, ActivityRecord r, Task rootTask, ActivityMetricsLogger.LaunchingState launchingState, RemoteTransition remoteTransition, Transition transition)599 private void startExistingRecentsIfPossibleInner(ActivityOptions options, ActivityRecord r, 600 Task rootTask, ActivityMetricsLogger.LaunchingState launchingState, 601 RemoteTransition remoteTransition, Transition transition) { 602 final Task task = r.getTask(); 603 mService.deferWindowLayout(); 604 try { 605 r.mTransitionController.requestStartTransition(transition, 606 task, remoteTransition, null /* displayChange */); 607 r.mTransitionController.collect(task); 608 r.mTransitionController.setTransientLaunch(r, 609 TaskDisplayArea.getRootTaskAbove(rootTask)); 610 task.moveToFront("startExistingRecents"); 611 task.mInResumeTopActivity = true; 612 task.resumeTopActivity(null /* prev */, options, true /* deferPause */); 613 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, 614 ActivityManager.START_TASK_TO_FRONT, false, r, options); 615 } finally { 616 task.mInResumeTopActivity = false; 617 mService.continueWindowLayout(); 618 } 619 } 620 registerRemoteAnimationForNextActivityStart(String packageName, RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie)621 void registerRemoteAnimationForNextActivityStart(String packageName, 622 RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) { 623 mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie); 624 } 625 getPendingRemoteAnimationRegistry()626 PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() { 627 return mPendingRemoteAnimationRegistry; 628 } 629 dumpLastHomeActivityStartResult(PrintWriter pw, String prefix)630 void dumpLastHomeActivityStartResult(PrintWriter pw, String prefix) { 631 pw.print(prefix); 632 pw.print("mLastHomeActivityStartResult="); 633 pw.println(mLastHomeActivityStartResult); 634 } 635 dump(PrintWriter pw, String prefix, String dumpPackage)636 void dump(PrintWriter pw, String prefix, String dumpPackage) { 637 boolean dumped = false; 638 639 final boolean dumpPackagePresent = dumpPackage != null; 640 641 if (mLastHomeActivityStartRecord != null && (!dumpPackagePresent 642 || dumpPackage.equals(mLastHomeActivityStartRecord.packageName))) { 643 dumped = true; 644 dumpLastHomeActivityStartResult(pw, prefix); 645 pw.print(prefix); 646 pw.println("mLastHomeActivityStartRecord:"); 647 mLastHomeActivityStartRecord.dump(pw, prefix + " ", true /* dumpAll */); 648 } 649 650 if (mLastStarter != null) { 651 final boolean dump = !dumpPackagePresent 652 || mLastStarter.relatedToPackage(dumpPackage) 653 || (mLastHomeActivityStartRecord != null 654 && dumpPackage.equals(mLastHomeActivityStartRecord.packageName)); 655 656 if (dump) { 657 if (!dumped) { 658 dumped = true; 659 dumpLastHomeActivityStartResult(pw, prefix); 660 } 661 pw.print(prefix); 662 pw.println("mLastStarter:"); 663 mLastStarter.dump(pw, prefix + " "); 664 665 if (dumpPackagePresent) { 666 return; 667 } 668 } 669 } 670 671 if (!dumped) { 672 pw.print(prefix); 673 pw.println("(nothing)"); 674 } 675 } 676 getBackgroundActivityLaunchController()677 BackgroundActivityStartController getBackgroundActivityLaunchController() { 678 return mBalController; 679 } 680 } 681