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