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