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