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