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