1 /*
2  * Copyright (C) 2016 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.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
20 import static android.app.Activity.RESULT_CANCELED;
21 import static android.app.ActivityManager.START_ABORTED;
22 import static android.app.ActivityManager.START_CANCELED;
23 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
24 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
25 import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
26 import static android.app.ActivityManager.START_PERMISSION_DENIED;
27 import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
28 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
29 import static android.app.ActivityManager.START_SUCCESS;
30 import static android.app.ActivityManager.START_TASK_TO_FRONT;
31 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
32 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
33 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
34 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
35 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
36 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
37 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
38 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
39 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
40 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
41 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
42 import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
43 import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
44 import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
45 import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
46 import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
47 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
48 import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
49 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
50 import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
51 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
52 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
53 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK;
54 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
55 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
56 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
57 import static android.os.Process.INVALID_UID;
58 import static android.view.Display.DEFAULT_DISPLAY;
59 import static android.view.WindowManager.TRANSIT_OPEN;
60 
61 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
62 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
63 import static com.android.server.wm.ActivityRecord.State.RESUMED;
64 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
65 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
66 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
67 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
68 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
69 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
70 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
71 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
72 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
73 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
74 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
75 import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
76 import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY;
77 import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
78 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
79 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
80 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
81 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
82 import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
83 import static com.android.server.wm.WindowContainer.POSITION_TOP;
84 
85 import android.annotation.NonNull;
86 import android.annotation.Nullable;
87 import android.app.ActivityManager;
88 import android.app.ActivityOptions;
89 import android.app.IApplicationThread;
90 import android.app.PendingIntent;
91 import android.app.ProfilerInfo;
92 import android.app.WaitResult;
93 import android.content.ComponentName;
94 import android.content.IIntentSender;
95 import android.content.Intent;
96 import android.content.IntentSender;
97 import android.content.pm.ActivityInfo;
98 import android.content.pm.ApplicationInfo;
99 import android.content.pm.AuxiliaryResolveInfo;
100 import android.content.pm.PackageManager;
101 import android.content.pm.PackageManagerInternal;
102 import android.content.pm.ResolveInfo;
103 import android.content.pm.UserInfo;
104 import android.content.res.Configuration;
105 import android.os.Binder;
106 import android.os.Bundle;
107 import android.os.IBinder;
108 import android.os.Process;
109 import android.os.RemoteException;
110 import android.os.Trace;
111 import android.os.UserHandle;
112 import android.os.UserManager;
113 import android.service.voice.IVoiceInteractionSession;
114 import android.text.TextUtils;
115 import android.util.ArraySet;
116 import android.util.DebugUtils;
117 import android.util.Pools.SynchronizedPool;
118 import android.util.Slog;
119 import android.window.RemoteTransition;
120 
121 import com.android.internal.annotations.VisibleForTesting;
122 import com.android.internal.app.HeavyWeightSwitcherActivity;
123 import com.android.internal.app.IVoiceInteractor;
124 import com.android.internal.protolog.common.ProtoLog;
125 import com.android.server.am.PendingIntentRecord;
126 import com.android.server.pm.InstantAppResolver;
127 import com.android.server.power.ShutdownCheckPoints;
128 import com.android.server.statusbar.StatusBarManagerInternal;
129 import com.android.server.uri.NeededUriGrants;
130 import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
131 import com.android.server.wm.LaunchParamsController.LaunchParams;
132 
133 import java.io.PrintWriter;
134 import java.text.DateFormat;
135 import java.util.Date;
136 
137 /**
138  * Controller for interpreting how and then launching an activity.
139  *
140  * This class collects all the logic for determining how an intent and flags should be turned into
141  * an activity and associated task and root task.
142  */
143 class ActivityStarter {
144     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
145     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
146     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
147     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
148     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
149     private static final int INVALID_LAUNCH_MODE = -1;
150 
151     private final ActivityTaskManagerService mService;
152     private final RootWindowContainer mRootWindowContainer;
153     private final ActivityTaskSupervisor mSupervisor;
154     private final ActivityStartInterceptor mInterceptor;
155     private final ActivityStartController mController;
156 
157     // Share state variable among methods when starting an activity.
158     @VisibleForTesting
159     ActivityRecord mStartActivity;
160     private Intent mIntent;
161     private int mCallingUid;
162     private ActivityOptions mOptions;
163 
164     // If it is true, background activity can only be started in an existing task that contains
165     // an activity with same uid, or if activity starts are enabled in developer options.
166     private boolean mRestrictedBgActivity;
167 
168     private int mLaunchMode;
169     private boolean mLaunchTaskBehind;
170     private int mLaunchFlags;
171 
172     private LaunchParams mLaunchParams = new LaunchParams();
173 
174     private ActivityRecord mNotTop;
175     private boolean mDoResume;
176     private int mStartFlags;
177     private ActivityRecord mSourceRecord;
178 
179     // The task display area to launch the activity onto, barring any strong reason to do otherwise.
180     private TaskDisplayArea mPreferredTaskDisplayArea;
181     private int mPreferredWindowingMode;
182 
183     private Task mInTask;
184     private TaskFragment mInTaskFragment;
185     @VisibleForTesting
186     boolean mAddingToTask;
187     private Task mReuseTask;
188 
189     private ActivityInfo mNewTaskInfo;
190     private Intent mNewTaskIntent;
191     private Task mSourceRootTask;
192     private Task mTargetRootTask;
193     // The task that the last activity was started into. We currently reset the actual start
194     // activity's task and as a result may not have a reference to the task in all cases
195     private Task mTargetTask;
196     private boolean mMovedToFront;
197     private boolean mNoAnimation;
198     private boolean mAvoidMoveToFront;
199     private boolean mFrozeTaskList;
200     private boolean mTransientLaunch;
201 
202     // We must track when we deliver the new intent since multiple code paths invoke
203     // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
204     // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
205     // delivered at most once.
206     private boolean mIntentDelivered;
207 
208     private IVoiceInteractionSession mVoiceSession;
209     private IVoiceInteractor mVoiceInteractor;
210 
211     // Last activity record we attempted to start
212     private ActivityRecord mLastStartActivityRecord;
213     // The result of the last activity we attempted to start.
214     private int mLastStartActivityResult;
215     // Time in milli seconds we attempted to start the last activity.
216     private long mLastStartActivityTimeMs;
217     // The reason we were trying to start the last activity
218     private String mLastStartReason;
219 
220     /*
221      * Request details provided through setter methods. Should be reset after {@link #execute()}
222      * to avoid unnecessarily retaining parameters. Note that the request is ignored when
223      * {@link #startResolvedActivity} is invoked directly.
224      */
225     @VisibleForTesting
226     Request mRequest = new Request();
227 
228     /**
229      * An interface that to provide {@link ActivityStarter} instances to the controller. This is
230      * used by tests to inject their own starter implementations for verification purposes.
231      */
232     @VisibleForTesting
233     interface Factory {
234         /**
235          * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
236          */
setController(ActivityStartController controller)237         void setController(ActivityStartController controller);
238 
239         /**
240          * Generates an {@link ActivityStarter} that is ready to handle a new start request.
241          * @param controller The {@link ActivityStartController} which the starter who will own
242          *                   this instance.
243          * @return an {@link ActivityStarter}
244          */
obtain()245         ActivityStarter obtain();
246 
247         /**
248          * Recycles a starter for reuse.
249          */
recycle(ActivityStarter starter)250         void recycle(ActivityStarter starter);
251     }
252 
253     /**
254      * Default implementation of {@link StarterFactory}.
255      */
256     static class DefaultFactory implements Factory {
257         /**
258          * The maximum count of starters that should be active at one time:
259          * 1. last ran starter (for logging and post activity processing)
260          * 2. current running starter
261          * 3. starter from re-entry in (2)
262          */
263         private final int MAX_STARTER_COUNT = 3;
264 
265         private ActivityStartController mController;
266         private ActivityTaskManagerService mService;
267         private ActivityTaskSupervisor mSupervisor;
268         private ActivityStartInterceptor mInterceptor;
269 
270         private SynchronizedPool<ActivityStarter> mStarterPool =
271                 new SynchronizedPool<>(MAX_STARTER_COUNT);
272 
DefaultFactory(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor)273         DefaultFactory(ActivityTaskManagerService service,
274                 ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) {
275             mService = service;
276             mSupervisor = supervisor;
277             mInterceptor = interceptor;
278         }
279 
280         @Override
setController(ActivityStartController controller)281         public void setController(ActivityStartController controller) {
282             mController = controller;
283         }
284 
285         @Override
obtain()286         public ActivityStarter obtain() {
287             ActivityStarter starter = mStarterPool.acquire();
288 
289             if (starter == null) {
290                 if (mService.mRootWindowContainer == null) {
291                     throw new IllegalStateException("Too early to start activity.");
292                 }
293                 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
294             }
295 
296             return starter;
297         }
298 
299         @Override
recycle(ActivityStarter starter)300         public void recycle(ActivityStarter starter) {
301             starter.reset(true /* clearRequest*/);
302             mStarterPool.release(starter);
303         }
304     }
305 
306     /**
307      * Container for capturing initial start request details. This information is NOT reset until
308      * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
309      * parameters.
310      *
311      * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
312      * the request object. Note that some member variables are referenced in
313      * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
314      * execution.
315      */
316     @VisibleForTesting
317     static class Request {
318         private static final int DEFAULT_CALLING_UID = -1;
319         private static final int DEFAULT_CALLING_PID = 0;
320         static final int DEFAULT_REAL_CALLING_UID = -1;
321         static final int DEFAULT_REAL_CALLING_PID = 0;
322 
323         IApplicationThread caller;
324         Intent intent;
325         NeededUriGrants intentGrants;
326         // A copy of the original requested intent, in case for ephemeral app launch.
327         Intent ephemeralIntent;
328         String resolvedType;
329         ActivityInfo activityInfo;
330         ResolveInfo resolveInfo;
331         IVoiceInteractionSession voiceSession;
332         IVoiceInteractor voiceInteractor;
333         IBinder resultTo;
334         String resultWho;
335         int requestCode;
336         int callingPid = DEFAULT_CALLING_PID;
337         int callingUid = DEFAULT_CALLING_UID;
338         String callingPackage;
339         @Nullable String callingFeatureId;
340         int realCallingPid = DEFAULT_REAL_CALLING_PID;
341         int realCallingUid = DEFAULT_REAL_CALLING_UID;
342         int startFlags;
343         SafeActivityOptions activityOptions;
344         boolean ignoreTargetSecurity;
345         boolean componentSpecified;
346         boolean avoidMoveToFront;
347         ActivityRecord[] outActivity;
348         Task inTask;
349         TaskFragment inTaskFragment;
350         String reason;
351         ProfilerInfo profilerInfo;
352         Configuration globalConfig;
353         int userId;
354         WaitResult waitResult;
355         int filterCallingUid;
356         PendingIntentRecord originatingPendingIntent;
357         boolean allowBackgroundActivityStart;
358 
359         /**
360          * If set to {@code true}, allows this activity start to look into
361          * {@link PendingRemoteAnimationRegistry}
362          */
363         boolean allowPendingRemoteAnimationRegistryLookup;
364 
365         /**
366          * Ensure constructed request matches reset instance.
367          */
Request()368         Request() {
369             reset();
370         }
371 
372         /**
373          * Sets values back to the initial state, clearing any held references.
374          */
reset()375         void reset() {
376             caller = null;
377             intent = null;
378             intentGrants = null;
379             ephemeralIntent = null;
380             resolvedType = null;
381             activityInfo = null;
382             resolveInfo = null;
383             voiceSession = null;
384             voiceInteractor = null;
385             resultTo = null;
386             resultWho = null;
387             requestCode = 0;
388             callingPid = DEFAULT_CALLING_PID;
389             callingUid = DEFAULT_CALLING_UID;
390             callingPackage = null;
391             callingFeatureId = null;
392             realCallingPid = DEFAULT_REAL_CALLING_PID;
393             realCallingUid = DEFAULT_REAL_CALLING_UID;
394             startFlags = 0;
395             activityOptions = null;
396             ignoreTargetSecurity = false;
397             componentSpecified = false;
398             outActivity = null;
399             inTask = null;
400             inTaskFragment = null;
401             reason = null;
402             profilerInfo = null;
403             globalConfig = null;
404             userId = 0;
405             waitResult = null;
406             avoidMoveToFront = false;
407             allowPendingRemoteAnimationRegistryLookup = true;
408             filterCallingUid = UserHandle.USER_NULL;
409             originatingPendingIntent = null;
410             allowBackgroundActivityStart = false;
411         }
412 
413         /**
414          * Adopts all values from passed in request.
415          */
set(@onNull Request request)416         void set(@NonNull Request request) {
417             caller = request.caller;
418             intent = request.intent;
419             intentGrants = request.intentGrants;
420             ephemeralIntent = request.ephemeralIntent;
421             resolvedType = request.resolvedType;
422             activityInfo = request.activityInfo;
423             resolveInfo = request.resolveInfo;
424             voiceSession = request.voiceSession;
425             voiceInteractor = request.voiceInteractor;
426             resultTo = request.resultTo;
427             resultWho = request.resultWho;
428             requestCode = request.requestCode;
429             callingPid = request.callingPid;
430             callingUid = request.callingUid;
431             callingPackage = request.callingPackage;
432             callingFeatureId = request.callingFeatureId;
433             realCallingPid = request.realCallingPid;
434             realCallingUid = request.realCallingUid;
435             startFlags = request.startFlags;
436             activityOptions = request.activityOptions;
437             ignoreTargetSecurity = request.ignoreTargetSecurity;
438             componentSpecified = request.componentSpecified;
439             outActivity = request.outActivity;
440             inTask = request.inTask;
441             inTaskFragment = request.inTaskFragment;
442             reason = request.reason;
443             profilerInfo = request.profilerInfo;
444             globalConfig = request.globalConfig;
445             userId = request.userId;
446             waitResult = request.waitResult;
447             avoidMoveToFront = request.avoidMoveToFront;
448             allowPendingRemoteAnimationRegistryLookup
449                     = request.allowPendingRemoteAnimationRegistryLookup;
450             filterCallingUid = request.filterCallingUid;
451             originatingPendingIntent = request.originatingPendingIntent;
452             allowBackgroundActivityStart = request.allowBackgroundActivityStart;
453         }
454 
455         /**
456          * Resolve activity from the given intent for this launch.
457          */
resolveActivity(ActivityTaskSupervisor supervisor)458         void resolveActivity(ActivityTaskSupervisor supervisor) {
459             if (realCallingPid == Request.DEFAULT_REAL_CALLING_PID) {
460                 realCallingPid = Binder.getCallingPid();
461             }
462             if (realCallingUid == Request.DEFAULT_REAL_CALLING_UID) {
463                 realCallingUid = Binder.getCallingUid();
464             }
465 
466             if (callingUid >= 0) {
467                 callingPid = -1;
468             } else if (caller == null) {
469                 callingPid = realCallingPid;
470                 callingUid = realCallingUid;
471             } else {
472                 callingPid = callingUid = -1;
473             }
474 
475             // To determine the set of needed Uri permission grants, we need the
476             // "resolved" calling UID, where we try our best to identify the
477             // actual caller that is starting this activity
478             int resolvedCallingUid = callingUid;
479             if (caller != null) {
480                 synchronized (supervisor.mService.mGlobalLock) {
481                     final WindowProcessController callerApp = supervisor.mService
482                             .getProcessController(caller);
483                     if (callerApp != null) {
484                         resolvedCallingUid = callerApp.mInfo.uid;
485                     }
486                 }
487             }
488 
489             // Save a copy in case ephemeral needs it
490             ephemeralIntent = new Intent(intent);
491             // Don't modify the client's object!
492             intent = new Intent(intent);
493             if (intent.getComponent() != null
494                     && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
495                     && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
496                     && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
497                     && supervisor.mService.getPackageManagerInternalLocked()
498                             .isInstantAppInstallerComponent(intent.getComponent())) {
499                 // Intercept intents targeted directly to the ephemeral installer the ephemeral
500                 // installer should never be started with a raw Intent; instead adjust the intent
501                 // so it looks like a "normal" instant app launch.
502                 intent.setComponent(null /* component */);
503             }
504 
505             resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
506                     0 /* matchFlags */,
507                     computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));
508             if (resolveInfo == null) {
509                 final UserInfo userInfo = supervisor.getUserInfo(userId);
510                 if (userInfo != null && userInfo.isManagedProfile()) {
511                     // Special case for managed profiles, if attempting to launch non-cryto aware
512                     // app in a locked managed profile from an unlocked parent allow it to resolve
513                     // as user will be sent via confirm credentials to unlock the profile.
514                     final UserManager userManager = UserManager.get(supervisor.mService.mContext);
515                     boolean profileLockedAndParentUnlockingOrUnlocked = false;
516                     final long token = Binder.clearCallingIdentity();
517                     try {
518                         final UserInfo parent = userManager.getProfileParent(userId);
519                         profileLockedAndParentUnlockingOrUnlocked = (parent != null)
520                                 && userManager.isUserUnlockingOrUnlocked(parent.id)
521                                 && !userManager.isUserUnlockingOrUnlocked(userId);
522                     } finally {
523                         Binder.restoreCallingIdentity(token);
524                     }
525                     if (profileLockedAndParentUnlockingOrUnlocked) {
526                         resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
527                                 PackageManager.MATCH_DIRECT_BOOT_AWARE
528                                         | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
529                                 computeResolveFilterUid(callingUid, realCallingUid,
530                                         filterCallingUid));
531                     }
532                 }
533             }
534 
535             // Collect information about the target of the Intent.
536             activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
537                     profilerInfo);
538 
539             // Carefully collect grants without holding lock
540             if (activityInfo != null) {
541                 intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent(
542                         intent, resolvedCallingUid, activityInfo.applicationInfo.packageName,
543                         UserHandle.getUserId(activityInfo.applicationInfo.uid));
544             }
545         }
546     }
547 
ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor)548     ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
549             ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) {
550         mController = controller;
551         mService = service;
552         mRootWindowContainer = service.mRootWindowContainer;
553         mSupervisor = supervisor;
554         mInterceptor = interceptor;
555         reset(true);
556     }
557 
558     /**
559      * Effectively duplicates the starter passed in. All state and request values will be
560      * mirrored.
561      * @param starter
562      */
set(ActivityStarter starter)563     void set(ActivityStarter starter) {
564         mStartActivity = starter.mStartActivity;
565         mIntent = starter.mIntent;
566         mCallingUid = starter.mCallingUid;
567         mOptions = starter.mOptions;
568         mRestrictedBgActivity = starter.mRestrictedBgActivity;
569 
570         mLaunchTaskBehind = starter.mLaunchTaskBehind;
571         mLaunchFlags = starter.mLaunchFlags;
572         mLaunchMode = starter.mLaunchMode;
573 
574         mLaunchParams.set(starter.mLaunchParams);
575 
576         mNotTop = starter.mNotTop;
577         mDoResume = starter.mDoResume;
578         mStartFlags = starter.mStartFlags;
579         mSourceRecord = starter.mSourceRecord;
580         mPreferredTaskDisplayArea = starter.mPreferredTaskDisplayArea;
581         mPreferredWindowingMode = starter.mPreferredWindowingMode;
582 
583         mInTask = starter.mInTask;
584         mInTaskFragment = starter.mInTaskFragment;
585         mAddingToTask = starter.mAddingToTask;
586         mReuseTask = starter.mReuseTask;
587 
588         mNewTaskInfo = starter.mNewTaskInfo;
589         mNewTaskIntent = starter.mNewTaskIntent;
590         mSourceRootTask = starter.mSourceRootTask;
591 
592         mTargetTask = starter.mTargetTask;
593         mTargetRootTask = starter.mTargetRootTask;
594         mMovedToFront = starter.mMovedToFront;
595         mNoAnimation = starter.mNoAnimation;
596         mAvoidMoveToFront = starter.mAvoidMoveToFront;
597         mFrozeTaskList = starter.mFrozeTaskList;
598 
599         mVoiceSession = starter.mVoiceSession;
600         mVoiceInteractor = starter.mVoiceInteractor;
601 
602         mIntentDelivered = starter.mIntentDelivered;
603 
604         mRequest.set(starter.mRequest);
605     }
606 
relatedToPackage(String packageName)607     boolean relatedToPackage(String packageName) {
608         return (mLastStartActivityRecord != null
609                 && packageName.equals(mLastStartActivityRecord.packageName))
610                 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
611     }
612 
613     /**
614      * Resolve necessary information according the request parameters provided earlier, and execute
615      * the request which begin the journey of starting an activity.
616      * @return The starter result.
617      */
execute()618     int execute() {
619         try {
620             // Refuse possible leaked file descriptors
621             if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
622                 throw new IllegalArgumentException("File descriptors passed in Intent");
623             }
624 
625             final LaunchingState launchingState;
626             synchronized (mService.mGlobalLock) {
627                 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
628                 final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
629                         ?  Binder.getCallingUid() : mRequest.realCallingUid;
630                 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
631                         mRequest.intent, caller, callingUid);
632             }
633 
634             // If the caller hasn't already resolved the activity, we're willing
635             // to do so here. If the caller is already holding the WM lock here,
636             // and we need to check dynamic Uri permissions, then we're forced
637             // to assume those permissions are denied to avoid deadlocking.
638             if (mRequest.activityInfo == null) {
639                 mRequest.resolveActivity(mSupervisor);
640             }
641 
642             // Add checkpoint for this shutdown or reboot attempt, so we can record the original
643             // intent action and package name.
644             if (mRequest.intent != null) {
645                 String intentAction = mRequest.intent.getAction();
646                 String callingPackage = mRequest.callingPackage;
647                 if (intentAction != null && callingPackage != null
648                         && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
649                                 || Intent.ACTION_SHUTDOWN.equals(intentAction)
650                                 || Intent.ACTION_REBOOT.equals(intentAction))) {
651                     ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
652                 }
653             }
654 
655             int res;
656             synchronized (mService.mGlobalLock) {
657                 final boolean globalConfigWillChange = mRequest.globalConfig != null
658                         && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
659                 final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
660                 if (rootTask != null) {
661                     rootTask.mConfigWillChange = globalConfigWillChange;
662                 }
663                 ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
664                         + "will change = %b", globalConfigWillChange);
665 
666                 final long origId = Binder.clearCallingIdentity();
667 
668                 res = resolveToHeavyWeightSwitcherIfNeeded();
669                 if (res != START_SUCCESS) {
670                     return res;
671                 }
672                 res = executeRequest(mRequest);
673 
674                 Binder.restoreCallingIdentity(origId);
675 
676                 if (globalConfigWillChange) {
677                     // If the caller also wants to switch to a new configuration, do so now.
678                     // This allows a clean switch, as we are waiting for the current activity
679                     // to pause (so we will not destroy it), and have not yet started the
680                     // next activity.
681                     mService.mAmInternal.enforceCallingPermission(
682                             android.Manifest.permission.CHANGE_CONFIGURATION,
683                             "updateConfiguration()");
684                     if (rootTask != null) {
685                         rootTask.mConfigWillChange = false;
686                     }
687                     ProtoLog.v(WM_DEBUG_CONFIGURATION,
688                                 "Updating to new configuration after starting activity.");
689 
690                     mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
691                 }
692 
693                 // The original options may have additional info about metrics. The mOptions is not
694                 // used here because it may be cleared in setTargetRootTaskIfNeeded.
695                 final ActivityOptions originalOptions = mRequest.activityOptions != null
696                         ? mRequest.activityOptions.getOriginalOptions() : null;
697                 // If the new record is the one that started, a new activity has created.
698                 final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
699                 // Notify ActivityMetricsLogger that the activity has launched.
700                 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
701                 // WaitResult.
702                 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
703                         newActivityCreated, mLastStartActivityRecord, originalOptions);
704                 if (mRequest.waitResult != null) {
705                     mRequest.waitResult.result = res;
706                     res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
707                             launchingState);
708                 }
709                 return getExternalResult(res);
710             }
711         } finally {
712             onExecutionComplete();
713         }
714     }
715 
716     /**
717      * Updates the request to heavy-weight switch if this is a heavy-weight process while there
718      * already have another, different heavy-weight process running.
719      */
resolveToHeavyWeightSwitcherIfNeeded()720     private int resolveToHeavyWeightSwitcherIfNeeded() {
721         if (mRequest.activityInfo == null || !mService.mHasHeavyWeightFeature
722                 || (mRequest.activityInfo.applicationInfo.privateFlags
723                         & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) == 0) {
724             return START_SUCCESS;
725         }
726 
727         if (!mRequest.activityInfo.processName.equals(
728                 mRequest.activityInfo.applicationInfo.packageName)) {
729             return START_SUCCESS;
730         }
731 
732         final WindowProcessController heavy = mService.mHeavyWeightProcess;
733         if (heavy == null || (heavy.mInfo.uid == mRequest.activityInfo.applicationInfo.uid
734                 && heavy.mName.equals(mRequest.activityInfo.processName))) {
735             return START_SUCCESS;
736         }
737 
738         int appCallingUid = mRequest.callingUid;
739         if (mRequest.caller != null) {
740             WindowProcessController callerApp = mService.getProcessController(mRequest.caller);
741             if (callerApp != null) {
742                 appCallingUid = callerApp.mInfo.uid;
743             } else {
744                 Slog.w(TAG, "Unable to find app for caller " + mRequest.caller + " (pid="
745                         + mRequest.callingPid + ") when starting: " + mRequest.intent.toString());
746                 SafeActivityOptions.abort(mRequest.activityOptions);
747                 return START_PERMISSION_DENIED;
748             }
749         }
750 
751         final IIntentSender target = mService.getIntentSenderLocked(
752                 ActivityManager.INTENT_SENDER_ACTIVITY, "android" /* packageName */,
753                 null /* featureId */, appCallingUid, mRequest.userId, null /* token */,
754                 null /* resultWho*/, 0 /* requestCode*/, new Intent[]{mRequest.intent},
755                 new String[]{mRequest.resolvedType},
756                 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT,
757                 null /* bOptions */);
758 
759         final Intent newIntent = new Intent();
760         if (mRequest.requestCode >= 0) {
761             // Caller is requesting a result.
762             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
763         }
764         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target));
765         heavy.updateIntentForHeavyWeightActivity(newIntent);
766         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
767                 mRequest.activityInfo.packageName);
768         newIntent.setFlags(mRequest.intent.getFlags());
769         newIntent.setClassName("android" /* packageName */,
770                 HeavyWeightSwitcherActivity.class.getName());
771         mRequest.intent = newIntent;
772         mRequest.resolvedType = null;
773         mRequest.caller = null;
774         mRequest.callingUid = Binder.getCallingUid();
775         mRequest.callingPid = Binder.getCallingPid();
776         mRequest.componentSpecified = true;
777         mRequest.resolveInfo = mSupervisor.resolveIntent(mRequest.intent, null /* resolvedType */,
778                 mRequest.userId, 0 /* matchFlags */,
779                 computeResolveFilterUid(mRequest.callingUid, mRequest.realCallingUid,
780                         mRequest.filterCallingUid));
781         mRequest.activityInfo =
782                 mRequest.resolveInfo != null ? mRequest.resolveInfo.activityInfo : null;
783         if (mRequest.activityInfo != null) {
784             mRequest.activityInfo = mService.mAmInternal.getActivityInfoForUser(
785                     mRequest.activityInfo, mRequest.userId);
786         }
787 
788         return START_SUCCESS;
789     }
790 
791     /**
792      * Wait for activity launch completes.
793      */
waitResultIfNeeded(WaitResult waitResult, ActivityRecord r, LaunchingState launchingState)794     private int waitResultIfNeeded(WaitResult waitResult, ActivityRecord r,
795             LaunchingState launchingState) {
796         final int res = waitResult.result;
797         if (res == START_DELIVERED_TO_TOP
798                 || (res == START_TASK_TO_FRONT && r.nowVisible && r.isState(RESUMED))) {
799             // The activity should already be visible, so nothing to wait.
800             waitResult.timeout = false;
801             waitResult.who = r.mActivityComponent;
802             waitResult.totalTime = 0;
803             return res;
804         }
805         mSupervisor.waitActivityVisibleOrLaunched(waitResult, r, launchingState);
806         if (res == START_SUCCESS && waitResult.result == START_TASK_TO_FRONT) {
807             // A trampoline activity is launched and it brings another existing activity to front.
808             return START_TASK_TO_FRONT;
809         }
810         return res;
811     }
812 
813     /**
814      * Executing activity start request and starts the journey of starting an activity. Here
815      * begins with performing several preliminary checks. The normally activity launch flow will
816      * go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
817      */
executeRequest(Request request)818     private int executeRequest(Request request) {
819         if (TextUtils.isEmpty(request.reason)) {
820             throw new IllegalArgumentException("Need to specify a reason.");
821         }
822         mLastStartReason = request.reason;
823         mLastStartActivityTimeMs = System.currentTimeMillis();
824         mLastStartActivityRecord = null;
825 
826         final IApplicationThread caller = request.caller;
827         Intent intent = request.intent;
828         NeededUriGrants intentGrants = request.intentGrants;
829         String resolvedType = request.resolvedType;
830         ActivityInfo aInfo = request.activityInfo;
831         ResolveInfo rInfo = request.resolveInfo;
832         final IVoiceInteractionSession voiceSession = request.voiceSession;
833         final IBinder resultTo = request.resultTo;
834         String resultWho = request.resultWho;
835         int requestCode = request.requestCode;
836         int callingPid = request.callingPid;
837         int callingUid = request.callingUid;
838         String callingPackage = request.callingPackage;
839         String callingFeatureId = request.callingFeatureId;
840         final int realCallingPid = request.realCallingPid;
841         final int realCallingUid = request.realCallingUid;
842         final int startFlags = request.startFlags;
843         final SafeActivityOptions options = request.activityOptions;
844         Task inTask = request.inTask;
845         TaskFragment inTaskFragment = request.inTaskFragment;
846 
847         int err = ActivityManager.START_SUCCESS;
848         // Pull the optional Ephemeral Installer-only bundle out of the options early.
849         final Bundle verificationBundle =
850                 options != null ? options.popAppVerificationBundle() : null;
851 
852         WindowProcessController callerApp = null;
853         if (caller != null) {
854             callerApp = mService.getProcessController(caller);
855             if (callerApp != null) {
856                 callingPid = callerApp.getPid();
857                 callingUid = callerApp.mInfo.uid;
858             } else {
859                 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
860                         + ") when starting: " + intent.toString());
861                 err = START_PERMISSION_DENIED;
862             }
863         }
864 
865         final int userId = aInfo != null && aInfo.applicationInfo != null
866                 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
867         if (err == ActivityManager.START_SUCCESS) {
868             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
869                     + "} from uid " + callingUid);
870         }
871 
872         ActivityRecord sourceRecord = null;
873         ActivityRecord resultRecord = null;
874         if (resultTo != null) {
875             sourceRecord = ActivityRecord.isInAnyTask(resultTo);
876             if (DEBUG_RESULTS) {
877                 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
878             }
879             if (sourceRecord != null) {
880                 if (requestCode >= 0 && !sourceRecord.finishing) {
881                     resultRecord = sourceRecord;
882                 }
883             }
884         }
885 
886         final int launchFlags = intent.getFlags();
887         if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
888             // Transfer the result target from the source activity to the new one being started,
889             // including any failures.
890             if (requestCode >= 0) {
891                 SafeActivityOptions.abort(options);
892                 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
893             }
894             resultRecord = sourceRecord.resultTo;
895             if (resultRecord != null && !resultRecord.isInRootTaskLocked()) {
896                 resultRecord = null;
897             }
898             resultWho = sourceRecord.resultWho;
899             requestCode = sourceRecord.requestCode;
900             sourceRecord.resultTo = null;
901             if (resultRecord != null) {
902                 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
903             }
904             if (sourceRecord.launchedFromUid == callingUid) {
905                 // The new activity is being launched from the same uid as the previous activity
906                 // in the flow, and asking to forward its result back to the previous.  In this
907                 // case the activity is serving as a trampoline between the two, so we also want
908                 // to update its launchedFromPackage to be the same as the previous activity.
909                 // Note that this is safe, since we know these two packages come from the same
910                 // uid; the caller could just as well have supplied that same package name itself
911                 // . This specifially deals with the case of an intent picker/chooser being
912                 // launched in the app flow to redirect to an activity picked by the user, where
913                 // we want the final activity to consider it to have been launched by the
914                 // previous app activity.
915                 callingPackage = sourceRecord.launchedFromPackage;
916                 callingFeatureId = sourceRecord.launchedFromFeatureId;
917             }
918         }
919 
920         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
921             // We couldn't find a class that can handle the given Intent.
922             // That's the end of that!
923             err = ActivityManager.START_INTENT_NOT_RESOLVED;
924         }
925 
926         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
927             // We couldn't find the specific class specified in the Intent.
928             // Also the end of the line.
929             err = ActivityManager.START_CLASS_NOT_FOUND;
930         }
931 
932         if (err == ActivityManager.START_SUCCESS && sourceRecord != null
933                 && sourceRecord.getTask().voiceSession != null) {
934             // If this activity is being launched as part of a voice session, we need to ensure
935             // that it is safe to do so.  If the upcoming activity will also be part of the voice
936             // session, we can only launch it if it has explicitly said it supports the VOICE
937             // category, or it is a part of the calling app.
938             if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
939                     && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
940                 try {
941                     intent.addCategory(Intent.CATEGORY_VOICE);
942                     if (!mService.getPackageManager().activitySupportsIntent(
943                             intent.getComponent(), intent, resolvedType)) {
944                         Slog.w(TAG, "Activity being started in current voice task does not support "
945                                 + "voice: " + intent);
946                         err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
947                     }
948                 } catch (RemoteException e) {
949                     Slog.w(TAG, "Failure checking voice capabilities", e);
950                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
951                 }
952             }
953         }
954 
955         if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
956             // If the caller is starting a new voice session, just make sure the target
957             // is actually allowing it to run this way.
958             try {
959                 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
960                         intent, resolvedType)) {
961                     Slog.w(TAG,
962                             "Activity being started in new voice task does not support: " + intent);
963                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
964                 }
965             } catch (RemoteException e) {
966                 Slog.w(TAG, "Failure checking voice capabilities", e);
967                 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
968             }
969         }
970 
971         final Task resultRootTask = resultRecord == null
972                 ? null : resultRecord.getRootTask();
973 
974         if (err != START_SUCCESS) {
975             if (resultRecord != null) {
976                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
977                         null /* data */, null /* dataGrants */);
978             }
979             SafeActivityOptions.abort(options);
980             return err;
981         }
982 
983         boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
984                 requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
985                 request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
986                 resultRootTask);
987         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
988                 callingPid, resolvedType, aInfo.applicationInfo);
989         abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
990                 callingPackage);
991 
992         boolean restrictedBgActivity = false;
993         if (!abort) {
994             try {
995                 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
996                         "shouldAbortBackgroundActivityStart");
997                 restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
998                         callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
999                         request.originatingPendingIntent, request.allowBackgroundActivityStart,
1000                         intent);
1001             } finally {
1002                 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1003             }
1004         }
1005 
1006         // Merge the two options bundles, while realCallerOptions takes precedence.
1007         ActivityOptions checkedOptions = options != null
1008                 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
1009         if (request.allowPendingRemoteAnimationRegistryLookup) {
1010             checkedOptions = mService.getActivityStartController()
1011                     .getPendingRemoteAnimationRegistry()
1012                     .overrideOptionsIfNeeded(callingPackage, checkedOptions);
1013         }
1014         if (mService.mController != null) {
1015             try {
1016                 // The Intent we give to the watcher has the extra data stripped off, since it
1017                 // can contain private information.
1018                 Intent watchIntent = intent.cloneFilter();
1019                 abort |= !mService.mController.activityStarting(watchIntent,
1020                         aInfo.applicationInfo.packageName);
1021             } catch (RemoteException e) {
1022                 mService.mController = null;
1023             }
1024         }
1025 
1026         mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
1027                 callingFeatureId);
1028         if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
1029                 callingUid, checkedOptions)) {
1030             // activity start was intercepted, e.g. because the target user is currently in quiet
1031             // mode (turn off work) or the target application is suspended
1032             intent = mInterceptor.mIntent;
1033             rInfo = mInterceptor.mRInfo;
1034             aInfo = mInterceptor.mAInfo;
1035             resolvedType = mInterceptor.mResolvedType;
1036             inTask = mInterceptor.mInTask;
1037             callingPid = mInterceptor.mCallingPid;
1038             callingUid = mInterceptor.mCallingUid;
1039             checkedOptions = mInterceptor.mActivityOptions;
1040 
1041             // The interception target shouldn't get any permission grants
1042             // intended for the original destination
1043             intentGrants = null;
1044         }
1045 
1046         if (abort) {
1047             if (resultRecord != null) {
1048                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1049                         null /* data */, null /* dataGrants */);
1050             }
1051             // We pretend to the caller that it was really started, but they will just get a
1052             // cancel result.
1053             ActivityOptions.abort(checkedOptions);
1054             return START_ABORTED;
1055         }
1056 
1057         // If permissions need a review before any of the app components can run, we
1058         // launch the review activity and pass a pending intent to start the activity
1059         // we are to launching now after the review is completed.
1060         if (aInfo != null) {
1061             if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
1062                     aInfo.packageName, userId)) {
1063                 final IIntentSender target = mService.getIntentSenderLocked(
1064                         ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
1065                         callingUid, userId, null, null, 0, new Intent[]{intent},
1066                         new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
1067                                 | PendingIntent.FLAG_ONE_SHOT, null);
1068 
1069                 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
1070 
1071                 int flags = intent.getFlags();
1072                 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
1073 
1074                 /*
1075                  * Prevent reuse of review activity: Each app needs their own review activity. By
1076                  * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
1077                  * with the same launch parameters (extras are ignored). Hence to avoid possible
1078                  * reuse force a new activity via the MULTIPLE_TASK flag.
1079                  *
1080                  * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
1081                  * hence no need to add the flag in this case.
1082                  */
1083                 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
1084                     flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1085                 }
1086                 newIntent.setFlags(flags);
1087 
1088                 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
1089                 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
1090                 if (resultRecord != null) {
1091                     newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
1092                 }
1093                 intent = newIntent;
1094 
1095                 // The permissions review target shouldn't get any permission
1096                 // grants intended for the original destination
1097                 intentGrants = null;
1098 
1099                 resolvedType = null;
1100                 callingUid = realCallingUid;
1101                 callingPid = realCallingPid;
1102 
1103                 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
1104                         computeResolveFilterUid(
1105                                 callingUid, realCallingUid, request.filterCallingUid));
1106                 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
1107                         null /*profilerInfo*/);
1108 
1109                 if (DEBUG_PERMISSIONS_REVIEW) {
1110                     final Task focusedRootTask =
1111                             mRootWindowContainer.getTopDisplayFocusedRootTask();
1112                     Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
1113                             true, false) + "} from uid " + callingUid + " on display "
1114                             + (focusedRootTask == null ? DEFAULT_DISPLAY
1115                                     : focusedRootTask.getDisplayId()));
1116                 }
1117             }
1118         }
1119 
1120         // If we have an ephemeral app, abort the process of launching the resolved intent.
1121         // Instead, launch the ephemeral installer. Once the installer is finished, it
1122         // starts either the intent we resolved here [on install error] or the ephemeral
1123         // app [on install success].
1124         if (rInfo != null && rInfo.auxiliaryInfo != null) {
1125             intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
1126                     callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
1127             resolvedType = null;
1128             callingUid = realCallingUid;
1129             callingPid = realCallingPid;
1130 
1131             // The ephemeral installer shouldn't get any permission grants
1132             // intended for the original destination
1133             intentGrants = null;
1134 
1135             aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
1136         }
1137         // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
1138         // Pending intent launched from systemui also depends on caller app
1139         if (callerApp == null && realCallingPid > 0) {
1140             final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
1141             if (wpc != null) {
1142                 callerApp = wpc;
1143             }
1144         }
1145         final ActivityRecord r = new ActivityRecord.Builder(mService)
1146                 .setCaller(callerApp)
1147                 .setLaunchedFromPid(callingPid)
1148                 .setLaunchedFromUid(callingUid)
1149                 .setLaunchedFromPackage(callingPackage)
1150                 .setLaunchedFromFeature(callingFeatureId)
1151                 .setIntent(intent)
1152                 .setResolvedType(resolvedType)
1153                 .setActivityInfo(aInfo)
1154                 .setConfiguration(mService.getGlobalConfiguration())
1155                 .setResultTo(resultRecord)
1156                 .setResultWho(resultWho)
1157                 .setRequestCode(requestCode)
1158                 .setComponentSpecified(request.componentSpecified)
1159                 .setRootVoiceInteraction(voiceSession != null)
1160                 .setActivityOptions(checkedOptions)
1161                 .setSourceRecord(sourceRecord)
1162                 .build();
1163 
1164         mLastStartActivityRecord = r;
1165 
1166         if (r.appTimeTracker == null && sourceRecord != null) {
1167             // If the caller didn't specify an explicit time tracker, we want to continue
1168             // tracking under any it has.
1169             r.appTimeTracker = sourceRecord.appTimeTracker;
1170         }
1171 
1172         // Only allow app switching to be resumed if activity is not a restricted background
1173         // activity and target app is not home process, otherwise any background activity
1174         // started in background task can stop home button protection mode.
1175         // As the targeted app is not a home process and we don't need to wait for the 2nd
1176         // activity to be started to resume app switching, we can just enable app switching
1177         // directly.
1178         WindowProcessController homeProcess = mService.mHomeProcess;
1179         boolean isHomeProcess = homeProcess != null
1180                 && aInfo.applicationInfo.uid == homeProcess.mUid;
1181         if (!restrictedBgActivity && !isHomeProcess) {
1182             mService.resumeAppSwitches();
1183         }
1184 
1185         mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1186                 request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
1187                 inTask, inTaskFragment, restrictedBgActivity, intentGrants);
1188 
1189         if (request.outActivity != null) {
1190             request.outActivity[0] = mLastStartActivityRecord;
1191         }
1192 
1193         return mLastStartActivityResult;
1194     }
1195 
1196     /**
1197      * Return true if background activity is really aborted.
1198      *
1199      * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1200      */
handleBackgroundActivityAbort(ActivityRecord r)1201     private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1202         // TODO(b/131747138): Remove toast and refactor related code in R release.
1203         final boolean abort = !mService.isBackgroundActivityStartsEnabled();
1204         if (!abort) {
1205             return false;
1206         }
1207         final ActivityRecord resultRecord = r.resultTo;
1208         final String resultWho = r.resultWho;
1209         int requestCode = r.requestCode;
1210         if (resultRecord != null) {
1211             resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1212                     null /* data */, null /* dataGrants */);
1213         }
1214         // We pretend to the caller that it was really started to make it backward compatible, but
1215         // they will just get a cancel result.
1216         ActivityOptions.abort(r.getOptions());
1217         return true;
1218     }
1219 
getExternalResult(int result)1220     static int getExternalResult(int result) {
1221         // Aborted results are treated as successes externally, but we must track them internally.
1222         return result != START_ABORTED ? result : START_SUCCESS;
1223     }
1224 
1225     /**
1226      * Called when execution is complete. Sets state indicating completion and proceeds with
1227      * recycling if appropriate.
1228      */
onExecutionComplete()1229     private void onExecutionComplete() {
1230         mController.onExecutionComplete(this);
1231     }
1232 
isHomeApp(int uid, @Nullable String packageName)1233     private boolean isHomeApp(int uid, @Nullable String packageName) {
1234         if (mService.mHomeProcess != null) {
1235             // Fast check
1236             return uid == mService.mHomeProcess.mUid;
1237         }
1238         if (packageName == null) {
1239             return false;
1240         }
1241         ComponentName activity =
1242                 mService.getPackageManagerInternalLocked().getDefaultHomeActivity(
1243                         UserHandle.getUserId(uid));
1244         return activity != null && packageName.equals(activity.getPackageName());
1245     }
1246 
shouldAbortBackgroundActivityStart(int callingUid, int callingPid, final String callingPackage, int realCallingUid, int realCallingPid, WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart, Intent intent)1247     boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
1248             final String callingPackage, int realCallingUid, int realCallingPid,
1249             WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
1250             boolean allowBackgroundActivityStart, Intent intent) {
1251         // don't abort for the most important UIDs
1252         final int callingAppId = UserHandle.getAppId(callingUid);
1253         if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
1254                 || callingAppId == Process.NFC_UID) {
1255             if (DEBUG_ACTIVITY_STARTS) {
1256                 Slog.d(TAG, "Activity start allowed for important callingUid (" + callingUid + ")");
1257             }
1258             return false;
1259         }
1260 
1261         // Always allow home application to start activities.
1262         if (isHomeApp(callingUid, callingPackage)) {
1263             if (DEBUG_ACTIVITY_STARTS) {
1264                 Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")");
1265             }
1266             return false;
1267         }
1268 
1269         // IME should always be allowed to start activity, like IME settings.
1270         final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow();
1271         if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) {
1272             if (DEBUG_ACTIVITY_STARTS) {
1273                 Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")");
1274             }
1275             return false;
1276         }
1277 
1278         // This is used to block background activity launch even if the app is still
1279         // visible to user after user clicking home button.
1280         final int appSwitchState = mService.getBalAppSwitchesState();
1281 
1282         // don't abort if the callingUid has a visible window or is a persistent system process
1283         final int callingUidProcState = mService.mActiveUids.getUidState(callingUid);
1284         final boolean callingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid);
1285         final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
1286                 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP
1287                 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
1288         final boolean isCallingUidPersistentSystemProcess =
1289                 callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
1290 
1291         // Normal apps with visible app window will be allowed to start activity if app switching
1292         // is allowed, or apps like live wallpaper with non app visible window will be allowed.
1293         final boolean appSwitchAllowedOrFg =
1294                 appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY;
1295         if (((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
1296                 && callingUidHasAnyVisibleWindow)
1297                 || isCallingUidPersistentSystemProcess) {
1298             if (DEBUG_ACTIVITY_STARTS) {
1299                 Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid
1300                         + ", isCallingUidPersistentSystemProcess = "
1301                         + isCallingUidPersistentSystemProcess);
1302             }
1303             return false;
1304         }
1305         // take realCallingUid into consideration
1306         final int realCallingUidProcState = (callingUid == realCallingUid)
1307                 ? callingUidProcState
1308                 : mService.mActiveUids.getUidState(realCallingUid);
1309         final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
1310                 ? callingUidHasAnyVisibleWindow
1311                 : mService.hasActiveVisibleWindow(realCallingUid);
1312         final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
1313                 ? isCallingUidForeground
1314                 : realCallingUidHasAnyVisibleWindow
1315                         || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
1316         final int realCallingAppId = UserHandle.getAppId(realCallingUid);
1317         final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
1318                 ? isCallingUidPersistentSystemProcess
1319                 : (realCallingAppId == Process.SYSTEM_UID)
1320                         || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
1321         if (realCallingUid != callingUid) {
1322             // don't abort if the realCallingUid has a visible window
1323             // TODO(b/171459802): We should check appSwitchAllowed also
1324             if (realCallingUidHasAnyVisibleWindow) {
1325                 if (DEBUG_ACTIVITY_STARTS) {
1326                     Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
1327                             + ") has visible (non-toast) window");
1328                 }
1329                 return false;
1330             }
1331             // if the realCallingUid is a persistent system process, abort if the IntentSender
1332             // wasn't allowed to start an activity
1333             if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
1334                 if (DEBUG_ACTIVITY_STARTS) {
1335                     Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
1336                             + ") is persistent system process AND intent sender allowed "
1337                             + "(allowBackgroundActivityStart = true)");
1338                 }
1339                 return false;
1340             }
1341             // don't abort if the realCallingUid is an associated companion app
1342             if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
1343                     realCallingUid)) {
1344                 if (DEBUG_ACTIVITY_STARTS) {
1345                     Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
1346                             + ") is companion app");
1347                 }
1348                 return false;
1349             }
1350         }
1351         // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
1352         if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
1353                 == PERMISSION_GRANTED) {
1354             if (DEBUG_ACTIVITY_STARTS) {
1355                 Slog.d(TAG,
1356                         "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
1357                                 + "permission granted for uid "
1358                                 + callingUid);
1359             }
1360             return false;
1361         }
1362         // don't abort if the caller has the same uid as the recents component
1363         if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
1364             if (DEBUG_ACTIVITY_STARTS) {
1365                 Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
1366                         + ") is recents");
1367             }
1368             return false;
1369         }
1370         // don't abort if the callingUid is the device owner
1371         if (mService.isDeviceOwner(callingUid)) {
1372             if (DEBUG_ACTIVITY_STARTS) {
1373                 Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
1374                         + ") is device owner");
1375             }
1376             return false;
1377         }
1378         // don't abort if the callingUid has companion device
1379         final int callingUserId = UserHandle.getUserId(callingUid);
1380         if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
1381             if (DEBUG_ACTIVITY_STARTS) {
1382                 Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
1383                         + ") is companion app");
1384             }
1385             return false;
1386         }
1387         // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
1388         if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
1389             Slog.w(TAG, "Background activity start for " + callingPackage
1390                     + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
1391             return false;
1392         }
1393         // If we don't have callerApp at this point, no caller was provided to startActivity().
1394         // That's the case for PendingIntent-based starts, since the creator's process might not be
1395         // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
1396         // caller, so that we can make the decision based on its state.
1397         int callerAppUid = callingUid;
1398         if (callerApp == null) {
1399             callerApp = mService.getProcessController(realCallingPid, realCallingUid);
1400             callerAppUid = realCallingUid;
1401         }
1402         // don't abort if the callerApp or other processes of that uid are allowed in any way
1403         if (callerApp != null) {
1404             // first check the original calling process
1405             if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) {
1406                 if (DEBUG_ACTIVITY_STARTS) {
1407                     Slog.d(TAG, "Background activity start allowed: callerApp process (pid = "
1408                             + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed");
1409                 }
1410                 return false;
1411             }
1412             // only if that one wasn't allowed, check the other ones
1413             final ArraySet<WindowProcessController> uidProcesses =
1414                     mService.mProcessMap.getProcesses(callerAppUid);
1415             if (uidProcesses != null) {
1416                 for (int i = uidProcesses.size() - 1; i >= 0; i--) {
1417                     final WindowProcessController proc = uidProcesses.valueAt(i);
1418                     if (proc != callerApp
1419                             && proc.areBackgroundActivityStartsAllowed(appSwitchState)) {
1420                         if (DEBUG_ACTIVITY_STARTS) {
1421                             Slog.d(TAG,
1422                                     "Background activity start allowed: process " + proc.getPid()
1423                                             + " from uid " + callerAppUid + " is allowed");
1424                         }
1425                         return false;
1426                     }
1427                 }
1428             }
1429         }
1430         // anything that has fallen through would currently be aborted
1431         Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
1432                 + "; callingUid: " + callingUid
1433                 + "; appSwitchState: " + appSwitchState
1434                 + "; isCallingUidForeground: " + isCallingUidForeground
1435                 + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow
1436                 + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
1437                 "PROCESS_STATE_", callingUidProcState)
1438                 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1439                 + "; realCallingUid: " + realCallingUid
1440                 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
1441                 + "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow
1442                 + "; realCallingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
1443                 "PROCESS_STATE_", realCallingUidProcState)
1444                 + "; isRealCallingUidPersistentSystemProcess: "
1445                 + isRealCallingUidPersistentSystemProcess
1446                 + "; originatingPendingIntent: " + originatingPendingIntent
1447                 + "; allowBackgroundActivityStart: " + allowBackgroundActivityStart
1448                 + "; intent: " + intent
1449                 + "; callerApp: " + callerApp
1450                 + "; inVisibleTask: " + (callerApp != null && callerApp.hasActivityInVisibleTask())
1451                 + "]");
1452         // log aborted activity start to TRON
1453         if (mService.isActivityStartsLoggingEnabled()) {
1454             mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1455                     callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1456                     realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
1457                     (originatingPendingIntent != null));
1458         }
1459         return true;
1460     }
1461 
1462     /**
1463      * Creates a launch intent for the given auxiliary resolution data.
1464      */
createLaunchIntent(@ullable AuxiliaryResolveInfo auxiliaryResponse, Intent originalIntent, String callingPackage, @Nullable String callingFeatureId, Bundle verificationBundle, String resolvedType, int userId)1465     private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
1466             Intent originalIntent, String callingPackage, @Nullable String callingFeatureId,
1467             Bundle verificationBundle, String resolvedType, int userId) {
1468         if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
1469             // request phase two resolution
1470             PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked();
1471             boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId);
1472             packageManager.requestInstantAppResolutionPhaseTwo(
1473                     auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1474                     callingFeatureId, isRequesterInstantApp, verificationBundle, userId);
1475         }
1476         return InstantAppResolver.buildEphemeralInstallerIntent(
1477                 originalIntent,
1478                 InstantAppResolver.sanitizeIntent(originalIntent),
1479                 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1480                 callingPackage,
1481                 callingFeatureId,
1482                 verificationBundle,
1483                 resolvedType,
1484                 userId,
1485                 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1486                 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1487                 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1488                 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
1489     }
1490 
postStartActivityProcessing(ActivityRecord r, int result, Task startedActivityRootTask)1491     void postStartActivityProcessing(ActivityRecord r, int result,
1492             Task startedActivityRootTask) {
1493         if (!ActivityManager.isStartResultSuccessful(result)) {
1494             if (mFrozeTaskList) {
1495                 // If we specifically froze the task list as part of starting an activity, then
1496                 // reset the frozen list state if it failed to start. This is normally otherwise
1497                 // called when the freeze-timeout has elapsed.
1498                 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
1499             }
1500         }
1501         if (ActivityManager.isStartResultFatalError(result)) {
1502             return;
1503         }
1504 
1505         // We're waiting for an activity launch to finish, but that activity simply
1506         // brought another activity to front. We must also handle the case where the task is already
1507         // in the front as a result of the trampoline activity being in the same task (it will be
1508         // considered focused as the trampoline will be finished). Let them know about this, so
1509         // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}.
1510         mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
1511 
1512         final Task targetTask = r.getTask() != null
1513                 ? r.getTask()
1514                 : mTargetTask;
1515         if (startedActivityRootTask == null || targetTask == null || !targetTask.isAttached()) {
1516             return;
1517         }
1518 
1519         final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1520         boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1521                 && mReuseTask != null;
1522         if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1523             // The activity was already running so it wasn't started, but either brought to the
1524             // front or the new intent was delivered to it since it was already in front. Notify
1525             // anyone interested in this piece of information.
1526             final Task rootHomeTask = targetTask.getDisplayArea().getRootHomeTask();
1527             final boolean homeTaskVisible = rootHomeTask != null
1528                     && rootHomeTask.shouldBeVisible(null);
1529             final ActivityRecord top = targetTask.getTopNonFinishingActivity();
1530             final boolean visible = top != null && top.isVisible();
1531             mService.getTaskChangeNotificationController().notifyActivityRestartAttempt(
1532                     targetTask.getTaskInfo(), homeTaskVisible, clearedTask, visible);
1533         }
1534     }
1535 
1536     /**
1537      * Compute the logical UID based on which the package manager would filter
1538      * app components i.e. based on which the instant app policy would be applied
1539      * because it is the logical calling UID.
1540      *
1541      * @param customCallingUid The UID on whose behalf to make the call.
1542      * @param actualCallingUid The UID actually making the call.
1543      * @param filterCallingUid The UID to be used to filter for instant apps.
1544      * @return The logical UID making the call.
1545      */
computeResolveFilterUid(int customCallingUid, int actualCallingUid, int filterCallingUid)1546     static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1547             int filterCallingUid) {
1548         return filterCallingUid != UserHandle.USER_NULL
1549                 ? filterCallingUid
1550                 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
1551     }
1552 
1553     /**
1554      * Start an activity while most of preliminary checks has been done and caller has been
1555      * confirmed that holds necessary permissions to do so.
1556      * Here also ensures that the starting activity is removed if the start wasn't successful.
1557      */
startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, boolean restrictedBgActivity, NeededUriGrants intentGrants)1558     private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1559             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1560             int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1561             TaskFragment inTaskFragment, boolean restrictedBgActivity,
1562             NeededUriGrants intentGrants) {
1563         int result = START_CANCELED;
1564         boolean startResultSuccessful = false;
1565         final Task startedActivityRootTask;
1566 
1567         // Create a transition now to record the original intent of actions taken within
1568         // startActivityInner. Otherwise, logic in startActivityInner could start a different
1569         // transition based on a sub-action.
1570         // Only do the create here (and defer requestStart) since startActivityInner might abort.
1571         final TransitionController transitionController = r.mTransitionController;
1572         Transition newTransition = (!transitionController.isCollecting()
1573                 && transitionController.getTransitionPlayer() != null)
1574                 ? transitionController.createTransition(TRANSIT_OPEN) : null;
1575         RemoteTransition remoteTransition = r.takeRemoteTransition();
1576         if (newTransition != null && remoteTransition != null) {
1577             newTransition.setRemoteTransition(remoteTransition);
1578         }
1579         transitionController.collect(r);
1580         final boolean isTransient = r.getOptions() != null && r.getOptions().getTransientLaunch();
1581         try {
1582             mService.deferWindowLayout();
1583             Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
1584             result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
1585                     startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
1586                     intentGrants);
1587             startResultSuccessful = ActivityManager.isStartResultSuccessful(result);
1588             final boolean taskAlwaysOnTop = options != null && options.getTaskAlwaysOnTop();
1589             // Apply setAlwaysOnTop when starting an Activity is successful regardless of creating
1590             // a new Activity or recycling the existing Activity.
1591             if (taskAlwaysOnTop && startResultSuccessful) {
1592                 final Task targetRootTask =
1593                         mTargetRootTask != null ? mTargetRootTask : mTargetTask.getRootTask();
1594                 targetRootTask.setAlwaysOnTop(true);
1595             }
1596         } finally {
1597             Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1598             startedActivityRootTask = handleStartResult(r, result);
1599             mService.continueWindowLayout();
1600             mSupervisor.mUserLeaving = false;
1601 
1602             // Transition housekeeping
1603             if (!startResultSuccessful) {
1604                 if (newTransition != null) {
1605                     newTransition.abort();
1606                 }
1607             } else {
1608                 if (!mAvoidMoveToFront && mDoResume
1609                         && mRootWindowContainer.hasVisibleWindowAboveButDoesNotOwnNotificationShade(
1610                             r.launchedFromUid)) {
1611                     // If the UID launching the activity has a visible window on top of the
1612                     // notification shade and it's launching an activity that's going to be at the
1613                     // front, we should move the shade out of the way so the user can see it.
1614                     // We want to avoid the case where the activity is launched on top of a
1615                     // background task which is not moved to the front.
1616                     StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
1617                     if (statusBar != null) {
1618                         // This results in a async call since the interface is one-way
1619                         statusBar.collapsePanels();
1620                     }
1621                 }
1622                 final boolean started = result == START_SUCCESS || result == START_TASK_TO_FRONT;
1623                 if (started) {
1624                     // The activity is started new rather than just brought forward, so record
1625                     // it as an existence change.
1626                     transitionController.collectExistenceChange(r);
1627                 } else if (result == START_DELIVERED_TO_TOP && newTransition != null) {
1628                     // We just delivered to top, so there isn't an actual transition here
1629                     newTransition.abort();
1630                     newTransition = null;
1631                 }
1632                 if (isTransient) {
1633                     // `r` isn't guaranteed to be the actual relevant activity, so we must wait
1634                     // until after we launched to identify the relevant activity.
1635                     transitionController.setTransientLaunch(mLastStartActivityRecord);
1636                 }
1637                 if (newTransition != null) {
1638                     transitionController.requestStartTransition(newTransition,
1639                             mTargetTask, remoteTransition);
1640                 } else if (started) {
1641                     // Make the collecting transition wait until this request is ready.
1642                     transitionController.setReady(r, false);
1643                 }
1644             }
1645         }
1646 
1647         postStartActivityProcessing(r, result, startedActivityRootTask);
1648 
1649         return result;
1650     }
1651 
1652     /**
1653      * If the start result is success, ensure that the configuration of the started activity matches
1654      * the current display. Otherwise clean up unassociated containers to avoid leakage.
1655      *
1656      * @return the root task where the successful started activity resides.
1657      */
handleStartResult(@onNull ActivityRecord started, int result)1658     private @Nullable Task handleStartResult(@NonNull ActivityRecord started, int result) {
1659         final Task currentRootTask = started.getRootTask();
1660         Task startedActivityRootTask = currentRootTask != null ? currentRootTask : mTargetRootTask;
1661 
1662         if (ActivityManager.isStartResultSuccessful(result)) {
1663             if (startedActivityRootTask != null) {
1664                 // If there is no state change (e.g. a resumed activity is reparented to top of
1665                 // another display) to trigger a visibility/configuration checking, we have to
1666                 // update the configuration for changing to different display.
1667                 final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity();
1668                 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
1669                     mRootWindowContainer.ensureVisibilityAndConfig(
1670                             currentTop, currentTop.getDisplayId(),
1671                             true /* markFrozenIfConfigChanged */, false /* deferResume */);
1672                 }
1673             }
1674             return startedActivityRootTask;
1675         }
1676 
1677         // If we are not able to proceed, disassociate the activity from the task. Leaving an
1678         // activity in an incomplete state can lead to issues, such as performing operations
1679         // without a window container.
1680         final Task rootTask = mStartActivity.getRootTask();
1681         if (rootTask != null) {
1682             mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
1683         }
1684 
1685         // Root task should also be detached from display and be removed if it's empty.
1686         if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
1687                 && !startedActivityRootTask.hasActivity()
1688                 && !startedActivityRootTask.isActivityTypeHome()) {
1689             startedActivityRootTask.removeIfPossible("handleStartResult");
1690             startedActivityRootTask = null;
1691         }
1692         return startedActivityRootTask;
1693     }
1694 
1695     /**
1696      * Start an activity and determine if the activity should be adding to the top of an existing
1697      * task or delivered new intent to an existing activity. Also manipulating the activity task
1698      * onto requested or valid root-task/display.
1699      *
1700      * Note: This method should only be called from {@link #startActivityUnchecked}.
1701      */
1702     // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
1703     @VisibleForTesting
startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, boolean restrictedBgActivity, NeededUriGrants intentGrants)1704     int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
1705             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1706             int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1707             TaskFragment inTaskFragment, boolean restrictedBgActivity,
1708             NeededUriGrants intentGrants) {
1709         setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
1710                 voiceSession, voiceInteractor, restrictedBgActivity);
1711 
1712         computeLaunchingTaskFlags();
1713 
1714         computeSourceRootTask();
1715 
1716         mIntent.setFlags(mLaunchFlags);
1717 
1718         // Get top task at beginning because the order may be changed when reusing existing task.
1719         final Task prevTopTask = mPreferredTaskDisplayArea.getFocusedRootTask();
1720         final Task reusedTask = getReusableTask();
1721 
1722         // If requested, freeze the task list
1723         if (mOptions != null && mOptions.freezeRecentTasksReordering()
1724                 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
1725                 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
1726             mFrozeTaskList = true;
1727             mSupervisor.mRecentTasks.setFreezeTaskListReordering();
1728         }
1729 
1730         // Compute if there is an existing task that should be used for.
1731         final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
1732         final boolean newTask = targetTask == null;
1733         mTargetTask = targetTask;
1734 
1735         computeLaunchParams(r, sourceRecord, targetTask);
1736 
1737         // Check if starting activity on given task or on a new task is allowed.
1738         int startResult = isAllowedToStart(r, newTask, targetTask);
1739         if (startResult != START_SUCCESS) {
1740             return startResult;
1741         }
1742 
1743         final ActivityRecord targetTaskTop = newTask
1744                 ? null : targetTask.getTopNonFinishingActivity();
1745         if (targetTaskTop != null) {
1746             // Recycle the target task for this launch.
1747             startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
1748             if (startResult != START_SUCCESS) {
1749                 return startResult;
1750             }
1751         } else {
1752             mAddingToTask = true;
1753         }
1754 
1755         // If the activity being launched is the same as the one currently at the top, then
1756         // we need to check if it should only be launched once.
1757         final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
1758         if (topRootTask != null) {
1759             startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
1760             if (startResult != START_SUCCESS) {
1761                 return startResult;
1762             }
1763         }
1764 
1765         if (mTargetRootTask == null) {
1766             mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
1767         }
1768         if (newTask) {
1769             final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1770                     ? mSourceRecord.getTask() : null;
1771             setNewTask(taskToAffiliate);
1772         } else if (mAddingToTask) {
1773             addOrReparentStartingActivity(targetTask, "adding to task");
1774         }
1775 
1776         if (!mAvoidMoveToFront && mDoResume) {
1777             mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
1778             if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.mInternal.isDreaming()) {
1779                 // Launching underneath dream activity (fullscreen, always-on-top). Run the launch-
1780                 // -behind transition so the Activity gets created and starts in visible state.
1781                 mLaunchTaskBehind = true;
1782                 r.mLaunchTaskBehind = true;
1783             }
1784         }
1785 
1786         mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
1787                 mStartActivity.getUriPermissionsLocked());
1788         if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
1789             // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
1790             final PackageManagerInternal pmInternal =
1791                     mService.getPackageManagerInternalLocked();
1792             final int resultToUid = pmInternal.getPackageUid(
1793                     mStartActivity.resultTo.info.packageName, 0 /* flags */,
1794                     mStartActivity.mUserId);
1795             pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
1796                     UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
1797                     resultToUid /*visible*/, true /*direct*/);
1798         }
1799         final Task startedTask = mStartActivity.getTask();
1800         if (newTask) {
1801             EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
1802         }
1803         mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);
1804 
1805         mStartActivity.getTaskFragment().clearLastPausedActivity();
1806 
1807         mRootWindowContainer.startPowerModeLaunchIfNeeded(
1808                 false /* forceSend */, mStartActivity);
1809 
1810         final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded();
1811         mTargetRootTask.startActivityLocked(mStartActivity,
1812                 topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask,
1813                 isTaskSwitch, mOptions, sourceRecord);
1814         if (mDoResume) {
1815             final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
1816             if (!mTargetRootTask.isTopActivityFocusable()
1817                     || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
1818                     && mStartActivity != topTaskActivity)) {
1819                 // If the activity is not focusable, we can't resume it, but still would like to
1820                 // make sure it becomes visible as it starts (this will also trigger entry
1821                 // animation). An example of this are PIP activities.
1822                 // Also, we don't want to resume activities in a task that currently has an overlay
1823                 // as the starting activity just needs to be in the visible paused state until the
1824                 // over is removed.
1825                 // Passing {@code null} as the start parameter ensures all activities are made
1826                 // visible.
1827                 mTargetRootTask.ensureActivitiesVisible(null /* starting */,
1828                         0 /* configChanges */, !PRESERVE_WINDOWS);
1829                 // Go ahead and tell window manager to execute app transition for this activity
1830                 // since the app transition will not be triggered through the resume channel.
1831                 mTargetRootTask.mDisplayContent.executeAppTransition();
1832             } else {
1833                 // If the target root-task was not previously focusable (previous top running
1834                 // activity on that root-task was not visible) then any prior calls to move the
1835                 // root-task to the will not update the focused root-task.  If starting the new
1836                 // activity now allows the task root-task to be focusable, then ensure that we
1837                 // now update the focused root-task accordingly.
1838                 if (mTargetRootTask.isTopActivityFocusable()
1839                         && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
1840                     mTargetRootTask.moveToFront("startActivityInner");
1841                 }
1842                 mRootWindowContainer.resumeFocusedTasksTopActivities(
1843                         mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
1844             }
1845         }
1846         mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
1847 
1848         // Update the recent tasks list immediately when the activity starts
1849         mSupervisor.mRecentTasks.add(startedTask);
1850         mSupervisor.handleNonResizableTaskIfNeeded(startedTask,
1851                 mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
1852 
1853         return START_SUCCESS;
1854     }
1855 
computeTargetTask()1856     private Task computeTargetTask() {
1857         if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1858                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1859             // A new task should be created instead of using existing one.
1860             return null;
1861         } else if (mSourceRecord != null) {
1862             return mSourceRecord.getTask();
1863         } else if (mInTask != null) {
1864             return mInTask;
1865         } else {
1866             final Task rootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, null /* task */,
1867                     mOptions);
1868             final ActivityRecord top = rootTask.getTopNonFinishingActivity();
1869             if (top != null) {
1870                 return top.getTask();
1871             } else {
1872                 // Remove the root task if no activity in the root task.
1873                 rootTask.removeIfPossible("computeTargetTask");
1874             }
1875         }
1876         return null;
1877     }
1878 
computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, Task targetTask)1879     private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord,
1880             Task targetTask) {
1881         final Task sourceRootTask = mSourceRootTask != null ? mSourceRootTask
1882                 : mRootWindowContainer.getTopDisplayFocusedRootTask();
1883         if (sourceRootTask != null && sourceRootTask.inSplitScreenWindowingMode()
1884                 && (mOptions == null
1885                         || mOptions.getLaunchWindowingMode() == WINDOWING_MODE_UNDEFINED)) {
1886             int windowingMode =
1887                     targetTask != null ? targetTask.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
1888             if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1889                 if (sourceRootTask.inSplitScreenPrimaryWindowingMode()) {
1890                     windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
1891                 } else if (sourceRootTask.inSplitScreenSecondaryWindowingMode()) {
1892                     windowingMode = WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
1893                 }
1894             }
1895 
1896             if (mOptions == null) {
1897                 mOptions = ActivityOptions.makeBasic();
1898             }
1899             mOptions.setLaunchWindowingMode(windowingMode);
1900         }
1901 
1902         mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
1903                 sourceRecord, mOptions, mRequest, PHASE_BOUNDS, mLaunchParams);
1904         mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
1905                 ? mLaunchParams.mPreferredTaskDisplayArea
1906                 : mRootWindowContainer.getDefaultTaskDisplayArea();
1907         mPreferredWindowingMode = mLaunchParams.mWindowingMode;
1908     }
1909 
isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask)1910     private int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
1911         if (mStartActivity.packageName == null) {
1912             if (mStartActivity.resultTo != null) {
1913                 mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
1914                         mStartActivity.requestCode, RESULT_CANCELED,
1915                         null /* data */, null /* dataGrants */);
1916             }
1917             ActivityOptions.abort(mOptions);
1918             return START_CLASS_NOT_FOUND;
1919         }
1920 
1921         // Do not start home activity if it cannot be launched on preferred display. We are not
1922         // doing this in ActivityTaskSupervisor#canPlaceEntityOnDisplay because it might
1923         // fallback to launch on other displays.
1924         if (r.isActivityTypeHome()) {
1925             if (!mRootWindowContainer.canStartHomeOnDisplayArea(r.info, mPreferredTaskDisplayArea,
1926                     true /* allowInstrumenting */)) {
1927                 Slog.w(TAG, "Cannot launch home on display area " + mPreferredTaskDisplayArea);
1928                 return START_CANCELED;
1929             }
1930         }
1931 
1932         // Do not allow background activity start in new task or in a task that uid is not present.
1933         // Also do not allow pinned window to start single instance activity in background,
1934         // as it will recreate the window and makes it to foreground.
1935         boolean blockBalInTask = (newTask
1936                 || !targetTask.isUidPresent(mCallingUid)
1937                 || (LAUNCH_SINGLE_INSTANCE == mLaunchMode && targetTask.inPinnedWindowingMode()));
1938 
1939         if (mRestrictedBgActivity && blockBalInTask
1940                 && handleBackgroundActivityAbort(mStartActivity)) {
1941             Slog.e(TAG, "Abort background activity starts from " + mCallingUid);
1942             return START_ABORTED;
1943         }
1944 
1945         // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still
1946         // needs to be a lock task mode violation since the task gets cleared out and the device
1947         // would otherwise leave the locked task.
1948         final boolean isNewClearTask =
1949                 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1950                         == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1951         if (!newTask) {
1952             if (mService.getLockTaskController().isLockTaskModeViolation(targetTask,
1953                     isNewClearTask)) {
1954                 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1955                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1956             }
1957         } else {
1958             if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(mStartActivity)) {
1959                 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
1960                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1961             }
1962         }
1963 
1964         if (mInTaskFragment != null && !canEmbedActivity(mInTaskFragment, r, newTask, targetTask)) {
1965             Slog.e(TAG, "Permission denied: Cannot embed " + r + " to " + mInTaskFragment.getTask()
1966                     + " targetTask= " + targetTask);
1967             return START_PERMISSION_DENIED;
1968         }
1969 
1970         return START_SUCCESS;
1971     }
1972 
1973     /**
1974      * Return {@code true} if an activity can be embedded to the TaskFragment.
1975      * @param taskFragment the TaskFragment for embedding.
1976      * @param starting the starting activity.
1977      * @param newTask whether the starting activity is going to be launched on a new task.
1978      * @param targetTask the target task for launching activity, which could be different from
1979      *                   the one who hosting the embedding.
1980      */
canEmbedActivity(@onNull TaskFragment taskFragment, ActivityRecord starting, boolean newTask, Task targetTask)1981     private boolean canEmbedActivity(@NonNull TaskFragment taskFragment, ActivityRecord starting,
1982             boolean newTask, Task targetTask) {
1983         final Task hostTask = taskFragment.getTask();
1984         if (hostTask == null) {
1985             return false;
1986         }
1987 
1988         // Allowing the embedding if the task is owned by system.
1989         final int hostUid = hostTask.effectiveUid;
1990         if (UserHandle.getAppId(hostUid) == Process.SYSTEM_UID) {
1991             return true;
1992         }
1993 
1994         // Not allowed embedding an activity of another app.
1995         if (hostUid != starting.getUid()) {
1996             return false;
1997         }
1998 
1999         // Not allowed embedding task.
2000         return !newTask && (targetTask == null || targetTask == hostTask);
2001     }
2002 
2003     /**
2004      * Prepare the target task to be reused for this launch, which including:
2005      * - Position the target task on valid root task on preferred display.
2006      * - Comply to the specified activity launch flags
2007      * - Determine whether need to add a new activity on top or just brought the task to front.
2008      */
2009     @VisibleForTesting
recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, NeededUriGrants intentGrants)2010     int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask,
2011             NeededUriGrants intentGrants) {
2012         // Should not recycle task which is from a different user, just adding the starting
2013         // activity to the task.
2014         if (targetTask.mUserId != mStartActivity.mUserId) {
2015             mTargetRootTask = targetTask.getRootTask();
2016             mAddingToTask = true;
2017             return START_SUCCESS;
2018         }
2019 
2020         if (reusedTask != null) {
2021             if (targetTask.intent == null) {
2022                 // This task was started because of movement of the activity based on
2023                 // affinity...
2024                 // Now that we are actually launching it, we can assign the base intent.
2025                 targetTask.setIntent(mStartActivity);
2026             } else {
2027                 final boolean taskOnHome =
2028                         (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
2029                 if (taskOnHome) {
2030                     targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
2031                 } else {
2032                     targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
2033                 }
2034             }
2035         }
2036 
2037         mRootWindowContainer.startPowerModeLaunchIfNeeded(false /* forceSend */,
2038                 targetTaskTop);
2039 
2040         setTargetRootTaskIfNeeded(targetTaskTop);
2041 
2042         // When there is a reused activity and the current result is a trampoline activity,
2043         // set the reused activity as the result.
2044         if (mLastStartActivityRecord != null
2045                 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) {
2046             mLastStartActivityRecord = targetTaskTop;
2047         }
2048 
2049         if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2050             // We don't need to start a new activity, and the client said not to do anything
2051             // if that is the case, so this is it!  And for paranoia, make sure we have
2052             // correctly resumed the top activity.
2053             if (!mMovedToFront && mDoResume) {
2054                 ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetRootTask,
2055                         targetTaskTop);
2056                 mTargetRootTask.moveToFront("intentActivityFound");
2057             }
2058             resumeTargetRootTaskIfNeeded();
2059             return START_RETURN_INTENT_TO_CALLER;
2060         }
2061 
2062         complyActivityFlags(targetTask,
2063                 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);
2064 
2065         if (mAddingToTask) {
2066             return START_SUCCESS;
2067         }
2068 
2069         // The reusedActivity could be finishing, for example of starting an activity with
2070         // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, use the top running activity in the
2071         // task instead.
2072         targetTaskTop = targetTaskTop.finishing
2073                 ? targetTask.getTopNonFinishingActivity()
2074                 : targetTaskTop;
2075 
2076         // At this point we are certain we want the task moved to the front. If we need to dismiss
2077         // any other always-on-top root tasks, now is the time to do it.
2078         if (targetTaskTop.canTurnScreenOn() && mService.mInternal.isDreaming()) {
2079             targetTaskTop.mTaskSupervisor.wakeUp("recycleTask#turnScreenOnFlag");
2080         }
2081 
2082         if (mMovedToFront) {
2083             // We moved the task to front, use starting window to hide initial drawn delay.
2084             targetTaskTop.showStartingWindow(true /* taskSwitch */);
2085         } else if (mDoResume) {
2086             // Make sure the root task and its belonging display are moved to topmost.
2087             mTargetRootTask.moveToFront("intentActivityFound");
2088         }
2089         // We didn't do anything...  but it was needed (a.k.a., client don't use that intent!)
2090         // And for paranoia, make sure we have correctly resumed the top activity.
2091         resumeTargetRootTaskIfNeeded();
2092 
2093         mLastStartActivityRecord = targetTaskTop;
2094         return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
2095     }
2096 
2097     /**
2098      * Check if the activity being launched is the same as the one currently at the top and it
2099      * should only be launched once.
2100      */
deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants)2101     private int deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants) {
2102         final ActivityRecord top = topRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2103         final boolean dontStart = top != null
2104                 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2105                 && top.mUserId == mStartActivity.mUserId
2106                 && top.attachedToProcess()
2107                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2108                 || LAUNCH_SINGLE_TOP == mLaunchMode)
2109                 // This allows home activity to automatically launch on secondary task display area
2110                 // when it was added, if home was the top activity on default task display area,
2111                 // instead of sending new intent to the home activity on default display area.
2112                 && (!top.isActivityTypeHome() || top.getDisplayArea() == mPreferredTaskDisplayArea);
2113         if (!dontStart) {
2114             return START_SUCCESS;
2115         }
2116 
2117         // For paranoia, make sure we have correctly resumed the top activity.
2118         top.getTaskFragment().clearLastPausedActivity();
2119         if (mDoResume) {
2120             mRootWindowContainer.resumeFocusedTasksTopActivities();
2121         }
2122         ActivityOptions.abort(mOptions);
2123         if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2124             // We don't need to start a new activity, and the client said not to do anything if
2125             // that is the case, so this is it!
2126             return START_RETURN_INTENT_TO_CALLER;
2127         }
2128 
2129         if (mStartActivity.resultTo != null) {
2130             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2131                     mStartActivity.requestCode, RESULT_CANCELED,
2132                     null /* data */, null /* dataGrants */);
2133             mStartActivity.resultTo = null;
2134         }
2135 
2136         deliverNewIntent(top, intentGrants);
2137 
2138         // Don't use mStartActivity.task to show the toast. We're not starting a new activity but
2139         // reusing 'top'. Fields in mStartActivity may not be fully initialized.
2140         mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(),
2141                 mLaunchParams.mWindowingMode, mPreferredTaskDisplayArea, topRootTask);
2142 
2143         return START_DELIVERED_TO_TOP;
2144     }
2145 
2146     /**
2147      * Applying the launching flags to the task, which might clear few or all the activities in the
2148      * task.
2149      */
complyActivityFlags(Task targetTask, ActivityRecord reusedActivity, NeededUriGrants intentGrants)2150     private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity,
2151             NeededUriGrants intentGrants) {
2152         ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
2153         final boolean resetTask =
2154                 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
2155         if (resetTask) {
2156             targetTaskTop = mTargetRootTask.resetTaskIfNeeded(targetTaskTop, mStartActivity);
2157         }
2158 
2159         if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2160                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2161             // The caller has requested to completely replace any existing task with its new
2162             // activity. Well that should not be too hard...
2163             // Note: we must persist the {@link Task} first as intentActivity could be
2164             // removed from calling performClearTaskLocked (For example, if it is being brought out
2165             // of history or if it is finished immediately), thus disassociating the task. Also note
2166             // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked}
2167             // launching another activity.
2168             targetTask.performClearTaskLocked();
2169             targetTask.setIntent(mStartActivity);
2170             mAddingToTask = true;
2171         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2172                 || isDocumentLaunchesIntoExisting(mLaunchFlags)
2173                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK,
2174                         LAUNCH_SINGLE_INSTANCE_PER_TASK)) {
2175             // In this situation we want to remove all activities from the task up to the one
2176             // being started. In most cases this means we are resetting the task to its initial
2177             // state.
2178             final ActivityRecord top = targetTask.performClearTaskForReuseLocked(mStartActivity,
2179                     mLaunchFlags);
2180 
2181             if (top != null) {
2182                 if (top.isRootOfTask()) {
2183                     // Activity aliases may mean we use different intents for the top activity,
2184                     // so make sure the task now has the identity of the new intent.
2185                     top.getTask().setIntent(mStartActivity);
2186                 }
2187                 deliverNewIntent(top, intentGrants);
2188             } else {
2189                 // A special case: we need to start the activity because it is not currently
2190                 // running, and the caller has asked to clear the current task to have this
2191                 // activity at the top.
2192                 mAddingToTask = true;
2193                 if (targetTask.getRootTask() == null) {
2194                     // Target root task got cleared when we all activities were removed above.
2195                     // Go ahead and reset it.
2196                     mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags,
2197                         null /* task */, mOptions);
2198                     mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
2199                             (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
2200                 }
2201             }
2202         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
2203                 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2204             // In this case, we are launching an activity in our own task that may
2205             // already be running somewhere in the history, and we want to shuffle it to
2206             // the front of the root task if so.
2207             final ActivityRecord act =
2208                     targetTask.findActivityInHistory(mStartActivity.mActivityComponent);
2209             if (act != null) {
2210                 final Task task = act.getTask();
2211                 task.moveActivityToFrontLocked(act);
2212                 act.updateOptionsLocked(mOptions);
2213                 deliverNewIntent(act, intentGrants);
2214                 act.getTaskFragment().clearLastPausedActivity();
2215             } else {
2216                 mAddingToTask = true;
2217             }
2218         } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
2219             if (targetTask == mInTask) {
2220                 // In this case we are bringing up an existing activity from a recent task. We
2221                 // don't need to add a new activity instance on top.
2222             } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2223                             || LAUNCH_SINGLE_TOP == mLaunchMode)
2224                     && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
2225                     && mStartActivity.resultTo == null) {
2226                 // In this case the top activity on the task is the same as the one being launched,
2227                 // so we take that as a request to bring the task to the foreground. If the top
2228                 // activity in the task is the root activity, deliver this new intent to it if it
2229                 // desires.
2230                 if (targetTaskTop.isRootOfTask()) {
2231                     targetTaskTop.getTask().setIntent(mStartActivity);
2232                 }
2233                 deliverNewIntent(targetTaskTop, intentGrants);
2234             } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
2235                 // In this case we are launching the root activity of the task, but with a
2236                 // different intent. We should start a new instance on top.
2237                 mAddingToTask = true;
2238             } else if (reusedActivity == null) {
2239                 mAddingToTask = true;
2240             }
2241         } else if (!resetTask) {
2242             // In this case an activity is being launched in to an existing task, without
2243             // resetting that task. This is typically the situation of launching an activity
2244             // from a notification or shortcut. We want to place the new activity on top of the
2245             // current task.
2246             mAddingToTask = true;
2247         } else if (!targetTask.rootWasReset) {
2248             // In this case we are launching into an existing task that has not yet been started
2249             // from its front door. The current task has been brought to the front. Ideally,
2250             // we'd probably like to place this new task at the bottom of its root task, but that's
2251             // a little hard to do with the current organization of the code so for now we'll
2252             // just drop it.
2253             targetTask.setIntent(mStartActivity);
2254         }
2255     }
2256 
2257     /**
2258      * Resets the {@link ActivityStarter} state.
2259      * @param clearRequest whether the request should be reset to default values.
2260      */
reset(boolean clearRequest)2261     void reset(boolean clearRequest) {
2262         mStartActivity = null;
2263         mIntent = null;
2264         mCallingUid = -1;
2265         mOptions = null;
2266         mRestrictedBgActivity = false;
2267 
2268         mLaunchTaskBehind = false;
2269         mLaunchFlags = 0;
2270         mLaunchMode = INVALID_LAUNCH_MODE;
2271 
2272         mLaunchParams.reset();
2273 
2274         mNotTop = null;
2275         mDoResume = false;
2276         mStartFlags = 0;
2277         mSourceRecord = null;
2278         mPreferredTaskDisplayArea = null;
2279         mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED;
2280 
2281         mInTask = null;
2282         mInTaskFragment = null;
2283         mAddingToTask = false;
2284         mReuseTask = null;
2285 
2286         mNewTaskInfo = null;
2287         mNewTaskIntent = null;
2288         mSourceRootTask = null;
2289 
2290         mTargetRootTask = null;
2291         mTargetTask = null;
2292         mMovedToFront = false;
2293         mNoAnimation = false;
2294         mAvoidMoveToFront = false;
2295         mFrozeTaskList = false;
2296         mTransientLaunch = false;
2297 
2298         mVoiceSession = null;
2299         mVoiceInteractor = null;
2300 
2301         mIntentDelivered = false;
2302 
2303         if (clearRequest) {
2304             mRequest.reset();
2305         }
2306     }
2307 
setInitialState(ActivityRecord r, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, boolean doResume, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, boolean restrictedBgActivity)2308     private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
2309             TaskFragment inTaskFragment, boolean doResume, int startFlags,
2310             ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession,
2311             IVoiceInteractor voiceInteractor, boolean restrictedBgActivity) {
2312         reset(false /* clearRequest */);
2313 
2314         mStartActivity = r;
2315         mIntent = r.intent;
2316         mOptions = options;
2317         mCallingUid = r.launchedFromUid;
2318         mSourceRecord = sourceRecord;
2319         mVoiceSession = voiceSession;
2320         mVoiceInteractor = voiceInteractor;
2321         mRestrictedBgActivity = restrictedBgActivity;
2322 
2323         mLaunchParams.reset();
2324 
2325         // Preferred display id is the only state we need for now and it could be updated again
2326         // after we located a reusable task (which might be resided in another display).
2327         mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
2328                 sourceRecord, options, mRequest, PHASE_DISPLAY, mLaunchParams);
2329         mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
2330                 ? mLaunchParams.mPreferredTaskDisplayArea
2331                 : mRootWindowContainer.getDefaultTaskDisplayArea();
2332         mPreferredWindowingMode = mLaunchParams.mWindowingMode;
2333 
2334         mLaunchMode = r.launchMode;
2335 
2336         mLaunchFlags = adjustLaunchFlagsToDocumentMode(
2337                 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
2338                 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
2339         mLaunchTaskBehind = r.mLaunchTaskBehind
2340                 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
2341                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
2342 
2343         if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) {
2344             // Adding NEW_TASK flag for singleInstancePerTask launch mode activity, so that the
2345             // activity won't be launched in source record's task.
2346             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2347         }
2348 
2349         sendNewTaskResultRequestIfNeeded();
2350 
2351         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
2352             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2353         }
2354 
2355         // If we are actually going to launch in to a new task, there are some cases where
2356         // we further want to do multiple task.
2357         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2358             if (mLaunchTaskBehind
2359                     || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
2360                 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
2361             }
2362         }
2363 
2364         // We'll invoke onUserLeaving before onPause only if the launching
2365         // activity did not explicitly state that this is an automated launch.
2366         mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
2367         if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2368                 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
2369 
2370         // If the caller has asked not to resume at this point, we make note
2371         // of this in the record so that we can skip it when trying to find
2372         // the top running activity.
2373         mDoResume = doResume;
2374         if (!doResume || !r.showToCurrentUser() || mLaunchTaskBehind) {
2375             r.delayedResume = true;
2376             mDoResume = false;
2377         }
2378 
2379         if (mOptions != null) {
2380             if (mOptions.getLaunchTaskId() != INVALID_TASK_ID && mOptions.getTaskOverlay()) {
2381                 r.setTaskOverlay(true);
2382                 if (!mOptions.canTaskOverlayResume()) {
2383                     final Task task = mRootWindowContainer.anyTaskForId(
2384                             mOptions.getLaunchTaskId());
2385                     final ActivityRecord top = task != null
2386                             ? task.getTopNonFinishingActivity() : null;
2387                     if (top != null && !top.isState(RESUMED)) {
2388 
2389                         // The caller specifies that we'd like to be avoided to be moved to the
2390                         // front, so be it!
2391                         mDoResume = false;
2392                         mAvoidMoveToFront = true;
2393                     }
2394                 }
2395             } else if (mOptions.getAvoidMoveToFront()) {
2396                 mDoResume = false;
2397                 mAvoidMoveToFront = true;
2398             }
2399             mTransientLaunch = mOptions.getTransientLaunch();
2400             mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask());
2401 
2402             if (inTaskFragment == null) {
2403                 inTaskFragment = TaskFragment.fromTaskFragmentToken(
2404                         mOptions.getLaunchTaskFragmentToken(), mService);
2405             }
2406         }
2407 
2408         mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
2409 
2410         mInTask = inTask;
2411         // In some flows in to this function, we retrieve the task record and hold on to it
2412         // without a lock before calling back in to here...  so the task at this point may
2413         // not actually be in recents.  Check for that, and if it isn't in recents just
2414         // consider it invalid.
2415         if (inTask != null && !inTask.inRecents) {
2416             Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
2417             mInTask = null;
2418         }
2419         mInTaskFragment = inTaskFragment;
2420 
2421         mStartFlags = startFlags;
2422         // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
2423         // is the same as the one making the call...  or, as a special case, if we do not know
2424         // the caller then we count the current top activity as the caller.
2425         if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2426             ActivityRecord checkedCaller = sourceRecord;
2427             if (checkedCaller == null) {
2428                 Task topFocusedRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
2429                 if (topFocusedRootTask != null) {
2430                     checkedCaller = topFocusedRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2431                 }
2432             }
2433             if (checkedCaller == null
2434                     || !checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
2435                 // Caller is not the same as launcher, so always needed.
2436                 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
2437             }
2438         }
2439 
2440         mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
2441 
2442         if (mRestrictedBgActivity && !mService.isBackgroundActivityStartsEnabled()) {
2443             mAvoidMoveToFront = true;
2444             mDoResume = false;
2445         }
2446     }
2447 
sendNewTaskResultRequestIfNeeded()2448     private void sendNewTaskResultRequestIfNeeded() {
2449         if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2450             // For whatever reason this activity is being launched into a new task...
2451             // yet the caller has requested a result back.  Well, that is pretty messed up,
2452             // so instead immediately send back a cancel and let the new task continue launched
2453             // as normal without a dependency on its originator.
2454             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
2455             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2456                     mStartActivity.requestCode, RESULT_CANCELED,
2457                     null /* data */, null /* dataGrants */);
2458             mStartActivity.resultTo = null;
2459         }
2460     }
2461 
computeLaunchingTaskFlags()2462     private void computeLaunchingTaskFlags() {
2463         // If the caller is not coming from another activity, but has given us an explicit task into
2464         // which they would like us to launch the new activity, then let's see about doing that.
2465         if (mSourceRecord == null && mInTask != null && mInTask.getRootTask() != null) {
2466             final Intent baseIntent = mInTask.getBaseIntent();
2467             final ActivityRecord root = mInTask.getRootActivity();
2468             if (baseIntent == null) {
2469                 ActivityOptions.abort(mOptions);
2470                 throw new IllegalArgumentException("Launching into task without base intent: "
2471                         + mInTask);
2472             }
2473 
2474             // If this task is empty, then we are adding the first activity -- it
2475             // determines the root, and must be launching as a NEW_TASK.
2476             if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2477                 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
2478                     ActivityOptions.abort(mOptions);
2479                     throw new IllegalArgumentException("Trying to launch singleInstance/Task "
2480                             + mStartActivity + " into different task " + mInTask);
2481                 }
2482                 if (root != null) {
2483                     ActivityOptions.abort(mOptions);
2484                     throw new IllegalArgumentException("Caller with mInTask " + mInTask
2485                             + " has root " + root + " but target is singleInstance/Task");
2486                 }
2487             }
2488 
2489             // If task is empty, then adopt the interesting intent launch flags in to the
2490             // activity being started.
2491             if (root == null) {
2492                 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
2493                         | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
2494                 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
2495                         | (baseIntent.getFlags() & flagsOfInterest);
2496                 mIntent.setFlags(mLaunchFlags);
2497                 mInTask.setIntent(mStartActivity);
2498                 mAddingToTask = true;
2499 
2500                 // If the task is not empty and the caller is asking to start it as the root of
2501                 // a new task, then we don't actually want to start this on the task. We will
2502                 // bring the task to the front, and possibly give it a new intent.
2503             } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2504                 mAddingToTask = false;
2505 
2506             } else {
2507                 mAddingToTask = true;
2508             }
2509 
2510             mReuseTask = mInTask;
2511         } else {
2512             mInTask = null;
2513             // Launch ResolverActivity in the source task, so that it stays in the task bounds
2514             // when in freeform workspace.
2515             // Also put noDisplay activities in the source task. These by itself can be placed
2516             // in any task/root-task, however it could launch other activities like
2517             // ResolverActivity, and we want those to stay in the original task.
2518             if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
2519                     && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
2520                 mAddingToTask = true;
2521             }
2522         }
2523 
2524         if (mInTask == null) {
2525             if (mSourceRecord == null) {
2526                 // This activity is not being started from another...  in this
2527                 // case we -always- start a new task.
2528                 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
2529                     Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
2530                             "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2531                     mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2532                 }
2533             } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
2534                 // The original activity who is starting us is running as a single
2535                 // instance...  this new activity it is starting must go on its
2536                 // own task.
2537                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2538             } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2539                 // The activity being started is a single instance...  it always
2540                 // gets launched into its own task.
2541                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2542             }
2543         }
2544     }
2545 
computeSourceRootTask()2546     private void computeSourceRootTask() {
2547         if (mSourceRecord == null) {
2548             mSourceRootTask = null;
2549             return;
2550         }
2551         if (!mSourceRecord.finishing) {
2552             mSourceRootTask = mSourceRecord.getRootTask();
2553             return;
2554         }
2555 
2556         // If the source is finishing, we can't further count it as our source. This is because the
2557         // task it is associated with may now be empty and on its way out, so we don't want to
2558         // blindly throw it in to that task.  Instead we will take the NEW_TASK flow and try to find
2559         // a task for it. But save the task information so it can be used when creating the new task.
2560         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
2561             Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
2562                     + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2563             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2564             mNewTaskInfo = mSourceRecord.info;
2565 
2566             // It is not guaranteed that the source record will have a task associated with it. For,
2567             // example, if this method is being called for processing a pending activity launch, it
2568             // is possible that the activity has been removed from the task after the launch was
2569             // enqueued.
2570             final Task sourceTask = mSourceRecord.getTask();
2571             mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
2572         }
2573         mSourceRecord = null;
2574         mSourceRootTask = null;
2575     }
2576 
2577     /**
2578      * Decide whether the new activity should be inserted into an existing task. Returns null
2579      * if not or an ActivityRecord with the task into which the new activity should be added.
2580      */
getReusableTask()2581     private Task getReusableTask() {
2582         // If a target task is specified, try to reuse that one
2583         if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
2584             Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
2585             if (launchTask != null) {
2586                 return launchTask;
2587             }
2588             return null;
2589         }
2590 
2591         // We may want to try to place the new activity in to an existing task.  We always
2592         // do this if the target activity is singleTask or singleInstance; we will also do
2593         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2594         // us to still place it in a new task: multi task, always doc mode, or being asked to
2595         // launch this as a new task behind the current one.
2596         boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2597                 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
2598                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
2599         // If bring to front is requested, and no result is requested and we have not been given
2600         // an explicit task to launch in to, and we can find a task that was started with this
2601         // same component, then instead of launching bring that one to the front.
2602         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2603         ActivityRecord intentActivity = null;
2604         if (putIntoExistingTask) {
2605             if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
2606                 // There can be one and only one instance of single instance activity in the
2607                 // history, and it is always in its own unique task, so we do a special search.
2608                 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
2609                        mStartActivity.isActivityTypeHome());
2610             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2611                 // For the launch adjacent case we only want to put the activity in an existing
2612                 // task if the activity already exists in the history.
2613                 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
2614                         !(LAUNCH_SINGLE_TASK == mLaunchMode));
2615             } else {
2616                 // Otherwise find the best task to put the activity in.
2617                 intentActivity =
2618                         mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);
2619             }
2620         }
2621 
2622         if (intentActivity != null && mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK
2623                 && !intentActivity.getTask().getRootActivity().mActivityComponent.equals(
2624                 mStartActivity.mActivityComponent)) {
2625             // The task could be selected due to same task affinity. Do not reuse the task while
2626             // starting the singleInstancePerTask activity if it is not the task root activity.
2627             intentActivity = null;
2628         }
2629 
2630         if (intentActivity != null
2631                 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
2632                 && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) {
2633             // Do not reuse home activity on other display areas.
2634             intentActivity = null;
2635         }
2636 
2637         return intentActivity != null ? intentActivity.getTask() : null;
2638     }
2639 
2640     /**
2641      * Figure out which task and activity to bring to front when we have found an existing matching
2642      * activity record in history. May also clear the task if needed.
2643      *
2644      * @param intentActivity Existing matching activity.
2645      * @return {@link ActivityRecord} brought to front.
2646      */
setTargetRootTaskIfNeeded(ActivityRecord intentActivity)2647     private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) {
2648         intentActivity.getTaskFragment().clearLastPausedActivity();
2649         Task intentTask = intentActivity.getTask();
2650 
2651         // Only update the target-root-task when it is not indicated.
2652         if (mTargetRootTask == null) {
2653             if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) {
2654                 // Inherit the target-root-task from source to ensure trampoline activities will be
2655                 // launched into the same root task.
2656                 mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask);
2657             } else {
2658                 final Task launchRootTask =
2659                         getLaunchRootTask(mStartActivity, mLaunchFlags, intentTask, mOptions);
2660                 mTargetRootTask =
2661                         launchRootTask != null ? launchRootTask : intentActivity.getRootTask();
2662             }
2663         }
2664 
2665         // If the target task is not in the front, then we need to bring it to the front...
2666         // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2667         // the same behavior as if a new instance was being started, which means not bringing it
2668         // to the front if the caller is not itself in the front.
2669         final boolean differentTopTask;
2670         if (mTargetRootTask.getDisplayArea() == mPreferredTaskDisplayArea) {
2671             final Task focusRootTask = mTargetRootTask.mDisplayContent.getFocusedRootTask();
2672             final ActivityRecord curTop = (focusRootTask == null)
2673                     ? null : focusRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2674             final Task topTask = curTop != null ? curTop.getTask() : null;
2675             differentTopTask = topTask != intentTask
2676                     || (focusRootTask != null && topTask != focusRootTask.getTopMostTask());
2677         } else {
2678             // The existing task should always be different from those in other displays.
2679             differentTopTask = true;
2680         }
2681 
2682         if (differentTopTask && !mAvoidMoveToFront) {
2683             mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
2684             if (mSourceRecord == null || (mSourceRootTask.getTopNonFinishingActivity() != null
2685                     && mSourceRootTask.getTopNonFinishingActivity().getTask()
2686                             == mSourceRecord.getTask())) {
2687                 // We really do want to push this one into the user's face, right now.
2688                 if (mLaunchTaskBehind && mSourceRecord != null) {
2689                     intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
2690                 }
2691 
2692                 if (mTargetRootTask == intentActivity.getRootTask()) {
2693                     // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels
2694                     //  tasks hierarchies.
2695                     if (mTargetRootTask != intentTask
2696                             && mTargetRootTask != intentTask.getParent().asTask()) {
2697                         intentTask.getParent().positionChildAt(POSITION_TOP, intentTask,
2698                                 false /* includingParents */);
2699                         intentTask = intentTask.getParent().asTaskFragment().getTask();
2700                     }
2701                     // If the task is in multi-windowing mode, the activity may already be on
2702                     // the top (visible to user but not the global top), then the result code
2703                     // should be START_DELIVERED_TO_TOP instead of START_TASK_TO_FRONT.
2704                     final boolean wasTopOfVisibleRootTask = intentActivity.mVisibleRequested
2705                             && intentActivity == mTargetRootTask.topRunningActivity();
2706                     // We only want to move to the front, if we aren't going to launch on a
2707                     // different root task. If we launch on a different root task, we will put the
2708                     // task on top there.
2709                     // Defer resuming the top activity while moving task to top, since the
2710                     // current task-top activity may not be the activity that should be resumed.
2711                     mTargetRootTask.moveTaskToFront(intentTask, mNoAnimation, mOptions,
2712                             mStartActivity.appTimeTracker, DEFER_RESUME,
2713                             "bringingFoundTaskToFront");
2714                     mMovedToFront = !wasTopOfVisibleRootTask;
2715                 } else if (intentActivity.getWindowingMode() != WINDOWING_MODE_PINNED) {
2716                     // Leaves reparenting pinned task operations to task organizer to make sure it
2717                     // dismisses pinned task properly.
2718                     // TODO(b/199997762): Consider leaving all reparent operation of organized tasks
2719                     //  to task organizer.
2720                     intentTask.reparent(mTargetRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT,
2721                             ANIMATE, DEFER_RESUME, "reparentToTargetRootTask");
2722                     mMovedToFront = true;
2723                 }
2724                 mOptions = null;
2725             }
2726         }
2727 
2728         if (mPreferredWindowingMode != WINDOWING_MODE_UNDEFINED
2729                 && intentTask.getWindowingMode() != mPreferredWindowingMode) {
2730             intentTask.setWindowingMode(mPreferredWindowingMode);
2731         }
2732 
2733         // Update the target's launch cookie to those specified in the options if set
2734         if (mStartActivity.mLaunchCookie != null) {
2735             intentActivity.mLaunchCookie = mStartActivity.mLaunchCookie;
2736         }
2737 
2738         // Need to update mTargetRootTask because if task was moved out of it, the original root
2739         // task may be destroyed.
2740         mTargetRootTask = intentActivity.getRootTask();
2741         mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED,
2742                 mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetRootTask);
2743 
2744         // We need to check if there is a launch root task in TDA for this target root task.
2745         // If it exist, we need to reparent target root task from TDA to launch root task.
2746         final TaskDisplayArea tda = mTargetRootTask.getDisplayArea();
2747         final Task launchRootTask = tda.getLaunchRootTask(mTargetRootTask.getWindowingMode(),
2748                 mTargetRootTask.getActivityType(), null /** options */, mSourceRootTask,
2749                 mLaunchFlags);
2750         // If target root task is created by organizer, let organizer handle reparent itself.
2751         if (!mTargetRootTask.mCreatedByOrganizer && launchRootTask != null
2752                 && launchRootTask != mTargetRootTask) {
2753             mTargetRootTask.reparent(launchRootTask, POSITION_TOP);
2754             mTargetRootTask = launchRootTask;
2755         }
2756     }
2757 
resumeTargetRootTaskIfNeeded()2758     private void resumeTargetRootTaskIfNeeded() {
2759         if (mDoResume) {
2760             final ActivityRecord next = mTargetRootTask.topRunningActivity(
2761                     true /* focusableOnly */);
2762             if (next != null) {
2763                 next.setCurrentLaunchCanTurnScreenOn(true);
2764             }
2765             if (mTargetRootTask.isFocusable()) {
2766                 mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, null,
2767                         mOptions, mTransientLaunch);
2768             } else {
2769                 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2770             }
2771         } else {
2772             ActivityOptions.abort(mOptions);
2773         }
2774         mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
2775     }
2776 
setNewTask(Task taskToAffiliate)2777     private void setNewTask(Task taskToAffiliate) {
2778         final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
2779         final Task task = mTargetRootTask.reuseOrCreateTask(
2780                 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
2781                 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
2782                 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
2783         task.mTransitionController.collectExistenceChange(task);
2784         addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
2785 
2786         ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s",
2787                 mStartActivity, mStartActivity.getTask());
2788 
2789         if (taskToAffiliate != null) {
2790             mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
2791         }
2792     }
2793 
deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants)2794     private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) {
2795         if (mIntentDelivered) {
2796             return;
2797         }
2798 
2799         activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
2800         activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants,
2801                 mStartActivity.launchedFromPackage);
2802         mIntentDelivered = true;
2803     }
2804 
addOrReparentStartingActivity(@onNull Task task, String reason)2805     private void addOrReparentStartingActivity(@NonNull Task task, String reason) {
2806         TaskFragment newParent = task;
2807         if (mInTaskFragment != null) {
2808             // mInTaskFragment is created and added to the leaf task by task fragment organizer's
2809             // request. If the task was resolved and different than mInTaskFragment, reparent the
2810             // task to mInTaskFragment for embedding.
2811             if (mInTaskFragment.getTask() != task) {
2812                 if (shouldReparentInTaskFragment(task)) {
2813                     task.reparent(mInTaskFragment, POSITION_TOP);
2814                 }
2815             } else {
2816                 newParent = mInTaskFragment;
2817             }
2818         } else {
2819             final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */,
2820                     false /* includingEmbeddedTask */);
2821             final TaskFragment taskFragment = top != null ? top.getTaskFragment() : null;
2822             if (taskFragment != null && taskFragment.isEmbedded()
2823                     && canEmbedActivity(taskFragment, mStartActivity, false /* newTask */, task)) {
2824                 // Use the embedded TaskFragment of the top activity as the new parent if the
2825                 // activity can be embedded.
2826                 newParent = top.getTaskFragment();
2827             }
2828         }
2829 
2830         if (mStartActivity.getTaskFragment() == null
2831                 || mStartActivity.getTaskFragment() == newParent) {
2832             newParent.addChild(mStartActivity, POSITION_TOP);
2833         } else {
2834             mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason);
2835         }
2836     }
2837 
shouldReparentInTaskFragment(Task task)2838     private boolean shouldReparentInTaskFragment(Task task) {
2839         // The task has not been embedded. We should reparent the task to TaskFragment.
2840         if (!task.isEmbedded()) {
2841             return true;
2842         }
2843         WindowContainer<?> parent = task.getParent();
2844         // If the Activity is going to launch on top of embedded Task in the same TaskFragment,
2845         // we don't need to reparent the Task. Otherwise, the embedded Task should reparent to
2846         // another TaskFragment.
2847         return parent.asTaskFragment() != mInTaskFragment;
2848     }
2849 
adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, boolean launchSingleTask, int launchFlags)2850     private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2851             boolean launchSingleTask, int launchFlags) {
2852         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2853                 (launchSingleInstance || launchSingleTask)) {
2854             // We have a conflict between the Intent and the Activity manifest, manifest wins.
2855             Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2856                     "\"singleInstance\" or \"singleTask\"");
2857             launchFlags &=
2858                     ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2859         } else {
2860             switch (r.info.documentLaunchMode) {
2861                 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2862                     break;
2863                 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2864                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2865                     break;
2866                 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2867                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2868                     break;
2869                 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2870                     if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) {
2871                         // Remove MULTIPLE_TASK flag along with NEW_DOCUMENT only if NEW_DOCUMENT
2872                         // is set, otherwise we still want to keep the MULTIPLE_TASK flag (if
2873                         // any) for singleInstancePerTask that the multiple tasks can be created,
2874                         // or a singleInstancePerTask activity is basically the same as a
2875                         // singleTask activity when documentLaunchMode set to never.
2876                         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
2877                             launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
2878                                     | FLAG_ACTIVITY_MULTIPLE_TASK);
2879                         }
2880                     } else {
2881                         // TODO(b/184903976): Should FLAG_ACTIVITY_MULTIPLE_TASK always be
2882                         // removed for document-never activity?
2883                         launchFlags &=
2884                                 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2885                     }
2886                     break;
2887             }
2888         }
2889         return launchFlags;
2890     }
2891 
getLaunchRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions)2892     private Task getLaunchRootTask(ActivityRecord r, int launchFlags, Task task,
2893             ActivityOptions aOptions) {
2894         // We are reusing a task, keep the root task!
2895         if (mReuseTask != null) {
2896             return mReuseTask.getRootTask();
2897         }
2898 
2899         final boolean onTop =
2900                 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
2901         return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop,
2902                 mLaunchParams, launchFlags, mRequest.realCallingPid, mRequest.realCallingUid);
2903     }
2904 
isLaunchModeOneOf(int mode1, int mode2)2905     private boolean isLaunchModeOneOf(int mode1, int mode2) {
2906         return mode1 == mLaunchMode || mode2 == mLaunchMode;
2907     }
2908 
isLaunchModeOneOf(int mode1, int mode2, int mode3)2909     private boolean isLaunchModeOneOf(int mode1, int mode2, int mode3) {
2910         return mode1 == mLaunchMode || mode2 == mLaunchMode || mode3 == mLaunchMode;
2911     }
2912 
isDocumentLaunchesIntoExisting(int flags)2913     static boolean isDocumentLaunchesIntoExisting(int flags) {
2914         return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2915                 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2916     }
2917 
setIntent(Intent intent)2918     ActivityStarter setIntent(Intent intent) {
2919         mRequest.intent = intent;
2920         return this;
2921     }
2922 
getIntent()2923     Intent getIntent() {
2924         return mRequest.intent;
2925     }
2926 
setIntentGrants(NeededUriGrants intentGrants)2927     ActivityStarter setIntentGrants(NeededUriGrants intentGrants) {
2928         mRequest.intentGrants = intentGrants;
2929         return this;
2930     }
2931 
setReason(String reason)2932     ActivityStarter setReason(String reason) {
2933         mRequest.reason = reason;
2934         return this;
2935     }
2936 
setCaller(IApplicationThread caller)2937     ActivityStarter setCaller(IApplicationThread caller) {
2938         mRequest.caller = caller;
2939         return this;
2940     }
2941 
setResolvedType(String type)2942     ActivityStarter setResolvedType(String type) {
2943         mRequest.resolvedType = type;
2944         return this;
2945     }
2946 
setActivityInfo(ActivityInfo info)2947     ActivityStarter setActivityInfo(ActivityInfo info) {
2948         mRequest.activityInfo = info;
2949         return this;
2950     }
2951 
setResolveInfo(ResolveInfo info)2952     ActivityStarter setResolveInfo(ResolveInfo info) {
2953         mRequest.resolveInfo = info;
2954         return this;
2955     }
2956 
setVoiceSession(IVoiceInteractionSession voiceSession)2957     ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2958         mRequest.voiceSession = voiceSession;
2959         return this;
2960     }
2961 
setVoiceInteractor(IVoiceInteractor voiceInteractor)2962     ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2963         mRequest.voiceInteractor = voiceInteractor;
2964         return this;
2965     }
2966 
setResultTo(IBinder resultTo)2967     ActivityStarter setResultTo(IBinder resultTo) {
2968         mRequest.resultTo = resultTo;
2969         return this;
2970     }
2971 
setResultWho(String resultWho)2972     ActivityStarter setResultWho(String resultWho) {
2973         mRequest.resultWho = resultWho;
2974         return this;
2975     }
2976 
setRequestCode(int requestCode)2977     ActivityStarter setRequestCode(int requestCode) {
2978         mRequest.requestCode = requestCode;
2979         return this;
2980     }
2981 
2982     /**
2983      * Sets the pid of the caller who originally started the activity.
2984      *
2985      * Normally, the pid/uid would be the calling pid from the binder call.
2986      * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered
2987      * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid,
2988      * which represents the entity who invoked pending intent via {@link PendingIntent#send}.
2989      */
setCallingPid(int pid)2990     ActivityStarter setCallingPid(int pid) {
2991         mRequest.callingPid = pid;
2992         return this;
2993     }
2994 
2995     /**
2996      * Sets the uid of the caller who originally started the activity.
2997      *
2998      * @see #setCallingPid
2999      */
setCallingUid(int uid)3000     ActivityStarter setCallingUid(int uid) {
3001         mRequest.callingUid = uid;
3002         return this;
3003     }
3004 
setCallingPackage(String callingPackage)3005     ActivityStarter setCallingPackage(String callingPackage) {
3006         mRequest.callingPackage = callingPackage;
3007         return this;
3008     }
3009 
setCallingFeatureId(String callingFeatureId)3010     ActivityStarter setCallingFeatureId(String callingFeatureId) {
3011         mRequest.callingFeatureId = callingFeatureId;
3012         return this;
3013     }
3014 
3015     /**
3016      * Sets the pid of the caller who requested to launch the activity.
3017      *
3018      * The pid/uid represents the caller who launches the activity in this request.
3019      * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}:
3020      * the pid/uid will be the caller who called {@link PendingIntent#send()}.
3021      *
3022      * @see #setCallingPid
3023      */
setRealCallingPid(int pid)3024     ActivityStarter setRealCallingPid(int pid) {
3025         mRequest.realCallingPid = pid;
3026         return this;
3027     }
3028 
3029     /**
3030      * Sets the uid of the caller who requested to launch the activity.
3031      *
3032      * @see #setRealCallingPid
3033      */
setRealCallingUid(int uid)3034     ActivityStarter setRealCallingUid(int uid) {
3035         mRequest.realCallingUid = uid;
3036         return this;
3037     }
3038 
setStartFlags(int startFlags)3039     ActivityStarter setStartFlags(int startFlags) {
3040         mRequest.startFlags = startFlags;
3041         return this;
3042     }
3043 
setActivityOptions(SafeActivityOptions options)3044     ActivityStarter setActivityOptions(SafeActivityOptions options) {
3045         mRequest.activityOptions = options;
3046         return this;
3047     }
3048 
setActivityOptions(Bundle bOptions)3049     ActivityStarter setActivityOptions(Bundle bOptions) {
3050         return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
3051     }
3052 
setIgnoreTargetSecurity(boolean ignoreTargetSecurity)3053     ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
3054         mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
3055         return this;
3056     }
3057 
setFilterCallingUid(int filterCallingUid)3058     ActivityStarter setFilterCallingUid(int filterCallingUid) {
3059         mRequest.filterCallingUid = filterCallingUid;
3060         return this;
3061     }
3062 
setComponentSpecified(boolean componentSpecified)3063     ActivityStarter setComponentSpecified(boolean componentSpecified) {
3064         mRequest.componentSpecified = componentSpecified;
3065         return this;
3066     }
3067 
setOutActivity(ActivityRecord[] outActivity)3068     ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
3069         mRequest.outActivity = outActivity;
3070         return this;
3071     }
3072 
setInTask(Task inTask)3073     ActivityStarter setInTask(Task inTask) {
3074         mRequest.inTask = inTask;
3075         return this;
3076     }
3077 
setInTaskFragment(TaskFragment taskFragment)3078     ActivityStarter setInTaskFragment(TaskFragment taskFragment) {
3079         mRequest.inTaskFragment = taskFragment;
3080         return this;
3081     }
3082 
setWaitResult(WaitResult result)3083     ActivityStarter setWaitResult(WaitResult result) {
3084         mRequest.waitResult = result;
3085         return this;
3086     }
3087 
setProfilerInfo(ProfilerInfo info)3088     ActivityStarter setProfilerInfo(ProfilerInfo info) {
3089         mRequest.profilerInfo = info;
3090         return this;
3091     }
3092 
setGlobalConfiguration(Configuration config)3093     ActivityStarter setGlobalConfiguration(Configuration config) {
3094         mRequest.globalConfig = config;
3095         return this;
3096     }
3097 
setUserId(int userId)3098     ActivityStarter setUserId(int userId) {
3099         mRequest.userId = userId;
3100         return this;
3101     }
3102 
setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup)3103     ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
3104         mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
3105         return this;
3106     }
3107 
setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent)3108     ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
3109         mRequest.originatingPendingIntent = originatingPendingIntent;
3110         return this;
3111     }
3112 
setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart)3113     ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
3114         mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
3115         return this;
3116     }
3117 
dump(PrintWriter pw, String prefix)3118     void dump(PrintWriter pw, String prefix) {
3119         prefix = prefix + "  ";
3120         pw.print(prefix);
3121         pw.print("mCurrentUser=");
3122         pw.println(mRootWindowContainer.mCurrentUser);
3123         pw.print(prefix);
3124         pw.print("mLastStartReason=");
3125         pw.println(mLastStartReason);
3126         pw.print(prefix);
3127         pw.print("mLastStartActivityTimeMs=");
3128         pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
3129         pw.print(prefix);
3130         pw.print("mLastStartActivityResult=");
3131         pw.println(mLastStartActivityResult);
3132         if (mLastStartActivityRecord != null) {
3133             pw.print(prefix);
3134             pw.println("mLastStartActivityRecord:");
3135             mLastStartActivityRecord.dump(pw, prefix + "  ", true /* dumpAll */);
3136         }
3137         if (mStartActivity != null) {
3138             pw.print(prefix);
3139             pw.println("mStartActivity:");
3140             mStartActivity.dump(pw, prefix + "  ", true /* dumpAll */);
3141         }
3142         if (mIntent != null) {
3143             pw.print(prefix);
3144             pw.print("mIntent=");
3145             pw.println(mIntent);
3146         }
3147         if (mOptions != null) {
3148             pw.print(prefix);
3149             pw.print("mOptions=");
3150             pw.println(mOptions);
3151         }
3152         pw.print(prefix);
3153         pw.print("mLaunchSingleTop=");
3154         pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
3155         pw.print(" mLaunchSingleInstance=");
3156         pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
3157         pw.print(" mLaunchSingleTask=");
3158         pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
3159         pw.print(prefix);
3160         pw.print("mLaunchFlags=0x");
3161         pw.print(Integer.toHexString(mLaunchFlags));
3162         pw.print(" mDoResume=");
3163         pw.print(mDoResume);
3164         pw.print(" mAddingToTask=");
3165         pw.println(mAddingToTask);
3166         pw.print(" mInTaskFragment=");
3167         pw.println(mInTaskFragment);
3168     }
3169 }
3170