blob: 2b23ff08439122e960a3b7ca949381e7641a0a52 [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;
Michal Karpinskiac213c62019-02-19 12:38:14 +0000104import android.content.res.Resources;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800105import android.graphics.Rect;
106import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800107import android.os.Bundle;
108import android.os.IBinder;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000109import android.os.Process;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800110import android.os.RemoteException;
111import android.os.SystemClock;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100112import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000114import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800115import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700116import android.text.TextUtils;
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;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000120import android.widget.Toast;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800121
Michal Karpinskiac213c62019-02-19 12:38:14 +0000122import com.android.internal.R;
Bryce Leed3624e12017-11-30 08:51:45 -0800123import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800124import com.android.internal.app.HeavyWeightSwitcherActivity;
125import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700126import com.android.server.am.EventLogTags;
127import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800128import com.android.server.pm.InstantAppResolver;
Wale Ogunwale59507092018-10-29 09:00:30 -0700129import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
130import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800131
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700132import java.io.PrintWriter;
133import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700134import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800135
136/**
Bryce Leed3624e12017-11-30 08:51:45 -0800137 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800138 *
139 * This class collects all the logic for determining how an intent and flags should be turned into
140 * an activity and associated task and stack.
141 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800142class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700143 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800144 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
145 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
146 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
147 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700148 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800149
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700150 private final ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800151 private final RootActivityContainer mRootActivityContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800152 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100153 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800154 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800155
Wale Ogunwale01d66562015-12-29 08:19:19 -0800156 // Share state variable among methods when starting an activity.
157 private ActivityRecord mStartActivity;
158 private Intent mIntent;
159 private int mCallingUid;
160 private ActivityOptions mOptions;
161
Bryce Lee7daee392017-10-12 13:46:18 -0700162 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800163 private boolean mLaunchTaskBehind;
164 private int mLaunchFlags;
165
Bryce Leeec55eb02017-12-05 20:51:27 -0800166 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800167
168 private ActivityRecord mNotTop;
169 private boolean mDoResume;
170 private int mStartFlags;
171 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700172
David Stevense5a7b642017-05-22 13:18:23 -0700173 // The display to launch the activity onto, barring any strong reason to do otherwise.
174 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800175
176 private TaskRecord mInTask;
177 private boolean mAddingToTask;
178 private TaskRecord mReuseTask;
179
180 private ActivityInfo mNewTaskInfo;
181 private Intent mNewTaskIntent;
182 private ActivityStack mSourceStack;
183 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800184 private boolean mMovedToFront;
185 private boolean mNoAnimation;
186 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700187 private boolean mAvoidMoveToFront;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800188
Bryce Lee325e09682017-10-05 17:20:25 -0700189 // We must track when we deliver the new intent since multiple code paths invoke
190 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
191 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
192 // delivered at most once.
193 private boolean mIntentDelivered;
194
Wale Ogunwale01d66562015-12-29 08:19:19 -0800195 private IVoiceInteractionSession mVoiceSession;
196 private IVoiceInteractor mVoiceInteractor;
197
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700198 // Last activity record we attempted to start
199 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
200 // The result of the last activity we attempted to start.
201 private int mLastStartActivityResult;
202 // Time in milli seconds we attempted to start the last activity.
203 private long mLastStartActivityTimeMs;
204 // The reason we were trying to start the last activity
205 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700206
Bryce Lee4c9a5972017-12-01 22:14:24 -0800207 /*
208 * Request details provided through setter methods. Should be reset after {@link #execute()}
209 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
210 * {@link #startResolvedActivity} is invoked directly.
211 */
212 private Request mRequest = new Request();
213
Bryce Leed3624e12017-11-30 08:51:45 -0800214 /**
215 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
216 * used by tests to inject their own starter implementations for verification purposes.
217 */
218 @VisibleForTesting
219 interface Factory {
220 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800221 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
222 */
223 void setController(ActivityStartController controller);
224
225 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800226 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
227 * @param controller The {@link ActivityStartController} which the starter who will own
228 * this instance.
229 * @return an {@link ActivityStarter}
230 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800231 ActivityStarter obtain();
232
233 /**
234 * Recycles a starter for reuse.
235 */
236 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800237 }
238
Bryce Leed3624e12017-11-30 08:51:45 -0800239 /**
240 * Default implementation of {@link StarterFactory}.
241 */
242 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800243 /**
244 * The maximum count of starters that should be active at one time:
245 * 1. last ran starter (for logging and post activity processing)
246 * 2. current running starter
247 * 3. starter from re-entry in (2)
248 */
249 private final int MAX_STARTER_COUNT = 3;
250
Bryce Lee4c9a5972017-12-01 22:14:24 -0800251 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700252 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800253 private ActivityStackSupervisor mSupervisor;
254 private ActivityStartInterceptor mInterceptor;
255
Bryce Leedaa91e42017-12-06 14:13:01 -0800256 private SynchronizedPool<ActivityStarter> mStarterPool =
257 new SynchronizedPool<>(MAX_STARTER_COUNT);
258
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700259 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800260 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
261 mService = service;
262 mSupervisor = supervisor;
263 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800264 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800265
266 @Override
267 public void setController(ActivityStartController controller) {
268 mController = controller;
269 }
270
271 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800272 public ActivityStarter obtain() {
273 ActivityStarter starter = mStarterPool.acquire();
274
275 if (starter == null) {
276 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
277 }
278
279 return starter;
280 }
281
282 @Override
283 public void recycle(ActivityStarter starter) {
284 starter.reset(true /* clearRequest*/);
285 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800286 }
287 }
288
289 /**
290 * Container for capturing initial start request details. This information is NOT reset until
291 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
292 * parameters.
293 *
294 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
295 * the request object. Note that some member variables are referenced in
296 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
297 * execution.
298 */
299 private static class Request {
300 private static final int DEFAULT_CALLING_UID = -1;
301 private static final int DEFAULT_CALLING_PID = 0;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000302 static final int DEFAULT_REAL_CALLING_UID = -1;
303 static final int DEFAULT_REAL_CALLING_PID = 0;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800304
305 IApplicationThread caller;
306 Intent intent;
307 Intent ephemeralIntent;
308 String resolvedType;
309 ActivityInfo activityInfo;
310 ResolveInfo resolveInfo;
311 IVoiceInteractionSession voiceSession;
312 IVoiceInteractor voiceInteractor;
313 IBinder resultTo;
314 String resultWho;
315 int requestCode;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000316 int callingPid = DEFAULT_CALLING_PID;
317 int callingUid = DEFAULT_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800318 String callingPackage;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000319 int realCallingPid = DEFAULT_REAL_CALLING_PID;
320 int realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800321 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100322 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800323 boolean ignoreTargetSecurity;
324 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000325 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800326 ActivityRecord[] outActivity;
327 TaskRecord inTask;
328 String reason;
329 ProfilerInfo profilerInfo;
330 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800331 int userId;
332 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700333 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100334 PendingIntentRecord originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000335 boolean allowBackgroundActivityStart;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800336
337 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200338 * If set to {@code true}, allows this activity start to look into
339 * {@link PendingRemoteAnimationRegistry}
340 */
341 boolean allowPendingRemoteAnimationRegistryLookup;
342
343 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800344 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100345 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800346 * {@see ActivityStarter#startActivityMayWait}.
347 */
348 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800349
350 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800351 * Ensure constructed request matches reset instance.
352 */
353 Request() {
354 reset();
355 }
356
357 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800358 * Sets values back to the initial state, clearing any held references.
359 */
360 void reset() {
361 caller = null;
362 intent = null;
363 ephemeralIntent = null;
364 resolvedType = null;
365 activityInfo = null;
366 resolveInfo = null;
367 voiceSession = null;
368 voiceInteractor = null;
369 resultTo = null;
370 resultWho = null;
371 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800372 callingPid = DEFAULT_CALLING_PID;
373 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800374 callingPackage = null;
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000375 realCallingPid = DEFAULT_REAL_CALLING_PID;
376 realCallingUid = DEFAULT_REAL_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800377 startFlags = 0;
378 activityOptions = null;
379 ignoreTargetSecurity = false;
380 componentSpecified = false;
381 outActivity = null;
382 inTask = null;
383 reason = null;
384 profilerInfo = null;
385 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800386 userId = 0;
387 waitResult = null;
388 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000389 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200390 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700391 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100392 originatingPendingIntent = null;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000393 allowBackgroundActivityStart = false;
Bryce Leedaa91e42017-12-06 14:13:01 -0800394 }
395
396 /**
397 * Adopts all values from passed in request.
398 */
399 void set(Request request) {
400 caller = request.caller;
401 intent = request.intent;
402 ephemeralIntent = request.ephemeralIntent;
403 resolvedType = request.resolvedType;
404 activityInfo = request.activityInfo;
405 resolveInfo = request.resolveInfo;
406 voiceSession = request.voiceSession;
407 voiceInteractor = request.voiceInteractor;
408 resultTo = request.resultTo;
409 resultWho = request.resultWho;
410 requestCode = request.requestCode;
411 callingPid = request.callingPid;
412 callingUid = request.callingUid;
413 callingPackage = request.callingPackage;
414 realCallingPid = request.realCallingPid;
415 realCallingUid = request.realCallingUid;
416 startFlags = request.startFlags;
417 activityOptions = request.activityOptions;
418 ignoreTargetSecurity = request.ignoreTargetSecurity;
419 componentSpecified = request.componentSpecified;
420 outActivity = request.outActivity;
421 inTask = request.inTask;
422 reason = request.reason;
423 profilerInfo = request.profilerInfo;
424 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800425 userId = request.userId;
426 waitResult = request.waitResult;
427 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000428 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200429 allowPendingRemoteAnimationRegistryLookup
430 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700431 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100432 originatingPendingIntent = request.originatingPendingIntent;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000433 allowBackgroundActivityStart = request.allowBackgroundActivityStart;
Bryce Leedaa91e42017-12-06 14:13:01 -0800434 }
Bryce Leed3624e12017-11-30 08:51:45 -0800435 }
436
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700437 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800438 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
439 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800440 mService = service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800441 mRootActivityContainer = service.mRootActivityContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800442 mSupervisor = supervisor;
443 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800444 reset(true);
445 }
446
447 /**
448 * Effectively duplicates the starter passed in. All state and request values will be
449 * mirrored.
450 * @param starter
451 */
452 void set(ActivityStarter starter) {
453 mStartActivity = starter.mStartActivity;
454 mIntent = starter.mIntent;
455 mCallingUid = starter.mCallingUid;
456 mOptions = starter.mOptions;
457
458 mLaunchTaskBehind = starter.mLaunchTaskBehind;
459 mLaunchFlags = starter.mLaunchFlags;
460 mLaunchMode = starter.mLaunchMode;
461
Bryce Leeec55eb02017-12-05 20:51:27 -0800462 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800463
464 mNotTop = starter.mNotTop;
465 mDoResume = starter.mDoResume;
466 mStartFlags = starter.mStartFlags;
467 mSourceRecord = starter.mSourceRecord;
468 mPreferredDisplayId = starter.mPreferredDisplayId;
469
470 mInTask = starter.mInTask;
471 mAddingToTask = starter.mAddingToTask;
472 mReuseTask = starter.mReuseTask;
473
474 mNewTaskInfo = starter.mNewTaskInfo;
475 mNewTaskIntent = starter.mNewTaskIntent;
476 mSourceStack = starter.mSourceStack;
477
478 mTargetStack = starter.mTargetStack;
479 mMovedToFront = starter.mMovedToFront;
480 mNoAnimation = starter.mNoAnimation;
481 mKeepCurTransition = starter.mKeepCurTransition;
482 mAvoidMoveToFront = starter.mAvoidMoveToFront;
483
484 mVoiceSession = starter.mVoiceSession;
485 mVoiceInteractor = starter.mVoiceInteractor;
486
487 mIntentDelivered = starter.mIntentDelivered;
488
489 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800490 }
491
Bryce Lee4c9a5972017-12-01 22:14:24 -0800492 ActivityRecord getStartActivity() {
493 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800494 }
495
Bryce Lee4c9a5972017-12-01 22:14:24 -0800496 boolean relatedToPackage(String packageName) {
497 return (mLastStartActivityRecord[0] != null
498 && packageName.equals(mLastStartActivityRecord[0].packageName))
499 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
500 }
501
502 /**
503 * Starts an activity based on the request parameters provided earlier.
504 * @return The starter result.
505 */
506 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800507 try {
508 // TODO(b/64750076): Look into passing request directly to these methods to allow
509 // for transactional diffs and preprocessing.
510 if (mRequest.mayWait) {
511 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000512 mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
513 mRequest.intent, mRequest.resolvedType,
Bryce Leedaa91e42017-12-06 14:13:01 -0800514 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
515 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
516 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100517 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200518 mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100519 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000520 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800521 } else {
522 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
523 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
524 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
525 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
526 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
527 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
528 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200529 mRequest.outActivity, mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100530 mRequest.allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000531 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
Bryce Leedaa91e42017-12-06 14:13:01 -0800532 }
533 } finally {
534 onExecutionComplete();
535 }
536 }
537
538 /**
539 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
540 * Note that this method is called internally as well as part of {@link #startActivity}.
541 *
542 * @return The start result.
543 */
544 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
545 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
546 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
547 ActivityRecord[] outActivity) {
548 try {
549 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
550 doResume, options, inTask, outActivity);
551 } finally {
552 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800553 }
554 }
555
556 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700557 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
558 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
559 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
560 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100561 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200562 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100563 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000564 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700565
566 if (TextUtils.isEmpty(reason)) {
567 throw new IllegalArgumentException("Need to specify a reason.");
568 }
569 mLastStartReason = reason;
570 mLastStartActivityTimeMs = System.currentTimeMillis();
571 mLastStartActivityRecord[0] = null;
572
573 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
574 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
575 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
576 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000577 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
578 allowBackgroundActivityStart);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700579
580 if (outActivity != null) {
581 // mLastStartActivityRecord[0] is set in the call to startActivity above.
582 outActivity[0] = mLastStartActivityRecord[0];
583 }
Bryce Leef9d49542017-06-26 16:27:32 -0700584
Bryce Lee93e7f792017-10-25 15:54:55 -0700585 return getExternalResult(mLastStartActivityResult);
586 }
587
Bryce Leed3624e12017-11-30 08:51:45 -0800588 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700589 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700590 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700591 }
592
Bryce Leedaa91e42017-12-06 14:13:01 -0800593 /**
594 * Called when execution is complete. Sets state indicating completion and proceeds with
595 * recycling if appropriate.
596 */
597 private void onExecutionComplete() {
598 mController.onExecutionComplete(this);
599 }
600
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700601 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800602 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
603 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
604 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
605 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100606 SafeActivityOptions options,
607 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100608 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000609 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800610 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700611 // Pull the optional Ephemeral Installer-only bundle out of the options early.
612 final Bundle verificationBundle
613 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800614
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700615 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800616 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700617 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800618 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700619 callingPid = callerApp.getPid();
620 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800621 } else {
622 Slog.w(TAG, "Unable to find app for caller " + caller
623 + " (pid=" + callingPid + ") when starting: "
624 + intent.toString());
625 err = ActivityManager.START_PERMISSION_DENIED;
626 }
627 }
628
Bryce Lee93e7f792017-10-25 15:54:55 -0700629 final int userId = aInfo != null && aInfo.applicationInfo != null
630 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800631
632 if (err == ActivityManager.START_SUCCESS) {
633 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800634 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800635 }
636
637 ActivityRecord sourceRecord = null;
638 ActivityRecord resultRecord = null;
639 if (resultTo != null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800640 sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800641 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
642 "Will send result to " + resultTo + " " + sourceRecord);
643 if (sourceRecord != null) {
644 if (requestCode >= 0 && !sourceRecord.finishing) {
645 resultRecord = sourceRecord;
646 }
647 }
648 }
649
650 final int launchFlags = intent.getFlags();
651
652 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
653 // Transfer the result target from the source activity to the new
654 // one being started, including any failures.
655 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100656 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800657 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
658 }
659 resultRecord = sourceRecord.resultTo;
660 if (resultRecord != null && !resultRecord.isInStackLocked()) {
661 resultRecord = null;
662 }
663 resultWho = sourceRecord.resultWho;
664 requestCode = sourceRecord.requestCode;
665 sourceRecord.resultTo = null;
666 if (resultRecord != null) {
667 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
668 }
669 if (sourceRecord.launchedFromUid == callingUid) {
670 // The new activity is being launched from the same uid as the previous
671 // activity in the flow, and asking to forward its result back to the
672 // previous. In this case the activity is serving as a trampoline between
673 // the two, so we also want to update its launchedFromPackage to be the
674 // same as the previous activity. Note that this is safe, since we know
675 // these two packages come from the same uid; the caller could just as
676 // well have supplied that same package name itself. This specifially
677 // deals with the case of an intent picker/chooser being launched in the app
678 // flow to redirect to an activity picked by the user, where we want the final
679 // activity to consider it to have been launched by the previous app activity.
680 callingPackage = sourceRecord.launchedFromPackage;
681 }
682 }
683
684 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
685 // We couldn't find a class that can handle the given Intent.
686 // That's the end of that!
687 err = ActivityManager.START_INTENT_NOT_RESOLVED;
688 }
689
690 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
691 // We couldn't find the specific class specified in the Intent.
692 // Also the end of the line.
693 err = ActivityManager.START_CLASS_NOT_FOUND;
694 }
695
696 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800697 && sourceRecord.getTaskRecord().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800698 // If this activity is being launched as part of a voice session, we need
699 // to ensure that it is safe to do so. If the upcoming activity will also
700 // be part of the voice session, we can only launch it if it has explicitly
701 // said it supports the VOICE category, or it is a part of the calling app.
702 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
703 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
704 try {
705 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700706 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800707 intent.getComponent(), intent, resolvedType)) {
708 Slog.w(TAG,
709 "Activity being started in current voice task does not support voice: "
710 + intent);
711 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
712 }
713 } catch (RemoteException e) {
714 Slog.w(TAG, "Failure checking voice capabilities", e);
715 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
716 }
717 }
718 }
719
720 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
721 // If the caller is starting a new voice session, just make sure the target
722 // is actually allowing it to run this way.
723 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700724 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800725 intent, resolvedType)) {
726 Slog.w(TAG,
727 "Activity being started in new voice task does not support: "
728 + intent);
729 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
730 }
731 } catch (RemoteException e) {
732 Slog.w(TAG, "Failure checking voice capabilities", e);
733 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
734 }
735 }
736
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800737 final ActivityStack resultStack = resultRecord == null
738 ? null : resultRecord.getActivityStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800739
Wale Ogunwale01d66562015-12-29 08:19:19 -0800740 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800741 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800742 resultStack.sendActivityResultLocked(
743 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800744 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100745 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800746 return err;
747 }
748
749 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100750 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700751 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700752 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800753 callingPid, resolvedType, aInfo.applicationInfo);
754
Michal Karpinskic02364c2019-01-22 13:00:04 +0000755 boolean abortBackgroundStart = false;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000756 if (!abort) {
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000757 try {
758 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
759 "shouldAbortBackgroundActivityStart");
760 abortBackgroundStart = shouldAbortBackgroundActivityStart(callingUid, callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000761 callingPackage, realCallingUid, realCallingPid, callerApp,
762 originatingPendingIntent, allowBackgroundActivityStart, intent);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000763 } finally {
764 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
765 }
Michal Karpinskic02364c2019-01-22 13:00:04 +0000766 abort |= (abortBackgroundStart && !mService.isBackgroundActivityStartsEnabled());
767 // TODO: remove this toast after feature development is done
768 if (abortBackgroundStart) {
Michal Karpinskiac213c62019-02-19 12:38:14 +0000769 final Resources res = mService.mContext.getResources();
770 final String toastMsg = res.getString(abort
771 ? R.string.activity_starter_block_bg_activity_starts_enforcing
772 : R.string.activity_starter_block_bg_activity_starts_permissive,
773 callingPackage);
Michal Karpinskic02364c2019-01-22 13:00:04 +0000774 mService.mUiHandler.post(() -> {
775 Toast.makeText(mService.mContext, toastMsg, Toast.LENGTH_LONG).show();
776 });
777 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000778 }
779
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100780 // Merge the two options bundles, while realCallerOptions takes precedence.
781 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700782 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200783 if (allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700784 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200785 .getPendingRemoteAnimationRegistry()
786 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
787 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700788 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800789 try {
790 // The Intent we give to the watcher has the extra data
791 // stripped off, since it can contain private information.
792 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700793 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800794 aInfo.applicationInfo.packageName);
795 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700796 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800797 }
798 }
799
Rubin Xu58d25992016-01-21 17:47:13 +0000800 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100801 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100802 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100803 // activity start was intercepted, e.g. because the target user is currently in quiet
804 // mode (turn off work) or the target application is suspended
805 intent = mInterceptor.mIntent;
806 rInfo = mInterceptor.mRInfo;
807 aInfo = mInterceptor.mAInfo;
808 resolvedType = mInterceptor.mResolvedType;
809 inTask = mInterceptor.mInTask;
810 callingPid = mInterceptor.mCallingPid;
811 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100812 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100813 }
814
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800815 if (abort) {
816 if (resultRecord != null) {
817 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale01d66562015-12-29 08:19:19 -0800818 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800819 }
820 // We pretend to the caller that it was really started, but
821 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100822 ActivityOptions.abort(checkedOptions);
Bryce Leef9d49542017-06-26 16:27:32 -0700823 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800824 }
825
826 // If permissions need a review before any of the app components can run, we
827 // launch the review activity and pass a pending intent to start the activity
828 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700829 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700830 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800831 aInfo.packageName, userId)) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700832 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800833 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
834 callingUid, userId, null, null, 0, new Intent[]{intent},
835 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
836 | PendingIntent.FLAG_ONE_SHOT, null);
837
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800838 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
Philip P. Moltmannc3e66d02019-01-31 15:56:18 -0800839
840 int flags = intent.getFlags();
841 flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
842
843 /*
844 * Prevent reuse of review activity: Each app needs their own review activity. By
845 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
846 * with the same launch parameters (extras are ignored). Hence to avoid possible
847 * reuse force a new activity via the MULTIPLE_TASK flag.
848 *
849 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
850 * hence no need to add the flag in this case.
851 */
852 if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
853 flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
854 }
855 newIntent.setFlags(flags);
856
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800857 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
858 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
859 if (resultRecord != null) {
860 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
861 }
862 intent = newIntent;
863
864 resolvedType = null;
865 callingUid = realCallingUid;
866 callingPid = realCallingPid;
867
Svet Ganovcbcbf662018-05-10 17:25:29 -0700868 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700869 computeResolveFilterUid(
870 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800871 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
872 null /*profilerInfo*/);
873
874 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800875 final ActivityStack focusedStack =
876 mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800877 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
878 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian52d255c2018-07-13 11:32:19 -0700879 + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800880 }
881 }
882 }
883
884 // If we have an ephemeral app, abort the process of launching the resolved intent.
885 // Instead, launch the ephemeral installer. Once the installer is finished, it
886 // starts either the intent we resolved here [on install error] or the ephemeral
887 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800888 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800889 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700890 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800891 resolvedType = null;
892 callingUid = realCallingUid;
893 callingPid = realCallingPid;
894
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800895 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
896 }
897
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700898 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -0700899 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800900 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100901 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800902 if (outActivity != null) {
903 outActivity[0] = r;
904 }
905
906 if (r.appTimeTracker == null && sourceRecord != null) {
907 // If the caller didn't specify an explicit time tracker, we want to continue
908 // tracking under any it has.
909 r.appTimeTracker = sourceRecord.appTimeTracker;
910 }
911
Wale Ogunwaled32da472018-11-16 07:19:28 -0800912 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100913
914 // If we are starting an activity that is not from the same uid as the currently resumed
915 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800916 if (voiceSession == null && (stack.getResumedActivity() == null
917 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700918 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800919 realCallingPid, realCallingUid, "Activity start")) {
Bryce Leed3624e12017-11-30 08:51:45 -0800920 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700921 sourceRecord, startFlags, stack, callerApp));
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100922 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800923 return ActivityManager.START_SWITCHES_CANCELED;
924 }
925 }
926
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700927 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -0800928 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800929
Bryce Leedaa91e42017-12-06 14:13:01 -0800930 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100931 true /* doResume */, checkedOptions, inTask, outActivity);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800932 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800933
Michal Karpinski7b97a022018-12-14 15:17:29 +0000934 private boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000935 final String callingPackage, int realCallingUid, int realCallingPid,
936 WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
937 boolean allowBackgroundActivityStart, Intent intent) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000938 // don't abort for the most important UIDs
Michal Karpinskib416f472019-01-24 14:34:28 +0000939 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID
940 || callingUid == Process.NFC_UID) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000941 return false;
942 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000943 // don't abort if the callingUid is in the foreground or is a persistent system process
Riddle Hsua0536432019-02-16 00:38:59 +0800944 final int callingUidProcState = mService.getUidState(callingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000945 final boolean callingUidHasAnyVisibleWindow =
946 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
947 final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
948 || callingUidProcState == ActivityManager.PROCESS_STATE_TOP;
949 final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID)
950 || callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskid0162852019-01-15 16:05:25 +0000951 if (isCallingUidForeground || isCallingUidPersistentSystemProcess) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000952 return false;
953 }
Michal Karpinskiac116df2018-12-10 17:51:42 +0000954 // take realCallingUid into consideration
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000955 final int realCallingUidProcState = (callingUid == realCallingUid)
956 ? callingUidProcState
Riddle Hsua0536432019-02-16 00:38:59 +0800957 : mService.getUidState(realCallingUid);
Michal Karpinski4fd5b842019-01-28 15:13:32 +0000958 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
959 ? callingUidHasAnyVisibleWindow
960 : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(realCallingUid);
961 final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
962 ? isCallingUidForeground
963 : realCallingUidHasAnyVisibleWindow
964 || realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
965 final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
966 ? isCallingUidPersistentSystemProcess
967 : (realCallingUid == Process.SYSTEM_UID)
968 || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000969 if (realCallingUid != callingUid) {
970 // don't abort if the realCallingUid is in the foreground and callingUid isn't
Michal Karpinskid0162852019-01-15 16:05:25 +0000971 if (isRealCallingUidForeground) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000972 return false;
973 }
974 // if the realCallingUid is a persistent system process, abort if the IntentSender
975 // wasn't whitelisted to start an activity
Michal Karpinskid0162852019-01-15 16:05:25 +0000976 if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
Michal Karpinskiac116df2018-12-10 17:51:42 +0000977 return false;
978 }
979 }
Michal Karpinski9cbb20b2019-02-05 17:31:50 +0000980 // If we don't have callerApp at this point, no caller was provided to startActivity().
981 // That's the case for PendingIntent-based starts, since the creator's process might not be
982 // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
983 // caller, so that we can make the decision based on its foreground/whitelisted state.
984 if (callerApp == null) {
985 callerApp = mService.getProcessController(realCallingPid, realCallingUid);
986 }
987 if (callerApp != null) {
988 // don't abort if the callerApp has any visible activity
989 if (callerApp.hasForegroundActivities()) {
990 return false;
991 }
992 // don't abort if the callerApp is instrumenting with background activity starts privs
993 if (callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
994 return false;
995 }
996 // don't abort if the caller is currently temporarily whitelisted
997 if (callerApp.areBackgroundActivityStartsAllowed()) {
998 return false;
999 }
Michal Karpinski8596ded2018-11-14 14:43:48 +00001000 }
Michal Karpinski7b97a022018-12-14 15:17:29 +00001001 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
1002 if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
1003 == PERMISSION_GRANTED) {
1004 return false;
1005 }
Michal Karpinski82bb5902018-11-28 15:52:52 +00001006 // don't abort if the caller has the same uid as the recents component
1007 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
1008 return false;
1009 }
Michal Karpinski4026cae2019-02-12 11:51:47 +00001010 // don't abort if the callingPackage is the device owner
1011 if (mService.isDeviceOwner(callingPackage)) {
Michal Karpinski302dcec2019-02-01 11:48:25 +00001012 return false;
1013 }
Michal Karpinski666631b2019-02-26 16:59:11 +00001014 // don't abort if the callingPackage is temporarily whitelisted
1015 if (mService.isPackageNameWhitelistedForBgActivityStarts(callingPackage)) {
1016 Slog.w(TAG, "Background activity start for " + callingPackage
1017 + " temporarily whitelisted. This will not be supported in future Q builds.");
1018 return false;
1019 }
Michal Karpinskic02364c2019-01-22 13:00:04 +00001020 // anything that has fallen through would currently be aborted
1021 Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
Michal Karpinskid0162852019-01-15 16:05:25 +00001022 + "; callingUid: " + callingUid
1023 + "; isCallingUidForeground: " + isCallingUidForeground
1024 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
1025 + "; realCallingUid: " + realCallingUid
1026 + "; isRealCallingUidForeground: " + isRealCallingUidForeground
1027 + "; isRealCallingUidPersistentSystemProcess: "
1028 + isRealCallingUidPersistentSystemProcess
1029 + "; originatingPendingIntent: " + originatingPendingIntent
1030 + "; isBgStartWhitelisted: " + allowBackgroundActivityStart
1031 + "; intent: " + intent
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001032 + "; callerApp: " + callerApp
Michal Karpinskid0162852019-01-15 16:05:25 +00001033 + "]");
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001034 // log aborted activity start to TRON
1035 if (mService.isActivityStartsLoggingEnabled()) {
1036 mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
1037 callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
1038 realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001039 (originatingPendingIntent != null));
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001040 }
Michal Karpinski4fd5b842019-01-28 15:13:32 +00001041 return true;
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001042 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001043
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001044 /**
1045 * Creates a launch intent for the given auxiliary resolution data.
1046 */
Patrick Baumann577d4022018-01-31 16:55:10 +00001047 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -07001048 Intent originalIntent, String callingPackage, Bundle verificationBundle,
1049 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +00001050 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -08001051 // request phase two resolution
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001052 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -07001053 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
1054 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -08001055 }
Todd Kennedydfc27c62017-05-17 15:32:10 -07001056 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +00001057 originalIntent,
1058 InstantAppResolver.sanitizeIntent(originalIntent),
1059 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
1060 callingPackage,
1061 verificationBundle,
1062 resolvedType,
1063 userId,
1064 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
1065 auxiliaryResponse == null ? null : auxiliaryResponse.token,
1066 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
1067 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001068 }
1069
Riddle Hsu16567132018-08-16 21:37:47 +08001070 void postStartActivityProcessing(ActivityRecord r, int result,
1071 ActivityStack startedActivityStack) {
Bryce Lee7f936862017-05-09 15:33:18 -07001072 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001073 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001074 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001075
Chong Zhang5022da32016-06-21 16:31:37 -07001076 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001077 // brought another activity to front. We must also handle the case where the task is already
1078 // in the front as a result of the trampoline activity being in the same task (it will be
1079 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
1080 // about this, so it waits for the new activity to become visible instead.
1081 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001082
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001083 if (startedActivityStack == null) {
1084 return;
1085 }
1086
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001087 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1088 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1089 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001090 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1091 // The activity was already running so it wasn't started, but either brought to the
1092 // front or the new intent was delivered to it since it was already in front. Notify
1093 // anyone interested in this piece of information.
1094 switch (startedActivityStack.getWindowingMode()) {
1095 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001096 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001097 clearedTask);
1098 break;
1099 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001100 final ActivityStack homeStack =
1101 startedActivityStack.getDisplay().getHomeStack();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001102 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1103 mService.mWindowManager.showRecentApps();
1104 }
1105 break;
1106 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001107 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001108 }
1109
Bryce Lee4c9a5972017-12-01 22:14:24 -08001110 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001111 String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
1112 Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
1113 IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
1114 int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001115 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001116 int userId, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001117 boolean allowPendingRemoteAnimationRegistryLookup,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001118 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001119 // Refuse possible leaked file descriptors
1120 if (intent != null && intent.hasFileDescriptors()) {
1121 throw new IllegalArgumentException("File descriptors passed in Intent");
1122 }
Igor Murashkin212d06c2018-10-22 16:34:39 -07001123 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001124 boolean componentSpecified = intent.getComponent() != null;
1125
Michal Karpinski84d9ebd2019-01-17 18:28:59 +00001126 final int realCallingPid = requestRealCallingPid != Request.DEFAULT_REAL_CALLING_PID
1127 ? requestRealCallingPid
1128 : Binder.getCallingPid();
1129 final int realCallingUid = requestRealCallingUid != Request.DEFAULT_REAL_CALLING_UID
1130 ? requestRealCallingUid
1131 : Binder.getCallingUid();
Makoto Onuki1a342742018-04-26 14:56:59 -07001132
Svet Ganovcbcbf662018-05-10 17:25:29 -07001133 int callingPid;
1134 if (callingUid >= 0) {
1135 callingPid = -1;
1136 } else if (caller == null) {
1137 callingPid = realCallingPid;
1138 callingUid = realCallingUid;
1139 } else {
1140 callingPid = callingUid = -1;
1141 }
1142
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001143 // Save a copy in case ephemeral needs it
1144 final Intent ephemeralIntent = new Intent(intent);
1145 // Don't modify the client's object!
1146 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -07001147 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -08001148 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +00001149 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1150 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001151 && mService.getPackageManagerInternalLocked()
Todd Kennedyb21be122017-03-24 14:10:01 -07001152 .isInstantAppInstallerComponent(intent.getComponent())) {
1153 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +00001154 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -07001155 // adjust the intent so it looks like a "normal" instant app launch
1156 intent.setComponent(null /*component*/);
1157 componentSpecified = false;
1158 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001159
Makoto Onuki1a342742018-04-26 14:56:59 -07001160 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001161 0 /* matchFlags */,
1162 computeResolveFilterUid(
1163 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001164 if (rInfo == null) {
1165 UserInfo userInfo = mSupervisor.getUserInfo(userId);
1166 if (userInfo != null && userInfo.isManagedProfile()) {
1167 // Special case for managed profiles, if attempting to launch non-cryto aware
1168 // app in a locked managed profile from an unlocked parent allow it to resolve
1169 // as user will be sent via confirm credentials to unlock the profile.
1170 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001171 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +00001172 long token = Binder.clearCallingIdentity();
1173 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001174 UserInfo parent = userManager.getProfileParent(userId);
1175 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1176 && userManager.isUserUnlockingOrUnlocked(parent.id)
1177 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001178 } finally {
1179 Binder.restoreCallingIdentity(token);
1180 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001181 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001182 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001183 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001184 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001185 computeResolveFilterUid(
1186 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001187 }
1188 }
1189 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001190 // Collect information about the target of the Intent.
1191 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1192
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001193 synchronized (mService.mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001194 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian8072d112016-09-16 11:11:01 -07001195 stack.mConfigWillChange = globalConfig != null
Wale Ogunwalef6733932018-06-27 05:14:34 -07001196 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001197 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1198 "Starting activity when config will change = " + stack.mConfigWillChange);
1199
1200 final long origId = Binder.clearCallingIdentity();
1201
1202 if (aInfo != null &&
1203 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001204 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
Wale Ogunwale214f3482018-10-04 11:00:47 -07001205 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001206 // This may be a heavy-weight process! Check to see if we already
1207 // have another, different heavy-weight process running.
1208 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
Wale Ogunwale53783742018-09-16 10:21:51 -07001209 final WindowProcessController heavy = mService.mHeavyWeightProcess;
1210 if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
1211 || !heavy.mName.equals(aInfo.processName))) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001212 int appCallingUid = callingUid;
1213 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001214 WindowProcessController callerApp =
1215 mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001216 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001217 appCallingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001218 } else {
1219 Slog.w(TAG, "Unable to find app for caller " + caller
1220 + " (pid=" + callingPid + ") when starting: "
1221 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001222 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001223 return ActivityManager.START_PERMISSION_DENIED;
1224 }
1225 }
1226
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07001227 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001228 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1229 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1230 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1231 | PendingIntent.FLAG_ONE_SHOT, null);
1232
1233 Intent newIntent = new Intent();
1234 if (requestCode >= 0) {
1235 // Caller is requesting a result.
1236 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1237 }
1238 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1239 new IntentSender(target));
Wale Ogunwale53783742018-09-16 10:21:51 -07001240 heavy.updateIntentForHeavyWeightActivity(newIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001241 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1242 aInfo.packageName);
1243 newIntent.setFlags(intent.getFlags());
1244 newIntent.setClassName("android",
1245 HeavyWeightSwitcherActivity.class.getName());
1246 intent = newIntent;
1247 resolvedType = null;
1248 caller = null;
1249 callingUid = Binder.getCallingUid();
1250 callingPid = Binder.getCallingPid();
1251 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001252 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001253 0 /* matchFlags */, computeResolveFilterUid(
1254 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001255 aInfo = rInfo != null ? rInfo.activityInfo : null;
1256 if (aInfo != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001257 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001258 }
1259 }
1260 }
1261 }
1262
Jorim Jaggi275561a2016-02-23 10:11:02 -05001263 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001264 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1265 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1266 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001267 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
Michal Karpinskiac116df2018-12-10 17:51:42 +00001268 allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
1269 allowBackgroundActivityStart);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001270
1271 Binder.restoreCallingIdentity(origId);
1272
1273 if (stack.mConfigWillChange) {
1274 // If the caller also wants to switch to a new configuration,
1275 // do so now. This allows a clean switch, as we are waiting
1276 // for the current activity to pause (so we will not destroy
1277 // it), and have not yet started the next activity.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001278 mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001279 "updateConfiguration()");
1280 stack.mConfigWillChange = false;
1281 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1282 "Updating to new configuration after starting activity.");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001283 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001284 }
1285
Vishnu Nair132ee832018-09-28 15:00:05 -07001286 // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
1287 // will then wait for the windows to be drawn and populate WaitResult.
1288 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001289 if (outResult != null) {
1290 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001291
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001292 final ActivityRecord r = outRecord[0];
1293
1294 switch(res) {
1295 case START_SUCCESS: {
1296 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001297 do {
1298 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001299 mService.mGlobalLock.wait();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001300 } catch (InterruptedException e) {
1301 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001302 } while (outResult.result != START_TASK_TO_FRONT
1303 && !outResult.timeout && outResult.who == null);
1304 if (outResult.result == START_TASK_TO_FRONT) {
1305 res = START_TASK_TO_FRONT;
1306 }
1307 break;
1308 }
1309 case START_DELIVERED_TO_TOP: {
1310 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001311 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001312 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001313 break;
1314 }
1315 case START_TASK_TO_FRONT: {
Louis Chang0513a942019-03-06 12:38:13 +08001316 outResult.launchState =
1317 r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001318 // ActivityRecord may represent a different activity, but it should not be
1319 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001320 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001321 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001322 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001323 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001324 } else {
Vishnu Nair132ee832018-09-28 15:00:05 -07001325 final long startTimeMs = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001326 mSupervisor.waitActivityVisible(
1327 r.mActivityComponent, outResult, startTimeMs);
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001328 // Note: the timeout variable is not currently not ever set.
1329 do {
1330 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001331 mService.mGlobalLock.wait();
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001332 } catch (InterruptedException e) {
1333 }
1334 } while (!outResult.timeout && outResult.who == null);
1335 }
1336 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001337 }
1338 }
1339 }
1340
1341 return res;
1342 }
1343 }
1344
Svet Ganovcbcbf662018-05-10 17:25:29 -07001345 /**
1346 * Compute the logical UID based on which the package manager would filter
1347 * app components i.e. based on which the instant app policy would be applied
1348 * because it is the logical calling UID.
1349 *
1350 * @param customCallingUid The UID on whose behalf to make the call.
1351 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001352 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001353 * @return The logical UID making the call.
1354 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001355 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1356 int filterCallingUid) {
1357 return filterCallingUid != UserHandle.USER_NULL
1358 ? filterCallingUid
1359 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001360 }
1361
Bryce Leedaa91e42017-12-06 14:13:01 -08001362 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1363 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1364 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1365 ActivityRecord[] outActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001366 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001367 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001368 try {
1369 mService.mWindowManager.deferSurfaceLayout();
1370 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001371 startFlags, doResume, options, inTask, outActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001372 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001373 final ActivityStack currentStack = r.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001374 startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1375
1376 if (ActivityManager.isStartResultSuccessful(result)) {
1377 if (startedActivityStack != null) {
1378 // If there is no state change (e.g. a resumed activity is reparented to
1379 // top of another display) to trigger a visibility/configuration checking,
1380 // we have to update the configuration for changing to different display.
1381 final ActivityRecord currentTop =
1382 startedActivityStack.topRunningActivityLocked();
1383 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001384 mRootActivityContainer.ensureVisibilityAndConfig(
1385 currentTop, currentTop.getDisplayId(),
Riddle Hsu16567132018-08-16 21:37:47 +08001386 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1387 }
1388 }
1389 } else {
1390 // If we are not able to proceed, disassociate the activity from the task.
1391 // Leaving an activity in an incomplete state can lead to issues, such as
1392 // performing operations without a window container.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001393 final ActivityStack stack = mStartActivity.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001394 if (stack != null) {
1395 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1396 null /* intentResultData */, "startActivity", true /* oomAdj */);
1397 }
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001398 }
1399 mService.mWindowManager.continueSurfaceLayout();
1400 }
1401
Riddle Hsu16567132018-08-16 21:37:47 +08001402 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001403
1404 return result;
1405 }
1406
1407 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001408 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1409 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001410 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1411 ActivityRecord[] outActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001412
1413 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1414 voiceInteractor);
Louis Chang39ba54b2018-10-18 11:28:57 +08001415 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001416
Louis Chang6fb1e842018-12-03 16:07:50 +08001417 computeLaunchingTaskFlags();
1418
1419 computeSourceStack();
1420
1421 mIntent.setFlags(mLaunchFlags);
1422
1423 ActivityRecord reusedActivity = getReusableIntentActivity();
1424
1425 mSupervisor.getLaunchParamsController().calculate(
1426 reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
1427 r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
1428 mPreferredDisplayId =
1429 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1430 : DEFAULT_DISPLAY;
1431
Louis Changbd48dca2018-08-29 17:44:34 +08001432 // Do not start home activity if it cannot be launched on preferred display. We are not
1433 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1434 // fallback to launch on other displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001435 if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
Louis Changdd3592a2018-11-05 11:04:14 +08001436 mPreferredDisplayId, true /* allowInstrumenting */)) {
Louis Changbd48dca2018-08-29 17:44:34 +08001437 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1438 return START_CANCELED;
1439 }
1440
Bryce Lee4a194382017-04-04 14:32:48 -07001441 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001442 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1443 // still needs to be a lock task mode violation since the task gets cleared out and
1444 // the device would otherwise leave the locked task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001445 if (mService.getLockTaskController().isLockTaskModeViolation(
1446 reusedActivity.getTaskRecord(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001447 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1448 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001449 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1450 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1451 }
1452
Bryce Leef65ee7e2018-03-26 16:03:47 -07001453 // True if we are clearing top and resetting of a standard (default) launch mode
1454 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1455 final boolean clearTopAndResetStandardLaunchMode =
1456 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1457 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1458 && mLaunchMode == LAUNCH_MULTIPLE;
1459
1460 // If mStartActivity does not have a task associated with it, associate it with the
1461 // reused activity's task. Do not do so if we're clearing top and resetting for a
1462 // standard launchMode activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001463 if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
1464 mStartActivity.setTask(reusedActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001465 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001466
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001467 if (reusedActivity.getTaskRecord().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001468 // This task was started because of movement of the activity based on affinity...
1469 // Now that we are actually launching it, we can assign the base intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001470 reusedActivity.getTaskRecord().setIntent(mStartActivity);
Louis Changb45ee7e2019-01-17 10:36:56 +08001471 } else {
1472 final boolean taskOnHome =
1473 (mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
1474 if (taskOnHome) {
1475 reusedActivity.getTaskRecord().intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1476 } else {
1477 reusedActivity.getTaskRecord().intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
1478 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001479 }
1480
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001481 // This code path leads to delivering a new intent, we want to make sure we schedule it
1482 // as the first operation, in case the activity will be resumed as a result of later
1483 // operations.
1484 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001485 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001486 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001487 final TaskRecord task = reusedActivity.getTaskRecord();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001488
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001489 // In this situation we want to remove all activities from the task up to the one
1490 // being started. In most cases this means we are resetting the task to its initial
1491 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001492 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1493 mLaunchFlags);
1494
Bryce Lee4a194382017-04-04 14:32:48 -07001495 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001496 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1497 // task reference is needed in the call below to
1498 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001499 if (reusedActivity.getTaskRecord() == null) {
Bryce Lee4a194382017-04-04 14:32:48 -07001500 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001501 }
1502
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001503 if (top != null) {
1504 if (top.frontOfTask) {
1505 // Activity aliases may mean we use different intents for the top activity,
1506 // so make sure the task now has the identity of the new intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001507 top.getTaskRecord().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001508 }
Bryce Lee325e09682017-10-05 17:20:25 -07001509 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001510 }
1511 }
1512
Wale Ogunwaled32da472018-11-16 07:19:28 -08001513 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
1514 (false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001515
Bryce Lee4a194382017-04-04 14:32:48 -07001516 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001517
Bryce Lee89cd19a2017-05-17 15:18:35 -07001518 final ActivityRecord outResult =
1519 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1520
1521 // When there is a reused activity and the current result is a trampoline activity,
1522 // set the reused activity as the result.
1523 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1524 outActivity[0] = reusedActivity;
1525 }
1526
Wale Ogunwale01d66562015-12-29 08:19:19 -08001527 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1528 // We don't need to start a new activity, and the client said not to do anything
1529 // if that is the case, so this is it! And for paranoia, make sure we have
1530 // correctly resumed the top activity.
1531 resumeTargetStackIfNeeded();
1532 return START_RETURN_INTENT_TO_CALLER;
1533 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001534
Bryce Leef65ee7e2018-03-26 16:03:47 -07001535 if (reusedActivity != null) {
1536 setTaskFromIntentActivity(reusedActivity);
1537
1538 if (!mAddingToTask && mReuseTask == null) {
1539 // We didn't do anything... but it was needed (a.k.a., client don't use that
1540 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
1541
1542 resumeTargetStackIfNeeded();
1543 if (outActivity != null && outActivity.length > 0) {
1544 outActivity[0] = reusedActivity;
1545 }
1546
1547 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001548 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001549 }
1550 }
1551
1552 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001553 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001554 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001555 if (sourceStack != null) {
1556 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1557 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1558 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001559 }
1560 ActivityOptions.abort(mOptions);
1561 return START_CLASS_NOT_FOUND;
1562 }
1563
1564 // If the activity being launched is the same as the one currently at the top, then
1565 // we need to check if it should only be launched once.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001566 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001567 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001568 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1569 final boolean dontStart = top != null && mStartActivity.resultTo == null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001570 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1571 && top.mUserId == mStartActivity.mUserId
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001572 && top.attachedToProcess()
Wale Ogunwale01d66562015-12-29 08:19:19 -08001573 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Louis Changbd48dca2018-08-29 17:44:34 +08001574 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1575 // This allows home activity to automatically launch on secondary display when
1576 // display added, if home was the top activity on default display, instead of
1577 // sending new intent to the home activity on default display.
1578 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001579 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001580 // For paranoia, make sure we have correctly resumed the top activity.
1581 topStack.mLastPausedActivity = null;
1582 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001583 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001584 }
1585 ActivityOptions.abort(mOptions);
1586 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1587 // We don't need to start a new activity, and the client said not to do
1588 // anything if that is the case, so this is it!
1589 return START_RETURN_INTENT_TO_CALLER;
1590 }
Bryce Lee325e09682017-10-05 17:20:25 -07001591
1592 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001593
1594 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1595 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001596 mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
Louis Chang39ba54b2018-10-18 11:28:57 +08001597 mPreferredDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001598
Wale Ogunwale01d66562015-12-29 08:19:19 -08001599 return START_DELIVERED_TO_TOP;
1600 }
1601
1602 boolean newTask = false;
1603 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001604 ? mSourceRecord.getTaskRecord() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001605
1606 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001607 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001608 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1609 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1610 newTask = true;
Louis Changceeb5062018-09-17 18:13:52 +08001611 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001612 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001613 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001614 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001615 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001616 } else {
1617 // This not being started from an existing activity, and not part of a new task...
1618 // just put it in the top task, though these days this case should never happen.
1619 setTaskToCurrentTopOrCreateNewTask();
1620 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001621 if (result != START_SUCCESS) {
1622 return result;
1623 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001624
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001625 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001626 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001627 mService.getPackageManagerInternalLocked().grantEphemeralAccess(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001628 mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001629 UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001630 if (newTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001631 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
1632 mStartActivity.getTaskRecord().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001633 }
1634 ActivityStack.logStartActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001635 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001636 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001637
Wale Ogunwaled32da472018-11-16 07:19:28 -08001638 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
1639 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001640
Winson Chungb5c41b72016-12-07 15:00:47 -08001641 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1642 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001643 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001644 final ActivityRecord topTaskActivity =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001645 mStartActivity.getTaskRecord().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001646 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001647 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1648 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001649 // If the activity is not focusable, we can't resume it, but still would like to
1650 // make sure it becomes visible as it starts (this will also trigger entry
1651 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001652 // Also, we don't want to resume activities in a task that currently has an overlay
1653 // as the starting activity just needs to be in the visible paused state until the
1654 // over is removed.
Andrii Kulian6b321512019-01-23 06:37:00 +00001655 mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001656 // Go ahead and tell window manager to execute app transition for this activity
1657 // since the app transition will not be triggered through the resume channel.
Wale Ogunwale3a256e62018-12-06 14:41:18 -08001658 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001659 } else {
Winson Chung32066032016-11-04 11:55:21 -07001660 // If the target stack was not previously focusable (previous top running activity
1661 // on that stack was not visible) then any prior calls to move the stack to the
1662 // will not update the focused stack. If starting the new activity now allows the
1663 // task stack to be focusable, then ensure that we now update the focused stack
1664 // accordingly.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001665 if (mTargetStack.isFocusable()
Wale Ogunwaled32da472018-11-16 07:19:28 -08001666 && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
Winson Chung32066032016-11-04 11:55:21 -07001667 mTargetStack.moveToFront("startActivityUnchecked");
1668 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001669 mRootActivityContainer.resumeFocusedStacksTopActivities(
1670 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001671 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001672 } else if (mStartActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001673 mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001674 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001675 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001676
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001677 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1678 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001679
1680 return START_SUCCESS;
1681 }
1682
Bryce Leedaa91e42017-12-06 14:13:01 -08001683 /**
1684 * Resets the {@link ActivityStarter} state.
1685 * @param clearRequest whether the request should be reset to default values.
1686 */
1687 void reset(boolean clearRequest) {
1688 mStartActivity = null;
1689 mIntent = null;
1690 mCallingUid = -1;
1691 mOptions = null;
1692
1693 mLaunchTaskBehind = false;
1694 mLaunchFlags = 0;
1695 mLaunchMode = INVALID_LAUNCH_MODE;
1696
Bryce Leeec55eb02017-12-05 20:51:27 -08001697 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001698
1699 mNotTop = null;
1700 mDoResume = false;
1701 mStartFlags = 0;
1702 mSourceRecord = null;
1703 mPreferredDisplayId = INVALID_DISPLAY;
1704
1705 mInTask = null;
1706 mAddingToTask = false;
1707 mReuseTask = null;
1708
1709 mNewTaskInfo = null;
1710 mNewTaskIntent = null;
1711 mSourceStack = null;
1712
1713 mTargetStack = null;
1714 mMovedToFront = false;
1715 mNoAnimation = false;
1716 mKeepCurTransition = false;
1717 mAvoidMoveToFront = false;
1718
1719 mVoiceSession = null;
1720 mVoiceInteractor = null;
1721
1722 mIntentDelivered = false;
1723
1724 if (clearRequest) {
1725 mRequest.reset();
1726 }
1727 }
1728
Wale Ogunwale01d66562015-12-29 08:19:19 -08001729 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1730 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1731 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001732 reset(false /* clearRequest */);
1733
Wale Ogunwale01d66562015-12-29 08:19:19 -08001734 mStartActivity = r;
1735 mIntent = r.intent;
1736 mOptions = options;
1737 mCallingUid = r.launchedFromUid;
1738 mSourceRecord = sourceRecord;
1739 mVoiceSession = voiceSession;
1740 mVoiceInteractor = voiceInteractor;
1741
Bryce Leeec55eb02017-12-05 20:51:27 -08001742 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001743
Louis Chang6fb1e842018-12-03 16:07:50 +08001744 // Preferred display id is the only state we need for now and it could be updated again
1745 // after we located a reusable task (which might be resided in another display).
Garfield Tan706dbcb2018-10-15 11:33:02 -07001746 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
Louis Chang6fb1e842018-12-03 16:07:50 +08001747 sourceRecord, options, PHASE_DISPLAY, mLaunchParams);
1748 mPreferredDisplayId =
1749 mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
1750 : DEFAULT_DISPLAY;
Garfield Tanb5cc09f2018-09-28 10:06:52 -07001751
Bryce Lee7daee392017-10-12 13:46:18 -07001752 mLaunchMode = r.launchMode;
1753
Wale Ogunwale01d66562015-12-29 08:19:19 -08001754 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001755 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1756 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001757 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001758 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001759 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1760
1761 sendNewTaskResultRequestIfNeeded();
1762
1763 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1764 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1765 }
1766
1767 // If we are actually going to launch in to a new task, there are some cases where
1768 // we further want to do multiple task.
1769 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1770 if (mLaunchTaskBehind
1771 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1772 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1773 }
1774 }
1775
1776 // We'll invoke onUserLeaving before onPause only if the launching
1777 // activity did not explicitly state that this is an automated launch.
1778 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1779 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1780 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1781
1782 // If the caller has asked not to resume at this point, we make note
1783 // of this in the record so that we can skip it when trying to find
1784 // the top running activity.
1785 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001786 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001787 r.delayedResume = true;
1788 mDoResume = false;
1789 }
1790
Winson Chunge2d72172018-01-25 17:46:20 +00001791 if (mOptions != null) {
1792 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1793 r.mTaskOverlay = true;
1794 if (!mOptions.canTaskOverlayResume()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001795 final TaskRecord task = mRootActivityContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00001796 mOptions.getLaunchTaskId());
1797 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001798 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001799
Winson Chunge2d72172018-01-25 17:46:20 +00001800 // The caller specifies that we'd like to be avoided to be moved to the
1801 // front, so be it!
1802 mDoResume = false;
1803 mAvoidMoveToFront = true;
1804 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001805 }
Winson Chunge2d72172018-01-25 17:46:20 +00001806 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001807 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001808 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001809 }
1810 }
1811
Louis Chang2f4e9b462019-03-05 16:43:15 +08001812 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001813
1814 mInTask = inTask;
1815 // In some flows in to this function, we retrieve the task record and hold on to it
1816 // without a lock before calling back in to here... so the task at this point may
1817 // not actually be in recents. Check for that, and if it isn't in recents just
1818 // consider it invalid.
1819 if (inTask != null && !inTask.inRecents) {
1820 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1821 mInTask = null;
1822 }
1823
1824 mStartFlags = startFlags;
1825 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1826 // is the same as the one making the call... or, as a special case, if we do not know
1827 // the caller then we count the current top activity as the caller.
1828 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1829 ActivityRecord checkedCaller = sourceRecord;
1830 if (checkedCaller == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001831 checkedCaller = mRootActivityContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001832 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001833 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001834 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001835 // Caller is not the same as launcher, so always needed.
1836 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1837 }
1838 }
1839
1840 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1841 }
1842
1843 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001844 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001845 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001846 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001847 // For whatever reason this activity is being launched into a new task...
1848 // yet the caller has requested a result back. Well, that is pretty messed up,
1849 // so instead immediately send back a cancel and let the new task continue launched
1850 // as normal without a dependency on its originator.
1851 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001852 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1853 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1854 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001855 mStartActivity.resultTo = null;
1856 }
1857 }
1858
1859 private void computeLaunchingTaskFlags() {
1860 // If the caller is not coming from another activity, but has given us an explicit task into
1861 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001862 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001863 final Intent baseIntent = mInTask.getBaseIntent();
1864 final ActivityRecord root = mInTask.getRootActivity();
1865 if (baseIntent == null) {
1866 ActivityOptions.abort(mOptions);
1867 throw new IllegalArgumentException("Launching into task without base intent: "
1868 + mInTask);
1869 }
1870
1871 // If this task is empty, then we are adding the first activity -- it
1872 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001873 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001874 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1875 ActivityOptions.abort(mOptions);
1876 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1877 + mStartActivity + " into different task " + mInTask);
1878 }
1879 if (root != null) {
1880 ActivityOptions.abort(mOptions);
1881 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1882 + " has root " + root + " but target is singleInstance/Task");
1883 }
1884 }
1885
1886 // If task is empty, then adopt the interesting intent launch flags in to the
1887 // activity being started.
1888 if (root == null) {
1889 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1890 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1891 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1892 | (baseIntent.getFlags() & flagsOfInterest);
1893 mIntent.setFlags(mLaunchFlags);
1894 mInTask.setIntent(mStartActivity);
1895 mAddingToTask = true;
1896
1897 // If the task is not empty and the caller is asking to start it as the root of
1898 // a new task, then we don't actually want to start this on the task. We will
1899 // bring the task to the front, and possibly give it a new intent.
1900 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1901 mAddingToTask = false;
1902
1903 } else {
1904 mAddingToTask = true;
1905 }
1906
1907 mReuseTask = mInTask;
1908 } else {
1909 mInTask = null;
1910 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1911 // when in freeform workspace.
1912 // Also put noDisplay activities in the source task. These by itself can be placed
1913 // in any task/stack, however it could launch other activities like ResolverActivity,
1914 // and we want those to stay in the original task.
1915 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001916 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001917 mAddingToTask = true;
1918 }
1919 }
1920
1921 if (mInTask == null) {
1922 if (mSourceRecord == null) {
1923 // This activity is not being started from another... in this
1924 // case we -always- start a new task.
1925 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1926 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1927 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1928 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1929 }
1930 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1931 // The original activity who is starting us is running as a single
1932 // instance... this new activity it is starting must go on its
1933 // own task.
1934 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001935 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001936 // The activity being started is a single instance... it always
1937 // gets launched into its own task.
1938 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1939 }
1940 }
1941 }
1942
1943 private void computeSourceStack() {
1944 if (mSourceRecord == null) {
1945 mSourceStack = null;
1946 return;
1947 }
1948 if (!mSourceRecord.finishing) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001949 mSourceStack = mSourceRecord.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001950 return;
1951 }
1952
1953 // If the source is finishing, we can't further count it as our source. This is because the
1954 // task it is associated with may now be empty and on its way out, so we don't want to
1955 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1956 // a task for it. But save the task information so it can be used when creating the new task.
1957 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1958 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1959 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1960 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1961 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001962
1963 // It is not guaranteed that the source record will have a task associated with it. For,
1964 // example, if this method is being called for processing a pending activity launch, it
1965 // is possible that the activity has been removed from the task after the launch was
1966 // enqueued.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001967 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
Bryce Leed9ed45d2017-05-22 15:57:24 -07001968 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001969 }
1970 mSourceRecord = null;
1971 mSourceStack = null;
1972 }
1973
1974 /**
1975 * Decide whether the new activity should be inserted into an existing task. Returns null
1976 * if not or an ActivityRecord with the task into which the new activity should be added.
1977 */
1978 private ActivityRecord getReusableIntentActivity() {
1979 // We may want to try to place the new activity in to an existing task. We always
1980 // do this if the target activity is singleTask or singleInstance; we will also do
1981 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1982 // us to still place it in a new task: multi task, always doc mode, or being asked to
1983 // launch this as a new task behind the current one.
1984 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1985 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001986 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001987 // If bring to front is requested, and no result is requested and we have not been given
1988 // an explicit task to launch in to, and we can find a task that was started with this
1989 // same component, then instead of launching bring that one to the front.
1990 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1991 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001992 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001993 final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
Jorim Jaggi2adba072016-03-03 13:43:39 +01001994 intentActivity = task != null ? task.getTopActivity() : null;
1995 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001996 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001997 // There can be one and only one instance of single instance activity in the
1998 // history, and it is always in its own unique task, so we do a special search.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001999 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07002000 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002001 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2002 // For the launch adjacent case we only want to put the activity in an existing
2003 // task if the activity already exists in the history.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002004 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07002005 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002006 } else {
2007 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002008 intentActivity =
2009 mRootActivityContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07002010 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002011 }
Louis Changbd48dca2018-08-29 17:44:34 +08002012
Louis Chang54506cb2018-11-23 11:03:41 +08002013 if (intentActivity != null
2014 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08002015 && intentActivity.getDisplayId() != mPreferredDisplayId) {
2016 // Do not reuse home activity on other displays.
2017 intentActivity = null;
2018 }
2019
Wale Ogunwale01d66562015-12-29 08:19:19 -08002020 return intentActivity;
2021 }
2022
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002023 /**
2024 * Figure out which task and activity to bring to front when we have found an existing matching
2025 * activity record in history. May also clear the task if needed.
2026 * @param intentActivity Existing matching activity.
2027 * @return {@link ActivityRecord} brought to front.
2028 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08002029 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002030 mTargetStack = intentActivity.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002031 mTargetStack.mLastPausedActivity = null;
2032 // If the target task is not in the front, then we need to bring it to the front...
2033 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
2034 // the same behavior as if a new instance was being started, which means not bringing it
2035 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08002036 final boolean differentTopTask;
2037 if (mPreferredDisplayId == mTargetStack.mDisplayId) {
2038 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
2039 final ActivityRecord curTop = (focusStack == null)
2040 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002041 final TaskRecord topTask = curTop != null ? curTop.getTaskRecord() : null;
Riddle Hsub70b36d2018-09-11 21:20:02 +08002042 differentTopTask = topTask != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002043 && (topTask != intentActivity.getTaskRecord() || topTask != focusStack.topTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08002044 } else {
2045 // The existing task should always be different from those in other displays.
2046 differentTopTask = true;
2047 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002048
Riddle Hsub70b36d2018-09-11 21:20:02 +08002049 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002050 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002051 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002052 mSourceStack.getTopActivity().getTaskRecord()
2053 == mSourceRecord.getTaskRecord())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002054 // We really do want to push this one into the user's face, right now.
2055 if (mLaunchTaskBehind && mSourceRecord != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002056 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002057 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07002058
2059 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
2060 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
2061 // So no point resuming any of the activities here, it just wastes one extra
2062 // resuming, plus enter AND exit transitions.
2063 // Here we only want to bring the target stack forward. Transition will be applied
2064 // to the new activity that's started after the old ones are gone.
2065 final boolean willClearTask =
2066 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2067 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
2068 if (!willClearTask) {
2069 final ActivityStack launchStack = getLaunchStack(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002070 mStartActivity, mLaunchFlags, mStartActivity.getTaskRecord(), mOptions);
2071 final TaskRecord intentTask = intentActivity.getTaskRecord();
Chong Zhangdea4bd92016-03-15 12:50:03 -07002072 if (launchStack == null || launchStack == mTargetStack) {
2073 // We only want to move to the front, if we aren't going to launch on a
2074 // different stack. If we launch on a different stack, we will put the
2075 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07002076 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
2077 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07002078 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002079 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002080 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
2081 // If we want to launch adjacent and mTargetStack is not the computed
2082 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002083 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08002084 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2085 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002086 } else {
2087 // TODO: This should be reevaluated in MW v2.
2088 // We choose to move task to front instead of launching it adjacent
2089 // when specific stack was requested explicitly and it appeared to be
2090 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07002091 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07002092 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002093 "bringToFrontInsteadOfAdjacentLaunch");
2094 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07002095 mMovedToFront = launchStack != launchStack.getDisplay()
2096 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002097 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
2098 // Target and computed stacks are on different displays and we've
2099 // found a matching task - move the existing instance to that display and
2100 // move it to front.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002101 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002102 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2103 "reparentToDisplay");
2104 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002105 } else if (launchStack.isActivityTypeHome()
2106 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07002107 // It is possible for the home activity to be in another stack initially.
2108 // For example, the activity may have been initially started with an intent
2109 // which placed it in the fullscreen stack. To ensure the proper handling of
2110 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002111 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07002112 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2113 "reparentingHome");
2114 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07002115 }
2116 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002117
2118 // We are moving a task to the front, use starting window to hide initial drawn
2119 // delay.
2120 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
2121 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002122 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002123 }
2124 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002125 // Need to update mTargetStack because if task was moved out of it, the original stack may
2126 // be destroyed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002127 mTargetStack = intentActivity.getActivityStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07002128 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002129 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2130 + " from " + intentActivity);
2131 mTargetStack.moveToFront("intentActivityFound");
2132 }
2133
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002134 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTaskRecord(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002135 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07002136
Wale Ogunwale01d66562015-12-29 08:19:19 -08002137 // If the caller has requested that the target task be reset, then do so.
2138 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2139 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2140 }
2141 return intentActivity;
2142 }
2143
2144 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2145 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2146 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2147 // The caller has requested to completely replace any existing task with its new
2148 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08002149 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2150 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08002151 // of history or if it is finished immediately), thus disassociating the task. Also note
2152 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2153 // launching another activity.
2154 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2155 // already launching one.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002156 final TaskRecord task = intentActivity.getTaskRecord();
Bryce Lee59dad4e2017-03-09 11:54:08 -08002157 task.performClearTaskLocked();
2158 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08002159 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002160 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002161 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002162 final ActivityRecord top = intentActivity.getTaskRecord().performClearTaskLocked(
2163 mStartActivity, mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002164 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002165 // A special case: we need to start the activity because it is not currently
2166 // running, and the caller has asked to clear the current task to have this
2167 // activity at the top.
2168 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08002169
2170 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07002171 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002172 // Now pretend like this activity is being started by the top of its task, so it
2173 // is put in the right place.
2174 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002175 final TaskRecord task = mSourceRecord.getTaskRecord();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002176 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002177 // Target stack got cleared when we all activities were removed above.
2178 // Go ahead and reset it.
2179 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07002180 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002181 mTargetStack.addTask(task,
2182 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2183 }
2184 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002185 } else if (mStartActivity.mActivityComponent.equals(
2186 intentActivity.getTaskRecord().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002187 // In this case the top activity on the task is the same as the one being launched,
2188 // so we take that as a request to bring the task to the foreground. If the top
2189 // activity in the task is the root activity, deliver this new intent to it if it
2190 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07002191 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2192 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002193 && intentActivity.mActivityComponent.equals(
2194 mStartActivity.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002195 if (intentActivity.frontOfTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002196 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002197 }
Bryce Lee325e09682017-10-05 17:20:25 -07002198 deliverNewIntent(intentActivity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002199 } else if (!intentActivity.getTaskRecord().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002200 // In this case we are launching the root activity of the task, but with a
2201 // different intent. We should start a new instance on top.
2202 mAddingToTask = true;
2203 mSourceRecord = intentActivity;
2204 }
2205 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2206 // In this case an activity is being launched in to an existing task, without
2207 // resetting that task. This is typically the situation of launching an activity
2208 // from a notification or shortcut. We want to place the new activity on top of the
2209 // current task.
2210 mAddingToTask = true;
2211 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002212 } else if (!intentActivity.getTaskRecord().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002213 // In this case we are launching into an existing task that has not yet been started
2214 // from its front door. The current task has been brought to the front. Ideally,
2215 // we'd probably like to place this new task at the bottom of its stack, but that's
2216 // a little hard to do with the current organization of the code so for now we'll
2217 // just drop it.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002218 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002219 }
2220 }
2221
2222 private void resumeTargetStackIfNeeded() {
2223 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002224 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002225 } else {
2226 ActivityOptions.abort(mOptions);
2227 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002228 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002229 }
2230
Louis Changceeb5062018-09-17 18:13:52 +08002231 private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
Bryce Leedacefc42017-10-10 12:56:02 -07002232 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002233
2234 // Do no move the target stack to front yet, as we might bail if
2235 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002236
2237 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002238 final TaskRecord task = mTargetStack.createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002239 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002240 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002241 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002242 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2243 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002244 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002245 updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002246
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002247 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002248 + " in new task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002249 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002250 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2251 }
2252
2253 if (taskToAffiliate != null) {
2254 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002255 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002256
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002257 if (mService.getLockTaskController().isLockTaskModeViolation(
2258 mStartActivity.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002259 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2260 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2261 }
2262
Chong Zhang6cda19c2016-06-14 19:07:56 -07002263 if (mDoResume) {
2264 mTargetStack.moveToFront("reuseOrNewTask");
2265 }
2266 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002267 }
2268
Bryce Lee325e09682017-10-05 17:20:25 -07002269 private void deliverNewIntent(ActivityRecord activity) {
2270 if (mIntentDelivered) {
2271 return;
2272 }
2273
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002274 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002275 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2276 mStartActivity.launchedFromPackage);
2277 mIntentDelivered = true;
2278 }
2279
Wale Ogunwale01d66562015-12-29 08:19:19 -08002280 private int setTaskFromSourceRecord() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002281 if (mService.getLockTaskController().isLockTaskModeViolation(
2282 mSourceRecord.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002283 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2284 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2285 }
2286
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002287 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
2288 final ActivityStack sourceStack = mSourceRecord.getActivityStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002289 // We only want to allow changing stack in two cases:
2290 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2291 // the other side, rather than show two side by side.
2292 // 2. If activity is not allowed on target display.
2293 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2294 : sourceStack.mDisplayId;
2295 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2296 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002297 if (moveStackAllowed) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002298 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags,
2299 mStartActivity.getTaskRecord(), mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002300 // If target stack is not found now - we can't just rely on the source stack, as it may
2301 // be not suitable. Let's check other displays.
2302 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2303 // Can't use target display, lets find a stack on the source display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002304 mTargetStack = mRootActivityContainer.getValidLaunchStackOnDisplay(
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002305 sourceStack.mDisplayId, mStartActivity, mOptions, mLaunchParams);
Andrii Kulian02689a72017-07-06 14:28:59 -07002306 }
2307 if (mTargetStack == null) {
2308 // There are no suitable stacks on the target and source display(s). Look on all
2309 // displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002310 mTargetStack = mRootActivityContainer.getNextValidLaunchStack(
Andrii Kulian02689a72017-07-06 14:28:59 -07002311 mStartActivity, -1 /* currentFocus */);
2312 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002313 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002314
2315 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002316 mTargetStack = sourceStack;
2317 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002318 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2319 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002320 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002321
Wale Ogunwale01d66562015-12-29 08:19:19 -08002322 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002323 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002324 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002325 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002326 } else if (mDoResume) {
2327 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002328 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002329
Wale Ogunwale01d66562015-12-29 08:19:19 -08002330 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2331 // In this case, we are adding the activity to an existing task, but the caller has
2332 // asked to clear that task if the activity is already running.
2333 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2334 mKeepCurTransition = true;
2335 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002336 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002337 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002338 // For paranoia, make sure we have correctly resumed the top activity.
2339 mTargetStack.mLastPausedActivity = null;
2340 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002341 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002342 }
2343 ActivityOptions.abort(mOptions);
2344 return START_DELIVERED_TO_TOP;
2345 }
2346 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2347 // In this case, we are launching an activity in our own task that may already be
2348 // running somewhere in the history, and we want to shuffle it to the front of the
2349 // stack if so.
2350 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2351 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002352 final TaskRecord task = top.getTaskRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002353 task.moveActivityToFrontLocked(top);
2354 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002355 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002356 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002357 mTargetStack.mLastPausedActivity = null;
2358 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002359 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002360 }
2361 return START_DELIVERED_TO_TOP;
2362 }
2363 }
2364
2365 // An existing activity is starting this new activity, so we want to keep the new one in
2366 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002367 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002368 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002369 + " in existing task " + mStartActivity.getTaskRecord()
2370 + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002371 return START_SUCCESS;
2372 }
2373
2374 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002375 // The caller is asking that the new activity be started in an explicit
2376 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002377 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002378 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2379 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2380 }
2381
Andrii Kulian02b7a832016-10-06 23:11:56 -07002382 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002383
2384 // Check whether we should actually launch the new activity in to the task,
2385 // or just reuse the current activity on top.
2386 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002387 if (top != null && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2388 && top.mUserId == mStartActivity.mUserId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002389 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002390 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002391 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002392 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002393 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2394 // We don't need to start a new activity, and the client said not to do
2395 // anything if that is the case, so this is it!
2396 return START_RETURN_INTENT_TO_CALLER;
2397 }
Bryce Lee325e09682017-10-05 17:20:25 -07002398 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002399 return START_DELIVERED_TO_TOP;
2400 }
2401 }
2402
2403 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002404 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002405 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002406 // We don't actually want to have this activity added to the task, so just
2407 // stop here but still tell the caller that we consumed the intent.
2408 ActivityOptions.abort(mOptions);
2409 return START_TASK_TO_FRONT;
2410 }
2411
Bryce Leeec55eb02017-12-05 20:51:27 -08002412 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002413 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwaled32da472018-11-16 07:19:28 -08002414 ActivityStack stack = mRootActivityContainer.getLaunchStack(
2415 null, null, mInTask, ON_TOP);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002416 if (stack != mInTask.getStack()) {
2417 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002418 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002419 mTargetStack = mInTask.getStack();
2420 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002421
Bryce Leeec55eb02017-12-05 20:51:27 -08002422 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002423 }
2424
chaviw0d562bf2018-03-15 14:24:14 -07002425 mTargetStack.moveTaskToFrontLocked(
2426 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002427
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002428 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2429 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002430 + " in explicit task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002431
2432 return START_SUCCESS;
2433 }
2434
Bryce Leed3624e12017-11-30 08:51:45 -08002435 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002436 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002437 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002438 return;
2439 }
2440
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002441 final ActivityStack stack = task.getStack();
2442 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002443 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002444 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002445 } else {
2446 task.updateOverrideConfiguration(bounds);
2447 }
2448 }
2449
Wale Ogunwale01d66562015-12-29 08:19:19 -08002450 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002451 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002452 if (mDoResume) {
2453 mTargetStack.moveToFront("addingToTopTask");
2454 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002455 final ActivityRecord prev = mTargetStack.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002456 final TaskRecord task = (prev != null)
2457 ? prev.getTaskRecord() : mTargetStack.createTaskRecord(
2458 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002459 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002460 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2461 mTargetStack.positionChildWindowContainerAtTop(task);
2462 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002463 + " in new guessed " + mStartActivity.getTaskRecord());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002464 }
2465
2466 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002467 if (mStartActivity.getTaskRecord() == null || mStartActivity.getTaskRecord() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002468 parent.addActivityToTop(mStartActivity);
2469 } else {
2470 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2471 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002472 }
2473
2474 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2475 boolean launchSingleTask, int launchFlags) {
2476 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2477 (launchSingleInstance || launchSingleTask)) {
2478 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2479 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2480 "\"singleInstance\" or \"singleTask\"");
2481 launchFlags &=
2482 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2483 } else {
2484 switch (r.info.documentLaunchMode) {
2485 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2486 break;
2487 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2488 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2489 break;
2490 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2491 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2492 break;
2493 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2494 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2495 break;
2496 }
2497 }
2498 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002499 }
2500
Bryce Leedacefc42017-10-10 12:56:02 -07002501 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2502 ActivityOptions aOptions) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002503 final TaskRecord task = r.getTaskRecord();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002504 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002505 if (stack != null) {
2506 return stack;
2507 }
2508
Andrii Kulian02b7a832016-10-06 23:11:56 -07002509 final ActivityStack currentStack = task != null ? task.getStack() : null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002510 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002511 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002512 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002513 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2514 "computeStackFocus: Setting " + "focused stack to r=" + r
2515 + " task=" + task);
2516 } else {
2517 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002518 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002519 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002520 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002521 }
2522
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002523 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002524 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002525 "computeStackFocus: Have a focused stack=" + focusedStack);
2526 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002527 }
2528
David Stevense5a7b642017-05-22 13:18:23 -07002529 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002530 // Try to put the activity in a stack on a secondary display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002531 stack = mRootActivityContainer.getValidLaunchStackOnDisplay(
2532 mPreferredDisplayId, r, aOptions, mLaunchParams);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002533 if (stack == null) {
2534 // If source display is not suitable - look for topmost valid stack in the system.
2535 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002536 "computeStackFocus: Can't launch on mPreferredDisplayId="
2537 + mPreferredDisplayId + ", looking on all displays.");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002538 stack = mRootActivityContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002539 }
2540 }
2541 if (stack == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002542 stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002543 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002544 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2545 + r + " stackId=" + stack.mStackId);
2546 return stack;
2547 }
2548
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002549 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002550 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002551 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002552 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002553 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002554 if (focusedStack.isActivityTypeAssistant()) {
2555 canUseFocusedStack = r.isActivityTypeAssistant();
2556 } else {
2557 switch (focusedStack.getWindowingMode()) {
2558 case WINDOWING_MODE_FULLSCREEN:
2559 // The fullscreen stack can contain any task regardless of if the task is
2560 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2561 // focus stack.
2562 canUseFocusedStack = true;
2563 break;
2564 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2565 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2566 // Any activity which supports split screen can go in the docked stack.
2567 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2568 break;
2569 case WINDOWING_MODE_FREEFORM:
2570 // Any activity which supports freeform can go in the freeform stack.
2571 canUseFocusedStack = r.supportsFreeform();
2572 break;
2573 default:
2574 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2575 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002576 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002577 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2578 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002579 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002580 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002581 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002582 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002583 }
2584
Wale Ogunwale854809c2015-12-27 16:18:19 -08002585 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002586 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002587 // We are reusing a task, keep the stack!
2588 if (mReuseTask != null) {
2589 return mReuseTask.getStack();
2590 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002591
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002592 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002593 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Winson Chung93442032018-12-04 13:24:29 -08002594 final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
Wale Ogunwaled32da472018-11-16 07:19:28 -08002595 final ActivityStack stack =
Winson Chung93442032018-12-04 13:24:29 -08002596 mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002597 return stack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002598 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002599 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002600
Wale Ogunwaled32da472018-11-16 07:19:28 -08002601 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002602 // The parent activity doesn't want to launch the activity on top of itself, but
2603 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002604 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002605
Andrii Kulian52d255c2018-07-13 11:32:19 -07002606 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002607 // If task's parent stack is not focused - use it during adjacent launch.
2608 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002609 } else {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002610 if (focusedStack != null && task == focusedStack.topTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002611 // If task is already on top of focused stack - use it. We don't want to move the
2612 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002613 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002614 }
2615
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002616 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002617 // If parent was in docked stack, the natural place to launch another activity
2618 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002619 final int activityType =
2620 mRootActivityContainer.resolveActivityType(r, mOptions, task);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002621 return parentStack.getDisplay().getOrCreateStack(
2622 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002623 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002624 // If the parent is not in the docked stack, we check if there is docked window
2625 // and if yes, we will launch into that stack. If not, we just put the new
2626 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002627 final ActivityStack dockedStack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002628 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002629 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002630 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002631 return mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002632 } else {
2633 return dockedStack;
2634 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002635 }
2636 }
2637 }
2638
Bryce Lee7daee392017-10-12 13:46:18 -07002639 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2640 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002641 }
2642
Daichi Hirono15a02992016-04-27 18:47:01 +09002643 static boolean isDocumentLaunchesIntoExisting(int flags) {
2644 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2645 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2646 }
liulvpingcfa825f2016-09-26 20:00:15 +08002647
Bryce Lee4c9a5972017-12-01 22:14:24 -08002648 ActivityStarter setIntent(Intent intent) {
2649 mRequest.intent = intent;
2650 return this;
2651 }
2652
Bryce Lee32e09ef2018-03-19 15:29:49 -07002653 @VisibleForTesting
2654 Intent getIntent() {
2655 return mRequest.intent;
2656 }
2657
Bryce Lee4c9a5972017-12-01 22:14:24 -08002658 ActivityStarter setReason(String reason) {
2659 mRequest.reason = reason;
2660 return this;
2661 }
2662
2663 ActivityStarter setCaller(IApplicationThread caller) {
2664 mRequest.caller = caller;
2665 return this;
2666 }
2667
2668 ActivityStarter setEphemeralIntent(Intent intent) {
2669 mRequest.ephemeralIntent = intent;
2670 return this;
2671 }
2672
2673
2674 ActivityStarter setResolvedType(String type) {
2675 mRequest.resolvedType = type;
2676 return this;
2677 }
2678
2679 ActivityStarter setActivityInfo(ActivityInfo info) {
2680 mRequest.activityInfo = info;
2681 return this;
2682 }
2683
2684 ActivityStarter setResolveInfo(ResolveInfo info) {
2685 mRequest.resolveInfo = info;
2686 return this;
2687 }
2688
2689 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2690 mRequest.voiceSession = voiceSession;
2691 return this;
2692 }
2693
2694 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2695 mRequest.voiceInteractor = voiceInteractor;
2696 return this;
2697 }
2698
2699 ActivityStarter setResultTo(IBinder resultTo) {
2700 mRequest.resultTo = resultTo;
2701 return this;
2702 }
2703
2704 ActivityStarter setResultWho(String resultWho) {
2705 mRequest.resultWho = resultWho;
2706 return this;
2707 }
2708
2709 ActivityStarter setRequestCode(int requestCode) {
2710 mRequest.requestCode = requestCode;
2711 return this;
2712 }
2713
2714 ActivityStarter setCallingPid(int pid) {
2715 mRequest.callingPid = pid;
2716 return this;
2717 }
2718
2719 ActivityStarter setCallingUid(int uid) {
2720 mRequest.callingUid = uid;
2721 return this;
2722 }
2723
2724 ActivityStarter setCallingPackage(String callingPackage) {
2725 mRequest.callingPackage = callingPackage;
2726 return this;
2727 }
2728
2729 ActivityStarter setRealCallingPid(int pid) {
2730 mRequest.realCallingPid = pid;
2731 return this;
2732 }
2733
2734 ActivityStarter setRealCallingUid(int uid) {
2735 mRequest.realCallingUid = uid;
2736 return this;
2737 }
2738
2739 ActivityStarter setStartFlags(int startFlags) {
2740 mRequest.startFlags = startFlags;
2741 return this;
2742 }
2743
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002744 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002745 mRequest.activityOptions = options;
2746 return this;
2747 }
2748
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002749 ActivityStarter setActivityOptions(Bundle bOptions) {
2750 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2751 }
2752
Bryce Lee4c9a5972017-12-01 22:14:24 -08002753 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2754 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2755 return this;
2756 }
2757
Patrick Baumann31426b22018-05-21 13:46:40 -07002758 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2759 mRequest.filterCallingUid = filterCallingUid;
2760 return this;
2761 }
2762
Bryce Lee4c9a5972017-12-01 22:14:24 -08002763 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2764 mRequest.componentSpecified = componentSpecified;
2765 return this;
2766 }
2767
2768 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2769 mRequest.outActivity = outActivity;
2770 return this;
2771 }
2772
2773 ActivityStarter setInTask(TaskRecord inTask) {
2774 mRequest.inTask = inTask;
2775 return this;
2776 }
2777
2778 ActivityStarter setWaitResult(WaitResult result) {
2779 mRequest.waitResult = result;
2780 return this;
2781 }
2782
2783 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2784 mRequest.profilerInfo = info;
2785 return this;
2786 }
2787
2788 ActivityStarter setGlobalConfiguration(Configuration config) {
2789 mRequest.globalConfig = config;
2790 return this;
2791 }
2792
Bryce Lee4c9a5972017-12-01 22:14:24 -08002793 ActivityStarter setUserId(int userId) {
2794 mRequest.userId = userId;
2795 return this;
2796 }
2797
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002798 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002799 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002800 mRequest.userId = userId;
2801
2802 return this;
2803 }
2804
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002805 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2806 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2807 return this;
2808 }
2809
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002810 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2811 mRequest.originatingPendingIntent = originatingPendingIntent;
2812 return this;
2813 }
2814
Michal Karpinskiac116df2018-12-10 17:51:42 +00002815 ActivityStarter setAllowBackgroundActivityStart(boolean allowBackgroundActivityStart) {
2816 mRequest.allowBackgroundActivityStart = allowBackgroundActivityStart;
2817 return this;
2818 }
2819
Bryce Leed3624e12017-11-30 08:51:45 -08002820 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002821 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002822 pw.print(prefix);
2823 pw.print("mCurrentUser=");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002824 pw.println(mRootActivityContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002825 pw.print(prefix);
2826 pw.print("mLastStartReason=");
2827 pw.println(mLastStartReason);
2828 pw.print(prefix);
2829 pw.print("mLastStartActivityTimeMs=");
2830 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2831 pw.print(prefix);
2832 pw.print("mLastStartActivityResult=");
2833 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002834 ActivityRecord r = mLastStartActivityRecord[0];
2835 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002836 pw.print(prefix);
2837 pw.println("mLastStartActivityRecord:");
2838 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002839 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002840 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002841 pw.print(prefix);
2842 pw.println("mStartActivity:");
2843 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002844 }
2845 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002846 pw.print(prefix);
2847 pw.print("mIntent=");
2848 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002849 }
2850 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002851 pw.print(prefix);
2852 pw.print("mOptions=");
2853 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002854 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002855 pw.print(prefix);
2856 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002857 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002858 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002859 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002860 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002861 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002862 pw.print(prefix);
2863 pw.print("mLaunchFlags=0x");
2864 pw.print(Integer.toHexString(mLaunchFlags));
2865 pw.print(" mDoResume=");
2866 pw.print(mDoResume);
2867 pw.print(" mAddingToTask=");
2868 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002869 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002870}