blob: b0ca0af8fe8896c88dc6f64d297eea6978e3586b [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;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800190
Bryce Lee325e09682017-10-05 17:20:25 -0700191 // We must track when we deliver the new intent since multiple code paths invoke
192 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
193 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
194 // delivered at most once.
195 private boolean mIntentDelivered;
196
Wale Ogunwale01d66562015-12-29 08:19:19 -0800197 private IVoiceInteractionSession mVoiceSession;
198 private IVoiceInteractor mVoiceInteractor;
199
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700200 // Last activity record we attempted to start
201 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
202 // The result of the last activity we attempted to start.
203 private int mLastStartActivityResult;
204 // Time in milli seconds we attempted to start the last activity.
205 private long mLastStartActivityTimeMs;
206 // The reason we were trying to start the last activity
207 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700208
Bryce Lee4c9a5972017-12-01 22:14:24 -0800209 /*
210 * Request details provided through setter methods. Should be reset after {@link #execute()}
211 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
212 * {@link #startResolvedActivity} is invoked directly.
213 */
214 private Request mRequest = new Request();
215
Bryce Leed3624e12017-11-30 08:51:45 -0800216 /**
217 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
218 * used by tests to inject their own starter implementations for verification purposes.
219 */
220 @VisibleForTesting
221 interface Factory {
222 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800223 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
224 */
225 void setController(ActivityStartController controller);
226
227 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800228 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
229 * @param controller The {@link ActivityStartController} which the starter who will own
230 * this instance.
231 * @return an {@link ActivityStarter}
232 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800233 ActivityStarter obtain();
234
235 /**
236 * Recycles a starter for reuse.
237 */
238 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800239 }
240
Bryce Leed3624e12017-11-30 08:51:45 -0800241 /**
242 * Default implementation of {@link StarterFactory}.
243 */
244 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800245 /**
246 * The maximum count of starters that should be active at one time:
247 * 1. last ran starter (for logging and post activity processing)
248 * 2. current running starter
249 * 3. starter from re-entry in (2)
250 */
251 private final int MAX_STARTER_COUNT = 3;
252
Bryce Lee4c9a5972017-12-01 22:14:24 -0800253 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700254 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800255 private ActivityStackSupervisor mSupervisor;
256 private ActivityStartInterceptor mInterceptor;
257
Bryce Leedaa91e42017-12-06 14:13:01 -0800258 private SynchronizedPool<ActivityStarter> mStarterPool =
259 new SynchronizedPool<>(MAX_STARTER_COUNT);
260
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700261 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800262 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
263 mService = service;
264 mSupervisor = supervisor;
265 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800266 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800267
268 @Override
269 public void setController(ActivityStartController controller) {
270 mController = controller;
271 }
272
273 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800274 public ActivityStarter obtain() {
275 ActivityStarter starter = mStarterPool.acquire();
276
277 if (starter == null) {
278 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
279 }
280
281 return starter;
282 }
283
284 @Override
285 public void recycle(ActivityStarter starter) {
286 starter.reset(true /* clearRequest*/);
287 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800288 }
289 }
290
291 /**
292 * Container for capturing initial start request details. This information is NOT reset until
293 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
294 * parameters.
295 *
296 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
297 * the request object. Note that some member variables are referenced in
298 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
299 * execution.
300 */
301 private static class Request {
302 private static final int DEFAULT_CALLING_UID = -1;
303 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000304 static final int DEFAULT_REAL_CALLING_UID = -1;
305 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800306
307 IApplicationThread caller;
308 Intent intent;
309 Intent ephemeralIntent;
310 String resolvedType;
311 ActivityInfo activityInfo;
312 ResolveInfo resolveInfo;
313 IVoiceInteractionSession voiceSession;
314 IVoiceInteractor voiceInteractor;
315 IBinder resultTo;
316 String resultWho;
317 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000318 int callingPid = DEFAULT_CALLING_PID;
319 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800320 String callingPackage;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000321 int realCallingPid = DEFAULT_REAL_CALLING_PID;
322 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800323 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100324 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800325 boolean ignoreTargetSecurity;
326 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000327 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800328 ActivityRecord[] outActivity;
329 TaskRecord inTask;
330 String reason;
331 ProfilerInfo profilerInfo;
332 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800333 int userId;
334 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700335 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100336 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000337 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800338
339 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200340 * If set to {@code true}, allows this activity start to look into
341 * {@link PendingRemoteAnimationRegistry}
342 */
343 boolean allowPendingRemoteAnimationRegistryLookup;
344
345 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800346 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100347 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800348 * {@see ActivityStarter#startActivityMayWait}.
349 */
350 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800351
352 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800353 * Ensure constructed request matches reset instance.
354 */
355 Request() {
356 reset();
357 }
358
359 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800360 * Sets values back to the initial state, clearing any held references.
361 */
362 void reset() {
363 caller = null;
364 intent = null;
365 ephemeralIntent = null;
366 resolvedType = null;
367 activityInfo = null;
368 resolveInfo = null;
369 voiceSession = null;
370 voiceInteractor = null;
371 resultTo = null;
372 resultWho = null;
373 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800374 callingPid = DEFAULT_CALLING_PID;
375 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800376 callingPackage = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000377 realCallingPid = DEFAULT_REAL_CALLING_PID;
378 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800379 startFlags = 0;
380 activityOptions = null;
381 ignoreTargetSecurity = false;
382 componentSpecified = false;
383 outActivity = null;
384 inTask = null;
385 reason = null;
386 profilerInfo = null;
387 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800388 userId = 0;
389 waitResult = null;
390 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000391 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200392 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700393 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100394 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000395 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800396 }
397
398 /**
399 * Adopts all values from passed in request.
400 */
401 void set(Request request) {
402 caller = request.caller;
403 intent = request.intent;
404 ephemeralIntent = request.ephemeralIntent;
405 resolvedType = request.resolvedType;
406 activityInfo = request.activityInfo;
407 resolveInfo = request.resolveInfo;
408 voiceSession = request.voiceSession;
409 voiceInteractor = request.voiceInteractor;
410 resultTo = request.resultTo;
411 resultWho = request.resultWho;
412 requestCode = request.requestCode;
413 callingPid = request.callingPid;
414 callingUid = request.callingUid;
415 callingPackage = request.callingPackage;
416 realCallingPid = request.realCallingPid;
417 realCallingUid = request.realCallingUid;
418 startFlags = request.startFlags;
419 activityOptions = request.activityOptions;
420 ignoreTargetSecurity = request.ignoreTargetSecurity;
421 componentSpecified = request.componentSpecified;
422 outActivity = request.outActivity;
423 inTask = request.inTask;
424 reason = request.reason;
425 profilerInfo = request.profilerInfo;
426 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800427 userId = request.userId;
428 waitResult = request.waitResult;
429 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000430 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200431 allowPendingRemoteAnimationRegistryLookup
432 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700433 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100434 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000435 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800436 }
Bryce Leed3624e12017-11-30 08:51:45 -0800437 }
438
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700439 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800440 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
441 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800442 mService = service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800443 mRootActivityContainer = service.mRootActivityContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800444 mSupervisor = supervisor;
445 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800446 reset(true);
447 }
448
449 /**
450 * Effectively duplicates the starter passed in. All state and request values will be
451 * mirrored.
452 * @param starter
453 */
454 void set(ActivityStarter starter) {
455 mStartActivity = starter.mStartActivity;
456 mIntent = starter.mIntent;
457 mCallingUid = starter.mCallingUid;
458 mOptions = starter.mOptions;
Ricky Waib147fa12019-04-25 16:08:30 +0100459 mRestrictedBgActivity = starter.mRestrictedBgActivity;
Bryce Leedaa91e42017-12-06 14:13:01 -0800460
461 mLaunchTaskBehind = starter.mLaunchTaskBehind;
462 mLaunchFlags = starter.mLaunchFlags;
463 mLaunchMode = starter.mLaunchMode;
464
Bryce Leeec55eb02017-12-05 20:51:27 -0800465 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800466
467 mNotTop = starter.mNotTop;
468 mDoResume = starter.mDoResume;
469 mStartFlags = starter.mStartFlags;
470 mSourceRecord = starter.mSourceRecord;
471 mPreferredDisplayId = starter.mPreferredDisplayId;
472
473 mInTask = starter.mInTask;
474 mAddingToTask = starter.mAddingToTask;
475 mReuseTask = starter.mReuseTask;
476
477 mNewTaskInfo = starter.mNewTaskInfo;
478 mNewTaskIntent = starter.mNewTaskIntent;
479 mSourceStack = starter.mSourceStack;
480
481 mTargetStack = starter.mTargetStack;
482 mMovedToFront = starter.mMovedToFront;
483 mNoAnimation = starter.mNoAnimation;
484 mKeepCurTransition = starter.mKeepCurTransition;
485 mAvoidMoveToFront = starter.mAvoidMoveToFront;
486
487 mVoiceSession = starter.mVoiceSession;
488 mVoiceInteractor = starter.mVoiceInteractor;
489
490 mIntentDelivered = starter.mIntentDelivered;
491
492 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800493 }
494
Bryce Lee4c9a5972017-12-01 22:14:24 -0800495 ActivityRecord getStartActivity() {
496 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800497 }
498
Bryce Lee4c9a5972017-12-01 22:14:24 -0800499 boolean relatedToPackage(String packageName) {
500 return (mLastStartActivityRecord[0] != null
501 && packageName.equals(mLastStartActivityRecord[0].packageName))
502 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
503 }
504
505 /**
506 * Starts an activity based on the request parameters provided earlier.
507 * @return The starter result.
508 */
509 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800510 try {
511 // TODO(b/64750076): Look into passing request directly to these methods to allow
512 // for transactional diffs and preprocessing.
513 if (mRequest.mayWait) {
514 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000515 mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
516 mRequest.intent, mRequest.resolvedType,
Bryce Leedaa91e42017-12-06 14:13:01 -0800517 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
518 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
519 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100520 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200521 mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100522 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000523 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800524 } else {
525 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
526 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
527 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
528 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
529 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
530 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
531 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200532 mRequest.outActivity, mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100533 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000534 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800535 }
536 } finally {
537 onExecutionComplete();
538 }
539 }
540
541 /**
542 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
543 * Note that this method is called internally as well as part of {@link #startActivity}.
544 *
545 * @return The start result.
546 */
547 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
548 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000549 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
Bryce Leedaa91e42017-12-06 14:13:01 -0800550 try {
Louis Chang136c82e2019-04-12 12:10:21 +0800551 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(r.intent);
552 mLastStartReason = "startResolvedActivity";
553 mLastStartActivityTimeMs = System.currentTimeMillis();
554 mLastStartActivityRecord[0] = r;
555 mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor,
Ricky Waib147fa12019-04-25 16:08:30 +0100556 startFlags, doResume, options, inTask, mLastStartActivityRecord,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000557 false /* restrictedBgActivity */);
Louis Chang136c82e2019-04-12 12:10:21 +0800558 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult,
559 mLastStartActivityRecord[0]);
560 return mLastStartActivityResult;
Bryce Leedaa91e42017-12-06 14:13:01 -0800561 } finally {
562 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800563 }
564 }
565
566 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700567 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
568 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
569 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
570 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100571 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200572 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100573 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000574 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700575
576 if (TextUtils.isEmpty(reason)) {
577 throw new IllegalArgumentException("Need to specify a reason.");
578 }
579 mLastStartReason = reason;
580 mLastStartActivityTimeMs = System.currentTimeMillis();
581 mLastStartActivityRecord[0] = null;
582
583 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
584 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
585 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
586 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000587 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000588 allowBackgroundActivityStart);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700589
590 if (outActivity != null) {
591 // mLastStartActivityRecord[0] is set in the call to startActivity above.
592 outActivity[0] = mLastStartActivityRecord[0];
593 }
Bryce Leef9d49542017-06-26 16:27:32 -0700594
Bryce Lee93e7f792017-10-25 15:54:55 -0700595 return getExternalResult(mLastStartActivityResult);
596 }
597
Bryce Leed3624e12017-11-30 08:51:45 -0800598 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700599 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700600 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700601 }
602
Bryce Leedaa91e42017-12-06 14:13:01 -0800603 /**
604 * Called when execution is complete. Sets state indicating completion and proceeds with
605 * recycling if appropriate.
606 */
607 private void onExecutionComplete() {
608 mController.onExecutionComplete(this);
609 }
610
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700611 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800612 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
613 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
614 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
615 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100616 SafeActivityOptions options,
617 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100618 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000619 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Jorim Jaggi2e3bcea2019-04-01 15:09:48 +0200620 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800621 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700622 // Pull the optional Ephemeral Installer-only bundle out of the options early.
623 final Bundle verificationBundle
624 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800625
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700626 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800627 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700628 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800629 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700630 callingPid = callerApp.getPid();
631 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800632 } else {
633 Slog.w(TAG, "Unable to find app for caller " + caller
634 + " (pid=" + callingPid + ") when starting: "
635 + intent.toString());
636 err = ActivityManager.START_PERMISSION_DENIED;
637 }
638 }
639
Bryce Lee93e7f792017-10-25 15:54:55 -0700640 final int userId = aInfo != null && aInfo.applicationInfo != null
641 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800642
643 if (err == ActivityManager.START_SUCCESS) {
644 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800645 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800646 }
647
648 ActivityRecord sourceRecord = null;
649 ActivityRecord resultRecord = null;
650 if (resultTo != null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800651 sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800652 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
653 "Will send result to " + resultTo + " " + sourceRecord);
654 if (sourceRecord != null) {
655 if (requestCode >= 0 && !sourceRecord.finishing) {
656 resultRecord = sourceRecord;
657 }
658 }
659 }
660
661 final int launchFlags = intent.getFlags();
662
663 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
664 // Transfer the result target from the source activity to the new
665 // one being started, including any failures.
666 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100667 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800668 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
669 }
670 resultRecord = sourceRecord.resultTo;
671 if (resultRecord != null && !resultRecord.isInStackLocked()) {
672 resultRecord = null;
673 }
674 resultWho = sourceRecord.resultWho;
675 requestCode = sourceRecord.requestCode;
676 sourceRecord.resultTo = null;
677 if (resultRecord != null) {
678 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
679 }
680 if (sourceRecord.launchedFromUid == callingUid) {
681 // The new activity is being launched from the same uid as the previous
682 // activity in the flow, and asking to forward its result back to the
683 // previous. In this case the activity is serving as a trampoline between
684 // the two, so we also want to update its launchedFromPackage to be the
685 // same as the previous activity. Note that this is safe, since we know
686 // these two packages come from the same uid; the caller could just as
687 // well have supplied that same package name itself. This specifially
688 // deals with the case of an intent picker/chooser being launched in the app
689 // flow to redirect to an activity picked by the user, where we want the final
690 // activity to consider it to have been launched by the previous app activity.
691 callingPackage = sourceRecord.launchedFromPackage;
692 }
693 }
694
695 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
696 // We couldn't find a class that can handle the given Intent.
697 // That's the end of that!
698 err = ActivityManager.START_INTENT_NOT_RESOLVED;
699 }
700
701 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
702 // We couldn't find the specific class specified in the Intent.
703 // Also the end of the line.
704 err = ActivityManager.START_CLASS_NOT_FOUND;
705 }
706
707 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800708 && sourceRecord.getTaskRecord().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800709 // If this activity is being launched as part of a voice session, we need
710 // to ensure that it is safe to do so. If the upcoming activity will also
711 // be part of the voice session, we can only launch it if it has explicitly
712 // said it supports the VOICE category, or it is a part of the calling app.
713 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
714 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
715 try {
716 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700717 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800718 intent.getComponent(), intent, resolvedType)) {
719 Slog.w(TAG,
720 "Activity being started in current voice task does not support voice: "
721 + intent);
722 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
723 }
724 } catch (RemoteException e) {
725 Slog.w(TAG, "Failure checking voice capabilities", e);
726 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
727 }
728 }
729 }
730
731 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
732 // If the caller is starting a new voice session, just make sure the target
733 // is actually allowing it to run this way.
734 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700735 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800736 intent, resolvedType)) {
737 Slog.w(TAG,
738 "Activity being started in new voice task does not support: "
739 + intent);
740 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
741 }
742 } catch (RemoteException e) {
743 Slog.w(TAG, "Failure checking voice capabilities", e);
744 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
745 }
746 }
747
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800748 final ActivityStack resultStack = resultRecord == null
749 ? null : resultRecord.getActivityStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800750
Wale Ogunwale01d66562015-12-29 08:19:19 -0800751 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800752 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800753 resultStack.sendActivityResultLocked(
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000754 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800755 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100756 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800757 return err;
758 }
759
760 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100761 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700762 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700763 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800764 callingPid, resolvedType, aInfo.applicationInfo);
Hai Zhangf4da9be2019-05-01 13:46:06 +0800765 abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
766 callingPackage);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800767
Ricky Waib147fa12019-04-25 16:08:30 +0100768 boolean restrictedBgActivity = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000769 if (!abort) {
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000770 try {
771 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
772 "shouldAbortBackgroundActivityStart");
Ricky Waib147fa12019-04-25 16:08:30 +0100773 restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
Ricky Waiaca8a772019-04-04 16:01:06 +0100774 callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000775 originatingPendingIntent, allowBackgroundActivityStart, intent);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000776 } finally {
777 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
778 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000779 }
780
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100781 // Merge the two options bundles, while realCallerOptions takes precedence.
782 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700783 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200784 if (allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700785 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200786 .getPendingRemoteAnimationRegistry()
787 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
788 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700789 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800790 try {
791 // The Intent we give to the watcher has the extra data
792 // stripped off, since it can contain private information.
793 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700794 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800795 aInfo.applicationInfo.packageName);
796 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700797 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800798 }
799 }
800
Rubin Xu58d25992016-01-21 17:47:13 +0000801 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100802 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100803 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100804 // activity start was intercepted, e.g. because the target user is currently in quiet
805 // mode (turn off work) or the target application is suspended
806 intent = mInterceptor.mIntent;
807 rInfo = mInterceptor.mRInfo;
808 aInfo = mInterceptor.mAInfo;
809 resolvedType = mInterceptor.mResolvedType;
810 inTask = mInterceptor.mInTask;
811 callingPid = mInterceptor.mCallingPid;
812 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100813 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100814 }
815
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800816 if (abort) {
817 if (resultRecord != null) {
818 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000819 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800820 }
821 // We pretend to the caller that it was really started, but
822 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100823 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700824 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800825 }
826
827 // If permissions need a review before any of the app components can run, we
828 // launch the review activity and pass a pending intent to start the activity
829 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700830 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700831 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800832 aInfo.packageName, userId)) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700833 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800834 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
835 callingUid, userId, null, null, 0, new Intent[]{intent},
836 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
837 | PendingIntent.FLAG_ONE_SHOT, null);
838
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800839 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
Philip P. Moltmannc3e66d02019-01-31 15:56:18 -0800840
841 int flags = intent.getFlags();
842 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
843
844 /*
845 * Prevent reuse of review activity: Each app needs their own review activity. By
846 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
847 * with the same launch parameters (extras are ignored). Hence to avoid possible
848 * reuse force a new activity via the MULTIPLE_TASK flag.
849 *
850 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
851 * hence no need to add the flag in this case.
852 */
853 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
854 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
855 }
856 newIntent.setFlags(flags);
857
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800858 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
859 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
860 if (resultRecord != null) {
861 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
862 }
863 intent = newIntent;
864
865 resolvedType = null;
866 callingUid = realCallingUid;
867 callingPid = realCallingPid;
868
Svet Ganovcbcbf662018-05-10 17:25:29 -0700869 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700870 computeResolveFilterUid(
871 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800872 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
873 null /*profilerInfo*/);
874
875 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800876 final ActivityStack focusedStack =
877 mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800878 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
879 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian52d255c2018-07-13 11:32:19 -0700880 + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800881 }
882 }
883 }
884
885 // If we have an ephemeral app, abort the process of launching the resolved intent.
886 // Instead, launch the ephemeral installer. Once the installer is finished, it
887 // starts either the intent we resolved here [on install error] or the ephemeral
888 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800889 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800890 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700891 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800892 resolvedType = null;
893 callingUid = realCallingUid;
894 callingPid = realCallingPid;
895
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800896 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
897 }
898
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700899 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -0700900 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800901 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100902 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800903 if (outActivity != null) {
904 outActivity[0] = r;
905 }
906
907 if (r.appTimeTracker == null && sourceRecord != null) {
908 // If the caller didn't specify an explicit time tracker, we want to continue
909 // tracking under any it has.
910 r.appTimeTracker = sourceRecord.appTimeTracker;
911 }
912
Wale Ogunwaled32da472018-11-16 07:19:28 -0800913 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100914
915 // If we are starting an activity that is not from the same uid as the currently resumed
916 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800917 if (voiceSession == null && (stack.getResumedActivity() == null
918 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700919 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800920 realCallingPid, realCallingUid, "Activity start")) {
Alan Stokes07389b62019-05-20 15:22:54 +0100921 if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
Ricky Waib147fa12019-04-25 16:08:30 +0100922 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000923 sourceRecord, startFlags, stack, callerApp));
Ricky Waib147fa12019-04-25 16:08:30 +0100924 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100925 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800926 return ActivityManager.START_SWITCHES_CANCELED;
927 }
928 }
929
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700930 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -0800931 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800932
Jorim Jaggi2e3bcea2019-04-01 15:09:48 +0200933 final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000934 true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
Jorim Jaggi2e3bcea2019-04-01 15:09:48 +0200935 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
936 return res;
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800937 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800938
Ricky Waiaca8a772019-04-04 16:01:06 +0100939 boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000940 final String callingPackage, int realCallingUid, int realCallingPid,
941 WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
942 boolean allowBackgroundActivityStart, Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000943 // don't abort for the most important UIDs
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100944 final int callingAppId = UserHandle.getAppId(callingUid);
945 if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
946 || callingAppId == Process.NFC_UID) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000947 return false;
948 }
Alan Stokeseea8d3e2019-04-10 17:37:25 +0100949 // don't abort if the callingUid has a visible window or is a persistent system process
Riddle Hsua0536432019-02-16 00:38:59 +0800950 final int callingUidProcState = mService.getUidState(callingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000951 final boolean callingUidHasAnyVisibleWindow =
952 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
953 final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
Amith Yamasanif235d0b2019-03-20 22:49:43 -0700954 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP
955 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100956 final boolean isCallingUidPersistentSystemProcess =
957 callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Alan Stokeseea8d3e2019-04-10 17:37:25 +0100958 if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000959 return false;
960 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000961 // take realCallingUid into consideration
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000962 final int realCallingUidProcState = (callingUid == realCallingUid)
963 ? callingUidProcState
Riddle Hsua0536432019-02-16 00:38:59 +0800964 : mService.getUidState(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000965 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
966 ? callingUidHasAnyVisibleWindow
967 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
968 final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
969 ? isCallingUidForeground
970 : realCallingUidHasAnyVisibleWindow
971 || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100972 final int realCallingAppId = UserHandle.getAppId(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000973 final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
974 ? isCallingUidPersistentSystemProcess
Alan Stokes2f4a4ed2019-05-08 16:56:45 +0100975 : (realCallingAppId == Process.SYSTEM_UID)
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000976 || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000977 if (realCallingUid != callingUid) {
Alan Stokes6ac9efd2019-05-09 12:50:37 +0000978 // don't abort if the realCallingUid has a visible window
979 if (realCallingUidHasAnyVisibleWindow) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000980 return false;
981 }
982 // if the realCallingUid is a persistent system process, abort if the IntentSender
983 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +0000984 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000985 return false;
986 }
Michal Karpinskida34cd42019-04-02 19:46:52 +0100987 // don't abort if the realCallingUid is an associated companion app
988 if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
989 realCallingUid)) {
990 return false;
991 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000992 }
Michal Karpinski7b97a022018-12-14 15:17:29 +0000993 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
994 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
995 == PERMISSION_GRANTED) {
996 return false;
997 }
Michal Karpinski82bb5902018-11-28 15:52:52 +0000998 // don't abort if the caller has the same uid as the recents component
999 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
1000 return false;
1001 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001002 // don't abort if the callingUid is the device owner
1003 if (mService.isDeviceOwner(callingUid)) {
Michal Karpinski302dcec2019-02-01 11:48:25 +00001004 return false;
1005 }
Ricky Wai96f5c352019-04-10 18:40:17 +01001006 // don't abort if the callingUid has companion device
Ricky Wai2452e2d2019-03-18 19:19:08 +00001007 final int callingUserId = UserHandle.getUserId(callingUid);
Michal Karpinskida34cd42019-04-02 19:46:52 +01001008 if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
Ricky Wai2452e2d2019-03-18 19:19:08 +00001009 return false;
1010 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +01001011 // If we don't have callerApp at this point, no caller was provided to startActivity().
1012 // That's the case for PendingIntent-based starts, since the creator's process might not be
1013 // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
1014 // caller, so that we can make the decision based on its foreground/whitelisted state.
1015 int callerAppUid = callingUid;
1016 if (callerApp == null) {
1017 callerApp = mService.getProcessController(realCallingPid, realCallingUid);
1018 callerAppUid = realCallingUid;
1019 }
1020 // don't abort if the callerApp or other processes of that uid are whitelisted in any way
1021 if (callerApp != null) {
1022 // first check the original calling process
1023 if (callerApp.areBackgroundActivityStartsAllowed()) {
1024 return false;
1025 }
1026 // only if that one wasn't whitelisted, check the other ones
1027 final ArraySet<WindowProcessController> uidProcesses =
1028 mService.mProcessMap.getProcesses(callerAppUid);
1029 if (uidProcesses != null) {
1030 for (int i = uidProcesses.size() - 1; i >= 0; i--) {
1031 final WindowProcessController proc = uidProcesses.valueAt(i);
1032 if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) {
1033 return false;
1034 }
1035 }
1036 }
1037 }
Michal Karpinski15486842019-04-25 17:33:42 +01001038 // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
1039 if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
1040 Slog.w(TAG, "Background activity start for " + callingPackage
1041 + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
1042 return false;
1043 }
Michal Karpinskic02364c2019-01-22 13:00:04 +00001044 // anything that has fallen through would currently be aborted
1045 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +00001046 + "; callingUid: " + callingUid
1047 + "; isCallingUidForeground: " + isCallingUidForeground
1048 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1049 + "; realCallingUid: " + realCallingUid
1050 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
1051 + "; isRealCallingUidPersistentSystemProcess: "
Ricky Waiaca8a772019-04-04 16:01:06 +01001052 + isRealCallingUidPersistentSystemProcess
Michal Karpinskid0162852019-01-15 16:05:25 +00001053 + "; originatingPendingIntent: " + originatingPendingIntent
1054 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
1055 + "; intent: " + intent
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001056 + "; callerApp: " + callerApp
Michal Karpinskid0162852019-01-15 16:05:25 +00001057 + "]");
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001058 // log aborted activity start to TRON
1059 if (mService.isActivityStartsLoggingEnabled()) {
1060 mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1061 callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1062 realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001063 (originatingPendingIntent != null));
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001064 }
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001065 return true;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001066 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001067
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001068 /**
1069 * Creates a launch intent for the given auxiliary resolution data.
1070 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001071 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -07001072 Intent originalIntent, String callingPackage, Bundle verificationBundle,
1073 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001074 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001075 // request phase two resolution
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001076 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001077 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1078 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001079 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001080 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001081 originalIntent,
1082 InstantAppResolver.sanitizeIntent(originalIntent),
1083 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1084 callingPackage,
1085 verificationBundle,
1086 resolvedType,
1087 userId,
1088 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1089 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1090 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1091 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001092 }
1093
Riddle Hsu16567132018-08-16 21:37:47 +08001094 void postStartActivityProcessing(ActivityRecord r, int result,
1095 ActivityStack startedActivityStack) {
Bryce Lee7f936862017-05-09 15:33:18 -07001096 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001097 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001098 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001099
Chong Zhang5022da32016-06-21 16:31:37 -07001100 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001101 // brought another activity to front. We must also handle the case where the task is already
1102 // in the front as a result of the trampoline activity being in the same task (it will be
1103 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
1104 // about this, so it waits for the new activity to become visible instead.
1105 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001106
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001107 if (startedActivityStack == null) {
1108 return;
1109 }
1110
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001111 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1112 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1113 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001114 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1115 // The activity was already running so it wasn't started, but either brought to the
1116 // front or the new intent was delivered to it since it was already in front. Notify
1117 // anyone interested in this piece of information.
1118 switch (startedActivityStack.getWindowingMode()) {
1119 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001120 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001121 clearedTask);
1122 break;
1123 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001124 final ActivityStack homeStack =
1125 startedActivityStack.getDisplay().getHomeStack();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001126 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1127 mService.mWindowManager.showRecentApps();
1128 }
1129 break;
1130 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001131 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001132 }
1133
Bryce Lee4c9a5972017-12-01 22:14:24 -08001134 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001135 String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
1136 Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
1137 IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
1138 int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001139 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001140 int userId, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001141 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001142 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001143 // Refuse possible leaked file descriptors
1144 if (intent != null && intent.hasFileDescriptors()) {
1145 throw new IllegalArgumentException("File descriptors passed in Intent");
1146 }
Igor Murashkin212d06c2018-10-22 16:34:39 -07001147 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001148 boolean componentSpecified = intent.getComponent() != null;
1149
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001150 final int realCallingPid = requestRealCallingPid != Request.DEFAULT_REAL_CALLING_PID
1151 ? requestRealCallingPid
1152 : Binder.getCallingPid();
1153 final int realCallingUid = requestRealCallingUid != Request.DEFAULT_REAL_CALLING_UID
1154 ? requestRealCallingUid
1155 : Binder.getCallingUid();
Makoto Onuki1a342742018-04-26 14:56:59 -07001156
Svet Ganovcbcbf662018-05-10 17:25:29 -07001157 int callingPid;
1158 if (callingUid >= 0) {
1159 callingPid = -1;
1160 } else if (caller == null) {
1161 callingPid = realCallingPid;
1162 callingUid = realCallingUid;
1163 } else {
1164 callingPid = callingUid = -1;
1165 }
1166
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001167 // Save a copy in case ephemeral needs it
1168 final Intent ephemeralIntent = new Intent(intent);
1169 // Don't modify the client's object!
1170 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -07001171 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -08001172 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +00001173 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1174 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001175 && mService.getPackageManagerInternalLocked()
Todd Kennedyb21be122017-03-24 14:10:01 -07001176 .isInstantAppInstallerComponent(intent.getComponent())) {
1177 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +00001178 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -07001179 // adjust the intent so it looks like a "normal" instant app launch
1180 intent.setComponent(null /*component*/);
1181 componentSpecified = false;
1182 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001183
Makoto Onuki1a342742018-04-26 14:56:59 -07001184 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001185 0 /* matchFlags */,
1186 computeResolveFilterUid(
1187 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001188 if (rInfo == null) {
1189 UserInfo userInfo = mSupervisor.getUserInfo(userId);
1190 if (userInfo != null && userInfo.isManagedProfile()) {
1191 // Special case for managed profiles, if attempting to launch non-cryto aware
1192 // app in a locked managed profile from an unlocked parent allow it to resolve
1193 // as user will be sent via confirm credentials to unlock the profile.
1194 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001195 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +00001196 long token = Binder.clearCallingIdentity();
1197 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001198 UserInfo parent = userManager.getProfileParent(userId);
1199 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1200 && userManager.isUserUnlockingOrUnlocked(parent.id)
1201 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001202 } finally {
1203 Binder.restoreCallingIdentity(token);
1204 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001205 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001206 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001207 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001208 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001209 computeResolveFilterUid(
1210 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001211 }
1212 }
1213 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001214 // Collect information about the target of the Intent.
1215 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1216
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001217 synchronized (mService.mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001218 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian8072d112016-09-16 11:11:01 -07001219 stack.mConfigWillChange = globalConfig != null
Wale Ogunwalef6733932018-06-27 05:14:34 -07001220 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001221 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1222 "Starting activity when config will change = " + stack.mConfigWillChange);
1223
1224 final long origId = Binder.clearCallingIdentity();
1225
1226 if (aInfo != null &&
1227 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001228 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
Wale Ogunwale214f3482018-10-04 11:00:47 -07001229 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001230 // This may be a heavy-weight process! Check to see if we already
1231 // have another, different heavy-weight process running.
1232 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
Wale Ogunwale53783742018-09-16 10:21:51 -07001233 final WindowProcessController heavy = mService.mHeavyWeightProcess;
1234 if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
1235 || !heavy.mName.equals(aInfo.processName))) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001236 int appCallingUid = callingUid;
1237 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001238 WindowProcessController callerApp =
1239 mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001240 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001241 appCallingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001242 } else {
1243 Slog.w(TAG, "Unable to find app for caller " + caller
1244 + " (pid=" + callingPid + ") when starting: "
1245 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001246 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001247 return ActivityManager.START_PERMISSION_DENIED;
1248 }
1249 }
1250
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07001251 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001252 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1253 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1254 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1255 | PendingIntent.FLAG_ONE_SHOT, null);
1256
1257 Intent newIntent = new Intent();
1258 if (requestCode >= 0) {
1259 // Caller is requesting a result.
1260 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1261 }
1262 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1263 new IntentSender(target));
Wale Ogunwale53783742018-09-16 10:21:51 -07001264 heavy.updateIntentForHeavyWeightActivity(newIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001265 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1266 aInfo.packageName);
1267 newIntent.setFlags(intent.getFlags());
1268 newIntent.setClassName("android",
1269 HeavyWeightSwitcherActivity.class.getName());
1270 intent = newIntent;
1271 resolvedType = null;
1272 caller = null;
1273 callingUid = Binder.getCallingUid();
1274 callingPid = Binder.getCallingPid();
1275 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001276 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001277 0 /* matchFlags */, computeResolveFilterUid(
1278 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001279 aInfo = rInfo != null ? rInfo.activityInfo : null;
1280 if (aInfo != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001281 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001282 }
1283 }
1284 }
1285 }
1286
Jorim Jaggi275561a2016-02-23 10:11:02 -05001287 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001288 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1289 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1290 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001291 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001292 allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001293 allowBackgroundActivityStart);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001294
1295 Binder.restoreCallingIdentity(origId);
1296
1297 if (stack.mConfigWillChange) {
1298 // If the caller also wants to switch to a new configuration,
1299 // do so now. This allows a clean switch, as we are waiting
1300 // for the current activity to pause (so we will not destroy
1301 // it), and have not yet started the next activity.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001302 mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001303 "updateConfiguration()");
1304 stack.mConfigWillChange = false;
1305 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1306 "Updating to new configuration after starting activity.");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001307 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001308 }
1309
Vishnu Nair132ee832018-09-28 15:00:05 -07001310 // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
1311 // will then wait for the windows to be drawn and populate WaitResult.
1312 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001313 if (outResult != null) {
1314 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001315
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001316 final ActivityRecord r = outRecord[0];
1317
1318 switch(res) {
1319 case START_SUCCESS: {
1320 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001321 do {
1322 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001323 mService.mGlobalLock.wait();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001324 } catch (InterruptedException e) {
1325 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001326 } while (outResult.result != START_TASK_TO_FRONT
1327 && !outResult.timeout && outResult.who == null);
1328 if (outResult.result == START_TASK_TO_FRONT) {
1329 res = START_TASK_TO_FRONT;
1330 }
1331 break;
1332 }
1333 case START_DELIVERED_TO_TOP: {
1334 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001335 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001336 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001337 break;
1338 }
1339 case START_TASK_TO_FRONT: {
Louis Chang0513a942019-03-06 12:38:13 +08001340 outResult.launchState =
1341 r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001342 // ActivityRecord may represent a different activity, but it should not be
1343 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001344 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001345 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001346 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001347 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001348 } else {
Vishnu Nair132ee832018-09-28 15:00:05 -07001349 final long startTimeMs = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001350 mSupervisor.waitActivityVisible(
1351 r.mActivityComponent, outResult, startTimeMs);
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001352 // Note: the timeout variable is not currently not ever set.
1353 do {
1354 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001355 mService.mGlobalLock.wait();
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001356 } catch (InterruptedException e) {
1357 }
1358 } while (!outResult.timeout && outResult.who == null);
1359 }
1360 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001361 }
1362 }
1363 }
1364
1365 return res;
1366 }
1367 }
1368
Svet Ganovcbcbf662018-05-10 17:25:29 -07001369 /**
1370 * Compute the logical UID based on which the package manager would filter
1371 * app components i.e. based on which the instant app policy would be applied
1372 * because it is the logical calling UID.
1373 *
1374 * @param customCallingUid The UID on whose behalf to make the call.
1375 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001376 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001377 * @return The logical UID making the call.
1378 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001379 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1380 int filterCallingUid) {
1381 return filterCallingUid != UserHandle.USER_NULL
1382 ? filterCallingUid
1383 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001384 }
1385
Bryce Leedaa91e42017-12-06 14:13:01 -08001386 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1387 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001388 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1389 ActivityRecord[] outActivity, boolean restrictedBgActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001390 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001391 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001392 try {
1393 mService.mWindowManager.deferSurfaceLayout();
1394 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001395 startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001396 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001397 final ActivityStack currentStack = r.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001398 startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1399
1400 if (ActivityManager.isStartResultSuccessful(result)) {
1401 if (startedActivityStack != null) {
1402 // If there is no state change (e.g. a resumed activity is reparented to
1403 // top of another display) to trigger a visibility/configuration checking,
1404 // we have to update the configuration for changing to different display.
1405 final ActivityRecord currentTop =
1406 startedActivityStack.topRunningActivityLocked();
1407 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001408 mRootActivityContainer.ensureVisibilityAndConfig(
1409 currentTop, currentTop.getDisplayId(),
Riddle Hsu16567132018-08-16 21:37:47 +08001410 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1411 }
1412 }
1413 } else {
1414 // If we are not able to proceed, disassociate the activity from the task.
1415 // Leaving an activity in an incomplete state can lead to issues, such as
1416 // performing operations without a window container.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001417 final ActivityStack stack = mStartActivity.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001418 if (stack != null) {
1419 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001420 null /* intentResultData */, "startActivity", true /* oomAdj */);
Riddle Hsu16567132018-08-16 21:37:47 +08001421 }
Louis Change8902452019-06-10 10:49:28 +08001422
1423 // Stack should also be detached from display and be removed if it's empty.
1424 if (startedActivityStack != null && startedActivityStack.isAttached()
1425 && startedActivityStack.numActivities() == 0
1426 && !startedActivityStack.isActivityTypeHome()) {
1427 startedActivityStack.remove();
1428 }
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001429 }
1430 mService.mWindowManager.continueSurfaceLayout();
1431 }
1432
Riddle Hsu16567132018-08-16 21:37:47 +08001433 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001434
1435 return result;
1436 }
1437
Ricky Waib147fa12019-04-25 16:08:30 +01001438 /**
1439 * Return true if background activity is really aborted.
1440 *
1441 * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere.
1442 */
1443 private boolean handleBackgroundActivityAbort(ActivityRecord r) {
1444 // TODO(b/131747138): Remove toast and refactor related code in Q release.
1445 boolean abort = !mService.isBackgroundActivityStartsEnabled();
Ricky Waib147fa12019-04-25 16:08:30 +01001446 if (!abort) {
1447 return false;
1448 }
1449 ActivityRecord resultRecord = r.resultTo;
1450 String resultWho = r.resultWho;
1451 int requestCode = r.requestCode;
1452 if (resultRecord != null) {
1453 ActivityStack resultStack = resultRecord.getActivityStack();
1454 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001455 RESULT_CANCELED, null);
Ricky Waib147fa12019-04-25 16:08:30 +01001456 }
1457 // We pretend to the caller that it was really started to make it backward compatible, but
1458 // they will just get a cancel result.
1459 ActivityOptions.abort(r.pendingOptions);
1460 return true;
1461 }
1462
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001463 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001464 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1465 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001466 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001467 ActivityRecord[] outActivity, boolean restrictedBgActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001468 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
Ricky Waib147fa12019-04-25 16:08:30 +01001469 voiceInteractor, restrictedBgActivity);
1470
Louis Chang39ba54b2018-10-18 11:28:57 +08001471 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001472
Louis Chang6fb1e842018-12-03 16:07:50 +08001473 computeLaunchingTaskFlags();
1474
1475 computeSourceStack();
1476
1477 mIntent.setFlags(mLaunchFlags);
1478
1479 ActivityRecord reusedActivity = getReusableIntentActivity();
1480
1481 mSupervisor.getLaunchParamsController().calculate(
1482 reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
1483 r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
1484 mPreferredDisplayId =
1485 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1486 : DEFAULT_DISPLAY;
1487
Louis Changbd48dca2018-08-29 17:44:34 +08001488 // Do not start home activity if it cannot be launched on preferred display. We are not
1489 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1490 // fallback to launch on other displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001491 if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
Louis Changdd3592a2018-11-05 11:04:14 +08001492 mPreferredDisplayId, true /* allowInstrumenting */)) {
Louis Changbd48dca2018-08-29 17:44:34 +08001493 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1494 return START_CANCELED;
1495 }
1496
Bryce Lee4a194382017-04-04 14:32:48 -07001497 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001498 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1499 // still needs to be a lock task mode violation since the task gets cleared out and
1500 // the device would otherwise leave the locked task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001501 if (mService.getLockTaskController().isLockTaskModeViolation(
1502 reusedActivity.getTaskRecord(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001503 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1504 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001505 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1506 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1507 }
1508
Bryce Leef65ee7e2018-03-26 16:03:47 -07001509 // True if we are clearing top and resetting of a standard (default) launch mode
1510 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1511 final boolean clearTopAndResetStandardLaunchMode =
1512 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1513 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1514 && mLaunchMode == LAUNCH_MULTIPLE;
1515
1516 // If mStartActivity does not have a task associated with it, associate it with the
1517 // reused activity's task. Do not do so if we're clearing top and resetting for a
1518 // standard launchMode activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001519 if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
1520 mStartActivity.setTask(reusedActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001521 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001522
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001523 if (reusedActivity.getTaskRecord().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001524 // This task was started because of movement of the activity based on affinity...
1525 // Now that we are actually launching it, we can assign the base intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001526 reusedActivity.getTaskRecord().setIntent(mStartActivity);
Louis Changb45ee7e2019-01-17 10:36:56 +08001527 } else {
1528 final boolean taskOnHome =
1529 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1530 if (taskOnHome) {
1531 reusedActivity.getTaskRecord().intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1532 } else {
1533 reusedActivity.getTaskRecord().intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1534 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001535 }
1536
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001537 // This code path leads to delivering a new intent, we want to make sure we schedule it
1538 // as the first operation, in case the activity will be resumed as a result of later
1539 // operations.
1540 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001541 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001542 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001543 final TaskRecord task = reusedActivity.getTaskRecord();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001544
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001545 // In this situation we want to remove all activities from the task up to the one
1546 // being started. In most cases this means we are resetting the task to its initial
1547 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001548 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1549 mLaunchFlags);
1550
Bryce Lee4a194382017-04-04 14:32:48 -07001551 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001552 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1553 // task reference is needed in the call below to
1554 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001555 if (reusedActivity.getTaskRecord() == null) {
Bryce Lee4a194382017-04-04 14:32:48 -07001556 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001557 }
1558
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001559 if (top != null) {
1560 if (top.frontOfTask) {
1561 // Activity aliases may mean we use different intents for the top activity,
1562 // so make sure the task now has the identity of the new intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001563 top.getTaskRecord().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001564 }
Bryce Lee325e09682017-10-05 17:20:25 -07001565 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001566 }
1567 }
1568
Wale Ogunwaled32da472018-11-16 07:19:28 -08001569 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
1570 (false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001571
Bryce Lee4a194382017-04-04 14:32:48 -07001572 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001573
Bryce Lee89cd19a2017-05-17 15:18:35 -07001574 final ActivityRecord outResult =
1575 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1576
1577 // When there is a reused activity and the current result is a trampoline activity,
1578 // set the reused activity as the result.
1579 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1580 outActivity[0] = reusedActivity;
1581 }
1582
Wale Ogunwale01d66562015-12-29 08:19:19 -08001583 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1584 // We don't need to start a new activity, and the client said not to do anything
1585 // if that is the case, so this is it! And for paranoia, make sure we have
1586 // correctly resumed the top activity.
1587 resumeTargetStackIfNeeded();
1588 return START_RETURN_INTENT_TO_CALLER;
1589 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001590
Bryce Leef65ee7e2018-03-26 16:03:47 -07001591 if (reusedActivity != null) {
1592 setTaskFromIntentActivity(reusedActivity);
1593
1594 if (!mAddingToTask && mReuseTask == null) {
1595 // We didn't do anything... but it was needed (a.k.a., client don't use that
1596 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
Bryce Leef65ee7e2018-03-26 16:03:47 -07001597 resumeTargetStackIfNeeded();
1598 if (outActivity != null && outActivity.length > 0) {
Louis Changa59937a2019-03-20 17:17:22 +08001599 // The reusedActivity could be finishing, for example of starting an
1600 // activity with FLAG_ACTIVITY_CLEAR_TOP flag. In that case, return the
1601 // top running activity in the task instead.
1602 outActivity[0] = reusedActivity.finishing
1603 ? reusedActivity.getTaskRecord().getTopActivity() : reusedActivity;
Bryce Leef65ee7e2018-03-26 16:03:47 -07001604 }
1605
1606 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001607 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001608 }
1609 }
1610
1611 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001612 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001613 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001614 if (sourceStack != null) {
1615 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1616 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001617 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001618 }
1619 ActivityOptions.abort(mOptions);
1620 return START_CLASS_NOT_FOUND;
1621 }
1622
1623 // If the activity being launched is the same as the one currently at the top, then
1624 // we need to check if it should only be launched once.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001625 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001626 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001627 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1628 final boolean dontStart = top != null && mStartActivity.resultTo == null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001629 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1630 && top.mUserId == mStartActivity.mUserId
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001631 && top.attachedToProcess()
Wale Ogunwale01d66562015-12-29 08:19:19 -08001632 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Louis Changbd48dca2018-08-29 17:44:34 +08001633 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1634 // This allows home activity to automatically launch on secondary display when
1635 // display added, if home was the top activity on default display, instead of
1636 // sending new intent to the home activity on default display.
1637 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001638 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001639 // For paranoia, make sure we have correctly resumed the top activity.
1640 topStack.mLastPausedActivity = null;
1641 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001642 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001643 }
1644 ActivityOptions.abort(mOptions);
1645 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1646 // We don't need to start a new activity, and the client said not to do
1647 // anything if that is the case, so this is it!
1648 return START_RETURN_INTENT_TO_CALLER;
1649 }
Bryce Lee325e09682017-10-05 17:20:25 -07001650
1651 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001652
1653 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1654 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001655 mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
Louis Chang39ba54b2018-10-18 11:28:57 +08001656 mPreferredDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001657
Wale Ogunwale01d66562015-12-29 08:19:19 -08001658 return START_DELIVERED_TO_TOP;
1659 }
1660
1661 boolean newTask = false;
1662 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001663 ? mSourceRecord.getTaskRecord() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001664
1665 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001666 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001667 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1668 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1669 newTask = true;
Louis Changceeb5062018-09-17 18:13:52 +08001670 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001671 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001672 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001673 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001674 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001675 } else {
1676 // This not being started from an existing activity, and not part of a new task...
1677 // just put it in the top task, though these days this case should never happen.
Ricky Waib147fa12019-04-25 16:08:30 +01001678 result = setTaskToCurrentTopOrCreateNewTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001679 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001680 if (result != START_SUCCESS) {
1681 return result;
1682 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001683
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001684 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
1685 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001686 mService.getPackageManagerInternalLocked().grantEphemeralAccess(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001687 mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001688 UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001689 if (newTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001690 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
1691 mStartActivity.getTaskRecord().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001692 }
1693 ActivityStack.logStartActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001694 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001695 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001696
Wale Ogunwaled32da472018-11-16 07:19:28 -08001697 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
1698 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001699
Winson Chungb5c41b72016-12-07 15:00:47 -08001700 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1701 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001702 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001703 final ActivityRecord topTaskActivity =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001704 mStartActivity.getTaskRecord().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001705 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001706 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1707 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001708 // If the activity is not focusable, we can't resume it, but still would like to
1709 // make sure it becomes visible as it starts (this will also trigger entry
1710 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001711 // Also, we don't want to resume activities in a task that currently has an overlay
1712 // as the starting activity just needs to be in the visible paused state until the
1713 // over is removed.
Andrii Kulian6b321512019-01-23 06:37:00 +00001714 mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001715 // Go ahead and tell window manager to execute app transition for this activity
1716 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001717 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001718 } else {
Winson Chung32066032016-11-04 11:55:21 -07001719 // If the target stack was not previously focusable (previous top running activity
1720 // on that stack was not visible) then any prior calls to move the stack to the
1721 // will not update the focused stack. If starting the new activity now allows the
1722 // task stack to be focusable, then ensure that we now update the focused stack
1723 // accordingly.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001724 if (mTargetStack.isFocusable()
Wale Ogunwaled32da472018-11-16 07:19:28 -08001725 && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
Winson Chung32066032016-11-04 11:55:21 -07001726 mTargetStack.moveToFront("startActivityUnchecked");
1727 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001728 mRootActivityContainer.resumeFocusedStacksTopActivities(
1729 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001730 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001731 } else if (mStartActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001732 mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001733 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001734 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001735
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001736 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1737 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001738
1739 return START_SUCCESS;
1740 }
1741
Bryce Leedaa91e42017-12-06 14:13:01 -08001742 /**
1743 * Resets the {@link ActivityStarter} state.
1744 * @param clearRequest whether the request should be reset to default values.
1745 */
1746 void reset(boolean clearRequest) {
1747 mStartActivity = null;
1748 mIntent = null;
1749 mCallingUid = -1;
1750 mOptions = null;
Ricky Waib147fa12019-04-25 16:08:30 +01001751 mRestrictedBgActivity = false;
Bryce Leedaa91e42017-12-06 14:13:01 -08001752
1753 mLaunchTaskBehind = false;
1754 mLaunchFlags = 0;
1755 mLaunchMode = INVALID_LAUNCH_MODE;
1756
Bryce Leeec55eb02017-12-05 20:51:27 -08001757 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001758
1759 mNotTop = null;
1760 mDoResume = false;
1761 mStartFlags = 0;
1762 mSourceRecord = null;
1763 mPreferredDisplayId = INVALID_DISPLAY;
1764
1765 mInTask = null;
1766 mAddingToTask = false;
1767 mReuseTask = null;
1768
1769 mNewTaskInfo = null;
1770 mNewTaskIntent = null;
1771 mSourceStack = null;
1772
1773 mTargetStack = null;
1774 mMovedToFront = false;
1775 mNoAnimation = false;
1776 mKeepCurTransition = false;
1777 mAvoidMoveToFront = false;
1778
1779 mVoiceSession = null;
1780 mVoiceInteractor = null;
1781
1782 mIntentDelivered = false;
1783
1784 if (clearRequest) {
1785 mRequest.reset();
1786 }
1787 }
1788
Wale Ogunwale01d66562015-12-29 08:19:19 -08001789 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1790 boolean doResume, int startFlags, ActivityRecord sourceRecord,
Ricky Waib147fa12019-04-25 16:08:30 +01001791 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1792 boolean restrictedBgActivity) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001793 reset(false /* clearRequest */);
1794
Wale Ogunwale01d66562015-12-29 08:19:19 -08001795 mStartActivity = r;
1796 mIntent = r.intent;
1797 mOptions = options;
1798 mCallingUid = r.launchedFromUid;
1799 mSourceRecord = sourceRecord;
1800 mVoiceSession = voiceSession;
1801 mVoiceInteractor = voiceInteractor;
Ricky Waib147fa12019-04-25 16:08:30 +01001802 mRestrictedBgActivity = restrictedBgActivity;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001803
Bryce Leeec55eb02017-12-05 20:51:27 -08001804 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001805
Louis Chang6fb1e842018-12-03 16:07:50 +08001806 // Preferred display id is the only state we need for now and it could be updated again
1807 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07001808 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08001809 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
1810 mPreferredDisplayId =
1811 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1812 : DEFAULT_DISPLAY;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07001813
Bryce Lee7daee392017-10-12 13:46:18 -07001814 mLaunchMode = r.launchMode;
1815
Wale Ogunwale01d66562015-12-29 08:19:19 -08001816 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001817 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1818 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001819 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001820 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001821 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1822
1823 sendNewTaskResultRequestIfNeeded();
1824
1825 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1826 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1827 }
1828
1829 // If we are actually going to launch in to a new task, there are some cases where
1830 // we further want to do multiple task.
1831 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1832 if (mLaunchTaskBehind
1833 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1834 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1835 }
1836 }
1837
1838 // We'll invoke onUserLeaving before onPause only if the launching
1839 // activity did not explicitly state that this is an automated launch.
1840 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1841 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1842 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1843
1844 // If the caller has asked not to resume at this point, we make note
1845 // of this in the record so that we can skip it when trying to find
1846 // the top running activity.
1847 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001848 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001849 r.delayedResume = true;
1850 mDoResume = false;
1851 }
1852
Winson Chunge2d72172018-01-25 17:46:20 +00001853 if (mOptions != null) {
1854 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1855 r.mTaskOverlay = true;
1856 if (!mOptions.canTaskOverlayResume()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001857 final TaskRecord task = mRootActivityContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00001858 mOptions.getLaunchTaskId());
1859 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001860 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001861
Winson Chunge2d72172018-01-25 17:46:20 +00001862 // The caller specifies that we'd like to be avoided to be moved to the
1863 // front, so be it!
1864 mDoResume = false;
1865 mAvoidMoveToFront = true;
1866 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001867 }
Winson Chunge2d72172018-01-25 17:46:20 +00001868 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001869 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001870 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001871 }
1872 }
1873
Louis Chang2f4e9b462019-03-05 16:43:15 +08001874 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001875
1876 mInTask = inTask;
1877 // In some flows in to this function, we retrieve the task record and hold on to it
1878 // without a lock before calling back in to here... so the task at this point may
1879 // not actually be in recents. Check for that, and if it isn't in recents just
1880 // consider it invalid.
1881 if (inTask != null && !inTask.inRecents) {
1882 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1883 mInTask = null;
1884 }
1885
1886 mStartFlags = startFlags;
1887 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1888 // is the same as the one making the call... or, as a special case, if we do not know
1889 // the caller then we count the current top activity as the caller.
1890 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1891 ActivityRecord checkedCaller = sourceRecord;
1892 if (checkedCaller == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001893 checkedCaller = mRootActivityContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001894 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001895 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001896 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001897 // Caller is not the same as launcher, so always needed.
1898 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1899 }
1900 }
1901
1902 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
Ricky Waib147fa12019-04-25 16:08:30 +01001903
Alan Stokes07389b62019-05-20 15:22:54 +01001904 if (mRestrictedBgActivity && !mService.isBackgroundActivityStartsEnabled()) {
Ricky Waib147fa12019-04-25 16:08:30 +01001905 mAvoidMoveToFront = true;
1906 mDoResume = false;
1907 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001908 }
1909
1910 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001911 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001912 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001913 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001914 // For whatever reason this activity is being launched into a new task...
1915 // yet the caller has requested a result back. Well, that is pretty messed up,
1916 // so instead immediately send back a cancel and let the new task continue launched
1917 // as normal without a dependency on its originator.
1918 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001919 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1920 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00001921 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001922 mStartActivity.resultTo = null;
1923 }
1924 }
1925
1926 private void computeLaunchingTaskFlags() {
1927 // If the caller is not coming from another activity, but has given us an explicit task into
1928 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001929 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001930 final Intent baseIntent = mInTask.getBaseIntent();
1931 final ActivityRecord root = mInTask.getRootActivity();
1932 if (baseIntent == null) {
1933 ActivityOptions.abort(mOptions);
1934 throw new IllegalArgumentException("Launching into task without base intent: "
1935 + mInTask);
1936 }
1937
1938 // If this task is empty, then we are adding the first activity -- it
1939 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001940 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001941 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1942 ActivityOptions.abort(mOptions);
1943 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1944 + mStartActivity + " into different task " + mInTask);
1945 }
1946 if (root != null) {
1947 ActivityOptions.abort(mOptions);
1948 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1949 + " has root " + root + " but target is singleInstance/Task");
1950 }
1951 }
1952
1953 // If task is empty, then adopt the interesting intent launch flags in to the
1954 // activity being started.
1955 if (root == null) {
1956 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1957 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1958 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1959 | (baseIntent.getFlags() & flagsOfInterest);
1960 mIntent.setFlags(mLaunchFlags);
1961 mInTask.setIntent(mStartActivity);
1962 mAddingToTask = true;
1963
1964 // If the task is not empty and the caller is asking to start it as the root of
1965 // a new task, then we don't actually want to start this on the task. We will
1966 // bring the task to the front, and possibly give it a new intent.
1967 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1968 mAddingToTask = false;
1969
1970 } else {
1971 mAddingToTask = true;
1972 }
1973
1974 mReuseTask = mInTask;
1975 } else {
1976 mInTask = null;
1977 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1978 // when in freeform workspace.
1979 // Also put noDisplay activities in the source task. These by itself can be placed
1980 // in any task/stack, however it could launch other activities like ResolverActivity,
1981 // and we want those to stay in the original task.
Louis Chang6a9be162019-07-15 10:41:32 +08001982 if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
1983 && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001984 mAddingToTask = true;
1985 }
1986 }
1987
1988 if (mInTask == null) {
1989 if (mSourceRecord == null) {
1990 // This activity is not being started from another... in this
1991 // case we -always- start a new task.
1992 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1993 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1994 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1995 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1996 }
1997 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1998 // The original activity who is starting us is running as a single
1999 // instance... this new activity it is starting must go on its
2000 // own task.
2001 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07002002 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002003 // The activity being started is a single instance... it always
2004 // gets launched into its own task.
2005 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2006 }
2007 }
2008 }
2009
2010 private void computeSourceStack() {
2011 if (mSourceRecord == null) {
2012 mSourceStack = null;
2013 return;
2014 }
2015 if (!mSourceRecord.finishing) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002016 mSourceStack = mSourceRecord.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002017 return;
2018 }
2019
2020 // If the source is finishing, we can't further count it as our source. This is because the
2021 // task it is associated with may now be empty and on its way out, so we don't want to
2022 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
2023 // a task for it. But save the task information so it can be used when creating the new task.
2024 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
2025 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
2026 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
2027 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
2028 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07002029
2030 // It is not guaranteed that the source record will have a task associated with it. For,
2031 // example, if this method is being called for processing a pending activity launch, it
2032 // is possible that the activity has been removed from the task after the launch was
2033 // enqueued.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002034 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
Bryce Leed9ed45d2017-05-22 15:57:24 -07002035 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002036 }
2037 mSourceRecord = null;
2038 mSourceStack = null;
2039 }
2040
2041 /**
2042 * Decide whether the new activity should be inserted into an existing task. Returns null
2043 * if not or an ActivityRecord with the task into which the new activity should be added.
2044 */
2045 private ActivityRecord getReusableIntentActivity() {
2046 // We may want to try to place the new activity in to an existing task. We always
2047 // do this if the target activity is singleTask or singleInstance; we will also do
2048 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2049 // us to still place it in a new task: multi task, always doc mode, or being asked to
2050 // launch this as a new task behind the current one.
2051 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
2052 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07002053 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002054 // If bring to front is requested, and no result is requested and we have not been given
2055 // an explicit task to launch in to, and we can find a task that was started with this
2056 // same component, then instead of launching bring that one to the front.
2057 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
2058 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01002059 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002060 final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
Jorim Jaggi2adba072016-03-03 13:43:39 +01002061 intentActivity = task != null ? task.getTopActivity() : null;
2062 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07002063 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002064 // There can be one and only one instance of single instance activity in the
2065 // history, and it is always in its own unique task, so we do a special search.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002066 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002067 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002068 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2069 // For the launch adjacent case we only want to put the activity in an existing
2070 // task if the activity already exists in the history.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002071 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07002072 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002073 } else {
2074 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002075 intentActivity =
2076 mRootActivityContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002077 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002078 }
Louis Changbd48dca2018-08-29 17:44:34 +08002079
Louis Chang54506cb2018-11-23 11:03:41 +08002080 if (intentActivity != null
2081 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08002082 && intentActivity.getDisplayId() != mPreferredDisplayId) {
2083 // Do not reuse home activity on other displays.
2084 intentActivity = null;
2085 }
2086
Wale Ogunwale01d66562015-12-29 08:19:19 -08002087 return intentActivity;
2088 }
2089
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002090 /**
2091 * Figure out which task and activity to bring to front when we have found an existing matching
2092 * activity record in history. May also clear the task if needed.
2093 * @param intentActivity Existing matching activity.
2094 * @return {@link ActivityRecord} brought to front.
2095 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08002096 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002097 mTargetStack = intentActivity.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002098 mTargetStack.mLastPausedActivity = null;
2099 // If the target task is not in the front, then we need to bring it to the front...
2100 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2101 // the same behavior as if a new instance was being started, which means not bringing it
2102 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002103 final boolean differentTopTask;
2104 if (mPreferredDisplayId == mTargetStack.mDisplayId) {
2105 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2106 final ActivityRecord curTop = (focusStack == null)
2107 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002108 final TaskRecord topTask = curTop != null ? curTop.getTaskRecord() : null;
Riddle Hsu273e9992019-04-29 22:40:59 +08002109 differentTopTask = topTask != intentActivity.getTaskRecord()
2110 || (focusStack != null && topTask != focusStack.topTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002111 } else {
2112 // The existing task should always be different from those in other displays.
2113 differentTopTask = true;
2114 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002115
Riddle Hsub70b36d2018-09-11 21:20:02 +08002116 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002117 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002118 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002119 mSourceStack.getTopActivity().getTaskRecord()
2120 == mSourceRecord.getTaskRecord())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002121 // We really do want to push this one into the user's face, right now.
2122 if (mLaunchTaskBehind && mSourceRecord != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002123 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002124 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002125
2126 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
2127 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
2128 // So no point resuming any of the activities here, it just wastes one extra
2129 // resuming, plus enter AND exit transitions.
2130 // Here we only want to bring the target stack forward. Transition will be applied
2131 // to the new activity that's started after the old ones are gone.
2132 final boolean willClearTask =
2133 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2134 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
2135 if (!willClearTask) {
2136 final ActivityStack launchStack = getLaunchStack(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002137 mStartActivity, mLaunchFlags, mStartActivity.getTaskRecord(), mOptions);
2138 final TaskRecord intentTask = intentActivity.getTaskRecord();
Chong Zhangdea4bd92016-03-15 12:50:03 -07002139 if (launchStack == null || launchStack == mTargetStack) {
2140 // We only want to move to the front, if we aren't going to launch on a
2141 // different stack. If we launch on a different stack, we will put the
2142 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07002143 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
2144 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07002145 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002146 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002147 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2148 // If we want to launch adjacent and mTargetStack is not the computed
2149 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002150 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08002151 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2152 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002153 } else {
2154 // TODO: This should be reevaluated in MW v2.
2155 // We choose to move task to front instead of launching it adjacent
2156 // when specific stack was requested explicitly and it appeared to be
2157 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07002158 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07002159 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002160 "bringToFrontInsteadOfAdjacentLaunch");
2161 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07002162 mMovedToFront = launchStack != launchStack.getDisplay()
2163 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002164 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
2165 // Target and computed stacks are on different displays and we've
2166 // found a matching task - move the existing instance to that display and
2167 // move it to front.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002168 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002169 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2170 "reparentToDisplay");
2171 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002172 } else if (launchStack.isActivityTypeHome()
2173 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07002174 // It is possible for the home activity to be in another stack initially.
2175 // For example, the activity may have been initially started with an intent
2176 // which placed it in the fullscreen stack. To ensure the proper handling of
2177 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002178 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07002179 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2180 "reparentingHome");
2181 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07002182 }
2183 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002184
2185 // We are moving a task to the front, use starting window to hide initial drawn
2186 // delay.
2187 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
2188 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002189 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002190 }
2191 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002192 // Need to update mTargetStack because if task was moved out of it, the original stack may
2193 // be destroyed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002194 mTargetStack = intentActivity.getActivityStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07002195 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002196 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2197 + " from " + intentActivity);
2198 mTargetStack.moveToFront("intentActivityFound");
2199 }
2200
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002201 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTaskRecord(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002202 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07002203
Wale Ogunwale01d66562015-12-29 08:19:19 -08002204 // If the caller has requested that the target task be reset, then do so.
2205 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2206 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2207 }
2208 return intentActivity;
2209 }
2210
2211 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2212 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2213 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2214 // The caller has requested to completely replace any existing task with its new
2215 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08002216 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2217 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08002218 // of history or if it is finished immediately), thus disassociating the task. Also note
2219 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2220 // launching another activity.
2221 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2222 // already launching one.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002223 final TaskRecord task = intentActivity.getTaskRecord();
Bryce Lee59dad4e2017-03-09 11:54:08 -08002224 task.performClearTaskLocked();
2225 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08002226 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002227 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002228 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002229 final ActivityRecord top = intentActivity.getTaskRecord().performClearTaskLocked(
2230 mStartActivity, mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002231 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002232 // A special case: we need to start the activity because it is not currently
2233 // running, and the caller has asked to clear the current task to have this
2234 // activity at the top.
2235 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08002236
2237 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07002238 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002239 // Now pretend like this activity is being started by the top of its task, so it
2240 // is put in the right place.
2241 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002242 final TaskRecord task = mSourceRecord.getTaskRecord();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002243 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002244 // Target stack got cleared when we all activities were removed above.
2245 // Go ahead and reset it.
2246 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07002247 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002248 mTargetStack.addTask(task,
2249 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2250 }
2251 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002252 } else if (mStartActivity.mActivityComponent.equals(
2253 intentActivity.getTaskRecord().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002254 // In this case the top activity on the task is the same as the one being launched,
2255 // so we take that as a request to bring the task to the foreground. If the top
2256 // activity in the task is the root activity, deliver this new intent to it if it
2257 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07002258 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2259 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002260 && intentActivity.mActivityComponent.equals(
2261 mStartActivity.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002262 if (intentActivity.frontOfTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002263 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002264 }
Bryce Lee325e09682017-10-05 17:20:25 -07002265 deliverNewIntent(intentActivity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002266 } else if (!intentActivity.getTaskRecord().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002267 // In this case we are launching the root activity of the task, but with a
2268 // different intent. We should start a new instance on top.
2269 mAddingToTask = true;
2270 mSourceRecord = intentActivity;
2271 }
2272 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2273 // In this case an activity is being launched in to an existing task, without
2274 // resetting that task. This is typically the situation of launching an activity
2275 // from a notification or shortcut. We want to place the new activity on top of the
2276 // current task.
2277 mAddingToTask = true;
2278 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002279 } else if (!intentActivity.getTaskRecord().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002280 // In this case we are launching into an existing task that has not yet been started
2281 // from its front door. The current task has been brought to the front. Ideally,
2282 // we'd probably like to place this new task at the bottom of its stack, but that's
2283 // a little hard to do with the current organization of the code so for now we'll
2284 // just drop it.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002285 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002286 }
2287 }
2288
2289 private void resumeTargetStackIfNeeded() {
2290 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002291 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002292 } else {
2293 ActivityOptions.abort(mOptions);
2294 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002295 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002296 }
2297
Louis Changceeb5062018-09-17 18:13:52 +08002298 private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
Louis Change8902452019-06-10 10:49:28 +08002299 if (mRestrictedBgActivity && (mReuseTask == null || !mReuseTask.containsAppUid(mCallingUid))
2300 && handleBackgroundActivityAbort(mStartActivity)) {
2301 return START_ABORTED;
2302 }
2303
Bryce Leedacefc42017-10-10 12:56:02 -07002304 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002305
2306 // Do no move the target stack to front yet, as we might bail if
2307 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002308
2309 if (mReuseTask == null) {
Riddle Hsu609a8e22019-06-27 16:46:29 -06002310 final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002311 final TaskRecord task = mTargetStack.createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002312 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002313 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002314 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Riddle Hsu609a8e22019-06-27 16:46:29 -06002315 mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002316 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002317 updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002318
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002319 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002320 + " in new task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002321 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002322 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2323 }
2324
2325 if (taskToAffiliate != null) {
2326 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002327 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002328
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002329 if (mService.getLockTaskController().isLockTaskModeViolation(
2330 mStartActivity.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002331 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2332 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2333 }
2334
Chong Zhang6cda19c2016-06-14 19:07:56 -07002335 if (mDoResume) {
2336 mTargetStack.moveToFront("reuseOrNewTask");
2337 }
2338 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002339 }
2340
Bryce Lee325e09682017-10-05 17:20:25 -07002341 private void deliverNewIntent(ActivityRecord activity) {
2342 if (mIntentDelivered) {
2343 return;
2344 }
2345
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002346 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTaskRecord());
Wale Ogunwale586a8ee2019-06-04 13:44:14 +00002347 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
Bryce Lee325e09682017-10-05 17:20:25 -07002348 mStartActivity.launchedFromPackage);
2349 mIntentDelivered = true;
2350 }
2351
Wale Ogunwale01d66562015-12-29 08:19:19 -08002352 private int setTaskFromSourceRecord() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002353 if (mService.getLockTaskController().isLockTaskModeViolation(
2354 mSourceRecord.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002355 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2356 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2357 }
2358
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002359 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
2360 final ActivityStack sourceStack = mSourceRecord.getActivityStack();
Ricky Waib147fa12019-04-25 16:08:30 +01002361 if (mRestrictedBgActivity && !sourceTask.containsAppUid(mCallingUid)) {
2362 if (handleBackgroundActivityAbort(mStartActivity)) {
2363 return START_ABORTED;
2364 }
Ricky Waib147fa12019-04-25 16:08:30 +01002365 }
Andrii Kulian02689a72017-07-06 14:28:59 -07002366 // We only want to allow changing stack in two cases:
2367 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2368 // the other side, rather than show two side by side.
2369 // 2. If activity is not allowed on target display.
2370 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2371 : sourceStack.mDisplayId;
2372 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2373 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002374 if (moveStackAllowed) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002375 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags,
2376 mStartActivity.getTaskRecord(), mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002377 // If target stack is not found now - we can't just rely on the source stack, as it may
2378 // be not suitable. Let's check other displays.
2379 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2380 // Can't use target display, lets find a stack on the source display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002381 mTargetStack = mRootActivityContainer.getValidLaunchStackOnDisplay(
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002382 sourceStack.mDisplayId, mStartActivity, mOptions, mLaunchParams);
Andrii Kulian02689a72017-07-06 14:28:59 -07002383 }
2384 if (mTargetStack == null) {
2385 // There are no suitable stacks on the target and source display(s). Look on all
2386 // displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002387 mTargetStack = mRootActivityContainer.getNextValidLaunchStack(
Andrii Kulian02689a72017-07-06 14:28:59 -07002388 mStartActivity, -1 /* currentFocus */);
2389 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002390 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002391
2392 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002393 mTargetStack = sourceStack;
2394 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002395 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2396 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002397 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002398
Wale Ogunwale01d66562015-12-29 08:19:19 -08002399 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002400 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002401 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002402 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002403 } else if (mDoResume) {
2404 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002405 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002406
Wale Ogunwale01d66562015-12-29 08:19:19 -08002407 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2408 // In this case, we are adding the activity to an existing task, but the caller has
2409 // asked to clear that task if the activity is already running.
2410 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2411 mKeepCurTransition = true;
2412 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002413 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002414 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002415 // For paranoia, make sure we have correctly resumed the top activity.
2416 mTargetStack.mLastPausedActivity = null;
2417 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002418 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002419 }
2420 ActivityOptions.abort(mOptions);
2421 return START_DELIVERED_TO_TOP;
2422 }
2423 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2424 // In this case, we are launching an activity in our own task that may already be
2425 // running somewhere in the history, and we want to shuffle it to the front of the
2426 // stack if so.
2427 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2428 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002429 final TaskRecord task = top.getTaskRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002430 task.moveActivityToFrontLocked(top);
2431 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002432 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002433 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002434 mTargetStack.mLastPausedActivity = null;
2435 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002436 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002437 }
2438 return START_DELIVERED_TO_TOP;
2439 }
2440 }
2441
2442 // An existing activity is starting this new activity, so we want to keep the new one in
2443 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002444 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002445 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002446 + " in existing task " + mStartActivity.getTaskRecord()
2447 + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002448 return START_SUCCESS;
2449 }
2450
2451 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002452 // The caller is asking that the new activity be started in an explicit
2453 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002454 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002455 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2456 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2457 }
2458
Andrii Kulian02b7a832016-10-06 23:11:56 -07002459 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002460
2461 // Check whether we should actually launch the new activity in to the task,
2462 // or just reuse the current activity on top.
2463 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002464 if (top != null && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2465 && top.mUserId == mStartActivity.mUserId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002466 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002467 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002468 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002469 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002470 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2471 // We don't need to start a new activity, and the client said not to do
2472 // anything if that is the case, so this is it!
2473 return START_RETURN_INTENT_TO_CALLER;
2474 }
Bryce Lee325e09682017-10-05 17:20:25 -07002475 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002476 return START_DELIVERED_TO_TOP;
2477 }
2478 }
2479
2480 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002481 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002482 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002483 // We don't actually want to have this activity added to the task, so just
2484 // stop here but still tell the caller that we consumed the intent.
2485 ActivityOptions.abort(mOptions);
2486 return START_TASK_TO_FRONT;
2487 }
2488
Bryce Leeec55eb02017-12-05 20:51:27 -08002489 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002490 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwaled32da472018-11-16 07:19:28 -08002491 ActivityStack stack = mRootActivityContainer.getLaunchStack(
2492 null, null, mInTask, ON_TOP);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002493 if (stack != mInTask.getStack()) {
2494 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002495 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002496 mTargetStack = mInTask.getStack();
2497 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002498
Bryce Leeec55eb02017-12-05 20:51:27 -08002499 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002500 }
2501
chaviw0d562bf2018-03-15 14:24:14 -07002502 mTargetStack.moveTaskToFrontLocked(
2503 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002504
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002505 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2506 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002507 + " in explicit task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002508
2509 return START_SUCCESS;
2510 }
2511
Bryce Leed3624e12017-11-30 08:51:45 -08002512 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002513 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002514 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002515 return;
2516 }
2517
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002518 final ActivityStack stack = task.getStack();
2519 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002520 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002521 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002522 } else {
2523 task.updateOverrideConfiguration(bounds);
2524 }
2525 }
2526
Ricky Waib147fa12019-04-25 16:08:30 +01002527 private int setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002528 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002529 if (mDoResume) {
2530 mTargetStack.moveToFront("addingToTopTask");
2531 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002532 final ActivityRecord prev = mTargetStack.getTopActivity();
Ricky Waib147fa12019-04-25 16:08:30 +01002533 if (mRestrictedBgActivity && prev == null) {
2534 if (handleBackgroundActivityAbort(mStartActivity)) {
2535 return START_ABORTED;
2536 }
Ricky Waib147fa12019-04-25 16:08:30 +01002537 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002538 final TaskRecord task = (prev != null)
2539 ? prev.getTaskRecord() : mTargetStack.createTaskRecord(
2540 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002541 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Alan Stokes07389b62019-05-20 15:22:54 +01002542 if (mRestrictedBgActivity && prev != null && !task.containsAppUid(mCallingUid)) {
Ricky Waib147fa12019-04-25 16:08:30 +01002543 if (handleBackgroundActivityAbort(mStartActivity)) {
2544 return START_ABORTED;
2545 }
Ricky Waib147fa12019-04-25 16:08:30 +01002546 }
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002547 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2548 mTargetStack.positionChildWindowContainerAtTop(task);
2549 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002550 + " in new guessed " + mStartActivity.getTaskRecord());
Ricky Waib147fa12019-04-25 16:08:30 +01002551 return START_SUCCESS;
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002552 }
2553
2554 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002555 if (mStartActivity.getTaskRecord() == null || mStartActivity.getTaskRecord() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002556 parent.addActivityToTop(mStartActivity);
2557 } else {
2558 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2559 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002560 }
2561
2562 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2563 boolean launchSingleTask, int launchFlags) {
2564 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2565 (launchSingleInstance || launchSingleTask)) {
2566 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2567 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2568 "\"singleInstance\" or \"singleTask\"");
2569 launchFlags &=
2570 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2571 } else {
2572 switch (r.info.documentLaunchMode) {
2573 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2574 break;
2575 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2576 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2577 break;
2578 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2579 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2580 break;
2581 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2582 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2583 break;
2584 }
2585 }
2586 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002587 }
2588
Bryce Leedacefc42017-10-10 12:56:02 -07002589 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2590 ActivityOptions aOptions) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002591 final TaskRecord task = r.getTaskRecord();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002592 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002593 if (stack != null) {
2594 return stack;
2595 }
2596
Andrii Kulian02b7a832016-10-06 23:11:56 -07002597 final ActivityStack currentStack = task != null ? task.getStack() : null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002598 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002599 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002600 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002601 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2602 "computeStackFocus: Setting " + "focused stack to r=" + r
2603 + " task=" + task);
2604 } else {
2605 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002606 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002607 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002608 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002609 }
2610
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002611 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002612 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002613 "computeStackFocus: Have a focused stack=" + focusedStack);
2614 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002615 }
2616
David Stevense5a7b642017-05-22 13:18:23 -07002617 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002618 // Try to put the activity in a stack on a secondary display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002619 stack = mRootActivityContainer.getValidLaunchStackOnDisplay(
2620 mPreferredDisplayId, r, aOptions, mLaunchParams);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002621 if (stack == null) {
2622 // If source display is not suitable - look for topmost valid stack in the system.
2623 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002624 "computeStackFocus: Can't launch on mPreferredDisplayId="
2625 + mPreferredDisplayId + ", looking on all displays.");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002626 stack = mRootActivityContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002627 }
2628 }
2629 if (stack == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002630 stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002631 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002632 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2633 + r + " stackId=" + stack.mStackId);
2634 return stack;
2635 }
2636
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002637 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002638 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002639 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002640 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002641 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002642 if (focusedStack.isActivityTypeAssistant()) {
2643 canUseFocusedStack = r.isActivityTypeAssistant();
2644 } else {
2645 switch (focusedStack.getWindowingMode()) {
2646 case WINDOWING_MODE_FULLSCREEN:
2647 // The fullscreen stack can contain any task regardless of if the task is
2648 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2649 // focus stack.
2650 canUseFocusedStack = true;
2651 break;
2652 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2653 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2654 // Any activity which supports split screen can go in the docked stack.
2655 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2656 break;
2657 case WINDOWING_MODE_FREEFORM:
2658 // Any activity which supports freeform can go in the freeform stack.
2659 canUseFocusedStack = r.supportsFreeform();
2660 break;
2661 default:
2662 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2663 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002664 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002665 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2666 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002667 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002668 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002669 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002670 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002671 }
2672
Wale Ogunwale854809c2015-12-27 16:18:19 -08002673 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002674 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002675 // We are reusing a task, keep the stack!
2676 if (mReuseTask != null) {
2677 return mReuseTask.getStack();
2678 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002679
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002680 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002681 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Winson Chung93442032018-12-04 13:24:29 -08002682 final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002683 final ActivityStack stack =
Winson Chung93442032018-12-04 13:24:29 -08002684 mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002685 return stack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002686 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002687 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002688
Wale Ogunwaled32da472018-11-16 07:19:28 -08002689 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002690 // The parent activity doesn't want to launch the activity on top of itself, but
2691 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002692 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002693
Andrii Kulian52d255c2018-07-13 11:32:19 -07002694 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002695 // If task's parent stack is not focused - use it during adjacent launch.
2696 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002697 } else {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002698 if (focusedStack != null && task == focusedStack.topTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002699 // If task is already on top of focused stack - use it. We don't want to move the
2700 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002701 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002702 }
2703
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002704 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002705 // If parent was in docked stack, the natural place to launch another activity
2706 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002707 final int activityType =
2708 mRootActivityContainer.resolveActivityType(r, mOptions, task);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002709 return parentStack.getDisplay().getOrCreateStack(
2710 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002711 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002712 // If the parent is not in the docked stack, we check if there is docked window
2713 // and if yes, we will launch into that stack. If not, we just put the new
2714 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002715 final ActivityStack dockedStack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002716 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002717 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002718 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002719 return mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002720 } else {
2721 return dockedStack;
2722 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002723 }
2724 }
2725 }
2726
Bryce Lee7daee392017-10-12 13:46:18 -07002727 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2728 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002729 }
2730
Daichi Hirono15a02992016-04-27 18:47:01 +09002731 static boolean isDocumentLaunchesIntoExisting(int flags) {
2732 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2733 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2734 }
liulvpingcfa825f2016-09-26 20:00:15 +08002735
Bryce Lee4c9a5972017-12-01 22:14:24 -08002736 ActivityStarter setIntent(Intent intent) {
2737 mRequest.intent = intent;
2738 return this;
2739 }
2740
Bryce Lee32e09ef2018-03-19 15:29:49 -07002741 @VisibleForTesting
2742 Intent getIntent() {
2743 return mRequest.intent;
2744 }
2745
Bryce Lee4c9a5972017-12-01 22:14:24 -08002746 ActivityStarter setReason(String reason) {
2747 mRequest.reason = reason;
2748 return this;
2749 }
2750
2751 ActivityStarter setCaller(IApplicationThread caller) {
2752 mRequest.caller = caller;
2753 return this;
2754 }
2755
2756 ActivityStarter setEphemeralIntent(Intent intent) {
2757 mRequest.ephemeralIntent = intent;
2758 return this;
2759 }
2760
2761
2762 ActivityStarter setResolvedType(String type) {
2763 mRequest.resolvedType = type;
2764 return this;
2765 }
2766
2767 ActivityStarter setActivityInfo(ActivityInfo info) {
2768 mRequest.activityInfo = info;
2769 return this;
2770 }
2771
2772 ActivityStarter setResolveInfo(ResolveInfo info) {
2773 mRequest.resolveInfo = info;
2774 return this;
2775 }
2776
2777 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2778 mRequest.voiceSession = voiceSession;
2779 return this;
2780 }
2781
2782 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2783 mRequest.voiceInteractor = voiceInteractor;
2784 return this;
2785 }
2786
2787 ActivityStarter setResultTo(IBinder resultTo) {
2788 mRequest.resultTo = resultTo;
2789 return this;
2790 }
2791
2792 ActivityStarter setResultWho(String resultWho) {
2793 mRequest.resultWho = resultWho;
2794 return this;
2795 }
2796
2797 ActivityStarter setRequestCode(int requestCode) {
2798 mRequest.requestCode = requestCode;
2799 return this;
2800 }
2801
2802 ActivityStarter setCallingPid(int pid) {
2803 mRequest.callingPid = pid;
2804 return this;
2805 }
2806
2807 ActivityStarter setCallingUid(int uid) {
2808 mRequest.callingUid = uid;
2809 return this;
2810 }
2811
2812 ActivityStarter setCallingPackage(String callingPackage) {
2813 mRequest.callingPackage = callingPackage;
2814 return this;
2815 }
2816
2817 ActivityStarter setRealCallingPid(int pid) {
2818 mRequest.realCallingPid = pid;
2819 return this;
2820 }
2821
2822 ActivityStarter setRealCallingUid(int uid) {
2823 mRequest.realCallingUid = uid;
2824 return this;
2825 }
2826
2827 ActivityStarter setStartFlags(int startFlags) {
2828 mRequest.startFlags = startFlags;
2829 return this;
2830 }
2831
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002832 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002833 mRequest.activityOptions = options;
2834 return this;
2835 }
2836
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002837 ActivityStarter setActivityOptions(Bundle bOptions) {
2838 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2839 }
2840
Bryce Lee4c9a5972017-12-01 22:14:24 -08002841 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2842 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2843 return this;
2844 }
2845
Patrick Baumann31426b22018-05-21 13:46:40 -07002846 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2847 mRequest.filterCallingUid = filterCallingUid;
2848 return this;
2849 }
2850
Bryce Lee4c9a5972017-12-01 22:14:24 -08002851 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2852 mRequest.componentSpecified = componentSpecified;
2853 return this;
2854 }
2855
2856 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2857 mRequest.outActivity = outActivity;
2858 return this;
2859 }
2860
2861 ActivityStarter setInTask(TaskRecord inTask) {
2862 mRequest.inTask = inTask;
2863 return this;
2864 }
2865
2866 ActivityStarter setWaitResult(WaitResult result) {
2867 mRequest.waitResult = result;
2868 return this;
2869 }
2870
2871 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2872 mRequest.profilerInfo = info;
2873 return this;
2874 }
2875
2876 ActivityStarter setGlobalConfiguration(Configuration config) {
2877 mRequest.globalConfig = config;
2878 return this;
2879 }
2880
Bryce Lee4c9a5972017-12-01 22:14:24 -08002881 ActivityStarter setUserId(int userId) {
2882 mRequest.userId = userId;
2883 return this;
2884 }
2885
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002886 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002887 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002888 mRequest.userId = userId;
2889
2890 return this;
2891 }
2892
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002893 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2894 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2895 return this;
2896 }
2897
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002898 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2899 mRequest.originatingPendingIntent = originatingPendingIntent;
2900 return this;
2901 }
2902
Michal Karpinskiac116df2018-12-10 17:51:42 +00002903 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2904 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2905 return this;
2906 }
2907
Bryce Leed3624e12017-11-30 08:51:45 -08002908 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002909 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002910 pw.print(prefix);
2911 pw.print("mCurrentUser=");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002912 pw.println(mRootActivityContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002913 pw.print(prefix);
2914 pw.print("mLastStartReason=");
2915 pw.println(mLastStartReason);
2916 pw.print(prefix);
2917 pw.print("mLastStartActivityTimeMs=");
2918 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2919 pw.print(prefix);
2920 pw.print("mLastStartActivityResult=");
2921 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002922 ActivityRecord r = mLastStartActivityRecord[0];
2923 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002924 pw.print(prefix);
2925 pw.println("mLastStartActivityRecord:");
2926 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002927 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002928 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002929 pw.print(prefix);
2930 pw.println("mStartActivity:");
2931 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002932 }
2933 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002934 pw.print(prefix);
2935 pw.print("mIntent=");
2936 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002937 }
2938 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002939 pw.print(prefix);
2940 pw.print("mOptions=");
2941 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002942 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002943 pw.print(prefix);
2944 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002945 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002946 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002947 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002948 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002949 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002950 pw.print(prefix);
2951 pw.print("mLaunchFlags=0x");
2952 pw.print(Integer.toHexString(mLaunchFlags));
2953 pw.print(" mDoResume=");
2954 pw.print(mDoResume);
2955 pw.print(" mAddingToTask=");
2956 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002957 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002958}