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