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