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