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