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 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.getStringForUser( 241 resolver, Settings.Secure.LAST_SETUP_SHOWN, resolver.getUserId()); 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, BackgroundStartPrivileges backgroundStartPrivileges)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 BackgroundStartPrivileges backgroundStartPrivileges) { 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 .setBackgroundStartPrivileges(backgroundStartPrivileges) 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, BackgroundStartPrivileges backgroundStartPrivileges)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, 321 BackgroundStartPrivileges backgroundStartPrivileges) { 322 return startActivitiesInPackage(uid, 0 /* realCallingPid */, -1 /* realCallingUid */, 323 callingPackage, callingFeatureId, intents, resolvedTypes, resultTo, options, userId, 324 validateIncomingUser, originatingPendingIntent, backgroundStartPrivileges); 325 } 326 327 /** 328 * Start intents as a package. 329 * 330 * @param uid Make a call as if this UID did. 331 * @param realCallingPid PID of the real caller. 332 * @param realCallingUid UID of the real caller. 333 * @param callingPackage Make a call as if this package did. 334 * @param intents Intents to start. 335 * @param userId Start the intents on this user. 336 * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID. 337 * @param originatingPendingIntent PendingIntentRecord that originated this activity start or 338 * null if not originated by PendingIntent 339 */ 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 backgroundStartPrivileges)340 final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid, 341 String callingPackage, @Nullable String callingFeatureId, Intent[] intents, 342 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, 343 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, 344 BackgroundStartPrivileges backgroundStartPrivileges) { 345 346 final String reason = "startActivityInPackage"; 347 348 userId = checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), 349 Binder.getCallingUid(), reason); 350 351 // TODO: Switch to user app stacks here. 352 return startActivities(null, uid, realCallingPid, realCallingUid, callingPackage, 353 callingFeatureId, intents, resolvedTypes, resultTo, options, userId, reason, 354 originatingPendingIntent, backgroundStartPrivileges); 355 } 356 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 backgroundStartPrivileges)357 int startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid, 358 int incomingRealCallingUid, String callingPackage, @Nullable String callingFeatureId, 359 Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, 360 int userId, String reason, PendingIntentRecord originatingPendingIntent, 361 BackgroundStartPrivileges backgroundStartPrivileges) { 362 if (intents == null) { 363 throw new NullPointerException("intents is null"); 364 } 365 if (resolvedTypes == null) { 366 throw new NullPointerException("resolvedTypes is null"); 367 } 368 if (intents.length != resolvedTypes.length) { 369 throw new IllegalArgumentException("intents are length different than resolvedTypes"); 370 } 371 372 final int realCallingPid = incomingRealCallingPid != 0 373 ? incomingRealCallingPid 374 : Binder.getCallingPid(); 375 final int realCallingUid = incomingRealCallingUid != -1 376 ? incomingRealCallingUid 377 : Binder.getCallingUid(); 378 379 int callingPid; 380 if (callingUid >= 0) { 381 callingPid = -1; 382 } else if (caller == null) { 383 callingPid = realCallingPid; 384 callingUid = realCallingUid; 385 } else { 386 callingPid = callingUid = -1; 387 } 388 final int filterCallingUid = ActivityStarter.computeResolveFilterUid( 389 callingUid, realCallingUid, UserHandle.USER_NULL); 390 final SparseArray<String> startingUidPkgs = new SparseArray<>(); 391 final long origId = Binder.clearCallingIdentity(); 392 393 SafeActivityOptions bottomOptions = null; 394 if (options != null) { 395 // To ensure the first N-1 activities (N == total # of activities) are also launched 396 // into the correct display and root task, use a copy of the passed-in options (keeping 397 // only display-related and launch-root-task information) for these activities. 398 bottomOptions = options.selectiveCloneLaunchOptions(); 399 } 400 try { 401 intents = ArrayUtils.filterNotNull(intents, Intent[]::new); 402 final ActivityStarter[] starters = new ActivityStarter[intents.length]; 403 // Do not hold WM global lock on this loop because when resolving intent, it may 404 // potentially acquire activity manager lock that leads to deadlock. 405 for (int i = 0; i < intents.length; i++) { 406 Intent intent = intents[i]; 407 NeededUriGrants intentGrants = null; 408 409 // Refuse possible leaked file descriptors. 410 if (intent.hasFileDescriptors()) { 411 throw new IllegalArgumentException("File descriptors passed in Intent"); 412 } 413 414 // Get the flag earlier because the intent may be modified in resolveActivity below. 415 final boolean componentSpecified = intent.getComponent() != null; 416 // Don't modify the client's object! 417 intent = new Intent(intent); 418 419 // Collect information about the target of the Intent. 420 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 421 0 /* startFlags */, null /* profilerInfo */, userId, filterCallingUid, 422 callingPid); 423 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId); 424 425 if (aInfo != null) { 426 try { 427 // Carefully collect grants without holding lock 428 intentGrants = mSupervisor.mService.mUgmInternal 429 .checkGrantUriPermissionFromIntent(intent, filterCallingUid, 430 aInfo.applicationInfo.packageName, 431 UserHandle.getUserId(aInfo.applicationInfo.uid)); 432 } catch (SecurityException e) { 433 Slog.d(TAG, "Not allowed to start activity since no uri permission."); 434 return START_CANCELED; 435 } 436 437 if ((aInfo.applicationInfo.privateFlags 438 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { 439 throw new IllegalArgumentException( 440 "FLAG_CANT_SAVE_STATE not supported here"); 441 } 442 startingUidPkgs.put(aInfo.applicationInfo.uid, 443 aInfo.applicationInfo.packageName); 444 } 445 446 final boolean top = i == intents.length - 1; 447 final SafeActivityOptions checkedOptions = top 448 ? options 449 : bottomOptions; 450 starters[i] = obtainStarter(intent, reason) 451 .setIntentGrants(intentGrants) 452 .setCaller(caller) 453 .setResolvedType(resolvedTypes[i]) 454 .setActivityInfo(aInfo) 455 .setRequestCode(-1) 456 .setCallingPid(callingPid) 457 .setCallingUid(callingUid) 458 .setCallingPackage(callingPackage) 459 .setCallingFeatureId(callingFeatureId) 460 .setRealCallingPid(realCallingPid) 461 .setRealCallingUid(realCallingUid) 462 .setActivityOptions(checkedOptions) 463 .setComponentSpecified(componentSpecified) 464 465 // Top activity decides on animation being run, so we allow only for the 466 // top one as otherwise an activity below might consume it. 467 .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/) 468 .setOriginatingPendingIntent(originatingPendingIntent) 469 .setBackgroundStartPrivileges(backgroundStartPrivileges); 470 } 471 // Log if the activities to be started have different uids. 472 if (startingUidPkgs.size() > 1) { 473 final StringBuilder sb = new StringBuilder("startActivities: different apps ["); 474 final int size = startingUidPkgs.size(); 475 for (int i = 0; i < size; i++) { 476 sb.append(startingUidPkgs.valueAt(i)).append(i == size - 1 ? "]" : ", "); 477 } 478 sb.append(" from ").append(callingPackage); 479 Slog.wtf(TAG, sb.toString()); 480 } 481 482 final IBinder sourceResultTo = resultTo; 483 final ActivityRecord[] outActivity = new ActivityRecord[1]; 484 // Lock the loop to ensure the activities launched in a sequence. 485 synchronized (mService.mGlobalLock) { 486 mService.deferWindowLayout(); 487 // To avoid creating multiple starting window when creating starting multiples 488 // activities, we defer the creation of the starting window once all start request 489 // are processed 490 mService.mWindowManager.mStartingSurfaceController.beginDeferAddStartingWindow(); 491 try { 492 for (int i = 0; i < starters.length; i++) { 493 final int startResult = starters[i].setResultTo(resultTo) 494 .setOutActivity(outActivity).execute(); 495 if (startResult < START_SUCCESS) { 496 // Abort by error result and recycle unused starters. 497 for (int j = i + 1; j < starters.length; j++) { 498 mFactory.recycle(starters[j]); 499 } 500 return startResult; 501 } 502 final ActivityRecord started = outActivity[0]; 503 if (started != null && started.getUid() == filterCallingUid) { 504 // Only the started activity which has the same uid as the source caller 505 // can be the caller of next activity. 506 resultTo = started.token; 507 } else { 508 resultTo = sourceResultTo; 509 // Different apps not adjacent to the caller are forced to be new task. 510 if (i < starters.length - 1) { 511 starters[i + 1].getIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 512 } 513 } 514 } 515 } finally { 516 mService.mWindowManager.mStartingSurfaceController.endDeferAddStartingWindow( 517 options != null ? options.getOriginalOptions() : null); 518 mService.continueWindowLayout(); 519 } 520 } 521 } finally { 522 Binder.restoreCallingIdentity(origId); 523 } 524 525 return START_SUCCESS; 526 } 527 528 /** 529 * Starts an activity in the TaskFragment. 530 * @param taskFragment TaskFragment {@link TaskFragment} to start the activity in. 531 * @param activityIntent intent to start the activity. 532 * @param activityOptions ActivityOptions to start the activity with. 533 * @param resultTo the caller activity 534 * @param callingUid the caller uid 535 * @param callingPid the caller pid 536 * @return the start result. 537 */ startActivityInTaskFragment(@onNull TaskFragment taskFragment, @NonNull Intent activityIntent, @Nullable Bundle activityOptions, @Nullable IBinder resultTo, int callingUid, int callingPid, @Nullable IBinder errorCallbackToken)538 int startActivityInTaskFragment(@NonNull TaskFragment taskFragment, 539 @NonNull Intent activityIntent, @Nullable Bundle activityOptions, 540 @Nullable IBinder resultTo, int callingUid, int callingPid, 541 @Nullable IBinder errorCallbackToken) { 542 final ActivityRecord caller = 543 resultTo != null ? ActivityRecord.forTokenLocked(resultTo) : null; 544 return obtainStarter(activityIntent, "startActivityInTaskFragment") 545 .setActivityOptions(activityOptions) 546 .setInTaskFragment(taskFragment) 547 .setResultTo(resultTo) 548 .setRequestCode(-1) 549 .setCallingUid(callingUid) 550 .setCallingPid(callingPid) 551 .setRealCallingUid(callingUid) 552 .setRealCallingPid(callingPid) 553 .setUserId(caller != null ? caller.mUserId : mService.getCurrentUserId()) 554 .setErrorCallbackToken(errorCallbackToken) 555 .execute(); 556 } 557 558 /** 559 * A quick path (skip general intent/task resolving) to start recents animation if the recents 560 * (or home) activity is available in background. 561 * @return {@code true} if the recents activity is moved to front. 562 */ startExistingRecentsIfPossible(Intent intent, ActivityOptions options)563 boolean startExistingRecentsIfPossible(Intent intent, ActivityOptions options) { 564 try { 565 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startExistingRecents"); 566 if (startExistingRecents(intent, options)) { 567 return true; 568 } 569 // Else follow the standard launch procedure. 570 } finally { 571 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 572 } 573 return false; 574 } 575 startExistingRecents(Intent intent, ActivityOptions options)576 private boolean startExistingRecents(Intent intent, ActivityOptions options) { 577 final int activityType = mService.getRecentTasks().getRecentsComponent() 578 .equals(intent.getComponent()) ? ACTIVITY_TYPE_RECENTS : ACTIVITY_TYPE_HOME; 579 final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea() 580 .getRootTask(WINDOWING_MODE_UNDEFINED, activityType); 581 if (rootTask == null) return false; 582 final ActivityRecord r = rootTask.topRunningActivity(); 583 if (r == null || r.isVisibleRequested() || !r.attachedToProcess() 584 || !r.mActivityComponent.equals(intent.getComponent()) 585 || !mService.isCallerRecents(r.getUid()) 586 // Recents keeps invisible while device is locked. 587 || r.mDisplayContent.isKeyguardLocked()) { 588 return false; 589 } 590 mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r); 591 final ActivityMetricsLogger.LaunchingState launchingState = 592 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent); 593 final Task task = r.getTask(); 594 mService.deferWindowLayout(); 595 try { 596 final TransitionController controller = r.mTransitionController; 597 final Transition transition = controller.getCollectingTransition(); 598 if (transition != null) { 599 transition.setRemoteAnimationApp(r.app.getThread()); 600 controller.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask)); 601 } 602 task.moveToFront("startExistingRecents"); 603 task.mInResumeTopActivity = true; 604 task.resumeTopActivity(null /* prev */, options, true /* deferPause */); 605 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, 606 ActivityManager.START_TASK_TO_FRONT, false, r, options); 607 } finally { 608 task.mInResumeTopActivity = false; 609 mService.continueWindowLayout(); 610 } 611 return true; 612 } 613 registerRemoteAnimationForNextActivityStart(String packageName, RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie)614 void registerRemoteAnimationForNextActivityStart(String packageName, 615 RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) { 616 mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie); 617 } 618 getPendingRemoteAnimationRegistry()619 PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() { 620 return mPendingRemoteAnimationRegistry; 621 } 622 dumpLastHomeActivityStartResult(PrintWriter pw, String prefix)623 void dumpLastHomeActivityStartResult(PrintWriter pw, String prefix) { 624 pw.print(prefix); 625 pw.print("mLastHomeActivityStartResult="); 626 pw.println(mLastHomeActivityStartResult); 627 } 628 dump(PrintWriter pw, String prefix, String dumpPackage)629 void dump(PrintWriter pw, String prefix, String dumpPackage) { 630 boolean dumped = false; 631 632 final boolean dumpPackagePresent = dumpPackage != null; 633 634 if (mLastHomeActivityStartRecord != null && (!dumpPackagePresent 635 || dumpPackage.equals(mLastHomeActivityStartRecord.packageName))) { 636 dumped = true; 637 dumpLastHomeActivityStartResult(pw, prefix); 638 pw.print(prefix); 639 pw.println("mLastHomeActivityStartRecord:"); 640 mLastHomeActivityStartRecord.dump(pw, prefix + " ", true /* dumpAll */); 641 } 642 643 if (mLastStarter != null) { 644 final boolean dump = !dumpPackagePresent 645 || mLastStarter.relatedToPackage(dumpPackage) 646 || (mLastHomeActivityStartRecord != null 647 && dumpPackage.equals(mLastHomeActivityStartRecord.packageName)); 648 649 if (dump) { 650 if (!dumped) { 651 dumped = true; 652 dumpLastHomeActivityStartResult(pw, prefix); 653 } 654 pw.print(prefix); 655 pw.println("mLastStarter:"); 656 mLastStarter.dump(pw, prefix + " "); 657 658 if (dumpPackagePresent) { 659 return; 660 } 661 } 662 } 663 664 if (!dumped) { 665 pw.print(prefix); 666 pw.println("(nothing)"); 667 } 668 } 669 getBackgroundActivityLaunchController()670 BackgroundActivityStartController getBackgroundActivityLaunchController() { 671 return mBalController; 672 } 673 } 674