• History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
  • current directory
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         mLastStartActivityRecord = null;
902 
903         final IApplicationThread caller = request.caller;
904         Intent intent = request.intent;
905         NeededUriGrants intentGrants = request.intentGrants;
906         String resolvedType = request.resolvedType;
907         ActivityInfo aInfo = request.activityInfo;
908         ResolveInfo rInfo = request.resolveInfo;
909         final IVoiceInteractionSession voiceSession = request.voiceSession;
910         final IBinder resultTo = request.resultTo;
911         String resultWho = request.resultWho;
912         int requestCode = request.requestCode;
913         int callingPid = request.callingPid;
914         int callingUid = request.callingUid;
915         String callingPackage = request.callingPackage;
916         String callingFeatureId = request.callingFeatureId;
917         final int realCallingPid = request.realCallingPid;
918         final int realCallingUid = request.realCallingUid;
919         final int startFlags = request.startFlags;
920         final SafeActivityOptions options = request.activityOptions;
921         Task inTask = request.inTask;
922         TaskFragment inTaskFragment = request.inTaskFragment;
923 
924         int err = ActivityManager.START_SUCCESS;
925         // Pull the optional Ephemeral Installer-only bundle out of the options early.
926         final Bundle verificationBundle =
927                 options != null ? options.popAppVerificationBundle() : null;
928 
929         WindowProcessController callerApp = null;
930         if (caller != null) {
931             callerApp = mService.getProcessController(caller);
932             if (callerApp != null) {
933                 callingPid = callerApp.getPid();
934                 callingUid = callerApp.mInfo.uid;
935             } else {
936                 Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
937                         + ") when starting: " + intent.toString());
938                 err = START_PERMISSION_DENIED;
939             }
940         }
941 
942         final int userId = aInfo != null && aInfo.applicationInfo != null
943                 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
944         final int launchMode = aInfo != null ? aInfo.launchMode : 0;
945         if (err == ActivityManager.START_SUCCESS) {
946             request.logMessage.append("START u").append(userId).append(" {")
947                     .append(intent.toShortString(true, true, true, false))
948                     .append("} with ").append(launchModeToString(launchMode))
949                     .append(" from uid ").append(callingUid);
950             if (callingUid != realCallingUid
951                     && realCallingUid != Request.DEFAULT_REAL_CALLING_UID) {
952                 request.logMessage.append(" (realCallingUid=").append(realCallingUid).append(")");
953             }
954         }
955 
956         ActivityRecord sourceRecord = null;
957         ActivityRecord resultRecord = null;
958         if (resultTo != null) {
959             sourceRecord = ActivityRecord.isInAnyTask(resultTo);
960             if (DEBUG_RESULTS) {
961                 Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
962             }
963             if (sourceRecord != null) {
964                 if (requestCode >= 0 && !sourceRecord.finishing) {
965                     resultRecord = sourceRecord;
966                 }
967             }
968         }
969 
970         final int launchFlags = intent.getFlags();
971         if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
972             // Transfer the result target from the source activity to the new one being started,
973             // including any failures.
974             if (requestCode >= 0) {
975                 SafeActivityOptions.abort(options);
976                 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
977             }
978             resultRecord = sourceRecord.resultTo;
979             if (resultRecord != null && !resultRecord.isInRootTaskLocked()) {
980                 resultRecord = null;
981             }
982             resultWho = sourceRecord.resultWho;
983             requestCode = sourceRecord.requestCode;
984             sourceRecord.resultTo = null;
985             if (resultRecord != null) {
986                 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
987             }
988             if (sourceRecord.launchedFromUid == callingUid) {
989                 // The new activity is being launched from the same uid as the previous activity
990                 // in the flow, and asking to forward its result back to the previous.  In this
991                 // case the activity is serving as a trampoline between the two, so we also want
992                 // to update its launchedFromPackage to be the same as the previous activity.
993                 // Note that this is safe, since we know these two packages come from the same
994                 // uid; the caller could just as well have supplied that same package name itself
995                 // . This specifially deals with the case of an intent picker/chooser being
996                 // launched in the app flow to redirect to an activity picked by the user, where
997                 // we want the final activity to consider it to have been launched by the
998                 // previous app activity.
999                 callingPackage = sourceRecord.launchedFromPackage;
1000                 callingFeatureId = sourceRecord.launchedFromFeatureId;
1001             }
1002         }
1003 
1004         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1005             // We couldn't find a class that can handle the given Intent.
1006             // That's the end of that!
1007             err = ActivityManager.START_INTENT_NOT_RESOLVED;
1008         }
1009 
1010         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1011             // We couldn't find the specific class specified in the Intent.
1012             // Also the end of the line.
1013             err = ActivityManager.START_CLASS_NOT_FOUND;
1014         }
1015 
1016         if (err == ActivityManager.START_SUCCESS && sourceRecord != null
1017                 && sourceRecord.getTask().voiceSession != null) {
1018             // If this activity is being launched as part of a voice session, we need to ensure
1019             // that it is safe to do so.  If the upcoming activity will also be part of the voice
1020             // session, we can only launch it if it has explicitly said it supports the VOICE
1021             // category, or it is a part of the calling app.
1022             if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
1023                     && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
1024                 try {
1025                     intent.addCategory(Intent.CATEGORY_VOICE);
1026                     if (!mService.getPackageManager().activitySupportsIntentAsUser(
1027                             intent.getComponent(), intent, resolvedType, userId)) {
1028                         Slog.w(TAG, "Activity being started in current voice task does not support "
1029                                 + "voice: " + intent);
1030                         err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1031                     }
1032                 } catch (RemoteException e) {
1033                     Slog.w(TAG, "Failure checking voice capabilities", e);
1034                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1035                 }
1036             }
1037         }
1038 
1039         if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
1040             // If the caller is starting a new voice session, just make sure the target
1041             // is actually allowing it to run this way.
1042             try {
1043                 if (!mService.getPackageManager().activitySupportsIntentAsUser(
1044                         intent.getComponent(), intent, resolvedType, userId)) {
1045                     Slog.w(TAG,
1046                             "Activity being started in new voice task does not support: " + intent);
1047                     err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1048                 }
1049             } catch (RemoteException e) {
1050                 Slog.w(TAG, "Failure checking voice capabilities", e);
1051                 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1052             }
1053         }
1054 
1055         final Task resultRootTask = resultRecord == null
1056                 ? null : resultRecord.getRootTask();
1057 
1058         if (err != START_SUCCESS) {
1059             if (resultRecord != null) {
1060                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1061                         null /* data */, null /* dataGrants */);
1062             }
1063             SafeActivityOptions.abort(options);
1064             return err;
1065         }
1066 
1067         boolean abort;
1068         try {
1069             abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
1070                     requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
1071                     request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
1072                     resultRootTask);
1073         } catch (SecurityException e) {
1074             // Return activity not found for the explicit intent if the caller can't see the target
1075             // to prevent the disclosure of package existence.
1076             final Intent originalIntent = request.ephemeralIntent;
1077             if (originalIntent != null && (originalIntent.getComponent() != null
1078                     || originalIntent.getPackage() != null)) {
1079                 final String targetPackageName = originalIntent.getComponent() != null
1080                         ? originalIntent.getComponent().getPackageName()
1081                         : originalIntent.getPackage();
1082                 if (mService.getPackageManagerInternalLocked()
1083                         .filterAppAccess(targetPackageName, callingUid, userId)) {
1084                     if (resultRecord != null) {
1085                         resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
1086                                 RESULT_CANCELED, null /* data */, null /* dataGrants */);
1087                     }
1088                     SafeActivityOptions.abort(options);
1089                     return ActivityManager.START_CLASS_NOT_FOUND;
1090                 }
1091             }
1092             throw e;
1093         }
1094         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1095                 callingPid, resolvedType, aInfo.applicationInfo);
1096         abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
1097                 callingPackage);
1098 
1099         // Merge the two options bundles, while realCallerOptions takes precedence.
1100         ActivityOptions checkedOptions = options != null
1101                 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
1102 
1103         @BalCode int balCode = BAL_ALLOW_DEFAULT;
1104         if (!abort) {
1105             try {
1106                 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
1107                         "shouldAbortBackgroundActivityStart");
1108                 BackgroundActivityStartController balController =
1109                         mController.getBackgroundActivityLaunchController();
1110                 balCode =
1111                         balController.checkBackgroundActivityStart(
1112                                 callingUid,
1113                                 callingPid,
1114                                 callingPackage,
1115                                 realCallingUid,
1116                                 realCallingPid,
1117                                 callerApp,
1118                                 request.originatingPendingIntent,
1119                                 request.backgroundStartPrivileges,
1120                                 intent,
1121                                 checkedOptions);
1122                 if (balCode != BAL_ALLOW_DEFAULT) {
1123                     request.logMessage.append(" (").append(
1124                                     BackgroundActivityStartController.balCodeToString(balCode))
1125                             .append(")");
1126                 }
1127             } finally {
1128                 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1129             }
1130         }
1131 
1132         if (request.allowPendingRemoteAnimationRegistryLookup) {
1133             checkedOptions = mService.getActivityStartController()
1134                     .getPendingRemoteAnimationRegistry()
1135                     .overrideOptionsIfNeeded(callingPackage, checkedOptions);
1136         }
1137         if (mService.mController != null) {
1138             try {
1139                 // The Intent we give to the watcher has the extra data stripped off, since it
1140                 // can contain private information.
1141                 Intent watchIntent = intent.cloneFilter();
1142                 abort |= !mService.mController.activityStarting(watchIntent,
1143                         aInfo.applicationInfo.packageName);
1144             } catch (RemoteException e) {
1145                 mService.mController = null;
1146             }
1147         }
1148 
1149         mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
1150                 callingFeatureId);
1151         if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
1152                 callingPid, callingUid, checkedOptions)) {
1153             // activity start was intercepted, e.g. because the target user is currently in quiet
1154             // mode (turn off work) or the target application is suspended
1155             intent = mInterceptor.mIntent;
1156             rInfo = mInterceptor.mRInfo;
1157             aInfo = mInterceptor.mAInfo;
1158             resolvedType = mInterceptor.mResolvedType;
1159             inTask = mInterceptor.mInTask;
1160             callingPid = mInterceptor.mCallingPid;
1161             callingUid = mInterceptor.mCallingUid;
1162             checkedOptions = mInterceptor.mActivityOptions;
1163 
1164             // The interception target shouldn't get any permission grants
1165             // intended for the original destination
1166             intentGrants = null;
1167         }
1168 
1169         if (abort) {
1170             if (resultRecord != null) {
1171                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1172                         null /* data */, null /* dataGrants */);
1173             }
1174             // We pretend to the caller that it was really started, but they will just get a
1175             // cancel result.
1176             ActivityOptions.abort(checkedOptions);
1177             return START_ABORTED;
1178         }
1179 
1180         // If permissions need a review before any of the app components can run, we
1181         // launch the review activity and pass a pending intent to start the activity
1182         // we are to launching now after the review is completed.
1183         if (aInfo != null) {
1184             if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
1185                     aInfo.packageName, userId)) {
1186                 final IIntentSender target = mService.getIntentSenderLocked(
1187                         ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
1188                         callingUid, userId, null, null, 0, new Intent[]{intent},
1189                         new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
1190                                 | PendingIntent.FLAG_ONE_SHOT, null);
1191 
1192                 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
1193 
1194                 int flags = intent.getFlags();
1195                 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
1196 
1197                 /*
1198                  * Prevent reuse of review activity: Each app needs their own review activity. By
1199                  * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
1200                  * with the same launch parameters (extras are ignored). Hence to avoid possible
1201                  * reuse force a new activity via the MULTIPLE_TASK flag.
1202                  *
1203                  * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
1204                  * hence no need to add the flag in this case.
1205                  */
1206                 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
1207                     flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1208                 }
1209                 newIntent.setFlags(flags);
1210 
1211                 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
1212                 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
1213                 if (resultRecord != null) {
1214                     newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
1215                 }
1216                 intent = newIntent;
1217 
1218                 // The permissions review target shouldn't get any permission
1219                 // grants intended for the original destination
1220                 intentGrants = null;
1221 
1222                 resolvedType = null;
1223                 callingUid = realCallingUid;
1224                 callingPid = realCallingPid;
1225 
1226                 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
1227                         computeResolveFilterUid(
1228                                 callingUid, realCallingUid, request.filterCallingUid),
1229                         realCallingPid);
1230                 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
1231                         null /*profilerInfo*/);
1232 
1233                 if (DEBUG_PERMISSIONS_REVIEW) {
1234                     final Task focusedRootTask =
1235                             mRootWindowContainer.getTopDisplayFocusedRootTask();
1236                     Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
1237                             true, false) + "} from uid " + callingUid + " on display "
1238                             + (focusedRootTask == null ? DEFAULT_DISPLAY
1239                                     : focusedRootTask.getDisplayId()));
1240                 }
1241             }
1242         }
1243 
1244         // If we have an ephemeral app, abort the process of launching the resolved intent.
1245         // Instead, launch the ephemeral installer. Once the installer is finished, it
1246         // starts either the intent we resolved here [on install error] or the ephemeral
1247         // app [on install success].
1248         if (rInfo != null && rInfo.auxiliaryInfo != null) {
1249             intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
1250                     callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
1251             resolvedType = null;
1252             callingUid = realCallingUid;
1253             callingPid = realCallingPid;
1254 
1255             // The ephemeral installer shouldn't get any permission grants
1256             // intended for the original destination
1257             intentGrants = null;
1258 
1259             aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
1260         }
1261         // TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
1262         // Pending intent launched from systemui also depends on caller app
1263         if (callerApp == null && realCallingPid > 0) {
1264             final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
1265             if (wpc != null) {
1266                 callerApp = wpc;
1267             }
1268         }
1269         final ActivityRecord r = new ActivityRecord.Builder(mService)
1270                 .setCaller(callerApp)
1271                 .setLaunchedFromPid(callingPid)
1272                 .setLaunchedFromUid(callingUid)
1273                 .setLaunchedFromPackage(callingPackage)
1274                 .setLaunchedFromFeature(callingFeatureId)
1275                 .setIntent(intent)
1276                 .setResolvedType(resolvedType)
1277                 .setActivityInfo(aInfo)
1278                 .setConfiguration(mService.getGlobalConfiguration())
1279                 .setResultTo(resultRecord)
1280                 .setResultWho(resultWho)
1281                 .setRequestCode(requestCode)
1282                 .setComponentSpecified(request.componentSpecified)
1283                 .setRootVoiceInteraction(voiceSession != null)
1284                 .setActivityOptions(checkedOptions)
1285                 .setSourceRecord(sourceRecord)
1286                 .build();
1287 
1288         mLastStartActivityRecord = r;
1289 
1290         if (r.appTimeTracker == null && sourceRecord != null) {
1291             // If the caller didn't specify an explicit time tracker, we want to continue
1292             // tracking under any it has.
1293             r.appTimeTracker = sourceRecord.appTimeTracker;
1294         }
1295 
1296         // Only allow app switching to be resumed if activity is not a restricted background
1297         // activity and target app is not home process, otherwise any background activity
1298         // started in background task can stop home button protection mode.
1299         // As the targeted app is not a home process and we don't need to wait for the 2nd
1300         // activity to be started to resume app switching, we can just enable app switching
1301         // directly.
1302         WindowProcessController homeProcess = mService.mHomeProcess;
1303         boolean isHomeProcess = homeProcess != null
1304                 && aInfo.applicationInfo.uid == homeProcess.mUid;
1305         if (balCode != BAL_BLOCK && !isHomeProcess) {
1306             mService.resumeAppSwitches();
1307         }
1308 
1309         mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1310                 request.voiceInteractor, startFlags, checkedOptions,
1311                 inTask, inTaskFragment, balCode, intentGrants, realCallingUid);
1312 
1313         if (request.outActivity != null) {
1314             request.outActivity[0] = mLastStartActivityRecord;
1315         }
1316 
1317         return mLastStartActivityResult;
1318     }
1319 
1320     /**
1321      * Return true if background activity is really aborted.
1322      *
1323      * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1324      */
handleBackgroundActivityAbort(ActivityRecord r)1325     private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1326         // TODO(b/131747138): Remove toast and refactor related code in R release.
1327         final boolean abort = !mService.isBackgroundActivityStartsEnabled();
1328         if (!abort) {
1329             return false;
1330         }
1331         final ActivityRecord resultRecord = r.resultTo;
1332         final String resultWho = r.resultWho;
1333         int requestCode = r.requestCode;
1334         if (resultRecord != null) {
1335             resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
1336                     null /* data */, null /* dataGrants */);
1337         }
1338         // We pretend to the caller that it was really started to make it backward compatible, but
1339         // they will just get a cancel result.
1340         ActivityOptions.abort(r.getOptions());
1341         return true;
1342     }
1343 
getExternalResult(int result)1344     static int getExternalResult(int result) {
1345         // Aborted results are treated as successes externally, but we must track them internally.
1346         return result != START_ABORTED ? result : START_SUCCESS;
1347     }
1348 
1349     /**
1350      * Called when execution is complete. Sets state indicating completion and proceeds with
1351      * recycling if appropriate.
1352      */
onExecutionComplete()1353     private void onExecutionComplete() {
1354         mController.onExecutionComplete(this);
1355     }
1356 
onExecutionStarted()1357     private void onExecutionStarted() {
1358         mController.onExecutionStarted();
1359     }
1360 
1361     /**
1362      * Creates a launch intent for the given auxiliary resolution data.
1363      */
createLaunchIntent(@ullable AuxiliaryResolveInfo auxiliaryResponse, Intent originalIntent, String callingPackage, @Nullable String callingFeatureId, Bundle verificationBundle, String resolvedType, int userId)1364     private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
1365             Intent originalIntent, String callingPackage, @Nullable String callingFeatureId,
1366             Bundle verificationBundle, String resolvedType, int userId) {
1367         if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
1368             // request phase two resolution
1369             PackageManagerInternal packageManager = mService.getPackageManagerInternalLocked();
1370             boolean isRequesterInstantApp = packageManager.isInstantApp(callingPackage, userId);
1371             packageManager.requestInstantAppResolutionPhaseTwo(
1372                     auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1373                     callingFeatureId, isRequesterInstantApp, verificationBundle, userId);
1374         }
1375         return InstantAppResolver.buildEphemeralInstallerIntent(
1376                 originalIntent,
1377                 InstantAppResolver.sanitizeIntent(originalIntent),
1378                 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1379                 callingPackage,
1380                 callingFeatureId,
1381                 verificationBundle,
1382                 resolvedType,
1383                 userId,
1384                 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1385                 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1386                 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1387                 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
1388     }
1389 
postStartActivityProcessing(ActivityRecord r, int result, Task startedActivityRootTask)1390     void postStartActivityProcessing(ActivityRecord r, int result,
1391             Task startedActivityRootTask) {
1392         if (!ActivityManager.isStartResultSuccessful(result)) {
1393             if (mFrozeTaskList) {
1394                 // If we specifically froze the task list as part of starting an activity, then
1395                 // reset the frozen list state if it failed to start. This is normally otherwise
1396                 // called when the freeze-timeout has elapsed.
1397                 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
1398             }
1399         }
1400         if (ActivityManager.isStartResultFatalError(result)) {
1401             return;
1402         }
1403 
1404         // We're waiting for an activity launch to finish, but that activity simply
1405         // brought another activity to front. We must also handle the case where the task is already
1406         // in the front as a result of the trampoline activity being in the same task (it will be
1407         // considered focused as the trampoline will be finished). Let them know about this, so
1408         // it waits for the new activity to become visible instead, {@link #waitResultIfNeeded}.
1409         mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
1410 
1411         final Task targetTask = r.getTask() != null
1412                 ? r.getTask()
1413                 : mTargetTask;
1414         if (startedActivityRootTask == null || targetTask == null || !targetTask.isAttached()) {
1415             return;
1416         }
1417 
1418         if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP) {
1419             // The activity was already running so it wasn't started, but either brought to the
1420             // front or the new intent was delivered to it since it was already in front. Notify
1421             // anyone interested in this piece of information.
1422             final Task rootHomeTask = targetTask.getDisplayArea().getRootHomeTask();
1423             final boolean homeTaskVisible = rootHomeTask != null
1424                     && rootHomeTask.shouldBeVisible(null);
1425             final ActivityRecord top = targetTask.getTopNonFinishingActivity();
1426             final boolean visible = top != null && top.isVisible();
1427             mService.getTaskChangeNotificationController().notifyActivityRestartAttempt(
1428                     targetTask.getTaskInfo(), homeTaskVisible, mIsTaskCleared, visible);
1429         }
1430 
1431         if (ActivityManager.isStartResultSuccessful(result)) {
1432             mInterceptor.onActivityLaunched(targetTask.getTaskInfo(), r);
1433         }
1434     }
1435 
1436     /**
1437      * Compute the logical UID based on which the package manager would filter
1438      * app components i.e. based on which the instant app policy would be applied
1439      * because it is the logical calling UID.
1440      *
1441      * @param customCallingUid The UID on whose behalf to make the call.
1442      * @param actualCallingUid The UID actually making the call.
1443      * @param filterCallingUid The UID to be used to filter for instant apps.
1444      * @return The logical UID making the call.
1445      */
computeResolveFilterUid(int customCallingUid, int actualCallingUid, int filterCallingUid)1446     static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1447             int filterCallingUid) {
1448         return filterCallingUid != UserHandle.USER_NULL
1449                 ? filterCallingUid
1450                 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
1451     }
1452 
1453     /**
1454      * Start an activity while most of preliminary checks has been done and caller has been
1455      * confirmed that holds necessary permissions to do so.
1456      * Here also ensures that the starting activity is removed if the start wasn't successful.
1457      */
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)1458     private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1459             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1460             int startFlags, ActivityOptions options, Task inTask,
1461             TaskFragment inTaskFragment, @BalCode int balCode,
1462             NeededUriGrants intentGrants, int realCallingUid) {
1463         int result = START_CANCELED;
1464         final Task startedActivityRootTask;
1465 
1466         // Create a transition now to record the original intent of actions taken within
1467         // startActivityInner. Otherwise, logic in startActivityInner could start a different
1468         // transition based on a sub-action.
1469         // Only do the create here (and defer requestStart) since startActivityInner might abort.
1470         final TransitionController transitionController = r.mTransitionController;
1471         Transition newTransition = transitionController.isShellTransitionsEnabled()
1472                 ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
1473         RemoteTransition remoteTransition = r.takeRemoteTransition();
1474         try {
1475             mService.deferWindowLayout();
1476             transitionController.collect(r);
1477             try {
1478                 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
1479                 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
1480                         startFlags, options, inTask, inTaskFragment, balCode,
1481                         intentGrants, realCallingUid);
1482             } finally {
1483                 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1484                 startedActivityRootTask = handleStartResult(r, options, result, newTransition,
1485                         remoteTransition);
1486             }
1487         } finally {
1488             mService.continueWindowLayout();
1489         }
1490         postStartActivityProcessing(r, result, startedActivityRootTask);
1491 
1492         return result;
1493     }
1494 
1495     /**
1496      * If the start result is success, ensure that the configuration of the started activity matches
1497      * the current display. Otherwise clean up unassociated containers to avoid leakage.
1498      *
1499      * @return the root task where the successful started activity resides.
1500      */
handleStartResult(@onNull ActivityRecord started, ActivityOptions options, int result, Transition newTransition, RemoteTransition remoteTransition)1501     private @Nullable Task handleStartResult(@NonNull ActivityRecord started,
1502             ActivityOptions options, int result, Transition newTransition,
1503             RemoteTransition remoteTransition) {
1504         final boolean userLeaving = mSupervisor.mUserLeaving;
1505         mSupervisor.mUserLeaving = false;
1506         final Task currentRootTask = started.getRootTask();
1507         final Task startedActivityRootTask =
1508                 currentRootTask != null ? currentRootTask : mTargetRootTask;
1509 
1510         if (!ActivityManager.isStartResultSuccessful(result) || startedActivityRootTask == null) {
1511             // If we are not able to proceed, disassociate the activity from the task. Leaving an
1512             // activity in an incomplete state can lead to issues, such as performing operations
1513             // without a window container.
1514             if (mStartActivity.getTask() != null) {
1515                 mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
1516             } else if (mStartActivity.getParent() != null) {
1517                 mStartActivity.getParent().removeChild(mStartActivity);
1518             }
1519 
1520             // Root task should also be detached from display and be removed if it's empty.
1521             if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
1522                     && !startedActivityRootTask.hasActivity()
1523                     && !startedActivityRootTask.isActivityTypeHome()
1524                     && !startedActivityRootTask.mCreatedByOrganizer) {
1525                 startedActivityRootTask.removeIfPossible("handleStartResult");
1526             }
1527             if (newTransition != null) {
1528                 newTransition.abort();
1529             }
1530             return null;
1531         }
1532 
1533         // Apply setAlwaysOnTop when starting an activity is successful regardless of creating
1534         // a new Activity or reusing the existing activity.
1535         if (options != null && options.getTaskAlwaysOnTop()) {
1536             startedActivityRootTask.setAlwaysOnTop(true);
1537         }
1538 
1539         // If there is no state change (e.g. a resumed activity is reparented to top of
1540         // another display) to trigger a visibility/configuration checking, we have to
1541         // update the configuration for changing to different display.
1542         final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity();
1543         if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
1544             mRootWindowContainer.ensureVisibilityAndConfig(
1545                     currentTop, currentTop.getDisplayId(),
1546                     true /* markFrozenIfConfigChanged */, false /* deferResume */);
1547         }
1548 
1549         if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer
1550                 .hasVisibleWindowAboveButDoesNotOwnNotificationShade(started.launchedFromUid)) {
1551             // If the UID launching the activity has a visible window on top of the notification
1552             // shade and it's launching an activity that's going to be at the front, we should move
1553             // the shade out of the way so the user can see it. We want to avoid the case where the
1554             // activity is launched on top of a background task which is not moved to the front.
1555             final StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
1556             if (statusBar != null) {
1557                 // This results in a async call since the interface is one-way.
1558                 statusBar.collapsePanels();
1559             }
1560         }
1561 
1562         // Transition housekeeping.
1563         final TransitionController transitionController = started.mTransitionController;
1564         final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT;
1565         final boolean isTransientLaunch = options != null && options.getTransientLaunch();
1566         // Start transient launch while keyguard locked and occluded by other app, for this
1567         // condition we would like to play the remote transition without modify any visible state
1568         // for the hierarchy in core, so here will force execute this transition.
1569         final boolean forceTransientTransition = isTransientLaunch && mPriorAboveTask != null
1570                 && mDisplayLockAndOccluded;
1571         if (isStarted) {
1572             // The activity is started new rather than just brought forward, so record it as an
1573             // existence change.
1574             transitionController.collectExistenceChange(started);
1575         } else if (result == START_DELIVERED_TO_TOP && newTransition != null
1576                 // An activity has changed order/visibility or the task is occluded by a transient
1577                 // activity, so this isn't just deliver-to-top
1578                 && mMovedToTopActivity == null
1579                 && !transitionController.isTransientHide(startedActivityRootTask)) {
1580             // We just delivered to top, so there isn't an actual transition here.
1581             if (!forceTransientTransition) {
1582                 newTransition.abort();
1583                 newTransition = null;
1584             }
1585         }
1586         if (isTransientLaunch) {
1587             if (forceTransientTransition) {
1588                 transitionController.collect(mLastStartActivityRecord);
1589                 transitionController.collect(mPriorAboveTask);
1590             }
1591             // `started` isn't guaranteed to be the actual relevant activity, so we must wait
1592             // until after we launched to identify the relevant activity.
1593             transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
1594             if (forceTransientTransition) {
1595                 final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
1596                 // update wallpaper target to TransientHide
1597                 dc.mWallpaperController.adjustWallpaperWindows();
1598                 // execute transition because there is no change
1599                 transitionController.setReady(dc, true /* ready */);
1600             }
1601         }
1602         if (!userLeaving) {
1603             // no-user-leaving implies not entering PiP.
1604             transitionController.setCanPipOnFinish(false /* canPipOnFinish */);
1605         }
1606         if (newTransition != null) {
1607             transitionController.requestStartTransition(newTransition,
1608                     mTargetTask == null ? started.getTask() : mTargetTask,
1609                     remoteTransition, null /* displayChange */);
1610         } else if (result == START_SUCCESS && mStartActivity.isState(RESUMED)) {
1611             // Do nothing if the activity is started and is resumed directly.
1612         } else if (isStarted) {
1613             // Make the collecting transition wait until this request is ready.
1614             transitionController.setReady(started, false);
1615         }
1616         return startedActivityRootTask;
1617     }
1618 
1619     /**
1620      * Start an activity and determine if the activity should be adding to the top of an existing
1621      * task or delivered new intent to an existing activity. Also manipulating the activity task
1622      * onto requested or valid root-task/display.
1623      *
1624      * Note: This method should only be called from {@link #startActivityUnchecked}.
1625      */
1626     // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
1627     @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)1628     int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
1629             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1630             int startFlags, ActivityOptions options, Task inTask,
1631             TaskFragment inTaskFragment, @BalCode int balCode,
1632             NeededUriGrants intentGrants, int realCallingUid) {
1633         setInitialState(r, options, inTask, inTaskFragment, startFlags, sourceRecord,
1634                 voiceSession, voiceInteractor, balCode, realCallingUid);
1635 
1636         computeLaunchingTaskFlags();
1637         mIntent.setFlags(mLaunchFlags);
1638 
1639         boolean dreamStopping = false;
1640 
1641         for (ActivityRecord stoppingActivity : mSupervisor.mStoppingActivities) {
1642             if (stoppingActivity.getActivityType()
1643                     == WindowConfiguration.ACTIVITY_TYPE_DREAM) {
1644                 dreamStopping = true;
1645                 break;
1646             }
1647         }
1648 
1649         // Get top task at beginning because the order may be changed when reusing existing task.
1650         final Task prevTopRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
1651         final Task prevTopTask = prevTopRootTask != null ? prevTopRootTask.getTopLeafTask() : null;
1652         final Task reusedTask = getReusableTask();
1653 
1654         // If requested, freeze the task list
1655         if (mOptions != null && mOptions.freezeRecentTasksReordering()
1656                 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
1657                 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
1658             mFrozeTaskList = true;
1659             mSupervisor.mRecentTasks.setFreezeTaskListReordering();
1660         }
1661 
1662         // Compute if there is an existing task that should be used for.
1663         final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
1664         final boolean newTask = targetTask == null;
1665         mTargetTask = targetTask;
1666 
1667         computeLaunchParams(r, sourceRecord, targetTask);
1668 
1669         // Check if starting activity on given task or on a new task is allowed.
1670         int startResult = isAllowedToStart(r, newTask, targetTask);
1671         if (startResult != START_SUCCESS) {
1672             if (r.resultTo != null) {
1673                 r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED,
1674                         null /* data */, null /* dataGrants */);
1675             }
1676             return startResult;
1677         }
1678 
1679         if (targetTask != null) {
1680             if (targetTask.getTreeWeight() > MAX_TASK_WEIGHT_FOR_ADDING_ACTIVITY) {
1681                 Slog.e(TAG, "Remove " + targetTask + " because it has contained too many"
1682                         + " activities or windows (abort starting " + r
1683                         + " from uid=" + mCallingUid);
1684                 targetTask.removeImmediately("bulky-task");
1685                 return START_ABORTED;
1686             }
1687             // When running transient transition, the transient launch target should keep on top.
1688             // So disallow the transient hide activity to move itself to front, e.g. trampoline.
1689             if (!mAvoidMoveToFront && r.mTransitionController.isTransientHide(targetTask)) {
1690                 mAvoidMoveToFront = true;
1691             }
1692             mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask());
1693         }
1694 
1695         final ActivityRecord targetTaskTop = newTask
1696                 ? null : targetTask.getTopNonFinishingActivity();
1697         if (targetTaskTop != null) {
1698             // Removes the existing singleInstance activity in another task (if any) while
1699             // launching a singleInstance activity on sourceRecord's task.
1700             if (LAUNCH_SINGLE_INSTANCE == mLaunchMode && mSourceRecord != null
1701                     && targetTask == mSourceRecord.getTask()) {
1702                 final ActivityRecord activity = mRootWindowContainer.findActivity(mIntent,
1703                         mStartActivity.info, false);
1704                 if (activity != null && activity.getTask() != targetTask) {
1705                     activity.destroyIfPossible("Removes redundant singleInstance");
1706                 }
1707             }
1708             // Recycle the target task for this launch.
1709             startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
1710             if (startResult != START_SUCCESS) {
1711                 return startResult;
1712             }
1713         } else {
1714             mAddingToTask = true;
1715         }
1716 
1717         // If the activity being launched is the same as the one currently at the top, then
1718         // we need to check if it should only be launched once.
1719         final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
1720         if (topRootTask != null) {
1721             startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
1722             if (startResult != START_SUCCESS) {
1723                 return startResult;
1724             }
1725         }
1726 
1727         if (mTargetRootTask == null) {
1728             mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
1729                     mOptions);
1730         }
1731         if (newTask) {
1732             final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1733                     ? mSourceRecord.getTask() : null;
1734             setNewTask(taskToAffiliate);
1735         } else if (mAddingToTask) {
1736             addOrReparentStartingActivity(targetTask, "adding to task");
1737         }
1738 
1739         if (!mAvoidMoveToFront && mDoResume) {
1740             mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
1741             if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
1742                     && !dreamStopping) {
1743                 // Launching underneath dream activity (fullscreen, always-on-top). Run the launch-
1744                 // -behind transition so the Activity gets created and starts in visible state.
1745                 mLaunchTaskBehind = true;
1746                 r.mLaunchTaskBehind = true;
1747             }
1748         }
1749 
1750         mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
1751                 mStartActivity.getUriPermissionsLocked());
1752         if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
1753             // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
1754             final PackageManagerInternal pmInternal =
1755                     mService.getPackageManagerInternalLocked();
1756             final int resultToUid = pmInternal.getPackageUid(
1757                     mStartActivity.resultTo.info.packageName, 0 /* flags */,
1758                     mStartActivity.mUserId);
1759             pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
1760                     UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
1761                     resultToUid /*visible*/, true /*direct*/);
1762         } else if (mStartActivity.mShareIdentity) {
1763             final PackageManagerInternal pmInternal =
1764                     mService.getPackageManagerInternalLocked();
1765             pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
1766                     UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
1767                     r.launchedFromUid /*visible*/, true /*direct*/);
1768         }
1769         final Task startedTask = mStartActivity.getTask();
1770         if (newTask) {
1771             EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId,
1772                     startedTask.getRootTaskId(), startedTask.getDisplayId());
1773         }
1774         mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);
1775 
1776         mStartActivity.getTaskFragment().clearLastPausedActivity();
1777 
1778         mRootWindowContainer.startPowerModeLaunchIfNeeded(
1779                 false /* forceSend */, mStartActivity);
1780 
1781         final boolean isTaskSwitch = startedTask != prevTopTask;
1782         mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
1783                 mOptions, sourceRecord);
1784         if (mDoResume) {
1785             final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
1786             if (!mTargetRootTask.isTopActivityFocusable()
1787                     || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
1788                     && mStartActivity != topTaskActivity)) {
1789                 // If the activity is not focusable, we can't resume it, but still would like to
1790                 // make sure it becomes visible as it starts (this will also trigger entry
1791                 // animation). An example of this are PIP activities.
1792                 // Also, we don't want to resume activities in a task that currently has an overlay
1793                 // as the starting activity just needs to be in the visible paused state until the
1794                 // over is removed.
1795                 // Passing {@code null} as the start parameter ensures all activities are made
1796                 // visible.
1797                 mTargetRootTask.ensureActivitiesVisible(null /* starting */,
1798                         0 /* configChanges */, !PRESERVE_WINDOWS);
1799                 // Go ahead and tell window manager to execute app transition for this activity
1800                 // since the app transition will not be triggered through the resume channel.
1801                 mTargetRootTask.mDisplayContent.executeAppTransition();
1802             } else {
1803                 // If the target root-task was not previously focusable (previous top running
1804                 // activity on that root-task was not visible) then any prior calls to move the
1805                 // root-task to the will not update the focused root-task.  If starting the new
1806                 // activity now allows the task root-task to be focusable, then ensure that we
1807                 // now update the focused root-task accordingly.
1808                 if (!mAvoidMoveToFront && mTargetRootTask.isTopActivityFocusable()
1809                         && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
1810                     mTargetRootTask.moveToFront("startActivityInner");
1811                 }
1812                 mRootWindowContainer.resumeFocusedTasksTopActivities(
1813                         mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
1814             }
1815         }
1816         mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
1817 
1818         // Update the recent tasks list immediately when the activity starts
1819         mSupervisor.mRecentTasks.add(startedTask);
1820         mSupervisor.handleNonResizableTaskIfNeeded(startedTask,
1821                 mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
1822 
1823         // If Activity's launching into PiP, move the mStartActivity immediately to pinned mode.
1824         // Note that mStartActivity and source should be in the same Task at this point.
1825         if (mOptions != null && mOptions.isLaunchIntoPip()
1826                 && sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
1827                 && balCode != BAL_BLOCK) {
1828             mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
1829                     sourceRecord, "launch-into-pip");
1830         }
1831 
1832         return START_SUCCESS;
1833     }
1834 
1835     /** Returns the leaf task where the target activity may be placed. */
computeTargetTask()1836     private Task computeTargetTask() {
1837         if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1838                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1839             // A new task should be created instead of using existing one.
1840             return null;
1841         } else if (mSourceRecord != null) {
1842             return mSourceRecord.getTask();
1843         } else if (mInTask != null) {
1844             // The task is specified from AppTaskImpl, so it may not be attached yet.
1845             if (!mInTask.isAttached()) {
1846                 // Attach the task to display area. Ignore the returned root task (though usually
1847                 // they are the same) because "target task" should be leaf task.
1848                 getOrCreateRootTask(mStartActivity, mLaunchFlags, mInTask, mOptions);
1849             }
1850             return mInTask;
1851         } else {
1852             final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */,
1853                     mOptions);
1854             final ActivityRecord top = rootTask.getTopNonFinishingActivity();
1855             if (top != null) {
1856                 return top.getTask();
1857             } else {
1858                 // Remove the root task if no activity in the root task.
1859                 rootTask.removeIfPossible("computeTargetTask");
1860             }
1861         }
1862         return null;
1863     }
1864 
computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord, Task targetTask)1865     private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord,
1866             Task targetTask) {
1867         mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r,
1868                 sourceRecord, mOptions, mRequest, PHASE_BOUNDS, mLaunchParams);
1869         mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
1870                 ? mLaunchParams.mPreferredTaskDisplayArea
1871                 : mRootWindowContainer.getDefaultTaskDisplayArea();
1872         mPreferredWindowingMode = mLaunchParams.mWindowingMode;
1873     }
1874 
1875     @VisibleForTesting
isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask)1876     int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
1877         if (r.packageName == null) {
1878             ActivityOptions.abort(mOptions);
1879             return START_CLASS_NOT_FOUND;
1880         }
1881 
1882         // Do not start home activity if it cannot be launched on preferred display. We are not
1883         // doing this in ActivityTaskSupervisor#canPlaceEntityOnDisplay because it might
1884         // fallback to launch on other displays.
1885         if (r.isActivityTypeHome()) {
1886             if (!mRootWindowContainer.canStartHomeOnDisplayArea(r.info, mPreferredTaskDisplayArea,
1887                     true /* allowInstrumenting */)) {
1888                 Slog.w(TAG, "Cannot launch home on display area " + mPreferredTaskDisplayArea);
1889                 return START_CANCELED;
1890             }
1891         }
1892 
1893         // Do not allow background activity start in new task or in a task that uid is not present.
1894         // Also do not allow pinned window to start single instance activity in background,
1895         // as it will recreate the window and makes it to foreground.
1896         boolean blockBalInTask = (newTask
1897                 || !targetTask.isUidPresent(mCallingUid)
1898                 || (LAUNCH_SINGLE_INSTANCE == mLaunchMode && targetTask.inPinnedWindowingMode()));
1899 
1900         if (mBalCode == BAL_BLOCK && blockBalInTask
1901                 && handleBackgroundActivityAbort(r)) {
1902             Slog.e(TAG, "Abort background activity starts from " + mCallingUid);
1903             return START_ABORTED;
1904         }
1905 
1906         // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but still
1907         // needs to be a lock task mode violation since the task gets cleared out and the device
1908         // would otherwise leave the locked task.
1909         final boolean isNewClearTask =
1910                 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1911                         == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1912         if (!newTask) {
1913             if (mService.getLockTaskController().isLockTaskModeViolation(targetTask,
1914                     isNewClearTask)) {
1915                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1916                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1917             }
1918         } else {
1919             if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(r)) {
1920                 Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
1921                 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1922             }
1923         }
1924 
1925         // Do not start the activity if target display's DWPC does not allow it.
1926         // We can't return fatal error code here because it will crash the caller of
1927         // startActivity() if they don't catch the exception. We don't expect 3P apps to make
1928         // changes.
1929         if (mPreferredTaskDisplayArea != null) {
1930             final DisplayContent displayContent = mRootWindowContainer.getDisplayContentOrCreate(
1931                     mPreferredTaskDisplayArea.getDisplayId());
1932             if (displayContent != null) {
1933                 final int targetWindowingMode = (targetTask != null)
1934                         ? targetTask.getWindowingMode() : displayContent.getWindowingMode();
1935                 final int launchingFromDisplayId =
1936                         mSourceRecord != null ? mSourceRecord.getDisplayId() : DEFAULT_DISPLAY;
1937                 if (!displayContent.mDwpcHelper
1938                         .canActivityBeLaunched(r.info, r.intent, targetWindowingMode,
1939                           launchingFromDisplayId, newTask)) {
1940                     Slog.w(TAG, "Abort to launch " + r.info.getComponentName()
1941                             + " on display area " + mPreferredTaskDisplayArea);
1942                     return START_ABORTED;
1943                 }
1944             }
1945         }
1946 
1947         if (!checkActivitySecurityModel(r, newTask, targetTask)) {
1948             return START_ABORTED;
1949         }
1950 
1951         return START_SUCCESS;
1952     }
1953 
1954     /**
1955      * TODO(b/263368846): Shift to BackgroundActivityStartController once class is ready
1956      * Log activity starts which violate one of the following rules of the
1957      * activity security model (ASM):
1958      * See go/activity-security for rationale behind the rules.
1959      * 1. Within a task, only an activity matching a top UID of the task can start activities
1960      * 2. Only activities within a foreground task, which match a top UID of the task, can
1961      * create a new task or bring an existing one into the foreground
1962      */
checkActivitySecurityModel(ActivityRecord r, boolean newTask, Task targetTask)1963     private boolean checkActivitySecurityModel(ActivityRecord r, boolean newTask, Task targetTask) {
1964         // BAL Exception allowed in all cases
1965         if (mBalCode == BAL_ALLOW_ALLOWLISTED_UID) {
1966             return true;
1967         }
1968 
1969         // Intents with FLAG_ACTIVITY_NEW_TASK will always be considered as creating a new task
1970         // even if the intent is delivered to an existing task.
1971         boolean taskToFront = newTask
1972                 || (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == FLAG_ACTIVITY_NEW_TASK;
1973 
1974         // BAL exception only allowed for new tasks
1975         if (taskToFront) {
1976             if (mBalCode == BAL_ALLOW_ALLOWLISTED_COMPONENT
1977                     || mBalCode == BAL_ALLOW_PERMISSION
1978                     || mBalCode == BAL_ALLOW_PENDING_INTENT
1979                     || mBalCode == BAL_ALLOW_SAW_PERMISSION
1980                     || mBalCode == BAL_ALLOW_VISIBLE_WINDOW) {
1981                 return true;
1982             }
1983         }
1984 
1985         boolean shouldBlockActivityStart = true;
1986         // Used for logging/toasts. Would we block the start if target sdk was U and feature was
1987         // enabled?
1988         boolean wouldBlockActivityStartIgnoringFlags = true;
1989 
1990         if (mSourceRecord != null) {
1991             boolean passesAsmChecks = true;
1992             Task sourceTask = mSourceRecord.getTask();
1993 
1994             // Allow launching into a new task (or a task matching the launched activity's
1995             // affinity) only if the current task is foreground or mutating its own task.
1996             // The latter can happen eg. if caller uses NEW_TASK flag and the activity being
1997             // launched matches affinity of source task.
1998             if (taskToFront) {
1999                 passesAsmChecks = sourceTask != null
2000                         && (sourceTask.isVisible() || sourceTask == targetTask);
2001             }
2002 
2003             if (passesAsmChecks) {
2004                 Task taskToCheck = taskToFront ? sourceTask : targetTask;
2005                 // first == false means Should Block
2006                 // second == false means Would Block disregarding flags
2007                 Pair<Boolean, Boolean> pair = ActivityTaskSupervisor
2008                         .doesTopActivityMatchingUidExistForAsm(taskToCheck, mSourceRecord.getUid(),
2009                                 mSourceRecord);
2010                 shouldBlockActivityStart = !pair.first;
2011                 wouldBlockActivityStartIgnoringFlags = !pair.second;
2012             }
2013 
2014             if (!wouldBlockActivityStartIgnoringFlags) {
2015                 return true;
2016             }
2017         }
2018 
2019         // ASM rules have failed. Log why
2020         ActivityRecord targetTopActivity = targetTask == null ? null
2021                 : targetTask.getActivity(ar -> !ar.finishing && !ar.isAlwaysOnTop());
2022 
2023         int action = newTask || mSourceRecord == null
2024                 ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK
2025                 : (mSourceRecord.getTask().equals(targetTask)
2026                         ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_SAME_TASK
2027                         :  FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_DIFFERENT_TASK);
2028 
2029         FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED,
2030                 /* caller_uid */
2031                 mSourceRecord != null ? mSourceRecord.getUid() : mCallingUid,
2032                 /* caller_activity_class_name */
2033                 mSourceRecord != null ? mSourceRecord.info.name : null,
2034                 /* target_task_top_activity_uid */
2035                 targetTopActivity != null ? targetTopActivity.getUid() : -1,
2036                 /* target_task_top_activity_class_name */
2037                 targetTopActivity != null ? targetTopActivity.info.name : null,
2038                 /* target_task_is_different */
2039                 newTask || mSourceRecord == null || targetTask == null
2040                         || !targetTask.equals(mSourceRecord.getTask()),
2041                 /* target_activity_uid */
2042                 r.getUid(),
2043                 /* target_activity_class_name */
2044                 r.info.name,
2045                 /* target_intent_action */
2046                 r.intent.getAction(),
2047                 /* target_intent_flags */
2048                 mLaunchFlags,
2049                 /* action */
2050                 action,
2051                 /* version */
2052                 ActivitySecurityModelFeatureFlags.ASM_VERSION,
2053                 /* multi_window - we have our source not in the target task, but both are visible */
2054                 targetTask != null && mSourceRecord != null
2055                         && !targetTask.equals(mSourceRecord.getTask()) && targetTask.isVisible(),
2056                 /* bal_code */
2057                 mBalCode
2058         );
2059 
2060         boolean blockActivityStartAndFeatureEnabled = ActivitySecurityModelFeatureFlags
2061                     .shouldRestrictActivitySwitch(mCallingUid)
2062                 && shouldBlockActivityStart;
2063 
2064         String launchedFromPackageName = r.launchedFromPackage;
2065         if (ActivitySecurityModelFeatureFlags.shouldShowToast(mCallingUid)) {
2066             String toastText = ActivitySecurityModelFeatureFlags.DOC_LINK
2067                     + (blockActivityStartAndFeatureEnabled ? " blocked " : " would block ")
2068                     + getApplicationLabel(mService.mContext.getPackageManager(),
2069                         launchedFromPackageName);
2070             UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
2071                     toastText, Toast.LENGTH_LONG).show());
2072 
2073             logDebugInfoForActivitySecurity("Launch", r, targetTask, targetTopActivity,
2074                     blockActivityStartAndFeatureEnabled, /* taskToFront */ taskToFront);
2075         }
2076 
2077         if (blockActivityStartAndFeatureEnabled) {
2078             Slog.e(TAG, "[ASM] Abort Launching r: " + r
2079                     + " as source: "
2080                     + (mSourceRecord != null ? mSourceRecord : launchedFromPackageName)
2081                     + " is in background. New task: " + newTask
2082                     + ". Top activity: " + targetTopActivity
2083                     + ". BAL Code: " + balCodeToString(mBalCode));
2084 
2085             return false;
2086         }
2087 
2088         return true;
2089     }
2090 
2091     /** Only called when an activity launch may be blocked, which should happen very rarely */
logDebugInfoForActivitySecurity(String action, ActivityRecord r, Task targetTask, ActivityRecord targetTopActivity, boolean blockActivityStartAndFeatureEnabled, boolean taskToFront)2092     private void logDebugInfoForActivitySecurity(String action, ActivityRecord r, Task targetTask,
2093             ActivityRecord targetTopActivity, boolean blockActivityStartAndFeatureEnabled,
2094             boolean taskToFront) {
2095         final String prefix = "[ASM] ";
2096         Function<ActivityRecord, String> recordToString = (ar) -> {
2097             if (ar == null) {
2098                 return null;
2099             }
2100             return (ar == mSourceRecord ? " [source]=> "
2101                     : ar == targetTopActivity ? " [ top  ]=> "
2102                             : ar == r ? " [target]=> "
2103                                     : "         => ")
2104                     + ar
2105                     + " :: visible=" + ar.isVisible()
2106                     + ", finishing=" + ar.isFinishing()
2107                     + ", alwaysOnTop=" + ar.isAlwaysOnTop()
2108                     + ", taskFragment=" + ar.getTaskFragment();
2109         };
2110 
2111         StringJoiner joiner = new StringJoiner("\n");
2112         joiner.add(prefix + "------ Activity Security " + action + " Debug Logging Start ------");
2113         joiner.add(prefix + "Block Enabled: " + blockActivityStartAndFeatureEnabled);
2114         joiner.add(prefix + "ASM Version: " + ActivitySecurityModelFeatureFlags.ASM_VERSION);
2115 
2116         boolean targetTaskMatchesSourceTask = targetTask != null
2117                 && mSourceRecord != null && mSourceRecord.getTask() == targetTask;
2118 
2119         if (mSourceRecord == null) {
2120             joiner.add(prefix + "Source Package: " + r.launchedFromPackage);
2121             String realCallingPackage = mService.mContext.getPackageManager().getNameForUid(
2122                     mRealCallingUid);
2123             joiner.add(prefix + "Real Calling Uid Package: " + realCallingPackage);
2124         } else {
2125             joiner.add(prefix + "Source Record: " + recordToString.apply(mSourceRecord));
2126             if (targetTaskMatchesSourceTask) {
2127                 joiner.add(prefix + "Source/Target Task: " + mSourceRecord.getTask());
2128                 joiner.add(prefix + "Source/Target Task Stack: ");
2129             } else {
2130                 joiner.add(prefix + "Source Task: " + mSourceRecord.getTask());
2131                 joiner.add(prefix + "Source Task Stack: ");
2132             }
2133             mSourceRecord.getTask().forAllActivities((Consumer<ActivityRecord>)
2134                     ar -> joiner.add(prefix + recordToString.apply(ar)));
2135         }
2136 
2137         joiner.add(prefix + "Target Task Top: " + recordToString.apply(targetTopActivity));
2138         if (!targetTaskMatchesSourceTask) {
2139             joiner.add(prefix + "Target Task: " + targetTask);
2140             if (targetTask != null) {
2141                 joiner.add(prefix + "Target Task Stack: ");
2142                 targetTask.forAllActivities((Consumer<ActivityRecord>)
2143                         ar -> joiner.add(prefix + recordToString.apply(ar)));
2144             }
2145         }
2146 
2147         joiner.add(prefix + "Target Record: " + recordToString.apply(r));
2148         joiner.add(prefix + "Intent: " + mIntent);
2149         joiner.add(prefix + "TaskToFront: " + taskToFront);
2150         joiner.add(prefix + "BalCode: " + balCodeToString(mBalCode));
2151 
2152         joiner.add(prefix + "------ Activity Security " + action + " Debug Logging End ------");
2153         Slog.i(TAG, joiner.toString());
2154     }
2155 
2156     /**
2157      * Returns whether embedding of {@code starting} is allowed.
2158      *
2159      * @param taskFragment the TaskFragment for embedding.
2160      * @param starting the starting activity.
2161      * @param targetTask the target task for launching activity, which could be different from
2162      *                   the one who hosting the embedding.
2163      */
2164     @VisibleForTesting
2165     @EmbeddingCheckResult
canEmbedActivity(@onNull TaskFragment taskFragment, @NonNull ActivityRecord starting, @NonNull Task targetTask)2166     static int canEmbedActivity(@NonNull TaskFragment taskFragment,
2167             @NonNull ActivityRecord starting, @NonNull Task targetTask) {
2168         final Task hostTask = taskFragment.getTask();
2169         // Not allowed embedding a separate task or without host task.
2170         if (hostTask == null || targetTask != hostTask) {
2171             return EMBEDDING_DISALLOWED_NEW_TASK;
2172         }
2173 
2174         return taskFragment.isAllowedToEmbedActivity(starting);
2175     }
2176 
2177     /**
2178      * Prepare the target task to be reused for this launch, which including:
2179      * - Position the target task on valid root task on preferred display.
2180      * - Comply to the specified activity launch flags
2181      * - Determine whether need to add a new activity on top or just brought the task to front.
2182      */
2183     @VisibleForTesting
recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask, NeededUriGrants intentGrants)2184     int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask,
2185             NeededUriGrants intentGrants) {
2186         // Should not recycle task which is from a different user, just adding the starting
2187         // activity to the task.
2188         if (targetTask.mUserId != mStartActivity.mUserId) {
2189             mTargetRootTask = targetTask.getRootTask();
2190             mAddingToTask = true;
2191             return START_SUCCESS;
2192         }
2193 
2194         if (reusedTask != null) {
2195             if (targetTask.intent == null) {
2196                 // This task was started because of movement of the activity based on
2197                 // affinity...
2198                 // Now that we are actually launching it, we can assign the base intent.
2199                 targetTask.setIntent(mStartActivity);
2200             } else {
2201                 final boolean taskOnHome =
2202                         (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
2203                 if (taskOnHome) {
2204                     targetTask.intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
2205                 } else {
2206                     targetTask.intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
2207                 }
2208             }
2209         }
2210 
2211         mRootWindowContainer.startPowerModeLaunchIfNeeded(false /* forceSend */,
2212                 targetTaskTop);
2213 
2214         setTargetRootTaskIfNeeded(targetTaskTop);
2215 
2216         // When there is a reused activity and the current result is a trampoline activity,
2217         // set the reused activity as the result.
2218         if (mLastStartActivityRecord != null
2219                 && (mLastStartActivityRecord.finishing || mLastStartActivityRecord.noDisplay)) {
2220             mLastStartActivityRecord = targetTaskTop;
2221         }
2222 
2223         if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2224             // We don't need to start a new activity, and the client said not to do anything
2225             // if that is the case, so this is it!  And for paranoia, make sure we have
2226             // correctly resumed the top activity.
2227             if (!mMovedToFront && mDoResume) {
2228                 ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetRootTask,
2229                         targetTaskTop);
2230                 mTargetRootTask.moveToFront("intentActivityFound");
2231             }
2232             resumeTargetRootTaskIfNeeded();
2233             return START_RETURN_INTENT_TO_CALLER;
2234         }
2235 
2236         complyActivityFlags(targetTask,
2237                 reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);
2238 
2239         if (mAddingToTask) {
2240             clearTopIfNeeded(targetTask, mCallingUid, mRealCallingUid, mStartActivity.getUid(),
2241                     mLaunchFlags);
2242             return START_SUCCESS;
2243         }
2244 
2245         // The reusedActivity could be finishing, for example of starting an activity with
2246         // FLAG_ACTIVITY_CLEAR_TOP flag. In that case, use the top running activity in the
2247         // task instead.
2248         targetTaskTop = targetTaskTop.finishing
2249                 ? targetTask.getTopNonFinishingActivity()
2250                 : targetTaskTop;
2251 
2252         if (mMovedToFront) {
2253             // We moved the task to front, use starting window to hide initial drawn delay.
2254             targetTaskTop.showStartingWindow(true /* taskSwitch */);
2255         } else if (mDoResume) {
2256             // Make sure the root task and its belonging display are moved to topmost.
2257             mTargetRootTask.moveToFront("intentActivityFound");
2258         }
2259         // We didn't do anything...  but it was needed (a.k.a., client don't use that intent!)
2260         // And for paranoia, make sure we have correctly resumed the top activity.
2261         resumeTargetRootTaskIfNeeded();
2262 
2263         // This is moving an existing task to front. But since dream activity has a higher z-order
2264         // to cover normal activities, it needs the awakening event to be dismissed.
2265         if (mService.isDreaming() && targetTaskTop.canTurnScreenOn()) {
2266             targetTaskTop.mTaskSupervisor.wakeUp("recycleTask#turnScreenOnFlag");
2267         }
2268 
2269         mLastStartActivityRecord = targetTaskTop;
2270         return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
2271     }
2272 
2273     /**
2274      * If the top activity uid does not match the launching or launched activity, and the launch was
2275      * not requested from the top uid, we want to clear out all non matching activities to prevent
2276      * the top activity being sandwiched.
2277      *
2278      * Both creator and sender UID are considered for the launching activity.
2279      */
clearTopIfNeeded(@onNull Task targetTask, int callingUid, int realCallingUid, int startingUid, int launchFlags)2280     private void clearTopIfNeeded(@NonNull Task targetTask, int callingUid, int realCallingUid,
2281             int startingUid, int launchFlags) {
2282         if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) != FLAG_ACTIVITY_NEW_TASK
2283                 || mBalCode == BAL_ALLOW_ALLOWLISTED_UID) {
2284             // Launch is from the same task, (a top or privileged UID), or is directly privileged.
2285             return;
2286         }
2287 
2288         Predicate<ActivityRecord> isLaunchingOrLaunched = ar ->
2289                 ar.isUid(startingUid) || ar.isUid(callingUid) || ar.isUid(realCallingUid);
2290 
2291         // Return early if we know for sure we won't need to clear any activities by just checking
2292         // the top activity.
2293         ActivityRecord targetTaskTop = targetTask.getTopMostActivity();
2294         if (targetTaskTop == null || isLaunchingOrLaunched.test(targetTaskTop)) {
2295             return;
2296         }
2297 
2298         // Find the first activity which matches a safe UID and is not finishing. Clear everything
2299         // above it
2300         boolean shouldBlockActivityStart = ActivitySecurityModelFeatureFlags
2301                 .shouldRestrictActivitySwitch(callingUid);
2302         int[] finishCount = new int[0];
2303         if (shouldBlockActivityStart) {
2304             ActivityRecord activity = targetTask.getActivity(isLaunchingOrLaunched);
2305             if (activity == null) {
2306                 // mStartActivity is not in task, so clear everything
2307                 activity = mStartActivity;
2308             }
2309 
2310             finishCount = new int[1];
2311             targetTask.performClearTop(activity, launchFlags, finishCount);
2312             if (finishCount[0] > 0) {
2313                 Slog.w(TAG, "Cleared top n: " + finishCount[0] + " activities from task t: "
2314                         + targetTask + " not matching top uid: " + callingUid);
2315             }
2316         }
2317 
2318         if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)
2319                 && (!shouldBlockActivityStart || finishCount[0] > 0)) {
2320             UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
2321                     (shouldBlockActivityStart
2322                             ? "Top activities cleared by "
2323                             : "Top activities would be cleared by ")
2324                             + ActivitySecurityModelFeatureFlags.DOC_LINK,
2325                     Toast.LENGTH_LONG).show());
2326 
2327             logDebugInfoForActivitySecurity("Clear Top", mStartActivity, targetTask, targetTaskTop,
2328                     shouldBlockActivityStart, /* taskToFront */ true);
2329         }
2330     }
2331 
2332     /**
2333      * Check if the activity being launched is the same as the one currently at the top and it
2334      * should only be launched once.
2335      */
deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants)2336     private int deliverToCurrentTopIfNeeded(Task topRootTask, NeededUriGrants intentGrants) {
2337         final ActivityRecord top = topRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2338         final boolean dontStart = top != null
2339                 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2340                 && top.mUserId == mStartActivity.mUserId
2341                 && top.attachedToProcess()
2342                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2343                 || LAUNCH_SINGLE_TOP == mLaunchMode)
2344                 // This allows home activity to automatically launch on secondary task display area
2345                 // when it was added, if home was the top activity on default task display area,
2346                 // instead of sending new intent to the home activity on default display area.
2347                 && (!top.isActivityTypeHome() || top.getDisplayArea() == mPreferredTaskDisplayArea);
2348         if (!dontStart) {
2349             return START_SUCCESS;
2350         }
2351 
2352         // For paranoia, make sure we have correctly resumed the top activity.
2353         top.getTaskFragment().clearLastPausedActivity();
2354         if (mDoResume) {
2355             mRootWindowContainer.resumeFocusedTasksTopActivities();
2356         }
2357         ActivityOptions.abort(mOptions);
2358         if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2359             // We don't need to start a new activity, and the client said not to do anything if
2360             // that is the case, so this is it!
2361             return START_RETURN_INTENT_TO_CALLER;
2362         }
2363 
2364         if (mStartActivity.resultTo != null) {
2365             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2366                     mStartActivity.requestCode, RESULT_CANCELED,
2367                     null /* data */, null /* dataGrants */);
2368             mStartActivity.resultTo = null;
2369         }
2370 
2371         deliverNewIntent(top, intentGrants);
2372 
2373         // Don't use mStartActivity.task to show the toast. We're not starting a new activity but
2374         // reusing 'top'. Fields in mStartActivity may not be fully initialized.
2375         mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(),
2376                 mLaunchParams.mWindowingMode, mPreferredTaskDisplayArea, topRootTask);
2377 
2378         return START_DELIVERED_TO_TOP;
2379     }
2380 
2381     /**
2382      * Applying the launching flags to the task, which might clear few or all the activities in the
2383      * task.
2384      */
complyActivityFlags(Task targetTask, ActivityRecord reusedActivity, NeededUriGrants intentGrants)2385     private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity,
2386             NeededUriGrants intentGrants) {
2387         ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
2388         final boolean resetTask =
2389                 reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
2390         if (resetTask) {
2391             targetTaskTop = mTargetRootTask.resetTaskIfNeeded(targetTaskTop, mStartActivity);
2392         }
2393 
2394         if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2395                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2396             // The caller has requested to completely replace any existing task with its new
2397             // activity. Well that should not be too hard...
2398             // Note: we must persist the {@link Task} first as intentActivity could be
2399             // removed from calling performClearTaskLocked (For example, if it is being brought out
2400             // of history or if it is finished immediately), thus disassociating the task. Keep the
2401             // task-overlay activity because the targetTask will be reused to launch new activity.
2402             targetTask.performClearTaskForReuse(true /* excludingTaskOverlay*/);
2403             targetTask.setIntent(mStartActivity);
2404             mAddingToTask = true;
2405             mIsTaskCleared = true;
2406         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2407                 || isDocumentLaunchesIntoExisting(mLaunchFlags)
2408                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK,
2409                         LAUNCH_SINGLE_INSTANCE_PER_TASK)) {
2410             // In this situation we want to remove all activities from the task up to the one
2411             // being started. In most cases this means we are resetting the task to its initial
2412             // state.
2413             int[] finishCount = new int[1];
2414             final ActivityRecord clearTop = targetTask.performClearTop(mStartActivity,
2415                     mLaunchFlags, finishCount);
2416 
2417             if (clearTop != null && !clearTop.finishing) {
2418                 if (finishCount[0] > 0) {
2419                     // Only record if actually moved to top.
2420                     mMovedToTopActivity = clearTop;
2421                 }
2422                 if (clearTop.isRootOfTask()) {
2423                     // Activity aliases may mean we use different intents for the top activity,
2424                     // so make sure the task now has the identity of the new intent.
2425                     clearTop.getTask().setIntent(mStartActivity);
2426                 }
2427                 deliverNewIntent(clearTop, intentGrants);
2428             } else {
2429                 // A special case: we need to start the activity because it is not currently
2430                 // running, and the caller has asked to clear the current task to have this
2431                 // activity at the top.
2432                 mAddingToTask = true;
2433                 // Adding the new activity to the same embedded TF of the clear-top activity if
2434                 // possible.
2435                 if (clearTop != null && clearTop.getTaskFragment() != null
2436                         && clearTop.getTaskFragment().isEmbedded()) {
2437                     mAddingToTaskFragment = clearTop.getTaskFragment();
2438                 }
2439                 if (targetTask.getRootTask() == null) {
2440                     // Target root task got cleared when we all activities were removed above.
2441                     // Go ahead and reset it.
2442                     mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags,
2443                         null /* task */, mOptions);
2444                     mTargetRootTask.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
2445                             (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
2446                 }
2447             }
2448         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
2449                 && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2450             // In this case, we are launching an activity in our own task that may
2451             // already be running somewhere in the history, and we want to shuffle it to
2452             // the front of the root task if so.
2453             final ActivityRecord act =
2454                     targetTask.findActivityInHistory(mStartActivity.mActivityComponent,
2455                             mStartActivity.mUserId);
2456             if (act != null) {
2457                 final Task task = act.getTask();
2458                 boolean actuallyMoved = task.moveActivityToFront(act);
2459                 if (actuallyMoved) {
2460                     // Only record if the activity actually moved.
2461                     mMovedToTopActivity = act;
2462                     if (mNoAnimation) {
2463                         act.mDisplayContent.prepareAppTransition(TRANSIT_NONE);
2464                     } else {
2465                         act.mDisplayContent.prepareAppTransition(TRANSIT_TO_FRONT);
2466                     }
2467                 }
2468                 act.updateOptionsLocked(mOptions);
2469                 deliverNewIntent(act, intentGrants);
2470                 act.getTaskFragment().clearLastPausedActivity();
2471             } else {
2472                 mAddingToTask = true;
2473             }
2474         } else if (mStartActivity.mActivityComponent.equals(targetTask.realActivity)) {
2475             if (targetTask == mInTask) {
2476                 // In this case we are bringing up an existing activity from a recent task. We
2477                 // don't need to add a new activity instance on top.
2478             } else if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2479                             || LAUNCH_SINGLE_TOP == mLaunchMode)
2480                     && targetTaskTop.mActivityComponent.equals(mStartActivity.mActivityComponent)
2481                     && mStartActivity.resultTo == null) {
2482                 // In this case the top activity on the task is the same as the one being launched,
2483                 // so we take that as a request to bring the task to the foreground. If the top
2484                 // activity in the task is the root activity, deliver this new intent to it if it
2485                 // desires.
2486                 if (targetTaskTop.isRootOfTask()) {
2487                     targetTaskTop.getTask().setIntent(mStartActivity);
2488                 }
2489                 deliverNewIntent(targetTaskTop, intentGrants);
2490             } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
2491                 // In this case we are launching the root activity of the task, but with a
2492                 // different intent. We should start a new instance on top.
2493                 mAddingToTask = true;
2494             } else if (reusedActivity == null) {
2495                 mAddingToTask = true;
2496             }
2497         } else if (!resetTask) {
2498             // In this case an activity is being launched in to an existing task, without
2499             // resetting that task. This is typically the situation of launching an activity
2500             // from a notification or shortcut. We want to place the new activity on top of the
2501             // current task.
2502             mAddingToTask = true;
2503         } else if (!targetTask.rootWasReset) {
2504             // In this case we are launching into an existing task that has not yet been started
2505             // from its front door. The current task has been brought to the front. Ideally,
2506             // we'd probably like to place this new task at the bottom of its root task, but that's
2507             // a little hard to do with the current organization of the code so for now we'll
2508             // just drop it.
2509             targetTask.setIntent(mStartActivity);
2510         }
2511     }
2512 
2513     /**
2514      * Resets the {@link ActivityStarter} state.
2515      * @param clearRequest whether the request should be reset to default values.
2516      */
reset(boolean clearRequest)2517     void reset(boolean clearRequest) {
2518         mStartActivity = null;
2519         mIntent = null;
2520         mCallingUid = -1;
2521         mRealCallingUid = -1;
2522         mOptions = null;
2523         mBalCode = BAL_ALLOW_DEFAULT;
2524 
2525         mLaunchTaskBehind = false;
2526         mLaunchFlags = 0;
2527         mLaunchMode = INVALID_LAUNCH_MODE;
2528 
2529         mLaunchParams.reset();
2530 
2531         mNotTop = null;
2532         mDoResume = false;
2533         mStartFlags = 0;
2534         mSourceRecord = null;
2535         mPreferredTaskDisplayArea = null;
2536         mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED;
2537 
2538         mInTask = null;
2539         mInTaskFragment = null;
2540         mAddingToTaskFragment = null;
2541         mAddingToTask = false;
2542 
2543         mSourceRootTask = null;
2544 
2545         mTargetRootTask = null;
2546         mTargetTask = null;
2547         mIsTaskCleared = false;
2548         mMovedToFront = false;
2549         mNoAnimation = false;
2550         mAvoidMoveToFront = false;
2551         mFrozeTaskList = false;
2552         mTransientLaunch = false;
2553         mPriorAboveTask = null;
2554         mDisplayLockAndOccluded = false;
2555 
2556         mVoiceSession = null;
2557         mVoiceInteractor = null;
2558 
2559         mIntentDelivered = false;
2560 
2561         if (clearRequest) {
2562             mRequest.reset();
2563         }
2564     }
2565 
setInitialState(ActivityRecord r, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, @BalCode int balCode, int realCallingUid)2566     private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
2567             TaskFragment inTaskFragment, int startFlags,
2568             ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession,
2569             IVoiceInteractor voiceInteractor, @BalCode int balCode, int realCallingUid) {
2570         reset(false /* clearRequest */);
2571 
2572         mStartActivity = r;
2573         mIntent = r.intent;
2574         mOptions = options;
2575         mCallingUid = r.launchedFromUid;
2576         mRealCallingUid = realCallingUid;
2577         mSourceRecord = sourceRecord;
2578         mSourceRootTask = mSourceRecord != null ? mSourceRecord.getRootTask() : null;
2579         mVoiceSession = voiceSession;
2580         mVoiceInteractor = voiceInteractor;
2581         mBalCode = balCode;
2582 
2583         mLaunchParams.reset();
2584 
2585         // Preferred display id is the only state we need for now and it could be updated again
2586         // after we located a reusable task (which might be resided in another display).
2587         mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
2588                 sourceRecord, options, mRequest, PHASE_DISPLAY, mLaunchParams);
2589         mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
2590                 ? mLaunchParams.mPreferredTaskDisplayArea
2591                 : mRootWindowContainer.getDefaultTaskDisplayArea();
2592         mPreferredWindowingMode = mLaunchParams.mWindowingMode;
2593 
2594         mLaunchMode = r.launchMode;
2595 
2596         mLaunchFlags = adjustLaunchFlagsToDocumentMode(
2597                 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
2598                 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
2599         mLaunchTaskBehind = r.mLaunchTaskBehind
2600                 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
2601                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
2602 
2603         if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) {
2604             // Adding NEW_TASK flag for singleInstancePerTask launch mode activity, so that the
2605             // activity won't be launched in source record's task.
2606             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2607         }
2608 
2609         if (r.info.requiredDisplayCategory != null && mSourceRecord != null
2610                 && !r.info.requiredDisplayCategory.equals(
2611                         mSourceRecord.info.requiredDisplayCategory)) {
2612             // Adding NEW_TASK flag for activity with display category attribute if the display
2613             // category of the source record is different, so that the activity won't be launched
2614             // in source record's task.
2615             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2616         }
2617 
2618         sendNewTaskResultRequestIfNeeded();
2619 
2620         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
2621             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2622         }
2623 
2624         // If we are actually going to launch in to a new task, there are some cases where
2625         // we further want to do multiple task.
2626         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2627             if (mLaunchTaskBehind
2628                     || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
2629                 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
2630             }
2631         }
2632 
2633         // We'll invoke onUserLeaving before onPause only if the launching
2634         // activity did not explicitly state that this is an automated launch.
2635         mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
2636         if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2637                 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
2638 
2639         // If the caller has asked not to resume at this point, we make note
2640         // of this in the record so that we can skip it when trying to find
2641         // the top running activity.
2642         if (!r.showToCurrentUser() || mLaunchTaskBehind) {
2643             r.delayedResume = true;
2644             mDoResume = false;
2645         } else {
2646             mDoResume = true;
2647         }
2648 
2649         if (mOptions != null) {
2650             if (mOptions.getLaunchTaskId() != INVALID_TASK_ID && mOptions.getTaskOverlay()) {
2651                 r.setTaskOverlay(true);
2652                 if (!mOptions.canTaskOverlayResume()) {
2653                     final Task task = mRootWindowContainer.anyTaskForId(
2654                             mOptions.getLaunchTaskId());
2655                     final ActivityRecord top = task != null
2656                             ? task.getTopNonFinishingActivity() : null;
2657                     if (top != null && !top.isState(RESUMED)) {
2658 
2659                         // The caller specifies that we'd like to be avoided to be moved to the
2660                         // front, so be it!
2661                         mDoResume = false;
2662                         mAvoidMoveToFront = true;
2663                     }
2664                 }
2665             } else if (mOptions.getAvoidMoveToFront()) {
2666                 mDoResume = false;
2667                 mAvoidMoveToFront = true;
2668             }
2669             mTransientLaunch = mOptions.getTransientLaunch();
2670             final KeyguardController kc = mSupervisor.getKeyguardController();
2671             final int displayId = mPreferredTaskDisplayArea.getDisplayId();
2672             mDisplayLockAndOccluded = kc.isKeyguardLocked(displayId)
2673                     && kc.isDisplayOccluded(displayId);
2674             // Recents animation on lock screen, do not resume & move launcher to top.
2675             if (mTransientLaunch && mDisplayLockAndOccluded
2676                     && mService.getTransitionController().isShellTransitionsEnabled()) {
2677                 mDoResume = false;
2678                 mAvoidMoveToFront = true;
2679             }
2680             mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask());
2681 
2682             if (inTaskFragment == null) {
2683                 inTaskFragment = TaskFragment.fromTaskFragmentToken(
2684                         mOptions.getLaunchTaskFragmentToken(), mService);
2685                 if (inTaskFragment != null && inTaskFragment.isEmbeddedTaskFragmentInPip()) {
2686                     // Do not start activity in TaskFragment in a PIP Task.
2687                     Slog.w(TAG, "Can not start activity in TaskFragment in PIP: "
2688                             + inTaskFragment);
2689                     inTaskFragment = null;
2690                 }
2691             }
2692         }
2693 
2694         mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
2695 
2696         mInTask = inTask;
2697         // In some flows in to this function, we retrieve the task record and hold on to it
2698         // without a lock before calling back in to here...  so the task at this point may
2699         // not actually be in recents.  Check for that, and if it isn't in recents just
2700         // consider it invalid.
2701         if (inTask != null && !inTask.inRecents) {
2702             Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
2703             mInTask = null;
2704         }
2705         // Prevent to start activity in Task with different display category
2706         if (mInTask != null && !mInTask.isSameRequiredDisplayCategory(r.info)) {
2707             Slog.w(TAG, "Starting activity in task with different display category: "
2708                     + mInTask);
2709             mInTask = null;
2710         }
2711         mInTaskFragment = inTaskFragment;
2712 
2713         mStartFlags = startFlags;
2714         // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
2715         // is the same as the one making the call...  or, as a special case, if we do not know
2716         // the caller then we count the current top activity as the caller.
2717         if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2718             ActivityRecord checkedCaller = sourceRecord;
2719             if (checkedCaller == null) {
2720                 Task topFocusedRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
2721                 if (topFocusedRootTask != null) {
2722                     checkedCaller = topFocusedRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2723                 }
2724             }
2725             if (checkedCaller == null
2726                     || !checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
2727                 // Caller is not the same as launcher, so always needed.
2728                 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
2729             }
2730         }
2731 
2732         mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
2733 
2734         if (mBalCode == BAL_BLOCK && !mService.isBackgroundActivityStartsEnabled()) {
2735             mAvoidMoveToFront = true;
2736             mDoResume = false;
2737         }
2738     }
2739 
sendNewTaskResultRequestIfNeeded()2740     private void sendNewTaskResultRequestIfNeeded() {
2741         if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2742             // For whatever reason this activity is being launched into a new task...
2743             // yet the caller has requested a result back.  Well, that is pretty messed up,
2744             // so instead immediately send back a cancel and let the new task continue launched
2745             // as normal without a dependency on its originator.
2746             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
2747             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
2748                     mStartActivity.requestCode, RESULT_CANCELED,
2749                     null /* data */, null /* dataGrants */);
2750             mStartActivity.resultTo = null;
2751         }
2752     }
2753 
computeLaunchingTaskFlags()2754     private void computeLaunchingTaskFlags() {
2755         // If the caller is not coming from another activity, but has given us an explicit task into
2756         // which they would like us to launch the new activity, then let's see about doing that.
2757         if (mSourceRecord == null && mInTask != null && mInTask.getRootTask() != null) {
2758             final Intent baseIntent = mInTask.getBaseIntent();
2759             final ActivityRecord root = mInTask.getRootActivity();
2760             if (baseIntent == null) {
2761                 ActivityOptions.abort(mOptions);
2762                 throw new IllegalArgumentException("Launching into task without base intent: "
2763                         + mInTask);
2764             }
2765 
2766             // If this task is empty, then we are adding the first activity -- it
2767             // determines the root, and must be launching as a NEW_TASK.
2768             if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2769                 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
2770                     ActivityOptions.abort(mOptions);
2771                     throw new IllegalArgumentException("Trying to launch singleInstance/Task "
2772                             + mStartActivity + " into different task " + mInTask);
2773                 }
2774                 if (root != null) {
2775                     ActivityOptions.abort(mOptions);
2776                     throw new IllegalArgumentException("Caller with mInTask " + mInTask
2777                             + " has root " + root + " but target is singleInstance/Task");
2778                 }
2779             }
2780 
2781             // If task is empty, then adopt the interesting intent launch flags in to the
2782             // activity being started.
2783             if (root == null) {
2784                 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
2785                         | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
2786                 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
2787                         | (baseIntent.getFlags() & flagsOfInterest);
2788                 mIntent.setFlags(mLaunchFlags);
2789                 mInTask.setIntent(mStartActivity);
2790                 mAddingToTask = true;
2791 
2792                 // If the task is not empty and the caller is asking to start it as the root of
2793                 // a new task, then we don't actually want to start this on the task. We will
2794                 // bring the task to the front, and possibly give it a new intent.
2795             } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
2796                 mAddingToTask = false;
2797 
2798             } else {
2799                 mAddingToTask = true;
2800             }
2801         } else {
2802             mInTask = null;
2803             // Launch ResolverActivity in the source task, so that it stays in the task bounds
2804             // when in freeform workspace.
2805             // Also put noDisplay activities in the source task. These by itself can be placed
2806             // in any task/root-task, however it could launch other activities like
2807             // ResolverActivity, and we want those to stay in the original task.
2808             if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
2809                     && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
2810                 mAddingToTask = true;
2811             }
2812         }
2813 
2814         if (mInTask == null) {
2815             if (mSourceRecord == null) {
2816                 // This activity is not being started from another...  in this
2817                 // case we -always- start a new task.
2818                 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
2819                     Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
2820                             "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2821                     mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2822                 }
2823             } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
2824                 // The original activity who is starting us is running as a single
2825                 // instance...  this new activity it is starting must go on its
2826                 // own task.
2827                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2828             } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
2829                 // The activity being started is a single instance...  it always
2830                 // gets launched into its own task.
2831                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2832             }
2833         }
2834 
2835         if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0
2836                 && ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 || mSourceRecord == null)) {
2837             // ignore the flag if there is no the sourceRecord or without new_task flag
2838             mLaunchFlags &= ~FLAG_ACTIVITY_LAUNCH_ADJACENT;
2839         }
2840     }
2841 
2842     /**
2843      * Decide whether the new activity should be inserted into an existing task. Returns null
2844      * if not or an ActivityRecord with the task into which the new activity should be added.
2845      */
getReusableTask()2846     private Task getReusableTask() {
2847         // If a target task is specified, try to reuse that one
2848         if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
2849             Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
2850             if (launchTask != null) {
2851                 return launchTask;
2852             }
2853             return null;
2854         }
2855 
2856         // We may want to try to place the new activity in to an existing task.  We always
2857         // do this if the target activity is singleTask or singleInstance; we will also do
2858         // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2859         // us to still place it in a new task: multi task, always doc mode, or being asked to
2860         // launch this as a new task behind the current one.
2861         boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2862                 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
2863                 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
2864         // If bring to front is requested, and no result is requested and we have not been given
2865         // an explicit task to launch in to, and we can find a task that was started with this
2866         // same component, then instead of launching bring that one to the front.
2867         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2868         ActivityRecord intentActivity = null;
2869         if (putIntoExistingTask) {
2870             if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
2871                 // There can be one and only one instance of single instance activity in the
2872                 // history, and it is always in its own unique task, so we do a special search.
2873                 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
2874                        mStartActivity.isActivityTypeHome());
2875             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2876                 // For the launch adjacent case we only want to put the activity in an existing
2877                 // task if the activity already exists in the history.
2878                 intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
2879                         !(LAUNCH_SINGLE_TASK == mLaunchMode));
2880             } else {
2881                 // Otherwise find the best task to put the activity in.
2882                 intentActivity =
2883                         mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);
2884             }
2885         }
2886 
2887         if (intentActivity != null && mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK
2888                 && !intentActivity.getTask().getRootActivity().mActivityComponent.equals(
2889                 mStartActivity.mActivityComponent)) {
2890             // The task could be selected due to same task affinity. Do not reuse the task while
2891             // starting the singleInstancePerTask activity if it is not the task root activity.
2892             intentActivity = null;
2893         }
2894 
2895         if (intentActivity != null
2896                 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
2897                 && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) {
2898             // Do not reuse home activity on other display areas.
2899             intentActivity = null;
2900         }
2901 
2902         return intentActivity != null ? intentActivity.getTask() : null;
2903     }
2904 
2905     /**
2906      * Figure out which task and activity to bring to front when we have found an existing matching
2907      * activity record in history. May also clear the task if needed.
2908      *
2909      * @param intentActivity Existing matching activity.
2910      * @return {@link ActivityRecord} brought to front.
2911      */
setTargetRootTaskIfNeeded(ActivityRecord intentActivity)2912     private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) {
2913         intentActivity.getTaskFragment().clearLastPausedActivity();
2914         Task intentTask = intentActivity.getTask();
2915         // The intent task might be reparented while in getOrCreateRootTask, caches the original
2916         // root task to distinguish if it is moving to front or not.
2917         final Task origRootTask = intentTask != null ? intentTask.getRootTask() : null;
2918 
2919         if (mTargetRootTask == null) {
2920             // Update launch target task when it is not indicated.
2921             if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) {
2922                 // Inherit the target-root-task from source to ensure trampoline activities will be
2923                 // launched into the same root task.
2924                 mTargetRootTask = Task.fromWindowContainerToken(mSourceRecord.mLaunchRootTask);
2925             } else {
2926                 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask,
2927                         mOptions);
2928             }
2929         }
2930 
2931         // If the matching task is already in the adjacent task of the launch target. Adjust to use
2932         // the adjacent task as its launch target. So the existing task will be launched into the
2933         // closer one and won't be reparent redundantly.
2934         final Task adjacentTargetTask = mTargetRootTask.getAdjacentTask();
2935         if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)
2936                 && intentTask.isOnTop()) {
2937             mTargetRootTask = adjacentTargetTask;
2938         }
2939 
2940         // If the target task is not in the front, then we need to bring it to the front...
2941         // except...  well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2942         // the same behavior as if a new instance was being started, which means not bringing it
2943         // to the front if the caller is not itself in the front.
2944         final boolean differentTopTask;
2945         if (mTargetRootTask.getDisplayArea() == mPreferredTaskDisplayArea) {
2946             final Task focusRootTask = mTargetRootTask.mDisplayContent.getFocusedRootTask();
2947             final ActivityRecord curTop = (focusRootTask == null)
2948                     ? null : focusRootTask.topRunningNonDelayedActivityLocked(mNotTop);
2949             final Task topTask = curTop != null ? curTop.getTask() : null;
2950             differentTopTask = topTask != intentTask
2951                     || (focusRootTask != null && topTask != focusRootTask.getTopMostTask())
2952                     || (focusRootTask != null && focusRootTask != origRootTask);
2953         } else {
2954             // The existing task should always be different from those in other displays.
2955             differentTopTask = true;
2956         }
2957 
2958         if (differentTopTask && !mAvoidMoveToFront) {
2959             mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
2960             if (mSourceRecord == null || inTopNonFinishingTask(mSourceRecord)) {
2961                 // We really do want to push this one into the user's face, right now.
2962                 if (mLaunchTaskBehind && mSourceRecord != null) {
2963                     intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
2964                 }
2965 
2966                 if (intentActivity.isDescendantOf(mTargetRootTask)) {
2967                     // TODO(b/151572268): Figure out a better way to move tasks in above 2-levels
2968                     //  tasks hierarchies.
2969                     if (mTargetRootTask != intentTask
2970                             && mTargetRootTask != intentTask.getParent().asTask()) {
2971                         intentTask.getParent().positionChildAt(POSITION_TOP, intentTask,
2972                                 false /* includingParents */);
2973                         intentTask = intentTask.getParent().asTaskFragment().getTask();
2974                     }
2975                     // If the activity is visible in multi-windowing mode, it may already be on
2976                     // the top (visible to user but not the global top), then the result code
2977                     // should be START_DELIVERED_TO_TOP instead of START_TASK_TO_FRONT.
2978                     final boolean wasTopOfVisibleRootTask = intentActivity.isVisibleRequested()
2979                             && intentActivity.inMultiWindowMode()
2980                             && intentActivity == mTargetRootTask.topRunningActivity();
2981                     // We only want to move to the front, if we aren't going to launch on a
2982                     // different root task. If we launch on a different root task, we will put the
2983                     // task on top there.
2984                     // Defer resuming the top activity while moving task to top, since the
2985                     // current task-top activity may not be the activity that should be resumed.
2986                     mTargetRootTask.moveTaskToFront(intentTask, mNoAnimation, mOptions,
2987                             mStartActivity.appTimeTracker, DEFER_RESUME,
2988                             "bringingFoundTaskToFront");
2989                     mMovedToFront = !wasTopOfVisibleRootTask;
2990                 } else if (intentActivity.getWindowingMode() != WINDOWING_MODE_PINNED) {
2991                     // Leaves reparenting pinned task operations to task organizer to make sure it
2992                     // dismisses pinned task properly.
2993                     // TODO(b/199997762): Consider leaving all reparent operation of organized tasks
2994                     //  to task organizer.
2995                     intentTask.reparent(mTargetRootTask, ON_TOP, REPARENT_MOVE_ROOT_TASK_TO_FRONT,
2996                             ANIMATE, DEFER_RESUME, "reparentToTargetRootTask");
2997                     mMovedToFront = true;
2998                 }
2999                 mOptions = null;
3000             }
3001         }
3002 
3003         // Update the target's launch cookie and pending remote animation to those specified in the
3004         // options if set.
3005         if (mStartActivity.mLaunchCookie != null) {
3006             intentActivity.mLaunchCookie = mStartActivity.mLaunchCookie;
3007         }
3008         if (mStartActivity.mPendingRemoteAnimation != null) {
3009             intentActivity.mPendingRemoteAnimation = mStartActivity.mPendingRemoteAnimation;
3010         }
3011 
3012         // Need to update mTargetRootTask because if task was moved out of it, the original root
3013         // task may be destroyed.
3014         mTargetRootTask = intentActivity.getRootTask();
3015         mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED,
3016                 mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetRootTask);
3017     }
3018 
inTopNonFinishingTask(ActivityRecord r)3019     private boolean inTopNonFinishingTask(ActivityRecord r) {
3020         if (r == null || r.getTask() == null) {
3021             return false;
3022         }
3023 
3024         final Task rTask = r.getTask();
3025         final Task parent = rTask.getCreatedByOrganizerTask() != null
3026                 ? rTask.getCreatedByOrganizerTask() : r.getRootTask();
3027         final ActivityRecord topNonFinishingActivity = parent != null
3028                 ? parent.getTopNonFinishingActivity() : null;
3029 
3030         return topNonFinishingActivity != null && topNonFinishingActivity.getTask() == rTask;
3031     }
3032 
resumeTargetRootTaskIfNeeded()3033     private void resumeTargetRootTaskIfNeeded() {
3034         if (mDoResume) {
3035             final ActivityRecord next = mTargetRootTask.topRunningActivity(
3036                     true /* focusableOnly */);
3037             if (next != null) {
3038                 next.setCurrentLaunchCanTurnScreenOn(true);
3039             }
3040             if (mTargetRootTask.isFocusable()) {
3041                 mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, null,
3042                         mOptions, mTransientLaunch);
3043             } else {
3044                 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
3045             }
3046         } else {
3047             ActivityOptions.abort(mOptions);
3048         }
3049         mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
3050     }
3051 
setNewTask(Task taskToAffiliate)3052     private void setNewTask(Task taskToAffiliate) {
3053         final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
3054         final Task task = mTargetRootTask.reuseOrCreateTask(
3055                 mStartActivity.info, mIntent, mVoiceSession,
3056                 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
3057         task.mTransitionController.collectExistenceChange(task);
3058         addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask");
3059 
3060         ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s",
3061                 mStartActivity, mStartActivity.getTask());
3062 
3063         if (taskToAffiliate != null) {
3064             mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
3065         }
3066     }
3067 
deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants)3068     private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) {
3069         if (mIntentDelivered) {
3070             return;
3071         }
3072 
3073         activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
3074         activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants,
3075                 mStartActivity.launchedFromPackage);
3076         mIntentDelivered = true;
3077     }
3078 
3079     /** Places {@link #mStartActivity} in {@code task} or an embedded {@link TaskFragment}. */
addOrReparentStartingActivity(@onNull Task task, String reason)3080     private void addOrReparentStartingActivity(@NonNull Task task, String reason) {
3081         TaskFragment newParent = task;
3082         if (mInTaskFragment != null) {
3083             int embeddingCheckResult = canEmbedActivity(mInTaskFragment, mStartActivity, task);
3084             if (embeddingCheckResult == EMBEDDING_ALLOWED) {
3085                 newParent = mInTaskFragment;
3086                 mStartActivity.mRequestedLaunchingTaskFragmentToken =
3087                         mInTaskFragment.getFragmentToken();
3088             } else {
3089                 // Start mStartActivity to task instead if it can't be embedded to mInTaskFragment.
3090                 sendCanNotEmbedActivityError(mInTaskFragment, embeddingCheckResult);
3091             }
3092         } else {
3093             TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null;
3094             if (candidateTf == null) {
3095                 final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */);
3096                 if (top != null) {
3097                     candidateTf = top.getTaskFragment();
3098                 }
3099             }
3100             if (candidateTf != null && candidateTf.isEmbedded()
3101                     && canEmbedActivity(candidateTf, mStartActivity, task) == EMBEDDING_ALLOWED) {
3102                 // Use the embedded TaskFragment of the top activity as the new parent if the
3103                 // activity can be embedded.
3104                 newParent = candidateTf;
3105             }
3106         }
3107         if (mStartActivity.getTaskFragment() == null
3108                 || mStartActivity.getTaskFragment() == newParent) {
3109             newParent.addChild(mStartActivity, POSITION_TOP);
3110         } else {
3111             mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason);
3112         }
3113     }
3114 
3115     /**
3116      * Notifies the client side that {@link #mStartActivity} cannot be embedded to
3117      * {@code taskFragment}.
3118      */
sendCanNotEmbedActivityError(TaskFragment taskFragment, @EmbeddingCheckResult int result)3119     private void sendCanNotEmbedActivityError(TaskFragment taskFragment,
3120             @EmbeddingCheckResult int result) {
3121         final String errMsg;
3122         switch(result) {
3123             case EMBEDDING_DISALLOWED_NEW_TASK: {
3124                 errMsg = "Cannot embed " + mStartActivity + " that launched on another task"
3125                         + ",mLaunchMode=" + launchModeToString(mLaunchMode)
3126                         + ",mLaunchFlag=" + Integer.toHexString(mLaunchFlags);
3127                 break;
3128             }
3129             case EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION: {
3130                 errMsg = "Cannot embed " + mStartActivity
3131                         + ". TaskFragment's bounds:" + taskFragment.getBounds()
3132                         + ", minimum dimensions:" + mStartActivity.getMinDimensions();
3133                 break;
3134             }
3135             case EMBEDDING_DISALLOWED_UNTRUSTED_HOST: {
3136                 errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity;
3137                 break;
3138             }
3139             default:
3140                 errMsg = "Unhandled embed result:" + result;
3141         }
3142         if (taskFragment.isOrganized()) {
3143             mService.mWindowOrganizerController.sendTaskFragmentOperationFailure(
3144                     taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken,
3145                     taskFragment, OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
3146                     new SecurityException(errMsg));
3147         } else {
3148             // If the taskFragment is not organized, just dump error message as warning logs.
3149             Slog.w(TAG, errMsg);
3150         }
3151     }
3152 
adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, boolean launchSingleTask, int launchFlags)3153     private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
3154             boolean launchSingleTask, int launchFlags) {
3155         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
3156                 (launchSingleInstance || launchSingleTask)) {
3157             // We have a conflict between the Intent and the Activity manifest, manifest wins.
3158             Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
3159                     "\"singleInstance\" or \"singleTask\"");
3160             launchFlags &=
3161                     ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
3162         } else {
3163             switch (r.info.documentLaunchMode) {
3164                 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
3165                     break;
3166                 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
3167                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
3168                     break;
3169                 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
3170                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
3171                     break;
3172                 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
3173                     if (mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) {
3174                         // Remove MULTIPLE_TASK flag along with NEW_DOCUMENT only if NEW_DOCUMENT
3175                         // is set, otherwise we still want to keep the MULTIPLE_TASK flag (if
3176                         // any) for singleInstancePerTask that the multiple tasks can be created,
3177                         // or a singleInstancePerTask activity is basically the same as a
3178                         // singleTask activity when documentLaunchMode set to never.
3179                         if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
3180                             launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
3181                                     | FLAG_ACTIVITY_MULTIPLE_TASK);
3182                         }
3183                     } else {
3184                         // TODO(b/184903976): Should FLAG_ACTIVITY_MULTIPLE_TASK always be
3185                         // removed for document-never activity?
3186                         launchFlags &=
3187                                 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
3188                     }
3189                     break;
3190             }
3191         }
3192         return launchFlags;
3193     }
3194 
getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions)3195     private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task,
3196             ActivityOptions aOptions) {
3197         final boolean onTop =
3198                 (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
3199         final Task sourceTask = mSourceRecord != null ? mSourceRecord.getTask() : null;
3200         return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, sourceTask, onTop,
3201                 mLaunchParams, launchFlags);
3202     }
3203 
isLaunchModeOneOf(int mode1, int mode2)3204     private boolean isLaunchModeOneOf(int mode1, int mode2) {
3205         return mode1 == mLaunchMode || mode2 == mLaunchMode;
3206     }
3207 
isLaunchModeOneOf(int mode1, int mode2, int mode3)3208     private boolean isLaunchModeOneOf(int mode1, int mode2, int mode3) {
3209         return mode1 == mLaunchMode || mode2 == mLaunchMode || mode3 == mLaunchMode;
3210     }
3211 
isDocumentLaunchesIntoExisting(int flags)3212     static boolean isDocumentLaunchesIntoExisting(int flags) {
3213         return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
3214                 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
3215     }
3216 
setIntent(Intent intent)3217     ActivityStarter setIntent(Intent intent) {
3218         mRequest.intent = intent;
3219         return this;
3220     }
3221 
getIntent()3222     Intent getIntent() {
3223         return mRequest.intent;
3224     }
3225 
setIntentGrants(NeededUriGrants intentGrants)3226     ActivityStarter setIntentGrants(NeededUriGrants intentGrants) {
3227         mRequest.intentGrants = intentGrants;
3228         return this;
3229     }
3230 
setReason(String reason)3231     ActivityStarter setReason(String reason) {
3232         mRequest.reason = reason;
3233         return this;
3234     }
3235 
setCaller(IApplicationThread caller)3236     ActivityStarter setCaller(IApplicationThread caller) {
3237         mRequest.caller = caller;
3238         return this;
3239     }
3240 
setResolvedType(String type)3241     ActivityStarter setResolvedType(String type) {
3242         mRequest.resolvedType = type;
3243         return this;
3244     }
3245 
setActivityInfo(ActivityInfo info)3246     ActivityStarter setActivityInfo(ActivityInfo info) {
3247         mRequest.activityInfo = info;
3248         return this;
3249     }
3250 
setResolveInfo(ResolveInfo info)3251     ActivityStarter setResolveInfo(ResolveInfo info) {
3252         mRequest.resolveInfo = info;
3253         return this;
3254     }
3255 
setVoiceSession(IVoiceInteractionSession voiceSession)3256     ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
3257         mRequest.voiceSession = voiceSession;
3258         return this;
3259     }
3260 
setVoiceInteractor(IVoiceInteractor voiceInteractor)3261     ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
3262         mRequest.voiceInteractor = voiceInteractor;
3263         return this;
3264     }
3265 
setResultTo(IBinder resultTo)3266     ActivityStarter setResultTo(IBinder resultTo) {
3267         mRequest.resultTo = resultTo;
3268         return this;
3269     }
3270 
setResultWho(String resultWho)3271     ActivityStarter setResultWho(String resultWho) {
3272         mRequest.resultWho = resultWho;
3273         return this;
3274     }
3275 
setRequestCode(int requestCode)3276     ActivityStarter setRequestCode(int requestCode) {
3277         mRequest.requestCode = requestCode;
3278         return this;
3279     }
3280 
3281     /**
3282      * Sets the pid of the caller who originally started the activity.
3283      *
3284      * Normally, the pid/uid would be the calling pid from the binder call.
3285      * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered
3286      * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid,
3287      * which represents the entity who invoked pending intent via {@link PendingIntent#send}.
3288      */
setCallingPid(int pid)3289     ActivityStarter setCallingPid(int pid) {
3290         mRequest.callingPid = pid;
3291         return this;
3292     }
3293 
3294     /**
3295      * Sets the uid of the caller who originally started the activity.
3296      *
3297      * @see #setCallingPid
3298      */
setCallingUid(int uid)3299     ActivityStarter setCallingUid(int uid) {
3300         mRequest.callingUid = uid;
3301         return this;
3302     }
3303 
setCallingPackage(String callingPackage)3304     ActivityStarter setCallingPackage(String callingPackage) {
3305         mRequest.callingPackage = callingPackage;
3306         return this;
3307     }
3308 
setCallingFeatureId(String callingFeatureId)3309     ActivityStarter setCallingFeatureId(String callingFeatureId) {
3310         mRequest.callingFeatureId = callingFeatureId;
3311         return this;
3312     }
3313 
3314     /**
3315      * Sets the pid of the caller who requested to launch the activity.
3316      *
3317      * The pid/uid represents the caller who launches the activity in this request.
3318      * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}:
3319      * the pid/uid will be the caller who called {@link PendingIntent#send()}.
3320      *
3321      * @see #setCallingPid
3322      */
setRealCallingPid(int pid)3323     ActivityStarter setRealCallingPid(int pid) {
3324         mRequest.realCallingPid = pid;
3325         return this;
3326     }
3327 
3328     /**
3329      * Sets the uid of the caller who requested to launch the activity.
3330      *
3331      * @see #setRealCallingPid
3332      */
setRealCallingUid(int uid)3333     ActivityStarter setRealCallingUid(int uid) {
3334         mRequest.realCallingUid = uid;
3335         return this;
3336     }
3337 
setStartFlags(int startFlags)3338     ActivityStarter setStartFlags(int startFlags) {
3339         mRequest.startFlags = startFlags;
3340         return this;
3341     }
3342 
setActivityOptions(SafeActivityOptions options)3343     ActivityStarter setActivityOptions(SafeActivityOptions options) {
3344         mRequest.activityOptions = options;
3345         return this;
3346     }
3347 
setActivityOptions(Bundle bOptions)3348     ActivityStarter setActivityOptions(Bundle bOptions) {
3349         return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
3350     }
3351 
setIgnoreTargetSecurity(boolean ignoreTargetSecurity)3352     ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
3353         mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
3354         return this;
3355     }
3356 
setFilterCallingUid(int filterCallingUid)3357     ActivityStarter setFilterCallingUid(int filterCallingUid) {
3358         mRequest.filterCallingUid = filterCallingUid;
3359         return this;
3360     }
3361 
setComponentSpecified(boolean componentSpecified)3362     ActivityStarter setComponentSpecified(boolean componentSpecified) {
3363         mRequest.componentSpecified = componentSpecified;
3364         return this;
3365     }
3366 
setOutActivity(ActivityRecord[] outActivity)3367     ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
3368         mRequest.outActivity = outActivity;
3369         return this;
3370     }
3371 
setInTask(Task inTask)3372     ActivityStarter setInTask(Task inTask) {
3373         mRequest.inTask = inTask;
3374         return this;
3375     }
3376 
setInTaskFragment(TaskFragment taskFragment)3377     ActivityStarter setInTaskFragment(TaskFragment taskFragment) {
3378         mRequest.inTaskFragment = taskFragment;
3379         return this;
3380     }
3381 
setWaitResult(WaitResult result)3382     ActivityStarter setWaitResult(WaitResult result) {
3383         mRequest.waitResult = result;
3384         return this;
3385     }
3386 
setProfilerInfo(ProfilerInfo info)3387     ActivityStarter setProfilerInfo(ProfilerInfo info) {
3388         mRequest.profilerInfo = info;
3389         return this;
3390     }
3391 
setGlobalConfiguration(Configuration config)3392     ActivityStarter setGlobalConfiguration(Configuration config) {
3393         mRequest.globalConfig = config;
3394         return this;
3395     }
3396 
setUserId(int userId)3397     ActivityStarter setUserId(int userId) {
3398         mRequest.userId = userId;
3399         return this;
3400     }
3401 
setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup)3402     ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
3403         mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
3404         return this;
3405     }
3406 
setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent)3407     ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
3408         mRequest.originatingPendingIntent = originatingPendingIntent;
3409         return this;
3410     }
3411 
setBackgroundStartPrivileges( BackgroundStartPrivileges backgroundStartPrivileges)3412     ActivityStarter setBackgroundStartPrivileges(
3413             BackgroundStartPrivileges backgroundStartPrivileges) {
3414         mRequest.backgroundStartPrivileges = backgroundStartPrivileges;
3415         return this;
3416     }
3417 
setErrorCallbackToken(@ullable IBinder errorCallbackToken)3418     ActivityStarter setErrorCallbackToken(@Nullable IBinder errorCallbackToken) {
3419         mRequest.errorCallbackToken = errorCallbackToken;
3420         return this;
3421     }
3422 
dump(PrintWriter pw, String prefix)3423     void dump(PrintWriter pw, String prefix) {
3424         pw.print(prefix);
3425         pw.print("mCurrentUser=");
3426         pw.println(mRootWindowContainer.mCurrentUser);
3427         pw.print(prefix);
3428         pw.print("mLastStartReason=");
3429         pw.println(mLastStartReason);
3430         pw.print(prefix);
3431         pw.print("mLastStartActivityTimeMs=");
3432         pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
3433         pw.print(prefix);
3434         pw.print("mLastStartActivityResult=");
3435         pw.println(mLastStartActivityResult);
3436         if (mLastStartActivityRecord != null) {
3437             pw.print(prefix);
3438             pw.println("mLastStartActivityRecord:");
3439             mLastStartActivityRecord.dump(pw, prefix + "  ", true /* dumpAll */);
3440         }
3441         if (mStartActivity != null) {
3442             pw.print(prefix);
3443             pw.println("mStartActivity:");
3444             mStartActivity.dump(pw, prefix + "  ", true /* dumpAll */);
3445         }
3446         if (mIntent != null) {
3447             pw.print(prefix);
3448             pw.print("mIntent=");
3449             pw.println(mIntent);
3450         }
3451         if (mOptions != null) {
3452             pw.print(prefix);
3453             pw.print("mOptions=");
3454             pw.println(mOptions);
3455         }
3456         pw.print(prefix);
3457         pw.print("mLaunchMode=");
3458         pw.print(launchModeToString(mLaunchMode));
3459         pw.print(prefix);
3460         pw.print("mLaunchFlags=0x");
3461         pw.print(Integer.toHexString(mLaunchFlags));
3462         pw.print(" mDoResume=");
3463         pw.print(mDoResume);
3464         pw.print(" mAddingToTask=");
3465         pw.print(mAddingToTask);
3466         pw.print(" mInTaskFragment=");
3467         pw.println(mInTaskFragment);
3468     }
3469 }
3470