blob: 5a1eed8897b643f527b4497fe17538fe44237c9c [file] [log] [blame]
Kenny Guyb1b30262016-02-09 16:02:35 +00001/*
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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080018
Michal Karpinski7b97a022018-12-14 15:17:29 +000019import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
Wale Ogunwale01d66562015-12-29 08:19:19 -080020import static android.app.Activity.RESULT_CANCELED;
Bryce Leef9d49542017-06-26 16:27:32 -070021import static android.app.ActivityManager.START_ABORTED;
Bryce Leeaa5e8c32017-03-01 16:01:06 -080022import static android.app.ActivityManager.START_CANCELED;
Wale Ogunwale01d66562015-12-29 08:19:19 -080023import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
24import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
25import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
26import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
27import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
28import static android.app.ActivityManager.START_SUCCESS;
29import static android.app.ActivityManager.START_TASK_TO_FRONT;
Louis Chang0513a942019-03-06 12:38:13 +080030import static android.app.WaitResult.LAUNCH_STATE_COLD;
31import static android.app.WaitResult.LAUNCH_STATE_HOT;
Wale Ogunwale68278562017-09-23 17:13:55 -070032import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
33import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -070034import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070035import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
36import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070037import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080038import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
39import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
Wale Ogunwale2a25a622016-01-30 11:27:21 -080040import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080041import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080042import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080043import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080044import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
45import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
Wale Ogunwale01d66562015-12-29 08:19:19 -080046import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
47import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
48import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
49import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
50import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
Louis Changb45ee7e2019-01-17 10:36:56 +080051import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
Wale Ogunwale01d66562015-12-29 08:19:19 -080052import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Bryce Leef65ee7e2018-03-26 16:03:47 -070053import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwale01d66562015-12-29 08:19:19 -080054import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
55import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
56import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
Michal Karpinski7b97a022018-12-14 15:17:29 +000057import static android.content.pm.PackageManager.PERMISSION_GRANTED;
David Stevensc6b91c62017-02-08 14:23:58 -080058import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070059import static android.view.Display.INVALID_DISPLAY;
Riddle Hsub70b36d2018-09-11 21:20:02 +080060
Louis Changdd3592a2018-11-05 11:04:14 +080061import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
Wale Ogunwale59507092018-10-29 09:00:30 -070062import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
63import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
64import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
65import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
66import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
67import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
68import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
69import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
70import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
71import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
72import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
75import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
76import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
77import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
78import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
79import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
80import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Louis Chang6fb1e842018-12-03 16:07:50 +080081import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
82import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
Wale Ogunwale59507092018-10-29 09:00:30 -070083import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
84import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
Winson Chung74666102017-02-22 17:49:24 -080085
Todd Kennedye9910222017-02-21 16:00:11 -080086import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010087import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080088import android.app.ActivityManager;
89import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080090import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080091import android.app.PendingIntent;
92import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070093import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080094import android.content.IIntentSender;
95import android.content.Intent;
96import android.content.IntentSender;
97import android.content.pm.ActivityInfo;
98import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080099import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +0000100import android.content.pm.PackageManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800101import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +0000102import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800103import android.content.res.Configuration;
104import android.graphics.Rect;
105import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800106import android.os.Bundle;
107import android.os.IBinder;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000108import android.os.Process;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109import android.os.RemoteException;
110import android.os.SystemClock;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100111import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800112import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000113import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800114import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700115import android.text.TextUtils;
Michal Karpinskib7daac22019-03-25 10:12:41 +0000116import android.util.ArraySet;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800117import android.util.EventLog;
Bryce Leedaa91e42017-12-06 14:13:01 -0800118import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800119import android.util.Slog;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800120
Bryce Leed3624e12017-11-30 08:51:45 -0800121import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800122import com.android.internal.app.HeavyWeightSwitcherActivity;
123import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700124import com.android.server.am.EventLogTags;
125import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800126import com.android.server.pm.InstantAppResolver;
Wale Ogunwale59507092018-10-29 09:00:30 -0700127import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
128import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800129
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700130import java.io.PrintWriter;
131import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700132import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800133
134/**
Bryce Leed3624e12017-11-30 08:51:45 -0800135 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800136 *
137 * This class collects all the logic for determining how an intent and flags should be turned into
138 * an activity and associated task and stack.
139 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800140class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700141 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800142 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
143 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
144 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
145 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700146 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800147
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700148 private final ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800149 private final RootActivityContainer mRootActivityContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800150 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100151 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800152 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800153
Wale Ogunwale01d66562015-12-29 08:19:19 -0800154 // Share state variable among methods when starting an activity.
155 private ActivityRecord mStartActivity;
156 private Intent mIntent;
157 private int mCallingUid;
158 private ActivityOptions mOptions;
159
Ricky Waib147fa12019-04-25 16:08:30 +0100160 // If it is true, background activity can only be started in an existing task that contains
Alan Stokes07389b62019-05-20 15:22:54 +0100161 // an activity with same uid, or if activity starts are enabled in developer options.
Ricky Waib147fa12019-04-25 16:08:30 +0100162 private boolean mRestrictedBgActivity;
163
Bryce Lee7daee392017-10-12 13:46:18 -0700164 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800165 private boolean mLaunchTaskBehind;
166 private int mLaunchFlags;
167
Bryce Leeec55eb02017-12-05 20:51:27 -0800168 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800169
170 private ActivityRecord mNotTop;
171 private boolean mDoResume;
172 private int mStartFlags;
173 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700174
David Stevense5a7b642017-05-22 13:18:23 -0700175 // The display to launch the activity onto, barring any strong reason to do otherwise.
176 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800177
178 private TaskRecord mInTask;
179 private boolean mAddingToTask;
180 private TaskRecord mReuseTask;
181
182 private ActivityInfo mNewTaskInfo;
183 private Intent mNewTaskIntent;
184 private ActivityStack mSourceStack;
185 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800186 private boolean mMovedToFront;
187 private boolean mNoAnimation;
188 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700189 private boolean mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700190 private boolean mFrozeTaskList;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800191
Bryce Lee325e09682017-10-05 17:20:25 -0700192 // We must track when we deliver the new intent since multiple code paths invoke
193 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
194 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
195 // delivered at most once.
196 private boolean mIntentDelivered;
197
Wale Ogunwale01d66562015-12-29 08:19:19 -0800198 private IVoiceInteractionSession mVoiceSession;
199 private IVoiceInteractor mVoiceInteractor;
200
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700201 // Last activity record we attempted to start
202 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
203 // The result of the last activity we attempted to start.
204 private int mLastStartActivityResult;
205 // Time in milli seconds we attempted to start the last activity.
206 private long mLastStartActivityTimeMs;
207 // The reason we were trying to start the last activity
208 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700209
Bryce Lee4c9a5972017-12-01 22:14:24 -0800210 /*
211 * Request details provided through setter methods. Should be reset after {@link #execute()}
212 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
213 * {@link #startResolvedActivity} is invoked directly.
214 */
215 private Request mRequest = new Request();
216
Bryce Leed3624e12017-11-30 08:51:45 -0800217 /**
218 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
219 * used by tests to inject their own starter implementations for verification purposes.
220 */
221 @VisibleForTesting
222 interface Factory {
223 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800224 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
225 */
226 void setController(ActivityStartController controller);
227
228 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800229 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
230 * @param controller The {@link ActivityStartController} which the starter who will own
231 * this instance.
232 * @return an {@link ActivityStarter}
233 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800234 ActivityStarter obtain();
235
236 /**
237 * Recycles a starter for reuse.
238 */
239 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800240 }
241
Bryce Leed3624e12017-11-30 08:51:45 -0800242 /**
243 * Default implementation of {@link StarterFactory}.
244 */
245 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800246 /**
247 * The maximum count of starters that should be active at one time:
248 * 1. last ran starter (for logging and post activity processing)
249 * 2. current running starter
250 * 3. starter from re-entry in (2)
251 */
252 private final int MAX_STARTER_COUNT = 3;
253
Bryce Lee4c9a5972017-12-01 22:14:24 -0800254 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700255 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800256 private ActivityStackSupervisor mSupervisor;
257 private ActivityStartInterceptor mInterceptor;
258
Bryce Leedaa91e42017-12-06 14:13:01 -0800259 private SynchronizedPool<ActivityStarter> mStarterPool =
260 new SynchronizedPool<>(MAX_STARTER_COUNT);
261
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700262 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800263 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
264 mService = service;
265 mSupervisor = supervisor;
266 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800267 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800268
269 @Override
270 public void setController(ActivityStartController controller) {
271 mController = controller;
272 }
273
274 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800275 public ActivityStarter obtain() {
276 ActivityStarter starter = mStarterPool.acquire();
277
278 if (starter == null) {
279 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
280 }
281
282 return starter;
283 }
284
285 @Override
286 public void recycle(ActivityStarter starter) {
287 starter.reset(true /* clearRequest*/);
288 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800289 }
290 }
291
292 /**
293 * Container for capturing initial start request details. This information is NOT reset until
294 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
295 * parameters.
296 *
297 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
298 * the request object. Note that some member variables are referenced in
299 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
300 * execution.
301 */
302 private static class Request {
303 private static final int DEFAULT_CALLING_UID = -1;
304 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000305 static final int DEFAULT_REAL_CALLING_UID = -1;
306 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800307
308 IApplicationThread caller;
309 Intent intent;
310 Intent ephemeralIntent;
311 String resolvedType;
312 ActivityInfo activityInfo;
313 ResolveInfo resolveInfo;
314 IVoiceInteractionSession voiceSession;
315 IVoiceInteractor voiceInteractor;
316 IBinder resultTo;
317 String resultWho;
318 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000319 int callingPid = DEFAULT_CALLING_PID;
320 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800321 String callingPackage;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000322 int realCallingPid = DEFAULT_REAL_CALLING_PID;
323 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800324 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100325 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800326 boolean ignoreTargetSecurity;
327 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000328 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800329 ActivityRecord[] outActivity;
330 TaskRecord inTask;
331 String reason;
332 ProfilerInfo profilerInfo;
333 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800334 int userId;
335 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700336 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100337 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000338 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800339
340 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200341 * If set to {@code true}, allows this activity start to look into
342 * {@link PendingRemoteAnimationRegistry}
343 */
344 boolean allowPendingRemoteAnimationRegistryLookup;
345
346 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800347 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100348 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800349 * {@see ActivityStarter#startActivityMayWait}.
350 */
351 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800352
353 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800354 * Ensure constructed request matches reset instance.
355 */
356 Request() {
357 reset();
358 }
359
360 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800361 * Sets values back to the initial state, clearing any held references.
362 */
363 void reset() {
364 caller = null;
365 intent = null;
366 ephemeralIntent = null;
367 resolvedType = null;
368 activityInfo = null;
369 resolveInfo = null;
370 voiceSession = null;
371 voiceInteractor = null;
372 resultTo = null;
373 resultWho = null;
374 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800375 callingPid = DEFAULT_CALLING_PID;
376 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800377 callingPackage = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000378 realCallingPid = DEFAULT_REAL_CALLING_PID;
379 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800380 startFlags = 0;
381 activityOptions = null;
382 ignoreTargetSecurity = false;
383 componentSpecified = false;
384 outActivity = null;
385 inTask = null;
386 reason = null;
387 profilerInfo = null;
388 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800389 userId = 0;
390 waitResult = null;
391 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000392 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200393 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700394 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100395 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000396 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800397 }
398
399 /**
400 * Adopts all values from passed in request.
401 */
402 void set(Request request) {
403 caller = request.caller;
404 intent = request.intent;
405 ephemeralIntent = request.ephemeralIntent;
406 resolvedType = request.resolvedType;
407 activityInfo = request.activityInfo;
408 resolveInfo = request.resolveInfo;
409 voiceSession = request.voiceSession;
410 voiceInteractor = request.voiceInteractor;
411 resultTo = request.resultTo;
412 resultWho = request.resultWho;
413 requestCode = request.requestCode;
414 callingPid = request.callingPid;
415 callingUid = request.callingUid;
416 callingPackage = request.callingPackage;
417 realCallingPid = request.realCallingPid;
418 realCallingUid = request.realCallingUid;
419 startFlags = request.startFlags;
420 activityOptions = request.activityOptions;
421 ignoreTargetSecurity = request.ignoreTargetSecurity;
422 componentSpecified = request.componentSpecified;
423 outActivity = request.outActivity;
424 inTask = request.inTask;
425 reason = request.reason;
426 profilerInfo = request.profilerInfo;
427 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800428 userId = request.userId;
429 waitResult = request.waitResult;
430 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000431 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200432 allowPendingRemoteAnimationRegistryLookup
433 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700434 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100435 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000436 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800437 }
Bryce Leed3624e12017-11-30 08:51:45 -0800438 }
439
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700440 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800441 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
442 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800443 mService = service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800444 mRootActivityContainer = service.mRootActivityContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800445 mSupervisor = supervisor;
446 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800447 reset(true);
448 }
449
450 /**
451 * Effectively duplicates the starter passed in. All state and request values will be
452 * mirrored.
453 * @param starter
454 */
455 void set(ActivityStarter starter) {
456 mStartActivity = starter.mStartActivity;
457 mIntent = starter.mIntent;
458 mCallingUid = starter.mCallingUid;
459 mOptions = starter.mOptions;
Ricky Waib147fa12019-04-25 16:08:30 +0100460 mRestrictedBgActivity = starter.mRestrictedBgActivity;
Bryce Leedaa91e42017-12-06 14:13:01 -0800461
462 mLaunchTaskBehind = starter.mLaunchTaskBehind;
463 mLaunchFlags = starter.mLaunchFlags;
464 mLaunchMode = starter.mLaunchMode;
465
Bryce Leeec55eb02017-12-05 20:51:27 -0800466 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800467
468 mNotTop = starter.mNotTop;
469 mDoResume = starter.mDoResume;
470 mStartFlags = starter.mStartFlags;
471 mSourceRecord = starter.mSourceRecord;
472 mPreferredDisplayId = starter.mPreferredDisplayId;
473
474 mInTask = starter.mInTask;
475 mAddingToTask = starter.mAddingToTask;
476 mReuseTask = starter.mReuseTask;
477
478 mNewTaskInfo = starter.mNewTaskInfo;
479 mNewTaskIntent = starter.mNewTaskIntent;
480 mSourceStack = starter.mSourceStack;
481
482 mTargetStack = starter.mTargetStack;
483 mMovedToFront = starter.mMovedToFront;
484 mNoAnimation = starter.mNoAnimation;
485 mKeepCurTransition = starter.mKeepCurTransition;
486 mAvoidMoveToFront = starter.mAvoidMoveToFront;
Winson Chunge219ae12019-07-18 13:43:23 -0700487 mFrozeTaskList = starter.mFrozeTaskList;
Bryce Leedaa91e42017-12-06 14:13:01 -0800488
489 mVoiceSession = starter.mVoiceSession;
490 mVoiceInteractor = starter.mVoiceInteractor;
491
492 mIntentDelivered = starter.mIntentDelivered;
493
494 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800495 }
496
Bryce Lee4c9a5972017-12-01 22:14:24 -0800497 ActivityRecord getStartActivity() {
498 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800499 }
500
Bryce Lee4c9a5972017-12-01 22:14:24 -0800501 boolean relatedToPackage(String packageName) {
502 return (mLastStartActivityRecord[0] != null
503 && packageName.equals(mLastStartActivityRecord[0].packageName))
504 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
505 }
506
507 /**
508 * Starts an activity based on the request parameters provided earlier.
509 * @return The starter result.
510 */
511 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800512 try {
513 // TODO(b/64750076): Look into passing request directly to these methods to allow
514 // for transactional diffs and preprocessing.
515 if (mRequest.mayWait) {
516 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000517 mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
518 mRequest.intent, mRequest.resolvedType,
Bryce Leedaa91e42017-12-06 14:13:01 -0800519 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
520 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
521 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100522 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200523 mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100524 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000525 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800526 } else {
527 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
528 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
529 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
530 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
531 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
532 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
533 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200534 mRequest.outActivity, mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100535 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000536 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800537 }
538 } finally {
539 onExecutionComplete();
540 }
541 }
542
543 /**
544 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
545 * Note that this method is called internally as well as part of {@link #startActivity}.
546 *
547 * @return The start result.
548 */
549 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
550 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000551 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
Bryce Leedaa91e42017-12-06 14:13:01 -0800552 try {
Louis Chang136c82e2019-04-12 12:10:21 +0800553 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(r.intent);
554 mLastStartReason = "startResolvedActivity";
555 mLastStartActivityTimeMs = System.currentTimeMillis();
556 mLastStartActivityRecord[0] = r;
557 mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor,
Ricky Waib147fa12019-04-25 16:08:30 +0100558 startFlags, doResume, options, inTask, mLastStartActivityRecord,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000559 false /* restrictedBgActivity */);
Louis Chang136c82e2019-04-12 12:10:21 +0800560 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult,
561 mLastStartActivityRecord[0]);
562 return mLastStartActivityResult;
Bryce Leedaa91e42017-12-06 14:13:01 -0800563 } finally {
564 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800565 }
566 }
567
568 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700569 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
570 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
571 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
572 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100573 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200574 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100575 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000576 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700577
578 if (TextUtils.isEmpty(reason)) {
579 throw new IllegalArgumentException("Need to specify a reason.");
580 }
581 mLastStartReason = reason;
582 mLastStartActivityTimeMs = System.currentTimeMillis();
583 mLastStartActivityRecord[0] = null;
584
585 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
586 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
587 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
588 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000589 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000590 allowBackgroundActivityStart);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700591
592 if (outActivity != null) {
593 // mLastStartActivityRecord[0] is set in the call to startActivity above.
594 outActivity[0] = mLastStartActivityRecord[0];
595 }
Bryce Leef9d49542017-06-26 16:27:32 -0700596
Bryce Lee93e7f792017-10-25 15:54:55 -0700597 return getExternalResult(mLastStartActivityResult);
598 }
599
Bryce Leed3624e12017-11-30 08:51:45 -0800600 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700601 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700602 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700603 }
604
Bryce Leedaa91e42017-12-06 14:13:01 -0800605 /**
606 * Called when execution is complete. Sets state indicating completion and proceeds with
607 * recycling if appropriate.
608 */
609 private void onExecutionComplete() {
610 mController.onExecutionComplete(this);
611 }
612
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700613 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800614 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
615 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
616 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
617 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100618 SafeActivityOptions options,
619 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100620 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000621 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Jorim Jaggi2e3bcea2019-04-01 15:09:48 +0200622 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800623 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700624 // Pull the optional Ephemeral Installer-only bundle out of the options early.
625 final Bundle verificationBundle
626 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800627
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700628 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800629 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700630 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800631 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700632 callingPid = callerApp.getPid();
633 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800634 } else {
635 Slog.w(TAG, "Unable to find app for caller " + caller
636 + " (pid=" + callingPid + ") when starting: "
637 + intent.toString());
638 err = ActivityManager.START_PERMISSION_DENIED;
639 }
640 }
641
Bryce Lee93e7f792017-10-25 15:54:55 -0700642 final int userId = aInfo != null && aInfo.applicationInfo != null
643 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800644
645 if (err == ActivityManager.START_SUCCESS) {
646 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800647 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800648 }
649
650 ActivityRecord sourceRecord = null;
651 ActivityRecord resultRecord = null;
652 if (resultTo != null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800653 sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800654 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
655 "Will send result to " + resultTo + " " + sourceRecord);
656 if (sourceRecord != null) {
657 if (requestCode >= 0 && !sourceRecord.finishing) {
658 resultRecord = sourceRecord;
659 }
660 }
661 }
662
663 final int launchFlags = intent.getFlags();
664
665 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
666 // Transfer the result target from the source activity to the new
667 // one being started, including any failures.
668 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100669 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800670 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
671 }
672 resultRecord = sourceRecord.resultTo;
673 if (resultRecord != null && !resultRecord.isInStackLocked()) {
674 resultRecord = null;
675 }
676 resultWho = sourceRecord.resultWho;
677 requestCode = sourceRecord.requestCode;
678 sourceRecord.resultTo = null;
679 if (resultRecord != null) {
680 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
681 }
682 if (sourceRecord.launchedFromUid == callingUid) {
683 // The new activity is being launched from the same uid as the previous
684 // activity in the flow, and asking to forward its result back to the
685 // previous. In this case the activity is serving as a trampoline between
686 // the two, so we also want to update its launchedFromPackage to be the
687 // same as the previous activity. Note that this is safe, since we know
688 // these two packages come from the same uid; the caller could just as
689 // well have supplied that same package name itself. This specifially
690 // deals with the case of an intent picker/chooser being launched in the app
691 // flow to redirect to an activity picked by the user, where we want the final
692 // activity to consider it to have been launched by the previous app activity.
693 callingPackage = sourceRecord.launchedFromPackage;
694 }
695 }
696
697 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
698 // We couldn't find a class that can handle the given Intent.
699 // That's the end of that!
700 err = ActivityManager.START_INTENT_NOT_RESOLVED;
701 }
702
703 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
704 // We couldn't find the specific class specified in the Intent.
705 // Also the end of the line.
706 err = ActivityManager.START_CLASS_NOT_FOUND;
707 }
708
709 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800710 && sourceRecord.getTaskRecord().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800711 // If this activity is being launched as part of a voice session, we need
712 // to ensure that it is safe to do so. If the upcoming activity will also
713 // be part of the voice session, we can only launch it if it has explicitly
714 // said it supports the VOICE category, or it is a part of the calling app.
715 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
716 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
717 try {
718 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700719 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800720 intent.getComponent(), intent, resolvedType)) {
721 Slog.w(TAG,
722 "Activity being started in current voice task does not support voice: "
723 + intent);
724 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
725 }
726 } catch (RemoteException e) {
727 Slog.w(TAG, "Failure checking voice capabilities", e);
728 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
729 }
730 }
731 }
732
733 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
734 // If the caller is starting a new voice session, just make sure the target
735 // is actually allowing it to run this way.
736 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700737 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800738 intent, resolvedType)) {
739 Slog.w(TAG,
740 "Activity being started in new voice task does not support: "
741 + intent);
742 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
743 }
744 } catch (RemoteException e) {
745 Slog.w(TAG, "Failure checking voice capabilities", e);
746 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
747 }
748 }
749
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800750 final ActivityStack resultStack = resultRecord == null
751 ? null : resultRecord.getActivityStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800752
Wale Ogunwale01d66562015-12-29 08:19:19 -0800753 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800754 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800755 resultStack.sendActivityResultLocked(
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000756 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800757 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100758 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800759 return err;
760 }
761
762 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100763 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700764 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700765 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800766 callingPid, resolvedType, aInfo.applicationInfo);
Hai Zhangf4da9be2019-05-01 13:46:06 +0800767 abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
768 callingPackage);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800769
Ricky Waib147fa12019-04-25 16:08:30 +0100770 boolean restrictedBgActivity = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000771 if (!abort) {
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000772 try {
773 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
774 "shouldAbortBackgroundActivityStart");
Ricky Waib147fa12019-04-25 16:08:30 +0100775 restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
Ricky Waiaca8a772019-04-04 16:01:06 +0100776 callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000777 originatingPendingIntent, allowBackgroundActivityStart, intent);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000778 } finally {
779 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
780 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000781 }
782
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100783 // Merge the two options bundles, while realCallerOptions takes precedence.
784 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700785 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200786 if (allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700787 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200788 .getPendingRemoteAnimationRegistry()
789 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
790 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700791 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800792 try {
793 // The Intent we give to the watcher has the extra data
794 // stripped off, since it can contain private information.
795 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700796 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800797 aInfo.applicationInfo.packageName);
798 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700799 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800800 }
801 }
802
Rubin Xu58d25992016-01-21 17:47:13 +0000803 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100804 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100805 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100806 // activity start was intercepted, e.g. because the target user is currently in quiet
807 // mode (turn off work) or the target application is suspended
808 intent = mInterceptor.mIntent;
809 rInfo = mInterceptor.mRInfo;
810 aInfo = mInterceptor.mAInfo;
811 resolvedType = mInterceptor.mResolvedType;
812 inTask = mInterceptor.mInTask;
813 callingPid = mInterceptor.mCallingPid;
814 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100815 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100816 }
817
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800818 if (abort) {
819 if (resultRecord != null) {
820 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000821 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800822 }
823 // We pretend to the caller that it was really started, but
824 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100825 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700826 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800827 }
828
829 // If permissions need a review before any of the app components can run, we
830 // launch the review activity and pass a pending intent to start the activity
831 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700832 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700833 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800834 aInfo.packageName, userId)) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700835 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800836 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
837 callingUid, userId, null, null, 0, new Intent[]{intent},
838 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
839 | PendingIntent.FLAG_ONE_SHOT, null);
840
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800841 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
Philip P. Moltmannc3e66d02019-01-31 15:56:18 -0800842
843 int flags = intent.getFlags();
844 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
845
846 /*
847 * Prevent reuse of review activity: Each app needs their own review activity. By
848 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
849 * with the same launch parameters (extras are ignored). Hence to avoid possible
850 * reuse force a new activity via the MULTIPLE_TASK flag.
851 *
852 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
853 * hence no need to add the flag in this case.
854 */
855 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
856 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
857 }
858 newIntent.setFlags(flags);
859
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800860 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
861 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
862 if (resultRecord != null) {
863 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
864 }
865 intent = newIntent;
866
867 resolvedType = null;
868 callingUid = realCallingUid;
869 callingPid = realCallingPid;
870
Svet Ganovcbcbf662018-05-10 17:25:29 -0700871 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700872 computeResolveFilterUid(
873 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800874 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
875 null /*profilerInfo*/);
876
877 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800878 final ActivityStack focusedStack =
879 mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800880 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
881 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian52d255c2018-07-13 11:32:19 -0700882 + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800883 }
884 }
885 }
886
887 // If we have an ephemeral app, abort the process of launching the resolved intent.
888 // Instead, launch the ephemeral installer. Once the installer is finished, it
889 // starts either the intent we resolved here [on install error] or the ephemeral
890 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800891 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800892 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700893 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800894 resolvedType = null;
895 callingUid = realCallingUid;
896 callingPid = realCallingPid;
897
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800898 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
899 }
900
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700901 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -0700902 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800903 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100904 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800905 if (outActivity != null) {
906 outActivity[0] = r;
907 }
908
909 if (r.appTimeTracker == null && sourceRecord != null) {
910 // If the caller didn't specify an explicit time tracker, we want to continue
911 // tracking under any it has.
912 r.appTimeTracker = sourceRecord.appTimeTracker;
913 }
914
Wale Ogunwaled32da472018-11-16 07:19:28 -0800915 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100916
917 // If we are starting an activity that is not from the same uid as the currently resumed
918 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800919 if (voiceSession == null && (stack.getResumedActivity() == null
920 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700921 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800922 realCallingPid, realCallingUid, "Activity start")) {
Alan Stokes07389b62019-05-20 15:22:54 +0100923 if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
Ricky Waib147fa12019-04-25 16:08:30 +0100924 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000925 sourceRecord, startFlags, stack, callerApp));
Ricky Waib147fa12019-04-25 16:08:30 +0100926 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100927 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800928 return ActivityManager.START_SWITCHES_CANCELED;
929 }
930 }
931
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700932 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -0800933 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800934
Jorim Jaggi2e3bcea2019-04-01 15:09:48 +0200935 final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000936 true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
Jorim Jaggi2e3bcea2019-04-01 15:09:48 +0200937 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
938 return res;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800939 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800940
Ricky Waiaca8a772019-04-04 16:01:06 +0100941 boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000942 final String callingPackage, int realCallingUid, int realCallingPid,
943 WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
944 boolean allowBackgroundActivityStart, Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000945 // don't abort for the most important UIDs
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100946 final int callingAppId = UserHandle.getAppId(callingUid);
947 if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
948 || callingAppId == Process.NFC_UID) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000949 return false;
950 }
Alan Stokeseea8d3e2019-04-10 17:37:25 +0100951 // don't abort if the callingUid has a visible window or is a persistent system process
Riddle Hsua0536432019-02-16 00:38:59 +0800952 final int callingUidProcState = mService.getUidState(callingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000953 final boolean callingUidHasAnyVisibleWindow =
954 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
955 final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
Amith Yamasanif235d0b2019-03-20 22:49:43 -0700956 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP
957 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100958 final boolean isCallingUidPersistentSystemProcess =
959 callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Alan Stokeseea8d3e2019-04-10 17:37:25 +0100960 if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000961 return false;
962 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000963 // take realCallingUid into consideration
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000964 final int realCallingUidProcState = (callingUid == realCallingUid)
965 ? callingUidProcState
Riddle Hsua0536432019-02-16 00:38:59 +0800966 : mService.getUidState(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000967 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
968 ? callingUidHasAnyVisibleWindow
969 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
970 final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
971 ? isCallingUidForeground
972 : realCallingUidHasAnyVisibleWindow
973 || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100974 final int realCallingAppId = UserHandle.getAppId(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000975 final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
976 ? isCallingUidPersistentSystemProcess
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100977 : (realCallingAppId == Process.SYSTEM_UID)
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000978 || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000979 if (realCallingUid != callingUid) {
Alan Stokes6ac9efd2019-05-09 12:50:37 +0000980 // don't abort if the realCallingUid has a visible window
981 if (realCallingUidHasAnyVisibleWindow) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000982 return false;
983 }
984 // if the realCallingUid is a persistent system process, abort if the IntentSender
985 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +0000986 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000987 return false;
988 }
Michal Karpinskida34cd42019-04-02 19:46:52 +0100989 // don't abort if the realCallingUid is an associated companion app
990 if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
991 realCallingUid)) {
992 return false;
993 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000994 }
Michal Karpinski7b97a022018-12-14 15:17:29 +0000995 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
996 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
997 == PERMISSION_GRANTED) {
998 return false;
999 }
Michal Karpinski82bb5902018-11-28 15:52:52 +00001000 // don't abort if the caller has the same uid as the recents component
1001 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
1002 return false;
1003 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001004 // don't abort if the callingUid is the device owner
1005 if (mService.isDeviceOwner(callingUid)) {
Michal Karpinski302dcec2019-02-01 11:48:25 +00001006 return false;
1007 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001008 // don't abort if the callingUid has companion device
Ricky Wai2452e2d2019-03-18 19:19:08 +00001009 final int callingUserId = UserHandle.getUserId(callingUid);
Michal Karpinskida34cd42019-04-02 19:46:52 +01001010 if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
Ricky Wai2452e2d2019-03-18 19:19:08 +00001011 return false;
1012 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +01001013 // If we don't have callerApp at this point, no caller was provided to startActivity().
1014 // That's the case for PendingIntent-based starts, since the creator's process might not be
1015 // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
1016 // caller, so that we can make the decision based on its foreground/whitelisted state.
1017 int callerAppUid = callingUid;
1018 if (callerApp == null) {
1019 callerApp = mService.getProcessController(realCallingPid, realCallingUid);
1020 callerAppUid = realCallingUid;
1021 }
1022 // don't abort if the callerApp or other processes of that uid are whitelisted in any way
1023 if (callerApp != null) {
1024 // first check the original calling process
1025 if (callerApp.areBackgroundActivityStartsAllowed()) {
1026 return false;
1027 }
1028 // only if that one wasn't whitelisted, check the other ones
1029 final ArraySet<WindowProcessController> uidProcesses =
1030 mService.mProcessMap.getProcesses(callerAppUid);
1031 if (uidProcesses != null) {
1032 for (int i = uidProcesses.size() - 1; i >= 0; i--) {
1033 final WindowProcessController proc = uidProcesses.valueAt(i);
1034 if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) {
1035 return false;
1036 }
1037 }
1038 }
1039 }
Michal Karpinski15486842019-04-25 17:33:42 +01001040 // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
1041 if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
1042 Slog.w(TAG, "Background activity start for " + callingPackage
1043 + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
1044 return false;
1045 }
Michal Karpinskic02364c2019-01-22 13:00:04 +00001046 // anything that has fallen through would currently be aborted
1047 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +00001048 + "; callingUid: " + callingUid
1049 + "; isCallingUidForeground: " + isCallingUidForeground
1050 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1051 + "; realCallingUid: " + realCallingUid
1052 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
1053 + "; isRealCallingUidPersistentSystemProcess: "
Ricky Waiaca8a772019-04-04 16:01:06 +01001054 + isRealCallingUidPersistentSystemProcess
Michal Karpinskid0162852019-01-15 16:05:25 +00001055 + "; originatingPendingIntent: " + originatingPendingIntent
1056 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
1057 + "; intent: " + intent
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001058 + "; callerApp: " + callerApp
Michal Karpinskid0162852019-01-15 16:05:25 +00001059 + "]");
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001060 // log aborted activity start to TRON
1061 if (mService.isActivityStartsLoggingEnabled()) {
1062 mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1063 callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1064 realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001065 (originatingPendingIntent != null));
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001066 }
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001067 return true;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001068 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001069
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001070 /**
1071 * Creates a launch intent for the given auxiliary resolution data.
1072 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001073 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -07001074 Intent originalIntent, String callingPackage, Bundle verificationBundle,
1075 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001076 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001077 // request phase two resolution
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001078 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001079 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1080 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001081 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001082 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001083 originalIntent,
1084 InstantAppResolver.sanitizeIntent(originalIntent),
1085 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1086 callingPackage,
1087 verificationBundle,
1088 resolvedType,
1089 userId,
1090 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1091 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1092 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1093 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001094 }
1095
Riddle Hsu16567132018-08-16 21:37:47 +08001096 void postStartActivityProcessing(ActivityRecord r, int result,
1097 ActivityStack startedActivityStack) {
Winson Chunge219ae12019-07-18 13:43:23 -07001098 if (!ActivityManager.isStartResultSuccessful(result)) {
1099 if (mFrozeTaskList) {
1100 // If we specifically froze the task list as part of starting an activity, then
1101 // reset the frozen list state if it failed to start. This is normally otherwise
1102 // called when the freeze-timeout has elapsed.
1103 mSupervisor.mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
1104 }
1105 }
Bryce Lee7f936862017-05-09 15:33:18 -07001106 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001107 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001108 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001109
Chong Zhang5022da32016-06-21 16:31:37 -07001110 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001111 // brought another activity to front. We must also handle the case where the task is already
1112 // in the front as a result of the trampoline activity being in the same task (it will be
1113 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
1114 // about this, so it waits for the new activity to become visible instead.
1115 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001116
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001117 if (startedActivityStack == null) {
1118 return;
1119 }
1120
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001121 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1122 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1123 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001124 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1125 // The activity was already running so it wasn't started, but either brought to the
1126 // front or the new intent was delivered to it since it was already in front. Notify
1127 // anyone interested in this piece of information.
1128 switch (startedActivityStack.getWindowingMode()) {
1129 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001130 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001131 clearedTask);
1132 break;
1133 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001134 final ActivityStack homeStack =
1135 startedActivityStack.getDisplay().getHomeStack();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001136 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1137 mService.mWindowManager.showRecentApps();
1138 }
1139 break;
1140 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001141 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001142 }
1143
Bryce Lee4c9a5972017-12-01 22:14:24 -08001144 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001145 String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
1146 Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
1147 IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
1148 int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001149 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001150 int userId, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001151 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001152 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001153 // Refuse possible leaked file descriptors
1154 if (intent != null && intent.hasFileDescriptors()) {
1155 throw new IllegalArgumentException("File descriptors passed in Intent");
1156 }
Igor Murashkin212d06c2018-10-22 16:34:39 -07001157 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001158 boolean componentSpecified = intent.getComponent() != null;
1159
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001160 final int realCallingPid = requestRealCallingPid != Request.DEFAULT_REAL_CALLING_PID
1161 ? requestRealCallingPid
1162 : Binder.getCallingPid();
1163 final int realCallingUid = requestRealCallingUid != Request.DEFAULT_REAL_CALLING_UID
1164 ? requestRealCallingUid
1165 : Binder.getCallingUid();
Makoto Onuki1a342742018-04-26 14:56:59 -07001166
Svet Ganovcbcbf662018-05-10 17:25:29 -07001167 int callingPid;
1168 if (callingUid >= 0) {
1169 callingPid = -1;
1170 } else if (caller == null) {
1171 callingPid = realCallingPid;
1172 callingUid = realCallingUid;
1173 } else {
1174 callingPid = callingUid = -1;
1175 }
1176
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001177 // Save a copy in case ephemeral needs it
1178 final Intent ephemeralIntent = new Intent(intent);
1179 // Don't modify the client's object!
1180 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -07001181 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -08001182 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +00001183 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1184 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001185 && mService.getPackageManagerInternalLocked()
Todd Kennedyb21be122017-03-24 14:10:01 -07001186 .isInstantAppInstallerComponent(intent.getComponent())) {
1187 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +00001188 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -07001189 // adjust the intent so it looks like a "normal" instant app launch
1190 intent.setComponent(null /*component*/);
1191 componentSpecified = false;
1192 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001193
Makoto Onuki1a342742018-04-26 14:56:59 -07001194 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001195 0 /* matchFlags */,
1196 computeResolveFilterUid(
1197 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001198 if (rInfo == null) {
1199 UserInfo userInfo = mSupervisor.getUserInfo(userId);
1200 if (userInfo != null && userInfo.isManagedProfile()) {
1201 // Special case for managed profiles, if attempting to launch non-cryto aware
1202 // app in a locked managed profile from an unlocked parent allow it to resolve
1203 // as user will be sent via confirm credentials to unlock the profile.
1204 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001205 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +00001206 long token = Binder.clearCallingIdentity();
1207 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001208 UserInfo parent = userManager.getProfileParent(userId);
1209 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1210 && userManager.isUserUnlockingOrUnlocked(parent.id)
1211 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001212 } finally {
1213 Binder.restoreCallingIdentity(token);
1214 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001215 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001216 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001217 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001218 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001219 computeResolveFilterUid(
1220 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001221 }
1222 }
1223 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001224 // Collect information about the target of the Intent.
1225 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1226
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001227 synchronized (mService.mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001228 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian8072d112016-09-16 11:11:01 -07001229 stack.mConfigWillChange = globalConfig != null
Wale Ogunwalef6733932018-06-27 05:14:34 -07001230 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001231 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1232 "Starting activity when config will change = " + stack.mConfigWillChange);
1233
1234 final long origId = Binder.clearCallingIdentity();
1235
1236 if (aInfo != null &&
1237 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001238 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
Wale Ogunwale214f3482018-10-04 11:00:47 -07001239 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001240 // This may be a heavy-weight process! Check to see if we already
1241 // have another, different heavy-weight process running.
1242 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
Wale Ogunwale53783742018-09-16 10:21:51 -07001243 final WindowProcessController heavy = mService.mHeavyWeightProcess;
1244 if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
1245 || !heavy.mName.equals(aInfo.processName))) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001246 int appCallingUid = callingUid;
1247 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001248 WindowProcessController callerApp =
1249 mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001250 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001251 appCallingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001252 } else {
1253 Slog.w(TAG, "Unable to find app for caller " + caller
1254 + " (pid=" + callingPid + ") when starting: "
1255 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001256 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001257 return ActivityManager.START_PERMISSION_DENIED;
1258 }
1259 }
1260
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07001261 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001262 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1263 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1264 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1265 | PendingIntent.FLAG_ONE_SHOT, null);
1266
1267 Intent newIntent = new Intent();
1268 if (requestCode >= 0) {
1269 // Caller is requesting a result.
1270 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1271 }
1272 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1273 new IntentSender(target));
Wale Ogunwale53783742018-09-16 10:21:51 -07001274 heavy.updateIntentForHeavyWeightActivity(newIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001275 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1276 aInfo.packageName);
1277 newIntent.setFlags(intent.getFlags());
1278 newIntent.setClassName("android",
1279 HeavyWeightSwitcherActivity.class.getName());
1280 intent = newIntent;
1281 resolvedType = null;
1282 caller = null;
1283 callingUid = Binder.getCallingUid();
1284 callingPid = Binder.getCallingPid();
1285 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001286 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001287 0 /* matchFlags */, computeResolveFilterUid(
1288 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001289 aInfo = rInfo != null ? rInfo.activityInfo : null;
1290 if (aInfo != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001291 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001292 }
1293 }
1294 }
1295 }
1296
Jorim Jaggi275561a2016-02-23 10:11:02 -05001297 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001298 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1299 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1300 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001301 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001302 allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001303 allowBackgroundActivityStart);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001304
1305 Binder.restoreCallingIdentity(origId);
1306
1307 if (stack.mConfigWillChange) {
1308 // If the caller also wants to switch to a new configuration,
1309 // do so now. This allows a clean switch, as we are waiting
1310 // for the current activity to pause (so we will not destroy
1311 // it), and have not yet started the next activity.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001312 mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001313 "updateConfiguration()");
1314 stack.mConfigWillChange = false;
1315 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1316 "Updating to new configuration after starting activity.");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001317 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001318 }
1319
Vishnu Nair132ee832018-09-28 15:00:05 -07001320 // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
1321 // will then wait for the windows to be drawn and populate WaitResult.
1322 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001323 if (outResult != null) {
1324 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001325
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001326 final ActivityRecord r = outRecord[0];
1327
1328 switch(res) {
1329 case START_SUCCESS: {
1330 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001331 do {
1332 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001333 mService.mGlobalLock.wait();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001334 } catch (InterruptedException e) {
1335 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001336 } while (outResult.result != START_TASK_TO_FRONT
1337 && !outResult.timeout && outResult.who == null);
1338 if (outResult.result == START_TASK_TO_FRONT) {
1339 res = START_TASK_TO_FRONT;
1340 }
1341 break;
1342 }
1343 case START_DELIVERED_TO_TOP: {
1344 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001345 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001346 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001347 break;
1348 }
1349 case START_TASK_TO_FRONT: {
Louis Chang0513a942019-03-06 12:38:13 +08001350 outResult.launchState =
1351 r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001352 // ActivityRecord may represent a different activity, but it should not be
1353 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001354 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001355 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001356 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001357 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001358 } else {
Vishnu Nair132ee832018-09-28 15:00:05 -07001359 final long startTimeMs = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001360 mSupervisor.waitActivityVisible(
1361 r.mActivityComponent, outResult, startTimeMs);
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001362 // Note: the timeout variable is not currently not ever set.
1363 do {
1364 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001365 mService.mGlobalLock.wait();
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001366 } catch (InterruptedException e) {
1367 }
1368 } while (!outResult.timeout && outResult.who == null);
1369 }
1370 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001371 }
1372 }
1373 }
1374
1375 return res;
1376 }
1377 }
1378
Svet Ganovcbcbf662018-05-10 17:25:29 -07001379 /**
1380 * Compute the logical UID based on which the package manager would filter
1381 * app components i.e. based on which the instant app policy would be applied
1382 * because it is the logical calling UID.
1383 *
1384 * @param customCallingUid The UID on whose behalf to make the call.
1385 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001386 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001387 * @return The logical UID making the call.
1388 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001389 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1390 int filterCallingUid) {
1391 return filterCallingUid != UserHandle.USER_NULL
1392 ? filterCallingUid
1393 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001394 }
1395
Bryce Leedaa91e42017-12-06 14:13:01 -08001396 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1397 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001398 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1399 ActivityRecord[] outActivity, boolean restrictedBgActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001400 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001401 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001402 try {
1403 mService.mWindowManager.deferSurfaceLayout();
1404 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001405 startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001406 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001407 final ActivityStack currentStack = r.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001408 startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1409
1410 if (ActivityManager.isStartResultSuccessful(result)) {
1411 if (startedActivityStack != null) {
1412 // If there is no state change (e.g. a resumed activity is reparented to
1413 // top of another display) to trigger a visibility/configuration checking,
1414 // we have to update the configuration for changing to different display.
1415 final ActivityRecord currentTop =
1416 startedActivityStack.topRunningActivityLocked();
1417 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001418 mRootActivityContainer.ensureVisibilityAndConfig(
1419 currentTop, currentTop.getDisplayId(),
Riddle Hsu16567132018-08-16 21:37:47 +08001420 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1421 }
1422 }
1423 } else {
1424 // If we are not able to proceed, disassociate the activity from the task.
1425 // Leaving an activity in an incomplete state can lead to issues, such as
1426 // performing operations without a window container.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001427 final ActivityStack stack = mStartActivity.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001428 if (stack != null) {
1429 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001430 null /* intentResultData */, "startActivity", true /* oomAdj */);
Riddle Hsu16567132018-08-16 21:37:47 +08001431 }
Louis Change8902452019-06-10 10:49:28 +08001432
1433 // Stack should also be detached from display and be removed if it's empty.
1434 if (startedActivityStack != null && startedActivityStack.isAttached()
1435 && startedActivityStack.numActivities() == 0
1436 && !startedActivityStack.isActivityTypeHome()) {
1437 startedActivityStack.remove();
1438 }
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001439 }
1440 mService.mWindowManager.continueSurfaceLayout();
1441 }
1442
Riddle Hsu16567132018-08-16 21:37:47 +08001443 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001444
1445 return result;
1446 }
1447
Ricky Waib147fa12019-04-25 16:08:30 +01001448 /**
1449 * Return true if background activity is really aborted.
1450 *
1451 * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1452 */
1453 private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1454 // TODO(b/131747138): Remove toast and refactor related code in Q release.
1455 boolean abort = !mService.isBackgroundActivityStartsEnabled();
Ricky Waib147fa12019-04-25 16:08:30 +01001456 if (!abort) {
1457 return false;
1458 }
1459 ActivityRecord resultRecord = r.resultTo;
1460 String resultWho = r.resultWho;
1461 int requestCode = r.requestCode;
1462 if (resultRecord != null) {
1463 ActivityStack resultStack = resultRecord.getActivityStack();
1464 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001465 RESULT_CANCELED, null);
Ricky Waib147fa12019-04-25 16:08:30 +01001466 }
1467 // We pretend to the caller that it was really started to make it backward compatible, but
1468 // they will just get a cancel result.
1469 ActivityOptions.abort(r.pendingOptions);
1470 return true;
1471 }
1472
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001473 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001474 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1475 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001476 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001477 ActivityRecord[] outActivity, boolean restrictedBgActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001478 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
Ricky Waib147fa12019-04-25 16:08:30 +01001479 voiceInteractor, restrictedBgActivity);
1480
Louis Chang39ba54b2018-10-18 11:28:57 +08001481 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001482
Louis Chang6fb1e842018-12-03 16:07:50 +08001483 computeLaunchingTaskFlags();
1484
1485 computeSourceStack();
1486
1487 mIntent.setFlags(mLaunchFlags);
1488
1489 ActivityRecord reusedActivity = getReusableIntentActivity();
1490
1491 mSupervisor.getLaunchParamsController().calculate(
1492 reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
1493 r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
1494 mPreferredDisplayId =
1495 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1496 : DEFAULT_DISPLAY;
1497
Winson Chunge219ae12019-07-18 13:43:23 -07001498 // If requested, freeze the task list
1499 if (mOptions != null && mOptions.freezeRecentTasksReordering()
1500 && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
1501 && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
1502 mFrozeTaskList = true;
1503 mSupervisor.mRecentTasks.setFreezeTaskListReordering();
1504 }
1505
Louis Changbd48dca2018-08-29 17:44:34 +08001506 // Do not start home activity if it cannot be launched on preferred display. We are not
1507 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1508 // fallback to launch on other displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001509 if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
Louis Changdd3592a2018-11-05 11:04:14 +08001510 mPreferredDisplayId, true /* allowInstrumenting */)) {
Louis Changbd48dca2018-08-29 17:44:34 +08001511 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1512 return START_CANCELED;
1513 }
1514
Bryce Lee4a194382017-04-04 14:32:48 -07001515 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001516 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1517 // still needs to be a lock task mode violation since the task gets cleared out and
1518 // the device would otherwise leave the locked task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001519 if (mService.getLockTaskController().isLockTaskModeViolation(
1520 reusedActivity.getTaskRecord(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001521 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1522 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001523 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1524 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1525 }
1526
Bryce Leef65ee7e2018-03-26 16:03:47 -07001527 // True if we are clearing top and resetting of a standard (default) launch mode
1528 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1529 final boolean clearTopAndResetStandardLaunchMode =
1530 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1531 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1532 && mLaunchMode == LAUNCH_MULTIPLE;
1533
1534 // If mStartActivity does not have a task associated with it, associate it with the
1535 // reused activity's task. Do not do so if we're clearing top and resetting for a
1536 // standard launchMode activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001537 if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
1538 mStartActivity.setTask(reusedActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001539 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001540
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001541 if (reusedActivity.getTaskRecord().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001542 // This task was started because of movement of the activity based on affinity...
1543 // Now that we are actually launching it, we can assign the base intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001544 reusedActivity.getTaskRecord().setIntent(mStartActivity);
Louis Changb45ee7e2019-01-17 10:36:56 +08001545 } else {
1546 final boolean taskOnHome =
1547 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1548 if (taskOnHome) {
1549 reusedActivity.getTaskRecord().intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1550 } else {
1551 reusedActivity.getTaskRecord().intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1552 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001553 }
1554
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001555 // This code path leads to delivering a new intent, we want to make sure we schedule it
1556 // as the first operation, in case the activity will be resumed as a result of later
1557 // operations.
1558 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001559 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001560 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001561 final TaskRecord task = reusedActivity.getTaskRecord();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001562
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001563 // In this situation we want to remove all activities from the task up to the one
1564 // being started. In most cases this means we are resetting the task to its initial
1565 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001566 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1567 mLaunchFlags);
1568
Bryce Lee4a194382017-04-04 14:32:48 -07001569 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001570 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1571 // task reference is needed in the call below to
1572 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001573 if (reusedActivity.getTaskRecord() == null) {
Bryce Lee4a194382017-04-04 14:32:48 -07001574 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001575 }
1576
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001577 if (top != null) {
1578 if (top.frontOfTask) {
1579 // Activity aliases may mean we use different intents for the top activity,
1580 // so make sure the task now has the identity of the new intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001581 top.getTaskRecord().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001582 }
Bryce Lee325e09682017-10-05 17:20:25 -07001583 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001584 }
1585 }
1586
Wale Ogunwaled32da472018-11-16 07:19:28 -08001587 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
1588 (false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001589
Bryce Lee4a194382017-04-04 14:32:48 -07001590 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001591
Bryce Lee89cd19a2017-05-17 15:18:35 -07001592 final ActivityRecord outResult =
1593 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1594
1595 // When there is a reused activity and the current result is a trampoline activity,
1596 // set the reused activity as the result.
1597 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1598 outActivity[0] = reusedActivity;
1599 }
1600
Wale Ogunwale01d66562015-12-29 08:19:19 -08001601 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1602 // We don't need to start a new activity, and the client said not to do anything
1603 // if that is the case, so this is it! And for paranoia, make sure we have
1604 // correctly resumed the top activity.
1605 resumeTargetStackIfNeeded();
1606 return START_RETURN_INTENT_TO_CALLER;
1607 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001608
Bryce Leef65ee7e2018-03-26 16:03:47 -07001609 if (reusedActivity != null) {
1610 setTaskFromIntentActivity(reusedActivity);
1611
1612 if (!mAddingToTask && mReuseTask == null) {
1613 // We didn't do anything... but it was needed (a.k.a., client don't use that
1614 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
Bryce Leef65ee7e2018-03-26 16:03:47 -07001615 resumeTargetStackIfNeeded();
1616 if (outActivity != null && outActivity.length > 0) {
Louis Changa59937a2019-03-20 17:17:22 +08001617 // The reusedActivity could be finishing, for example of starting an
1618 // activity with FLAG_ACTIVITY_CLEAR_TOP flag. In that case, return the
1619 // top running activity in the task instead.
1620 outActivity[0] = reusedActivity.finishing
1621 ? reusedActivity.getTaskRecord().getTopActivity() : reusedActivity;
Bryce Leef65ee7e2018-03-26 16:03:47 -07001622 }
1623
1624 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001625 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001626 }
1627 }
1628
1629 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001630 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001631 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001632 if (sourceStack != null) {
1633 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1634 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001635 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001636 }
1637 ActivityOptions.abort(mOptions);
1638 return START_CLASS_NOT_FOUND;
1639 }
1640
1641 // If the activity being launched is the same as the one currently at the top, then
1642 // we need to check if it should only be launched once.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001643 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001644 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001645 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1646 final boolean dontStart = top != null && mStartActivity.resultTo == null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001647 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1648 && top.mUserId == mStartActivity.mUserId
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001649 && top.attachedToProcess()
Wale Ogunwale01d66562015-12-29 08:19:19 -08001650 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Louis Changbd48dca2018-08-29 17:44:34 +08001651 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1652 // This allows home activity to automatically launch on secondary display when
1653 // display added, if home was the top activity on default display, instead of
1654 // sending new intent to the home activity on default display.
1655 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001656 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001657 // For paranoia, make sure we have correctly resumed the top activity.
1658 topStack.mLastPausedActivity = null;
1659 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001660 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001661 }
1662 ActivityOptions.abort(mOptions);
1663 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1664 // We don't need to start a new activity, and the client said not to do
1665 // anything if that is the case, so this is it!
1666 return START_RETURN_INTENT_TO_CALLER;
1667 }
Bryce Lee325e09682017-10-05 17:20:25 -07001668
1669 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001670
1671 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1672 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001673 mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
Louis Chang39ba54b2018-10-18 11:28:57 +08001674 mPreferredDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001675
Wale Ogunwale01d66562015-12-29 08:19:19 -08001676 return START_DELIVERED_TO_TOP;
1677 }
1678
1679 boolean newTask = false;
1680 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001681 ? mSourceRecord.getTaskRecord() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001682
1683 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001684 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001685 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1686 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1687 newTask = true;
Louis Changceeb5062018-09-17 18:13:52 +08001688 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001689 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001690 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001691 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001692 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001693 } else {
1694 // This not being started from an existing activity, and not part of a new task...
1695 // just put it in the top task, though these days this case should never happen.
Ricky Waib147fa12019-04-25 16:08:30 +01001696 result = setTaskToCurrentTopOrCreateNewTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001697 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001698 if (result != START_SUCCESS) {
1699 return result;
1700 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001701
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001702 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
1703 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001704 mService.getPackageManagerInternalLocked().grantEphemeralAccess(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001705 mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001706 UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001707 if (newTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001708 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
1709 mStartActivity.getTaskRecord().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001710 }
1711 ActivityStack.logStartActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001712 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001713 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001714
Wale Ogunwaled32da472018-11-16 07:19:28 -08001715 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
1716 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001717
Winson Chungb5c41b72016-12-07 15:00:47 -08001718 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1719 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001720 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001721 final ActivityRecord topTaskActivity =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001722 mStartActivity.getTaskRecord().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001723 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001724 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1725 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001726 // If the activity is not focusable, we can't resume it, but still would like to
1727 // make sure it becomes visible as it starts (this will also trigger entry
1728 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001729 // Also, we don't want to resume activities in a task that currently has an overlay
1730 // as the starting activity just needs to be in the visible paused state until the
1731 // over is removed.
Andrii Kulian6b321512019-01-23 06:37:00 +00001732 mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001733 // Go ahead and tell window manager to execute app transition for this activity
1734 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001735 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001736 } else {
Winson Chung32066032016-11-04 11:55:21 -07001737 // If the target stack was not previously focusable (previous top running activity
1738 // on that stack was not visible) then any prior calls to move the stack to the
1739 // will not update the focused stack. If starting the new activity now allows the
1740 // task stack to be focusable, then ensure that we now update the focused stack
1741 // accordingly.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001742 if (mTargetStack.isFocusable()
Wale Ogunwaled32da472018-11-16 07:19:28 -08001743 && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
Winson Chung32066032016-11-04 11:55:21 -07001744 mTargetStack.moveToFront("startActivityUnchecked");
1745 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001746 mRootActivityContainer.resumeFocusedStacksTopActivities(
1747 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001748 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001749 } else if (mStartActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001750 mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001751 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001752 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001753
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001754 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1755 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001756
1757 return START_SUCCESS;
1758 }
1759
Bryce Leedaa91e42017-12-06 14:13:01 -08001760 /**
1761 * Resets the {@link ActivityStarter} state.
1762 * @param clearRequest whether the request should be reset to default values.
1763 */
1764 void reset(boolean clearRequest) {
1765 mStartActivity = null;
1766 mIntent = null;
1767 mCallingUid = -1;
1768 mOptions = null;
Ricky Waib147fa12019-04-25 16:08:30 +01001769 mRestrictedBgActivity = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08001770
1771 mLaunchTaskBehind = false;
1772 mLaunchFlags = 0;
1773 mLaunchMode = INVALID_LAUNCH_MODE;
1774
Bryce Leeec55eb02017-12-05 20:51:27 -08001775 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001776
1777 mNotTop = null;
1778 mDoResume = false;
1779 mStartFlags = 0;
1780 mSourceRecord = null;
1781 mPreferredDisplayId = INVALID_DISPLAY;
1782
1783 mInTask = null;
1784 mAddingToTask = false;
1785 mReuseTask = null;
1786
1787 mNewTaskInfo = null;
1788 mNewTaskIntent = null;
1789 mSourceStack = null;
1790
1791 mTargetStack = null;
1792 mMovedToFront = false;
1793 mNoAnimation = false;
1794 mKeepCurTransition = false;
1795 mAvoidMoveToFront = false;
Winson Chunge219ae12019-07-18 13:43:23 -07001796 mFrozeTaskList = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08001797
1798 mVoiceSession = null;
1799 mVoiceInteractor = null;
1800
1801 mIntentDelivered = false;
1802
1803 if (clearRequest) {
1804 mRequest.reset();
1805 }
1806 }
1807
Wale Ogunwale01d66562015-12-29 08:19:19 -08001808 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1809 boolean doResume, int startFlags, ActivityRecord sourceRecord,
Ricky Waib147fa12019-04-25 16:08:30 +01001810 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1811 boolean restrictedBgActivity) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001812 reset(false /* clearRequest */);
1813
Wale Ogunwale01d66562015-12-29 08:19:19 -08001814 mStartActivity = r;
1815 mIntent = r.intent;
1816 mOptions = options;
1817 mCallingUid = r.launchedFromUid;
1818 mSourceRecord = sourceRecord;
1819 mVoiceSession = voiceSession;
1820 mVoiceInteractor = voiceInteractor;
Ricky Waib147fa12019-04-25 16:08:30 +01001821 mRestrictedBgActivity = restrictedBgActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001822
Bryce Leeec55eb02017-12-05 20:51:27 -08001823 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001824
Louis Chang6fb1e842018-12-03 16:07:50 +08001825 // Preferred display id is the only state we need for now and it could be updated again
1826 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07001827 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08001828 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
1829 mPreferredDisplayId =
1830 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1831 : DEFAULT_DISPLAY;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07001832
Bryce Lee7daee392017-10-12 13:46:18 -07001833 mLaunchMode = r.launchMode;
1834
Wale Ogunwale01d66562015-12-29 08:19:19 -08001835 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001836 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1837 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001838 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001839 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001840 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1841
1842 sendNewTaskResultRequestIfNeeded();
1843
1844 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1845 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1846 }
1847
1848 // If we are actually going to launch in to a new task, there are some cases where
1849 // we further want to do multiple task.
1850 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1851 if (mLaunchTaskBehind
1852 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1853 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1854 }
1855 }
1856
1857 // We'll invoke onUserLeaving before onPause only if the launching
1858 // activity did not explicitly state that this is an automated launch.
1859 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1860 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1861 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1862
1863 // If the caller has asked not to resume at this point, we make note
1864 // of this in the record so that we can skip it when trying to find
1865 // the top running activity.
1866 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001867 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001868 r.delayedResume = true;
1869 mDoResume = false;
1870 }
1871
Winson Chunge2d72172018-01-25 17:46:20 +00001872 if (mOptions != null) {
1873 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1874 r.mTaskOverlay = true;
1875 if (!mOptions.canTaskOverlayResume()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001876 final TaskRecord task = mRootActivityContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00001877 mOptions.getLaunchTaskId());
1878 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001879 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001880
Winson Chunge2d72172018-01-25 17:46:20 +00001881 // The caller specifies that we'd like to be avoided to be moved to the
1882 // front, so be it!
1883 mDoResume = false;
1884 mAvoidMoveToFront = true;
1885 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001886 }
Winson Chunge2d72172018-01-25 17:46:20 +00001887 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001888 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001889 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001890 }
1891 }
1892
Louis Chang2f4e9b462019-03-05 16:43:15 +08001893 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001894
1895 mInTask = inTask;
1896 // In some flows in to this function, we retrieve the task record and hold on to it
1897 // without a lock before calling back in to here... so the task at this point may
1898 // not actually be in recents. Check for that, and if it isn't in recents just
1899 // consider it invalid.
1900 if (inTask != null && !inTask.inRecents) {
1901 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1902 mInTask = null;
1903 }
1904
1905 mStartFlags = startFlags;
1906 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1907 // is the same as the one making the call... or, as a special case, if we do not know
1908 // the caller then we count the current top activity as the caller.
1909 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1910 ActivityRecord checkedCaller = sourceRecord;
1911 if (checkedCaller == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001912 checkedCaller = mRootActivityContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001913 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001914 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001915 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001916 // Caller is not the same as launcher, so always needed.
1917 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1918 }
1919 }
1920
1921 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
Ricky Waib147fa12019-04-25 16:08:30 +01001922
Alan Stokes07389b62019-05-20 15:22:54 +01001923 if (mRestrictedBgActivity && !mService.isBackgroundActivityStartsEnabled()) {
Ricky Waib147fa12019-04-25 16:08:30 +01001924 mAvoidMoveToFront = true;
1925 mDoResume = false;
1926 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001927 }
1928
1929 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001930 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001931 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001932 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001933 // For whatever reason this activity is being launched into a new task...
1934 // yet the caller has requested a result back. Well, that is pretty messed up,
1935 // so instead immediately send back a cancel and let the new task continue launched
1936 // as normal without a dependency on its originator.
1937 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001938 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1939 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001940 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001941 mStartActivity.resultTo = null;
1942 }
1943 }
1944
1945 private void computeLaunchingTaskFlags() {
1946 // If the caller is not coming from another activity, but has given us an explicit task into
1947 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001948 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001949 final Intent baseIntent = mInTask.getBaseIntent();
1950 final ActivityRecord root = mInTask.getRootActivity();
1951 if (baseIntent == null) {
1952 ActivityOptions.abort(mOptions);
1953 throw new IllegalArgumentException("Launching into task without base intent: "
1954 + mInTask);
1955 }
1956
1957 // If this task is empty, then we are adding the first activity -- it
1958 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001959 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001960 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1961 ActivityOptions.abort(mOptions);
1962 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1963 + mStartActivity + " into different task " + mInTask);
1964 }
1965 if (root != null) {
1966 ActivityOptions.abort(mOptions);
1967 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1968 + " has root " + root + " but target is singleInstance/Task");
1969 }
1970 }
1971
1972 // If task is empty, then adopt the interesting intent launch flags in to the
1973 // activity being started.
1974 if (root == null) {
1975 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1976 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1977 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1978 | (baseIntent.getFlags() & flagsOfInterest);
1979 mIntent.setFlags(mLaunchFlags);
1980 mInTask.setIntent(mStartActivity);
1981 mAddingToTask = true;
1982
1983 // If the task is not empty and the caller is asking to start it as the root of
1984 // a new task, then we don't actually want to start this on the task. We will
1985 // bring the task to the front, and possibly give it a new intent.
1986 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1987 mAddingToTask = false;
1988
1989 } else {
1990 mAddingToTask = true;
1991 }
1992
1993 mReuseTask = mInTask;
1994 } else {
1995 mInTask = null;
1996 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1997 // when in freeform workspace.
1998 // Also put noDisplay activities in the source task. These by itself can be placed
1999 // in any task/stack, however it could launch other activities like ResolverActivity,
2000 // and we want those to stay in the original task.
Louis Chang6a9be162019-07-15 10:41:32 +08002001 if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
2002 && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002003 mAddingToTask = true;
2004 }
2005 }
2006
2007 if (mInTask == null) {
2008 if (mSourceRecord == null) {
2009 // This activity is not being started from another... in this
2010 // case we -always- start a new task.
2011 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
2012 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
2013 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2014 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2015 }
2016 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
2017 // The original activity who is starting us is running as a single
2018 // instance... this new activity it is starting must go on its
2019 // own task.
2020 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07002021 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002022 // The activity being started is a single instance... it always
2023 // gets launched into its own task.
2024 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2025 }
2026 }
2027 }
2028
2029 private void computeSourceStack() {
2030 if (mSourceRecord == null) {
2031 mSourceStack = null;
2032 return;
2033 }
2034 if (!mSourceRecord.finishing) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002035 mSourceStack = mSourceRecord.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002036 return;
2037 }
2038
2039 // If the source is finishing, we can't further count it as our source. This is because the
2040 // task it is associated with may now be empty and on its way out, so we don't want to
2041 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
2042 // a task for it. But save the task information so it can be used when creating the new task.
2043 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
2044 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
2045 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2046 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2047 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07002048
2049 // It is not guaranteed that the source record will have a task associated with it. For,
2050 // example, if this method is being called for processing a pending activity launch, it
2051 // is possible that the activity has been removed from the task after the launch was
2052 // enqueued.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002053 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
Bryce Leed9ed45d2017-05-22 15:57:24 -07002054 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002055 }
2056 mSourceRecord = null;
2057 mSourceStack = null;
2058 }
2059
2060 /**
2061 * Decide whether the new activity should be inserted into an existing task. Returns null
2062 * if not or an ActivityRecord with the task into which the new activity should be added.
2063 */
2064 private ActivityRecord getReusableIntentActivity() {
2065 // We may want to try to place the new activity in to an existing task. We always
2066 // do this if the target activity is singleTask or singleInstance; we will also do
2067 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2068 // us to still place it in a new task: multi task, always doc mode, or being asked to
2069 // launch this as a new task behind the current one.
2070 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2071 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07002072 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002073 // If bring to front is requested, and no result is requested and we have not been given
2074 // an explicit task to launch in to, and we can find a task that was started with this
2075 // same component, then instead of launching bring that one to the front.
2076 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2077 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01002078 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002079 final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
Jorim Jaggi2adba072016-03-03 13:43:39 +01002080 intentActivity = task != null ? task.getTopActivity() : null;
2081 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07002082 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002083 // There can be one and only one instance of single instance activity in the
2084 // history, and it is always in its own unique task, so we do a special search.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002085 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002086 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002087 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2088 // For the launch adjacent case we only want to put the activity in an existing
2089 // task if the activity already exists in the history.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002090 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07002091 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002092 } else {
2093 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002094 intentActivity =
2095 mRootActivityContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002096 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002097 }
Louis Changbd48dca2018-08-29 17:44:34 +08002098
Louis Chang54506cb2018-11-23 11:03:41 +08002099 if (intentActivity != null
2100 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08002101 && intentActivity.getDisplayId() != mPreferredDisplayId) {
2102 // Do not reuse home activity on other displays.
2103 intentActivity = null;
2104 }
2105
Wale Ogunwale01d66562015-12-29 08:19:19 -08002106 return intentActivity;
2107 }
2108
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002109 /**
2110 * Figure out which task and activity to bring to front when we have found an existing matching
2111 * activity record in history. May also clear the task if needed.
2112 * @param intentActivity Existing matching activity.
2113 * @return {@link ActivityRecord} brought to front.
2114 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08002115 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002116 mTargetStack = intentActivity.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002117 mTargetStack.mLastPausedActivity = null;
2118 // If the target task is not in the front, then we need to bring it to the front...
2119 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2120 // the same behavior as if a new instance was being started, which means not bringing it
2121 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002122 final boolean differentTopTask;
2123 if (mPreferredDisplayId == mTargetStack.mDisplayId) {
2124 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2125 final ActivityRecord curTop = (focusStack == null)
2126 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002127 final TaskRecord topTask = curTop != null ? curTop.getTaskRecord() : null;
Riddle Hsu273e9992019-04-29 22:40:59 +08002128 differentTopTask = topTask != intentActivity.getTaskRecord()
2129 || (focusStack != null && topTask != focusStack.topTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002130 } else {
2131 // The existing task should always be different from those in other displays.
2132 differentTopTask = true;
2133 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002134
Riddle Hsub70b36d2018-09-11 21:20:02 +08002135 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002136 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002137 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002138 mSourceStack.getTopActivity().getTaskRecord()
2139 == mSourceRecord.getTaskRecord())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002140 // We really do want to push this one into the user's face, right now.
2141 if (mLaunchTaskBehind && mSourceRecord != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002142 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002143 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002144
2145 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
2146 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
2147 // So no point resuming any of the activities here, it just wastes one extra
2148 // resuming, plus enter AND exit transitions.
2149 // Here we only want to bring the target stack forward. Transition will be applied
2150 // to the new activity that's started after the old ones are gone.
2151 final boolean willClearTask =
2152 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2153 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
2154 if (!willClearTask) {
2155 final ActivityStack launchStack = getLaunchStack(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002156 mStartActivity, mLaunchFlags, mStartActivity.getTaskRecord(), mOptions);
2157 final TaskRecord intentTask = intentActivity.getTaskRecord();
Chong Zhangdea4bd92016-03-15 12:50:03 -07002158 if (launchStack == null || launchStack == mTargetStack) {
2159 // We only want to move to the front, if we aren't going to launch on a
2160 // different stack. If we launch on a different stack, we will put the
2161 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07002162 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
2163 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07002164 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002165 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002166 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2167 // If we want to launch adjacent and mTargetStack is not the computed
2168 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002169 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08002170 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2171 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002172 } else {
2173 // TODO: This should be reevaluated in MW v2.
2174 // We choose to move task to front instead of launching it adjacent
2175 // when specific stack was requested explicitly and it appeared to be
2176 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07002177 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07002178 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002179 "bringToFrontInsteadOfAdjacentLaunch");
2180 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07002181 mMovedToFront = launchStack != launchStack.getDisplay()
2182 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002183 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
2184 // Target and computed stacks are on different displays and we've
2185 // found a matching task - move the existing instance to that display and
2186 // move it to front.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002187 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002188 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2189 "reparentToDisplay");
2190 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002191 } else if (launchStack.isActivityTypeHome()
2192 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07002193 // It is possible for the home activity to be in another stack initially.
2194 // For example, the activity may have been initially started with an intent
2195 // which placed it in the fullscreen stack. To ensure the proper handling of
2196 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002197 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07002198 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2199 "reparentingHome");
2200 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07002201 }
2202 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002203
2204 // We are moving a task to the front, use starting window to hide initial drawn
2205 // delay.
2206 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
2207 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002208 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002209 }
2210 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002211 // Need to update mTargetStack because if task was moved out of it, the original stack may
2212 // be destroyed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002213 mTargetStack = intentActivity.getActivityStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07002214 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002215 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2216 + " from " + intentActivity);
2217 mTargetStack.moveToFront("intentActivityFound");
2218 }
2219
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002220 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTaskRecord(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002221 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07002222
Wale Ogunwale01d66562015-12-29 08:19:19 -08002223 // If the caller has requested that the target task be reset, then do so.
2224 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2225 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2226 }
2227 return intentActivity;
2228 }
2229
2230 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2231 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2232 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2233 // The caller has requested to completely replace any existing task with its new
2234 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08002235 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2236 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08002237 // of history or if it is finished immediately), thus disassociating the task. Also note
2238 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2239 // launching another activity.
2240 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2241 // already launching one.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002242 final TaskRecord task = intentActivity.getTaskRecord();
Bryce Lee59dad4e2017-03-09 11:54:08 -08002243 task.performClearTaskLocked();
2244 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08002245 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002246 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002247 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002248 final ActivityRecord top = intentActivity.getTaskRecord().performClearTaskLocked(
2249 mStartActivity, mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002250 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002251 // A special case: we need to start the activity because it is not currently
2252 // running, and the caller has asked to clear the current task to have this
2253 // activity at the top.
2254 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08002255
2256 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07002257 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002258 // Now pretend like this activity is being started by the top of its task, so it
2259 // is put in the right place.
2260 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002261 final TaskRecord task = mSourceRecord.getTaskRecord();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002262 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002263 // Target stack got cleared when we all activities were removed above.
2264 // Go ahead and reset it.
2265 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07002266 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002267 mTargetStack.addTask(task,
2268 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2269 }
2270 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002271 } else if (mStartActivity.mActivityComponent.equals(
2272 intentActivity.getTaskRecord().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002273 // In this case the top activity on the task is the same as the one being launched,
2274 // so we take that as a request to bring the task to the foreground. If the top
2275 // activity in the task is the root activity, deliver this new intent to it if it
2276 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07002277 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2278 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002279 && intentActivity.mActivityComponent.equals(
2280 mStartActivity.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002281 if (intentActivity.frontOfTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002282 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002283 }
Bryce Lee325e09682017-10-05 17:20:25 -07002284 deliverNewIntent(intentActivity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002285 } else if (!intentActivity.getTaskRecord().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002286 // In this case we are launching the root activity of the task, but with a
2287 // different intent. We should start a new instance on top.
2288 mAddingToTask = true;
2289 mSourceRecord = intentActivity;
2290 }
2291 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2292 // In this case an activity is being launched in to an existing task, without
2293 // resetting that task. This is typically the situation of launching an activity
2294 // from a notification or shortcut. We want to place the new activity on top of the
2295 // current task.
2296 mAddingToTask = true;
2297 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002298 } else if (!intentActivity.getTaskRecord().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002299 // In this case we are launching into an existing task that has not yet been started
2300 // from its front door. The current task has been brought to the front. Ideally,
2301 // we'd probably like to place this new task at the bottom of its stack, but that's
2302 // a little hard to do with the current organization of the code so for now we'll
2303 // just drop it.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002304 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002305 }
2306 }
2307
2308 private void resumeTargetStackIfNeeded() {
2309 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002310 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002311 } else {
2312 ActivityOptions.abort(mOptions);
2313 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002314 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002315 }
2316
Louis Changceeb5062018-09-17 18:13:52 +08002317 private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
Louis Change8902452019-06-10 10:49:28 +08002318 if (mRestrictedBgActivity && (mReuseTask == null || !mReuseTask.containsAppUid(mCallingUid))
2319 && handleBackgroundActivityAbort(mStartActivity)) {
2320 return START_ABORTED;
2321 }
2322
Bryce Leedacefc42017-10-10 12:56:02 -07002323 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002324
2325 // Do no move the target stack to front yet, as we might bail if
2326 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002327
2328 if (mReuseTask == null) {
Riddle Hsu609a8e22019-06-27 16:46:29 -06002329 final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002330 final TaskRecord task = mTargetStack.createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002331 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002332 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002333 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Riddle Hsu609a8e22019-06-27 16:46:29 -06002334 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002335 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002336 updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002337
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002338 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002339 + " in new task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002340 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002341 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2342 }
2343
2344 if (taskToAffiliate != null) {
2345 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002346 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002347
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002348 if (mService.getLockTaskController().isLockTaskModeViolation(
2349 mStartActivity.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002350 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2351 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2352 }
2353
Chong Zhang6cda19c2016-06-14 19:07:56 -07002354 if (mDoResume) {
2355 mTargetStack.moveToFront("reuseOrNewTask");
2356 }
2357 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002358 }
2359
Bryce Lee325e09682017-10-05 17:20:25 -07002360 private void deliverNewIntent(ActivityRecord activity) {
2361 if (mIntentDelivered) {
2362 return;
2363 }
2364
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002365 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTaskRecord());
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00002366 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
Bryce Lee325e09682017-10-05 17:20:25 -07002367 mStartActivity.launchedFromPackage);
2368 mIntentDelivered = true;
2369 }
2370
Wale Ogunwale01d66562015-12-29 08:19:19 -08002371 private int setTaskFromSourceRecord() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002372 if (mService.getLockTaskController().isLockTaskModeViolation(
2373 mSourceRecord.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002374 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2375 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2376 }
2377
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002378 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
2379 final ActivityStack sourceStack = mSourceRecord.getActivityStack();
Ricky Waib147fa12019-04-25 16:08:30 +01002380 if (mRestrictedBgActivity && !sourceTask.containsAppUid(mCallingUid)) {
2381 if (handleBackgroundActivityAbort(mStartActivity)) {
2382 return START_ABORTED;
2383 }
Ricky Waib147fa12019-04-25 16:08:30 +01002384 }
Andrii Kulian02689a72017-07-06 14:28:59 -07002385 // We only want to allow changing stack in two cases:
2386 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2387 // the other side, rather than show two side by side.
2388 // 2. If activity is not allowed on target display.
2389 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2390 : sourceStack.mDisplayId;
2391 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2392 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002393 if (moveStackAllowed) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002394 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags,
2395 mStartActivity.getTaskRecord(), mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002396 // If target stack is not found now - we can't just rely on the source stack, as it may
2397 // be not suitable. Let's check other displays.
2398 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2399 // Can't use target display, lets find a stack on the source display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002400 mTargetStack = mRootActivityContainer.getValidLaunchStackOnDisplay(
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002401 sourceStack.mDisplayId, mStartActivity, mOptions, mLaunchParams);
Andrii Kulian02689a72017-07-06 14:28:59 -07002402 }
2403 if (mTargetStack == null) {
2404 // There are no suitable stacks on the target and source display(s). Look on all
2405 // displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002406 mTargetStack = mRootActivityContainer.getNextValidLaunchStack(
Andrii Kulian02689a72017-07-06 14:28:59 -07002407 mStartActivity, -1 /* currentFocus */);
2408 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002409 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002410
2411 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002412 mTargetStack = sourceStack;
2413 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002414 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2415 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002416 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002417
Wale Ogunwale01d66562015-12-29 08:19:19 -08002418 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002419 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002420 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002421 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002422 } else if (mDoResume) {
2423 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002424 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002425
Wale Ogunwale01d66562015-12-29 08:19:19 -08002426 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2427 // In this case, we are adding the activity to an existing task, but the caller has
2428 // asked to clear that task if the activity is already running.
2429 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2430 mKeepCurTransition = true;
2431 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002432 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002433 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002434 // For paranoia, make sure we have correctly resumed the top activity.
2435 mTargetStack.mLastPausedActivity = null;
2436 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002437 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002438 }
2439 ActivityOptions.abort(mOptions);
2440 return START_DELIVERED_TO_TOP;
2441 }
2442 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2443 // In this case, we are launching an activity in our own task that may already be
2444 // running somewhere in the history, and we want to shuffle it to the front of the
2445 // stack if so.
2446 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2447 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002448 final TaskRecord task = top.getTaskRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002449 task.moveActivityToFrontLocked(top);
2450 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002451 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002452 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002453 mTargetStack.mLastPausedActivity = null;
2454 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002455 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002456 }
2457 return START_DELIVERED_TO_TOP;
2458 }
2459 }
2460
2461 // An existing activity is starting this new activity, so we want to keep the new one in
2462 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002463 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002464 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002465 + " in existing task " + mStartActivity.getTaskRecord()
2466 + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002467 return START_SUCCESS;
2468 }
2469
2470 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002471 // The caller is asking that the new activity be started in an explicit
2472 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002473 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002474 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2475 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2476 }
2477
Andrii Kulian02b7a832016-10-06 23:11:56 -07002478 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002479
2480 // Check whether we should actually launch the new activity in to the task,
2481 // or just reuse the current activity on top.
2482 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002483 if (top != null && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2484 && top.mUserId == mStartActivity.mUserId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002485 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002486 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002487 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002488 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002489 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2490 // We don't need to start a new activity, and the client said not to do
2491 // anything if that is the case, so this is it!
2492 return START_RETURN_INTENT_TO_CALLER;
2493 }
Bryce Lee325e09682017-10-05 17:20:25 -07002494 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002495 return START_DELIVERED_TO_TOP;
2496 }
2497 }
2498
2499 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002500 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002501 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002502 // We don't actually want to have this activity added to the task, so just
2503 // stop here but still tell the caller that we consumed the intent.
2504 ActivityOptions.abort(mOptions);
2505 return START_TASK_TO_FRONT;
2506 }
2507
Bryce Leeec55eb02017-12-05 20:51:27 -08002508 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002509 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwaled32da472018-11-16 07:19:28 -08002510 ActivityStack stack = mRootActivityContainer.getLaunchStack(
2511 null, null, mInTask, ON_TOP);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002512 if (stack != mInTask.getStack()) {
2513 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002514 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002515 mTargetStack = mInTask.getStack();
2516 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002517
Bryce Leeec55eb02017-12-05 20:51:27 -08002518 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002519 }
2520
chaviw0d562bf2018-03-15 14:24:14 -07002521 mTargetStack.moveTaskToFrontLocked(
2522 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002523
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002524 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2525 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002526 + " in explicit task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002527
2528 return START_SUCCESS;
2529 }
2530
Bryce Leed3624e12017-11-30 08:51:45 -08002531 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002532 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002533 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002534 return;
2535 }
2536
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002537 final ActivityStack stack = task.getStack();
2538 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002539 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002540 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002541 } else {
2542 task.updateOverrideConfiguration(bounds);
2543 }
2544 }
2545
Ricky Waib147fa12019-04-25 16:08:30 +01002546 private int setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002547 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002548 if (mDoResume) {
2549 mTargetStack.moveToFront("addingToTopTask");
2550 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002551 final ActivityRecord prev = mTargetStack.getTopActivity();
Ricky Waib147fa12019-04-25 16:08:30 +01002552 if (mRestrictedBgActivity && prev == null) {
2553 if (handleBackgroundActivityAbort(mStartActivity)) {
2554 return START_ABORTED;
2555 }
Ricky Waib147fa12019-04-25 16:08:30 +01002556 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002557 final TaskRecord task = (prev != null)
2558 ? prev.getTaskRecord() : mTargetStack.createTaskRecord(
2559 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002560 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Alan Stokes07389b62019-05-20 15:22:54 +01002561 if (mRestrictedBgActivity && prev != null && !task.containsAppUid(mCallingUid)) {
Ricky Waib147fa12019-04-25 16:08:30 +01002562 if (handleBackgroundActivityAbort(mStartActivity)) {
2563 return START_ABORTED;
2564 }
Ricky Waib147fa12019-04-25 16:08:30 +01002565 }
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002566 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2567 mTargetStack.positionChildWindowContainerAtTop(task);
2568 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002569 + " in new guessed " + mStartActivity.getTaskRecord());
Ricky Waib147fa12019-04-25 16:08:30 +01002570 return START_SUCCESS;
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002571 }
2572
2573 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002574 if (mStartActivity.getTaskRecord() == null || mStartActivity.getTaskRecord() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002575 parent.addActivityToTop(mStartActivity);
2576 } else {
2577 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2578 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002579 }
2580
2581 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2582 boolean launchSingleTask, int launchFlags) {
2583 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2584 (launchSingleInstance || launchSingleTask)) {
2585 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2586 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2587 "\"singleInstance\" or \"singleTask\"");
2588 launchFlags &=
2589 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2590 } else {
2591 switch (r.info.documentLaunchMode) {
2592 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2593 break;
2594 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2595 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2596 break;
2597 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2598 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2599 break;
2600 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2601 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2602 break;
2603 }
2604 }
2605 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002606 }
2607
Bryce Leedacefc42017-10-10 12:56:02 -07002608 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2609 ActivityOptions aOptions) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002610 final TaskRecord task = r.getTaskRecord();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002611 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002612 if (stack != null) {
2613 return stack;
2614 }
2615
Andrii Kulian02b7a832016-10-06 23:11:56 -07002616 final ActivityStack currentStack = task != null ? task.getStack() : null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002617 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002618 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002619 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002620 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2621 "computeStackFocus: Setting " + "focused stack to r=" + r
2622 + " task=" + task);
2623 } else {
2624 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002625 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002626 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002627 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002628 }
2629
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002630 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002631 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002632 "computeStackFocus: Have a focused stack=" + focusedStack);
2633 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002634 }
2635
David Stevense5a7b642017-05-22 13:18:23 -07002636 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002637 // Try to put the activity in a stack on a secondary display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002638 stack = mRootActivityContainer.getValidLaunchStackOnDisplay(
2639 mPreferredDisplayId, r, aOptions, mLaunchParams);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002640 if (stack == null) {
2641 // If source display is not suitable - look for topmost valid stack in the system.
2642 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002643 "computeStackFocus: Can't launch on mPreferredDisplayId="
2644 + mPreferredDisplayId + ", looking on all displays.");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002645 stack = mRootActivityContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002646 }
2647 }
2648 if (stack == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002649 stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002650 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002651 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2652 + r + " stackId=" + stack.mStackId);
2653 return stack;
2654 }
2655
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002656 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002657 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002658 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002659 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002660 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002661 if (focusedStack.isActivityTypeAssistant()) {
2662 canUseFocusedStack = r.isActivityTypeAssistant();
2663 } else {
2664 switch (focusedStack.getWindowingMode()) {
2665 case WINDOWING_MODE_FULLSCREEN:
2666 // The fullscreen stack can contain any task regardless of if the task is
2667 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2668 // focus stack.
2669 canUseFocusedStack = true;
2670 break;
2671 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2672 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2673 // Any activity which supports split screen can go in the docked stack.
2674 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2675 break;
2676 case WINDOWING_MODE_FREEFORM:
2677 // Any activity which supports freeform can go in the freeform stack.
2678 canUseFocusedStack = r.supportsFreeform();
2679 break;
2680 default:
2681 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2682 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002683 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002684 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2685 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002686 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002687 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002688 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002689 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002690 }
2691
Wale Ogunwale854809c2015-12-27 16:18:19 -08002692 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002693 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002694 // We are reusing a task, keep the stack!
2695 if (mReuseTask != null) {
2696 return mReuseTask.getStack();
2697 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002698
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002699 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002700 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Winson Chung93442032018-12-04 13:24:29 -08002701 final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002702 final ActivityStack stack =
Winson Chung93442032018-12-04 13:24:29 -08002703 mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002704 return stack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002705 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002706 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002707
Wale Ogunwaled32da472018-11-16 07:19:28 -08002708 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002709 // The parent activity doesn't want to launch the activity on top of itself, but
2710 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002711 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002712
Andrii Kulian52d255c2018-07-13 11:32:19 -07002713 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002714 // If task's parent stack is not focused - use it during adjacent launch.
2715 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002716 } else {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002717 if (focusedStack != null && task == focusedStack.topTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002718 // If task is already on top of focused stack - use it. We don't want to move the
2719 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002720 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002721 }
2722
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002723 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002724 // If parent was in docked stack, the natural place to launch another activity
2725 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002726 final int activityType =
2727 mRootActivityContainer.resolveActivityType(r, mOptions, task);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002728 return parentStack.getDisplay().getOrCreateStack(
2729 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002730 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002731 // If the parent is not in the docked stack, we check if there is docked window
2732 // and if yes, we will launch into that stack. If not, we just put the new
2733 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002734 final ActivityStack dockedStack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002735 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002736 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002737 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002738 return mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002739 } else {
2740 return dockedStack;
2741 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002742 }
2743 }
2744 }
2745
Bryce Lee7daee392017-10-12 13:46:18 -07002746 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2747 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002748 }
2749
Daichi Hirono15a02992016-04-27 18:47:01 +09002750 static boolean isDocumentLaunchesIntoExisting(int flags) {
2751 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2752 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2753 }
liulvpingcfa825f2016-09-26 20:00:15 +08002754
Bryce Lee4c9a5972017-12-01 22:14:24 -08002755 ActivityStarter setIntent(Intent intent) {
2756 mRequest.intent = intent;
2757 return this;
2758 }
2759
Bryce Lee32e09ef2018-03-19 15:29:49 -07002760 @VisibleForTesting
2761 Intent getIntent() {
2762 return mRequest.intent;
2763 }
2764
Bryce Lee4c9a5972017-12-01 22:14:24 -08002765 ActivityStarter setReason(String reason) {
2766 mRequest.reason = reason;
2767 return this;
2768 }
2769
2770 ActivityStarter setCaller(IApplicationThread caller) {
2771 mRequest.caller = caller;
2772 return this;
2773 }
2774
2775 ActivityStarter setEphemeralIntent(Intent intent) {
2776 mRequest.ephemeralIntent = intent;
2777 return this;
2778 }
2779
2780
2781 ActivityStarter setResolvedType(String type) {
2782 mRequest.resolvedType = type;
2783 return this;
2784 }
2785
2786 ActivityStarter setActivityInfo(ActivityInfo info) {
2787 mRequest.activityInfo = info;
2788 return this;
2789 }
2790
2791 ActivityStarter setResolveInfo(ResolveInfo info) {
2792 mRequest.resolveInfo = info;
2793 return this;
2794 }
2795
2796 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2797 mRequest.voiceSession = voiceSession;
2798 return this;
2799 }
2800
2801 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2802 mRequest.voiceInteractor = voiceInteractor;
2803 return this;
2804 }
2805
2806 ActivityStarter setResultTo(IBinder resultTo) {
2807 mRequest.resultTo = resultTo;
2808 return this;
2809 }
2810
2811 ActivityStarter setResultWho(String resultWho) {
2812 mRequest.resultWho = resultWho;
2813 return this;
2814 }
2815
2816 ActivityStarter setRequestCode(int requestCode) {
2817 mRequest.requestCode = requestCode;
2818 return this;
2819 }
2820
2821 ActivityStarter setCallingPid(int pid) {
2822 mRequest.callingPid = pid;
2823 return this;
2824 }
2825
2826 ActivityStarter setCallingUid(int uid) {
2827 mRequest.callingUid = uid;
2828 return this;
2829 }
2830
2831 ActivityStarter setCallingPackage(String callingPackage) {
2832 mRequest.callingPackage = callingPackage;
2833 return this;
2834 }
2835
2836 ActivityStarter setRealCallingPid(int pid) {
2837 mRequest.realCallingPid = pid;
2838 return this;
2839 }
2840
2841 ActivityStarter setRealCallingUid(int uid) {
2842 mRequest.realCallingUid = uid;
2843 return this;
2844 }
2845
2846 ActivityStarter setStartFlags(int startFlags) {
2847 mRequest.startFlags = startFlags;
2848 return this;
2849 }
2850
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002851 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002852 mRequest.activityOptions = options;
2853 return this;
2854 }
2855
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002856 ActivityStarter setActivityOptions(Bundle bOptions) {
2857 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2858 }
2859
Bryce Lee4c9a5972017-12-01 22:14:24 -08002860 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2861 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2862 return this;
2863 }
2864
Patrick Baumann31426b22018-05-21 13:46:40 -07002865 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2866 mRequest.filterCallingUid = filterCallingUid;
2867 return this;
2868 }
2869
Bryce Lee4c9a5972017-12-01 22:14:24 -08002870 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2871 mRequest.componentSpecified = componentSpecified;
2872 return this;
2873 }
2874
2875 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2876 mRequest.outActivity = outActivity;
2877 return this;
2878 }
2879
2880 ActivityStarter setInTask(TaskRecord inTask) {
2881 mRequest.inTask = inTask;
2882 return this;
2883 }
2884
2885 ActivityStarter setWaitResult(WaitResult result) {
2886 mRequest.waitResult = result;
2887 return this;
2888 }
2889
2890 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2891 mRequest.profilerInfo = info;
2892 return this;
2893 }
2894
2895 ActivityStarter setGlobalConfiguration(Configuration config) {
2896 mRequest.globalConfig = config;
2897 return this;
2898 }
2899
Bryce Lee4c9a5972017-12-01 22:14:24 -08002900 ActivityStarter setUserId(int userId) {
2901 mRequest.userId = userId;
2902 return this;
2903 }
2904
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002905 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002906 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002907 mRequest.userId = userId;
2908
2909 return this;
2910 }
2911
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002912 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2913 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2914 return this;
2915 }
2916
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002917 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2918 mRequest.originatingPendingIntent = originatingPendingIntent;
2919 return this;
2920 }
2921
Michal Karpinskiac116df2018-12-10 17:51:42 +00002922 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2923 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2924 return this;
2925 }
2926
Bryce Leed3624e12017-11-30 08:51:45 -08002927 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002928 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002929 pw.print(prefix);
2930 pw.print("mCurrentUser=");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002931 pw.println(mRootActivityContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002932 pw.print(prefix);
2933 pw.print("mLastStartReason=");
2934 pw.println(mLastStartReason);
2935 pw.print(prefix);
2936 pw.print("mLastStartActivityTimeMs=");
2937 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2938 pw.print(prefix);
2939 pw.print("mLastStartActivityResult=");
2940 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002941 ActivityRecord r = mLastStartActivityRecord[0];
2942 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002943 pw.print(prefix);
2944 pw.println("mLastStartActivityRecord:");
2945 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002946 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002947 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002948 pw.print(prefix);
2949 pw.println("mStartActivity:");
2950 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002951 }
2952 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002953 pw.print(prefix);
2954 pw.print("mIntent=");
2955 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002956 }
2957 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002958 pw.print(prefix);
2959 pw.print("mOptions=");
2960 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002961 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002962 pw.print(prefix);
2963 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002964 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002965 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002966 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002967 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002968 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002969 pw.print(prefix);
2970 pw.print("mLaunchFlags=0x");
2971 pw.print(Integer.toHexString(mLaunchFlags));
2972 pw.print(" mDoResume=");
2973 pw.print(mDoResume);
2974 pw.print(" mAddingToTask=");
2975 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002976 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002977}