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