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