blob: bc2136ebcf15d5217e55fc1f304ceb410a0c3ef9 [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
Wale Ogunwale01d66562015-12-29 08:19:19 -080019import static android.app.Activity.RESULT_CANCELED;
Bryce Leef9d49542017-06-26 16:27:32 -070020import static android.app.ActivityManager.START_ABORTED;
Bryce Leeaa5e8c32017-03-01 16:01:06 -080021import static android.app.ActivityManager.START_CANCELED;
Wale Ogunwale01d66562015-12-29 08:19:19 -080022import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
23import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
24import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
25import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
26import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
27import static android.app.ActivityManager.START_SUCCESS;
28import static android.app.ActivityManager.START_TASK_TO_FRONT;
Wale Ogunwale68278562017-09-23 17:13:55 -070029import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
30import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -070031import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -070032import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
33import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070034import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080035import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
36import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
Wale Ogunwale2a25a622016-01-30 11:27:21 -080037import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080038import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080039import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080040import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale01d66562015-12-29 08:19:19 -080041import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
42import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
Wale Ogunwale01d66562015-12-29 08:19:19 -080043import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
44import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
45import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
46import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
47import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
48import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
Bryce Leef65ee7e2018-03-26 16:03:47 -070049import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
Wale Ogunwale01d66562015-12-29 08:19:19 -080050import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
51import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
52import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
David Stevensc6b91c62017-02-08 14:23:58 -080053import static android.view.Display.DEFAULT_DISPLAY;
Andrii Kulian16802aa2016-11-02 12:21:33 -070054import static android.view.Display.INVALID_DISPLAY;
Riddle Hsub70b36d2018-09-11 21:20:02 +080055
Louis Changdd3592a2018-11-05 11:04:14 +080056import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
Wale Ogunwale59507092018-10-29 09:00:30 -070057import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
58import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
59import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
60import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
61import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
62import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
63import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
64import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
65import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
66import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
67import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
68import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
69import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
70import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
71import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
72import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
73import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
74import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
75import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
Wale Ogunwale59507092018-10-29 09:00:30 -070076import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
77import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
Winson Chung74666102017-02-22 17:49:24 -080078
Todd Kennedye9910222017-02-21 16:00:11 -080079import android.annotation.NonNull;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +010080import android.annotation.Nullable;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080081import android.app.ActivityManager;
82import android.app.ActivityOptions;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080083import android.app.IApplicationThread;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080084import android.app.PendingIntent;
85import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070086import android.app.WaitResult;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080087import android.content.IIntentSender;
88import android.content.Intent;
89import android.content.IntentSender;
90import android.content.pm.ActivityInfo;
91import android.content.pm.ApplicationInfo;
Todd Kennedye9910222017-02-21 16:00:11 -080092import android.content.pm.AuxiliaryResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000093import android.content.pm.PackageManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080094import android.content.pm.ResolveInfo;
Kenny Guyb1b30262016-02-09 16:02:35 +000095import android.content.pm.UserInfo;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080096import android.content.res.Configuration;
97import android.graphics.Rect;
98import android.os.Binder;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -080099import android.os.Bundle;
100import android.os.IBinder;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000101import android.os.Process;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800102import android.os.RemoteException;
103import android.os.SystemClock;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100104import android.os.Trace;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800105import android.os.UserHandle;
Kenny Guyb1b30262016-02-09 16:02:35 +0000106import android.os.UserManager;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800107import android.service.voice.IVoiceInteractionSession;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700108import android.text.TextUtils;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800109import android.util.EventLog;
Bryce Leedaa91e42017-12-06 14:13:01 -0800110import android.util.Pools.SynchronizedPool;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800111import android.util.Slog;
Michal Karpinski8596ded2018-11-14 14:43:48 +0000112import android.widget.Toast;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800113
Bryce Leed3624e12017-11-30 08:51:45 -0800114import com.android.internal.annotations.VisibleForTesting;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800115import com.android.internal.app.HeavyWeightSwitcherActivity;
116import com.android.internal.app.IVoiceInteractor;
Wale Ogunwale59507092018-10-29 09:00:30 -0700117import com.android.server.am.EventLogTags;
118import com.android.server.am.PendingIntentRecord;
Louis Changdd3592a2018-11-05 11:04:14 +0800119import com.android.server.pm.InstantAppResolver;
Wale Ogunwale59507092018-10-29 09:00:30 -0700120import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
121import com.android.server.wm.LaunchParamsController.LaunchParams;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800122
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700123import java.io.PrintWriter;
124import java.text.DateFormat;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700125import java.util.Date;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800126
127/**
Bryce Leed3624e12017-11-30 08:51:45 -0800128 * Controller for interpreting how and then launching an activity.
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800129 *
130 * This class collects all the logic for determining how an intent and flags should be turned into
131 * an activity and associated task and stack.
132 */
Wale Ogunwale01d66562015-12-29 08:19:19 -0800133class ActivityStarter {
Wale Ogunwale98875612018-10-12 07:53:02 -0700134 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800135 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
136 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
137 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
138 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
Bryce Lee7daee392017-10-12 13:46:18 -0700139 private static final int INVALID_LAUNCH_MODE = -1;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800140
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700141 private final ActivityTaskManagerService mService;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800142 private final RootActivityContainer mRootActivityContainer;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800143 private final ActivityStackSupervisor mSupervisor;
Benjamin Franz563707b2017-06-29 15:06:13 +0100144 private final ActivityStartInterceptor mInterceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800145 private final ActivityStartController mController;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800146
Wale Ogunwale01d66562015-12-29 08:19:19 -0800147 // Share state variable among methods when starting an activity.
148 private ActivityRecord mStartActivity;
149 private Intent mIntent;
150 private int mCallingUid;
151 private ActivityOptions mOptions;
152
Bryce Lee7daee392017-10-12 13:46:18 -0700153 private int mLaunchMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800154 private boolean mLaunchTaskBehind;
155 private int mLaunchFlags;
156
Bryce Leeec55eb02017-12-05 20:51:27 -0800157 private LaunchParams mLaunchParams = new LaunchParams();
Wale Ogunwale01d66562015-12-29 08:19:19 -0800158
159 private ActivityRecord mNotTop;
160 private boolean mDoResume;
161 private int mStartFlags;
162 private ActivityRecord mSourceRecord;
Bryce Lee7daee392017-10-12 13:46:18 -0700163
David Stevense5a7b642017-05-22 13:18:23 -0700164 // The display to launch the activity onto, barring any strong reason to do otherwise.
165 private int mPreferredDisplayId;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800166
167 private TaskRecord mInTask;
168 private boolean mAddingToTask;
169 private TaskRecord mReuseTask;
170
171 private ActivityInfo mNewTaskInfo;
172 private Intent mNewTaskIntent;
173 private ActivityStack mSourceStack;
174 private ActivityStack mTargetStack;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800175 private boolean mMovedToFront;
176 private boolean mNoAnimation;
177 private boolean mKeepCurTransition;
Jorim Jaggic875ae72016-04-26 22:41:06 -0700178 private boolean mAvoidMoveToFront;
Wale Ogunwale01d66562015-12-29 08:19:19 -0800179
Bryce Lee325e09682017-10-05 17:20:25 -0700180 // We must track when we deliver the new intent since multiple code paths invoke
181 // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
182 // inside {@link #deliverNewIntent} to suppress duplicate requests and ensure the intent is
183 // delivered at most once.
184 private boolean mIntentDelivered;
185
Wale Ogunwale01d66562015-12-29 08:19:19 -0800186 private IVoiceInteractionSession mVoiceSession;
187 private IVoiceInteractor mVoiceInteractor;
188
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700189 // Last activity record we attempted to start
190 private final ActivityRecord[] mLastStartActivityRecord = new ActivityRecord[1];
191 // The result of the last activity we attempted to start.
192 private int mLastStartActivityResult;
193 // Time in milli seconds we attempted to start the last activity.
194 private long mLastStartActivityTimeMs;
195 // The reason we were trying to start the last activity
196 private String mLastStartReason;
Wale Ogunwale59bcba62017-06-16 12:42:51 -0700197
Bryce Lee4c9a5972017-12-01 22:14:24 -0800198 /*
199 * Request details provided through setter methods. Should be reset after {@link #execute()}
200 * to avoid unnecessarily retaining parameters. Note that the request is ignored when
201 * {@link #startResolvedActivity} is invoked directly.
202 */
203 private Request mRequest = new Request();
204
Bryce Leed3624e12017-11-30 08:51:45 -0800205 /**
206 * An interface that to provide {@link ActivityStarter} instances to the controller. This is
207 * used by tests to inject their own starter implementations for verification purposes.
208 */
209 @VisibleForTesting
210 interface Factory {
211 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800212 * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
213 */
214 void setController(ActivityStartController controller);
215
216 /**
Bryce Leed3624e12017-11-30 08:51:45 -0800217 * Generates an {@link ActivityStarter} that is ready to handle a new start request.
218 * @param controller The {@link ActivityStartController} which the starter who will own
219 * this instance.
220 * @return an {@link ActivityStarter}
221 */
Bryce Leedaa91e42017-12-06 14:13:01 -0800222 ActivityStarter obtain();
223
224 /**
225 * Recycles a starter for reuse.
226 */
227 void recycle(ActivityStarter starter);
Wale Ogunwale01d66562015-12-29 08:19:19 -0800228 }
229
Bryce Leed3624e12017-11-30 08:51:45 -0800230 /**
231 * Default implementation of {@link StarterFactory}.
232 */
233 static class DefaultFactory implements Factory {
Bryce Leedaa91e42017-12-06 14:13:01 -0800234 /**
235 * The maximum count of starters that should be active at one time:
236 * 1. last ran starter (for logging and post activity processing)
237 * 2. current running starter
238 * 3. starter from re-entry in (2)
239 */
240 private final int MAX_STARTER_COUNT = 3;
241
Bryce Lee4c9a5972017-12-01 22:14:24 -0800242 private ActivityStartController mController;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700243 private ActivityTaskManagerService mService;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800244 private ActivityStackSupervisor mSupervisor;
245 private ActivityStartInterceptor mInterceptor;
246
Bryce Leedaa91e42017-12-06 14:13:01 -0800247 private SynchronizedPool<ActivityStarter> mStarterPool =
248 new SynchronizedPool<>(MAX_STARTER_COUNT);
249
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700250 DefaultFactory(ActivityTaskManagerService service,
Bryce Lee4c9a5972017-12-01 22:14:24 -0800251 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
252 mService = service;
253 mSupervisor = supervisor;
254 mInterceptor = interceptor;
Bryce Leed3624e12017-11-30 08:51:45 -0800255 }
Bryce Lee4c9a5972017-12-01 22:14:24 -0800256
257 @Override
258 public void setController(ActivityStartController controller) {
259 mController = controller;
260 }
261
262 @Override
Bryce Leedaa91e42017-12-06 14:13:01 -0800263 public ActivityStarter obtain() {
264 ActivityStarter starter = mStarterPool.acquire();
265
266 if (starter == null) {
267 starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
268 }
269
270 return starter;
271 }
272
273 @Override
274 public void recycle(ActivityStarter starter) {
275 starter.reset(true /* clearRequest*/);
276 mStarterPool.release(starter);
Bryce Lee4c9a5972017-12-01 22:14:24 -0800277 }
278 }
279
280 /**
281 * Container for capturing initial start request details. This information is NOT reset until
282 * the {@link ActivityStarter} is recycled, allowing for multiple invocations with the same
283 * parameters.
284 *
285 * TODO(b/64750076): Investigate consolidating member variables of {@link ActivityStarter} with
286 * the request object. Note that some member variables are referenced in
287 * {@link #dump(PrintWriter, String)} and therefore cannot be cleared immediately after
288 * execution.
289 */
290 private static class Request {
291 private static final int DEFAULT_CALLING_UID = -1;
292 private static final int DEFAULT_CALLING_PID = 0;
293
294 IApplicationThread caller;
295 Intent intent;
296 Intent ephemeralIntent;
297 String resolvedType;
298 ActivityInfo activityInfo;
299 ResolveInfo resolveInfo;
300 IVoiceInteractionSession voiceSession;
301 IVoiceInteractor voiceInteractor;
302 IBinder resultTo;
303 String resultWho;
304 int requestCode;
305 int callingPid = DEFAULT_CALLING_UID;
306 int callingUid = DEFAULT_CALLING_PID;
307 String callingPackage;
308 int realCallingPid;
309 int realCallingUid;
310 int startFlags;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100311 SafeActivityOptions activityOptions;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800312 boolean ignoreTargetSecurity;
313 boolean componentSpecified;
Winson Chunge2d72172018-01-25 17:46:20 +0000314 boolean avoidMoveToFront;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800315 ActivityRecord[] outActivity;
316 TaskRecord inTask;
317 String reason;
318 ProfilerInfo profilerInfo;
319 Configuration globalConfig;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800320 int userId;
321 WaitResult waitResult;
Patrick Baumann31426b22018-05-21 13:46:40 -0700322 int filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100323 PendingIntentRecord originatingPendingIntent;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800324
325 /**
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200326 * If set to {@code true}, allows this activity start to look into
327 * {@link PendingRemoteAnimationRegistry}
328 */
329 boolean allowPendingRemoteAnimationRegistryLookup;
330
331 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800332 * Indicates that we should wait for the result of the start request. This flag is set when
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100333 * {@link ActivityStarter#setMayWait(int)} is called.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800334 * {@see ActivityStarter#startActivityMayWait}.
335 */
336 boolean mayWait;
Bryce Leedaa91e42017-12-06 14:13:01 -0800337
338 /**
Bryce Leea3cd8e02018-01-09 15:44:24 -0800339 * Ensure constructed request matches reset instance.
340 */
341 Request() {
342 reset();
343 }
344
345 /**
Bryce Leedaa91e42017-12-06 14:13:01 -0800346 * Sets values back to the initial state, clearing any held references.
347 */
348 void reset() {
349 caller = null;
350 intent = null;
351 ephemeralIntent = null;
352 resolvedType = null;
353 activityInfo = null;
354 resolveInfo = null;
355 voiceSession = null;
356 voiceInteractor = null;
357 resultTo = null;
358 resultWho = null;
359 requestCode = 0;
Bryce Leea3cd8e02018-01-09 15:44:24 -0800360 callingPid = DEFAULT_CALLING_PID;
361 callingUid = DEFAULT_CALLING_UID;
Bryce Leedaa91e42017-12-06 14:13:01 -0800362 callingPackage = null;
363 realCallingPid = 0;
364 realCallingUid = 0;
365 startFlags = 0;
366 activityOptions = null;
367 ignoreTargetSecurity = false;
368 componentSpecified = false;
369 outActivity = null;
370 inTask = null;
371 reason = null;
372 profilerInfo = null;
373 globalConfig = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800374 userId = 0;
375 waitResult = null;
376 mayWait = false;
Winson Chunge2d72172018-01-25 17:46:20 +0000377 avoidMoveToFront = false;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200378 allowPendingRemoteAnimationRegistryLookup = true;
Patrick Baumann31426b22018-05-21 13:46:40 -0700379 filterCallingUid = UserHandle.USER_NULL;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100380 originatingPendingIntent = null;
Bryce Leedaa91e42017-12-06 14:13:01 -0800381 }
382
383 /**
384 * Adopts all values from passed in request.
385 */
386 void set(Request request) {
387 caller = request.caller;
388 intent = request.intent;
389 ephemeralIntent = request.ephemeralIntent;
390 resolvedType = request.resolvedType;
391 activityInfo = request.activityInfo;
392 resolveInfo = request.resolveInfo;
393 voiceSession = request.voiceSession;
394 voiceInteractor = request.voiceInteractor;
395 resultTo = request.resultTo;
396 resultWho = request.resultWho;
397 requestCode = request.requestCode;
398 callingPid = request.callingPid;
399 callingUid = request.callingUid;
400 callingPackage = request.callingPackage;
401 realCallingPid = request.realCallingPid;
402 realCallingUid = request.realCallingUid;
403 startFlags = request.startFlags;
404 activityOptions = request.activityOptions;
405 ignoreTargetSecurity = request.ignoreTargetSecurity;
406 componentSpecified = request.componentSpecified;
407 outActivity = request.outActivity;
408 inTask = request.inTask;
409 reason = request.reason;
410 profilerInfo = request.profilerInfo;
411 globalConfig = request.globalConfig;
Bryce Leedaa91e42017-12-06 14:13:01 -0800412 userId = request.userId;
413 waitResult = request.waitResult;
414 mayWait = request.mayWait;
Winson Chunge2d72172018-01-25 17:46:20 +0000415 avoidMoveToFront = request.avoidMoveToFront;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200416 allowPendingRemoteAnimationRegistryLookup
417 = request.allowPendingRemoteAnimationRegistryLookup;
Patrick Baumann31426b22018-05-21 13:46:40 -0700418 filterCallingUid = request.filterCallingUid;
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100419 originatingPendingIntent = request.originatingPendingIntent;
Bryce Leedaa91e42017-12-06 14:13:01 -0800420 }
Bryce Leed3624e12017-11-30 08:51:45 -0800421 }
422
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700423 ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
Bryce Leed3624e12017-11-30 08:51:45 -0800424 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
425 mController = controller;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800426 mService = service;
Wale Ogunwaled32da472018-11-16 07:19:28 -0800427 mRootActivityContainer = service.mRootActivityContainer;
Bryce Leed3624e12017-11-30 08:51:45 -0800428 mSupervisor = supervisor;
429 mInterceptor = interceptor;
Bryce Leedaa91e42017-12-06 14:13:01 -0800430 reset(true);
431 }
432
433 /**
434 * Effectively duplicates the starter passed in. All state and request values will be
435 * mirrored.
436 * @param starter
437 */
438 void set(ActivityStarter starter) {
439 mStartActivity = starter.mStartActivity;
440 mIntent = starter.mIntent;
441 mCallingUid = starter.mCallingUid;
442 mOptions = starter.mOptions;
443
444 mLaunchTaskBehind = starter.mLaunchTaskBehind;
445 mLaunchFlags = starter.mLaunchFlags;
446 mLaunchMode = starter.mLaunchMode;
447
Bryce Leeec55eb02017-12-05 20:51:27 -0800448 mLaunchParams.set(starter.mLaunchParams);
Bryce Leedaa91e42017-12-06 14:13:01 -0800449
450 mNotTop = starter.mNotTop;
451 mDoResume = starter.mDoResume;
452 mStartFlags = starter.mStartFlags;
453 mSourceRecord = starter.mSourceRecord;
454 mPreferredDisplayId = starter.mPreferredDisplayId;
455
456 mInTask = starter.mInTask;
457 mAddingToTask = starter.mAddingToTask;
458 mReuseTask = starter.mReuseTask;
459
460 mNewTaskInfo = starter.mNewTaskInfo;
461 mNewTaskIntent = starter.mNewTaskIntent;
462 mSourceStack = starter.mSourceStack;
463
464 mTargetStack = starter.mTargetStack;
465 mMovedToFront = starter.mMovedToFront;
466 mNoAnimation = starter.mNoAnimation;
467 mKeepCurTransition = starter.mKeepCurTransition;
468 mAvoidMoveToFront = starter.mAvoidMoveToFront;
469
470 mVoiceSession = starter.mVoiceSession;
471 mVoiceInteractor = starter.mVoiceInteractor;
472
473 mIntentDelivered = starter.mIntentDelivered;
474
475 mRequest.set(starter.mRequest);
Bryce Leed3624e12017-11-30 08:51:45 -0800476 }
477
Bryce Lee4c9a5972017-12-01 22:14:24 -0800478 ActivityRecord getStartActivity() {
479 return mStartActivity;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800480 }
481
Bryce Lee4c9a5972017-12-01 22:14:24 -0800482 boolean relatedToPackage(String packageName) {
483 return (mLastStartActivityRecord[0] != null
484 && packageName.equals(mLastStartActivityRecord[0].packageName))
485 || (mStartActivity != null && packageName.equals(mStartActivity.packageName));
486 }
487
488 /**
489 * Starts an activity based on the request parameters provided earlier.
490 * @return The starter result.
491 */
492 int execute() {
Bryce Leedaa91e42017-12-06 14:13:01 -0800493 try {
494 // TODO(b/64750076): Look into passing request directly to these methods to allow
495 // for transactional diffs and preprocessing.
496 if (mRequest.mayWait) {
497 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
498 mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
499 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
500 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
501 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100502 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200503 mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100504 mRequest.allowPendingRemoteAnimationRegistryLookup,
505 mRequest.originatingPendingIntent);
Bryce Leedaa91e42017-12-06 14:13:01 -0800506 } else {
507 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
508 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
509 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
510 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
511 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
512 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
513 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200514 mRequest.outActivity, mRequest.inTask, mRequest.reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100515 mRequest.allowPendingRemoteAnimationRegistryLookup,
516 mRequest.originatingPendingIntent);
Bryce Leedaa91e42017-12-06 14:13:01 -0800517 }
518 } finally {
519 onExecutionComplete();
520 }
521 }
522
523 /**
524 * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
525 * Note that this method is called internally as well as part of {@link #startActivity}.
526 *
527 * @return The start result.
528 */
529 int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
530 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
531 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
532 ActivityRecord[] outActivity) {
533 try {
534 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
535 doResume, options, inTask, outActivity);
536 } finally {
537 onExecutionComplete();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800538 }
539 }
540
541 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700542 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
543 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
544 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
545 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100546 SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200547 ActivityRecord[] outActivity, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100548 boolean allowPendingRemoteAnimationRegistryLookup,
549 PendingIntentRecord originatingPendingIntent) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700550
551 if (TextUtils.isEmpty(reason)) {
552 throw new IllegalArgumentException("Need to specify a reason.");
553 }
554 mLastStartReason = reason;
555 mLastStartActivityTimeMs = System.currentTimeMillis();
556 mLastStartActivityRecord[0] = null;
557
558 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
559 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
560 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
561 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100562 inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700563
564 if (outActivity != null) {
565 // mLastStartActivityRecord[0] is set in the call to startActivity above.
566 outActivity[0] = mLastStartActivityRecord[0];
567 }
Bryce Leef9d49542017-06-26 16:27:32 -0700568
Bryce Lee93e7f792017-10-25 15:54:55 -0700569 return getExternalResult(mLastStartActivityResult);
570 }
571
Bryce Leed3624e12017-11-30 08:51:45 -0800572 static int getExternalResult(int result) {
Bryce Leef9d49542017-06-26 16:27:32 -0700573 // Aborted results are treated as successes externally, but we must track them internally.
Bryce Lee93e7f792017-10-25 15:54:55 -0700574 return result != START_ABORTED ? result : START_SUCCESS;
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700575 }
576
Bryce Leedaa91e42017-12-06 14:13:01 -0800577 /**
578 * Called when execution is complete. Sets state indicating completion and proceeds with
579 * recycling if appropriate.
580 */
581 private void onExecutionComplete() {
582 mController.onExecutionComplete(this);
583 }
584
Wale Ogunwale692dcd62017-06-20 13:38:14 -0700585 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800586 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
587 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
588 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
589 String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100590 SafeActivityOptions options,
591 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100592 TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
593 PendingIntentRecord originatingPendingIntent) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800594 int err = ActivityManager.START_SUCCESS;
Chad Brubaker06068612017-04-06 09:43:47 -0700595 // Pull the optional Ephemeral Installer-only bundle out of the options early.
596 final Bundle verificationBundle
597 = options != null ? options.popAppVerificationBundle() : null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800598
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700599 WindowProcessController callerApp = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800600 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700601 callerApp = mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800602 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700603 callingPid = callerApp.getPid();
604 callingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800605 } else {
606 Slog.w(TAG, "Unable to find app for caller " + caller
607 + " (pid=" + callingPid + ") when starting: "
608 + intent.toString());
609 err = ActivityManager.START_PERMISSION_DENIED;
610 }
611 }
612
Bryce Lee93e7f792017-10-25 15:54:55 -0700613 final int userId = aInfo != null && aInfo.applicationInfo != null
614 ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800615
616 if (err == ActivityManager.START_SUCCESS) {
617 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
Andrii Kulian03c403d2016-11-11 11:14:12 -0800618 + "} from uid " + callingUid);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800619 }
620
621 ActivityRecord sourceRecord = null;
622 ActivityRecord resultRecord = null;
623 if (resultTo != null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800624 sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800625 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
626 "Will send result to " + resultTo + " " + sourceRecord);
627 if (sourceRecord != null) {
628 if (requestCode >= 0 && !sourceRecord.finishing) {
629 resultRecord = sourceRecord;
630 }
631 }
632 }
633
634 final int launchFlags = intent.getFlags();
635
636 if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
637 // Transfer the result target from the source activity to the new
638 // one being started, including any failures.
639 if (requestCode >= 0) {
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100640 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800641 return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
642 }
643 resultRecord = sourceRecord.resultTo;
644 if (resultRecord != null && !resultRecord.isInStackLocked()) {
645 resultRecord = null;
646 }
647 resultWho = sourceRecord.resultWho;
648 requestCode = sourceRecord.requestCode;
649 sourceRecord.resultTo = null;
650 if (resultRecord != null) {
651 resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
652 }
653 if (sourceRecord.launchedFromUid == callingUid) {
654 // The new activity is being launched from the same uid as the previous
655 // activity in the flow, and asking to forward its result back to the
656 // previous. In this case the activity is serving as a trampoline between
657 // the two, so we also want to update its launchedFromPackage to be the
658 // same as the previous activity. Note that this is safe, since we know
659 // these two packages come from the same uid; the caller could just as
660 // well have supplied that same package name itself. This specifially
661 // deals with the case of an intent picker/chooser being launched in the app
662 // flow to redirect to an activity picked by the user, where we want the final
663 // activity to consider it to have been launched by the previous app activity.
664 callingPackage = sourceRecord.launchedFromPackage;
665 }
666 }
667
668 if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
669 // We couldn't find a class that can handle the given Intent.
670 // That's the end of that!
671 err = ActivityManager.START_INTENT_NOT_RESOLVED;
672 }
673
674 if (err == ActivityManager.START_SUCCESS && aInfo == null) {
675 // We couldn't find the specific class specified in the Intent.
676 // Also the end of the line.
677 err = ActivityManager.START_CLASS_NOT_FOUND;
678 }
679
680 if (err == ActivityManager.START_SUCCESS && sourceRecord != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800681 && sourceRecord.getTaskRecord().voiceSession != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800682 // If this activity is being launched as part of a voice session, we need
683 // to ensure that it is safe to do so. If the upcoming activity will also
684 // be part of the voice session, we can only launch it if it has explicitly
685 // said it supports the VOICE category, or it is a part of the calling app.
686 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
687 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
688 try {
689 intent.addCategory(Intent.CATEGORY_VOICE);
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700690 if (!mService.getPackageManager().activitySupportsIntent(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800691 intent.getComponent(), intent, resolvedType)) {
692 Slog.w(TAG,
693 "Activity being started in current voice task does not support voice: "
694 + intent);
695 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
696 }
697 } catch (RemoteException e) {
698 Slog.w(TAG, "Failure checking voice capabilities", e);
699 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
700 }
701 }
702 }
703
704 if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
705 // If the caller is starting a new voice session, just make sure the target
706 // is actually allowing it to run this way.
707 try {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700708 if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800709 intent, resolvedType)) {
710 Slog.w(TAG,
711 "Activity being started in new voice task does not support: "
712 + intent);
713 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
714 }
715 } catch (RemoteException e) {
716 Slog.w(TAG, "Failure checking voice capabilities", e);
717 err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
718 }
719 }
720
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800721 final ActivityStack resultStack = resultRecord == null
722 ? null : resultRecord.getActivityStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800723
Wale Ogunwale01d66562015-12-29 08:19:19 -0800724 if (err != START_SUCCESS) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800725 if (resultRecord != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -0800726 resultStack.sendActivityResultLocked(
727 -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800728 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100729 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800730 return err;
731 }
732
733 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100734 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
Winson Chungc9804e72018-05-15 11:01:44 -0700735 inTask != null, callerApp, resultRecord, resultStack);
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700736 abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800737 callingPid, resolvedType, aInfo.applicationInfo);
738
Michal Karpinski8596ded2018-11-14 14:43:48 +0000739 // not sure if we need to create START_ABORTED_BACKGROUND so for now piggybacking
740 // on START_ABORTED
741 if (!abort) {
Michal Karpinski0ad4e2f2018-11-29 16:22:34 +0000742 abort |= shouldAbortBackgroundActivityStart(callingUid, callingPackage, realCallingUid,
743 callerApp);
Michal Karpinski8596ded2018-11-14 14:43:48 +0000744 }
745
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100746 // Merge the two options bundles, while realCallerOptions takes precedence.
747 ActivityOptions checkedOptions = options != null
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700748 ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200749 if (allowPendingRemoteAnimationRegistryLookup) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700750 checkedOptions = mService.getActivityStartController()
Jorim Jaggi6fa41c32018-04-23 18:35:00 +0200751 .getPendingRemoteAnimationRegistry()
752 .overrideOptionsIfNeeded(callingPackage, checkedOptions);
753 }
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700754 if (mService.mController != null) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800755 try {
756 // The Intent we give to the watcher has the extra data
757 // stripped off, since it can contain private information.
758 Intent watchIntent = intent.cloneFilter();
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700759 abort |= !mService.mController.activityStarting(watchIntent,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800760 aInfo.applicationInfo.packageName);
761 } catch (RemoteException e) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700762 mService.mController = null;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800763 }
764 }
765
Rubin Xu58d25992016-01-21 17:47:13 +0000766 mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
Benjamin Franz563707b2017-06-29 15:06:13 +0100767 if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100768 callingUid, checkedOptions)) {
Benjamin Franz563707b2017-06-29 15:06:13 +0100769 // activity start was intercepted, e.g. because the target user is currently in quiet
770 // mode (turn off work) or the target application is suspended
771 intent = mInterceptor.mIntent;
772 rInfo = mInterceptor.mRInfo;
773 aInfo = mInterceptor.mAInfo;
774 resolvedType = mInterceptor.mResolvedType;
775 inTask = mInterceptor.mInTask;
776 callingPid = mInterceptor.mCallingPid;
777 callingUid = mInterceptor.mCallingUid;
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100778 checkedOptions = mInterceptor.mActivityOptions;
Benjamin Franz563707b2017-06-29 15:06:13 +0100779 }
780
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800781 if (abort) {
782 if (resultRecord != null) {
783 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Wale Ogunwale01d66562015-12-29 08:19:19 -0800784 RESULT_CANCELED, null);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800785 }
786 // We pretend to the caller that it was really started, but
787 // they will just get a cancel result.
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100788 ActivityOptions.abort(checkedOptions);
Michal Karpinski8596ded2018-11-14 14:43:48 +0000789 maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp,
Michal Karpinski82bb5902018-11-28 15:52:52 +0000790 null /*r*/, originatingPendingIntent, true /*abortedStart*/);
Bryce Leef9d49542017-06-26 16:27:32 -0700791 return START_ABORTED;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800792 }
793
794 // If permissions need a review before any of the app components can run, we
795 // launch the review activity and pass a pending intent to start the activity
796 // we are to launching now after the review is completed.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700797 if (aInfo != null) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700798 if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800799 aInfo.packageName, userId)) {
Wale Ogunwaleee6eca12018-09-19 20:37:53 -0700800 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800801 ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
802 callingUid, userId, null, null, 0, new Intent[]{intent},
803 new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
804 | PendingIntent.FLAG_ONE_SHOT, null);
805
806 final int flags = intent.getFlags();
807 Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
808 newIntent.setFlags(flags
809 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
810 newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
811 newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
812 if (resultRecord != null) {
813 newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
814 }
815 intent = newIntent;
816
817 resolvedType = null;
818 callingUid = realCallingUid;
819 callingPid = realCallingPid;
820
Svet Ganovcbcbf662018-05-10 17:25:29 -0700821 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
Patrick Baumann31426b22018-05-21 13:46:40 -0700822 computeResolveFilterUid(
823 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800824 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
825 null /*profilerInfo*/);
826
827 if (DEBUG_PERMISSIONS_REVIEW) {
Wale Ogunwaled32da472018-11-16 07:19:28 -0800828 final ActivityStack focusedStack =
829 mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800830 Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
831 true, false) + "} from uid " + callingUid + " on display "
Andrii Kulian52d255c2018-07-13 11:32:19 -0700832 + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800833 }
834 }
835 }
836
837 // If we have an ephemeral app, abort the process of launching the resolved intent.
838 // Instead, launch the ephemeral installer. Once the installer is finished, it
839 // starts either the intent we resolved here [on install error] or the ephemeral
840 // app [on install success].
Patrick Baumanna89a1722018-02-07 15:26:52 -0800841 if (rInfo != null && rInfo.auxiliaryInfo != null) {
Todd Kennedye9910222017-02-21 16:00:11 -0800842 intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
Chad Brubaker06068612017-04-06 09:43:47 -0700843 callingPackage, verificationBundle, resolvedType, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800844 resolvedType = null;
845 callingUid = realCallingUid;
846 callingPid = realCallingPid;
847
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800848 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
849 }
850
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700851 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
Wale Ogunwalef6733932018-06-27 05:14:34 -0700852 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800853 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100854 mSupervisor, checkedOptions, sourceRecord);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800855 if (outActivity != null) {
856 outActivity[0] = r;
857 }
858
859 if (r.appTimeTracker == null && sourceRecord != null) {
860 // If the caller didn't specify an explicit time tracker, we want to continue
861 // tracking under any it has.
862 r.appTimeTracker = sourceRecord.appTimeTracker;
863 }
864
Wale Ogunwaled32da472018-11-16 07:19:28 -0800865 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100866
867 // If we are starting an activity that is not from the same uid as the currently resumed
868 // one, check whether app switches are allowed.
Bryce Leec4ab62a2018-03-05 14:19:26 -0800869 if (voiceSession == null && (stack.getResumedActivity() == null
870 || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700871 if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800872 realCallingPid, realCallingUid, "Activity start")) {
Bryce Leed3624e12017-11-30 08:51:45 -0800873 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700874 sourceRecord, startFlags, stack, callerApp));
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100875 ActivityOptions.abort(checkedOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800876 return ActivityManager.START_SWITCHES_CANCELED;
877 }
878 }
879
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700880 mService.onStartActivitySetDidAppSwitch();
Bryce Leed3624e12017-11-30 08:51:45 -0800881 mController.doPendingActivityLaunches(false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800882
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100883 maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp, r,
Michal Karpinski82bb5902018-11-28 15:52:52 +0000884 originatingPendingIntent, false /*abortedStart*/);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100885
Bryce Leedaa91e42017-12-06 14:13:01 -0800886 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100887 true /* doResume */, checkedOptions, inTask, outActivity);
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -0800888 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -0800889
Michal Karpinski8596ded2018-11-14 14:43:48 +0000890 private boolean shouldAbortBackgroundActivityStart(int callingUid, final String callingPackage,
Michal Karpinski0ad4e2f2018-11-29 16:22:34 +0000891 int realCallingUid, WindowProcessController callerApp) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000892 if (mService.isBackgroundActivityStartsEnabled()) {
893 return false;
894 }
895 // don't abort for the most important UIDs
896 if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
897 return false;
898 }
899 // don't abort if the callerApp has any visible activity
900 if (callerApp != null && callerApp.hasForegroundActivities()) {
901 return false;
902 }
Michal Karpinski0ad4e2f2018-11-29 16:22:34 +0000903 // don't abort if the callingUid is in the foreground
904 if (isUidForeground(callingUid)) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000905 return false;
906 }
Michal Karpinski0ad4e2f2018-11-29 16:22:34 +0000907 // don't abort if the realCallingUid is in the foreground and callingUid isn't
908 if ((realCallingUid != callingUid) && isUidForeground(realCallingUid)) {
Michal Karpinski8596ded2018-11-14 14:43:48 +0000909 return false;
910 }
Michal Karpinski82bb5902018-11-28 15:52:52 +0000911 // don't abort if the caller has the same uid as the recents component
912 if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
913 return false;
914 }
Michal Karpinski8596ded2018-11-14 14:43:48 +0000915 // anything that has fallen through will currently be aborted
916 // TODO: remove this toast after feature development is done
917 mService.mUiHandler.post(() -> {
918 Toast.makeText(mService.mContext,
919 "Blocking background activity start for " + callingPackage,
920 Toast.LENGTH_SHORT).show();
921 });
922 return true;
923 }
924
Michal Karpinski0ad4e2f2018-11-29 16:22:34 +0000925 /** Returns true if uid has a visible window or its process is in top or persistent state. */
926 private boolean isUidForeground(int uid) {
927 return (mService.getUidStateLocked(uid) <= ActivityManager.PROCESS_STATE_TOP)
928 || mService.mWindowManager.isAnyWindowVisibleForUid(uid);
929 }
930
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100931 private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700932 Intent intent, WindowProcessController callerApp, ActivityRecord r,
Michal Karpinski8596ded2018-11-14 14:43:48 +0000933 PendingIntentRecord originatingPendingIntent, boolean abortedStart) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700934 boolean callerAppHasForegroundActivity =
935 callerApp != null && callerApp.hasForegroundActivities();
936 if (!mService.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
Michal Karpinski8596ded2018-11-14 14:43:48 +0000937 || (!abortedStart && r == null)) {
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100938 // skip logging in this case
939 return;
940 }
941
942 try {
943 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700944 final int callingUidProcState = mService.getUidStateLocked(callingUid);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100945 final boolean callingUidHasAnyVisibleWindow =
946 mService.mWindowManager.isAnyWindowVisibleForUid(callingUid);
947 final int realCallingUidProcState = (callingUid == realCallingUid)
948 ? callingUidProcState
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700949 : mService.getUidStateLocked(realCallingUid);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100950 final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
951 ? callingUidHasAnyVisibleWindow
952 : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid);
Michal Karpinski8596ded2018-11-14 14:43:48 +0000953 final String targetPackage = (r != null) ? r.packageName : null;
954 final int targetUid = (r!= null) ? ((r.appInfo != null) ? r.appInfo.uid : -1) : -1;
Wale Ogunwalebff2df42018-10-18 17:09:19 -0700955 final int targetUidProcState = mService.getUidStateLocked(targetUid);
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100956 final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
957 ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid)
958 : false;
959 final String targetWhitelistTag = (targetUid != -1)
Wale Ogunwale9de19442018-10-18 19:05:03 -0700960 ? mService.getPendingTempWhitelistTagForUidLocked(targetUid)
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100961 : null;
962
963 mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r,
964 callingUid, callingPackage, callingUidProcState,
965 callingUidHasAnyVisibleWindow,
966 realCallingUid, realCallingUidProcState,
967 realCallingUidHasAnyVisibleWindow,
968 targetUid, targetPackage, targetUidProcState,
969 targetUidHasAnyVisibleWindow, targetWhitelistTag,
970 (originatingPendingIntent != null));
971 } finally {
972 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
973 }
974 }
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100975
Bryce Leeaa5e8c32017-03-01 16:01:06 -0800976 /**
977 * Creates a launch intent for the given auxiliary resolution data.
978 */
Patrick Baumann577d4022018-01-31 16:55:10 +0000979 private @NonNull Intent createLaunchIntent(@Nullable AuxiliaryResolveInfo auxiliaryResponse,
Chad Brubaker06068612017-04-06 09:43:47 -0700980 Intent originalIntent, String callingPackage, Bundle verificationBundle,
981 String resolvedType, int userId) {
Patrick Baumann577d4022018-01-31 16:55:10 +0000982 if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
Todd Kennedye9910222017-02-21 16:00:11 -0800983 // request phase two resolution
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700984 mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
Chad Brubaker06068612017-04-06 09:43:47 -0700985 auxiliaryResponse, originalIntent, resolvedType, callingPackage,
986 verificationBundle, userId);
Todd Kennedye9910222017-02-21 16:00:11 -0800987 }
Todd Kennedydfc27c62017-05-17 15:32:10 -0700988 return InstantAppResolver.buildEphemeralInstallerIntent(
Patrick Baumann577d4022018-01-31 16:55:10 +0000989 originalIntent,
990 InstantAppResolver.sanitizeIntent(originalIntent),
991 auxiliaryResponse == null ? null : auxiliaryResponse.failureIntent,
992 callingPackage,
993 verificationBundle,
994 resolvedType,
995 userId,
996 auxiliaryResponse == null ? null : auxiliaryResponse.installFailureActivity,
997 auxiliaryResponse == null ? null : auxiliaryResponse.token,
998 auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo,
999 auxiliaryResponse == null ? null : auxiliaryResponse.filters);
Todd Kennedye9910222017-02-21 16:00:11 -08001000 }
1001
Riddle Hsu16567132018-08-16 21:37:47 +08001002 void postStartActivityProcessing(ActivityRecord r, int result,
1003 ActivityStack startedActivityStack) {
Bryce Lee7f936862017-05-09 15:33:18 -07001004 if (ActivityManager.isStartResultFatalError(result)) {
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001005 return;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001006 }
Filip Gruszczynski303210b2016-01-08 16:28:08 -08001007
Chong Zhang5022da32016-06-21 16:31:37 -07001008 // We're waiting for an activity launch to finish, but that activity simply
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001009 // brought another activity to front. We must also handle the case where the task is already
1010 // in the front as a result of the trampoline activity being in the same task (it will be
1011 // considered focused as the trampoline will be finished). Let startActivityMayWait() know
1012 // about this, so it waits for the new activity to become visible instead.
1013 mSupervisor.reportWaitingActivityLaunchedIfNeeded(r, result);
Chong Zhang5022da32016-06-21 16:31:37 -07001014
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001015 if (startedActivityStack == null) {
1016 return;
1017 }
1018
Wale Ogunwaleac36e4d2017-11-29 13:30:26 -08001019 final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
1020 boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags
1021 && mReuseTask != null;
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001022 if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) {
1023 // The activity was already running so it wasn't started, but either brought to the
1024 // front or the new intent was delivered to it since it was already in front. Notify
1025 // anyone interested in this piece of information.
1026 switch (startedActivityStack.getWindowingMode()) {
1027 case WINDOWING_MODE_PINNED:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001028 mService.getTaskChangeNotificationController().notifyPinnedActivityRestartAttempt(
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001029 clearedTask);
1030 break;
1031 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
Louis Changbd48dca2018-08-29 17:44:34 +08001032 final ActivityStack homeStack =
1033 startedActivityStack.getDisplay().getHomeStack();
Wale Ogunwale7d7973a2018-04-05 10:25:59 -07001034 if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
1035 mService.mWindowManager.showRecentApps();
1036 }
1037 break;
1038 }
Wale Ogunwalecc25a8a2016-01-23 14:31:37 -08001039 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001040 }
1041
Bryce Lee4c9a5972017-12-01 22:14:24 -08001042 private int startActivityMayWait(IApplicationThread caller, int callingUid,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001043 String callingPackage, Intent intent, String resolvedType,
1044 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1045 IBinder resultTo, String resultWho, int requestCode, int startFlags,
Sudheer Shankafc46e9b2016-10-21 17:55:27 -07001046 ProfilerInfo profilerInfo, WaitResult outResult,
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001047 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001048 int userId, TaskRecord inTask, String reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001049 boolean allowPendingRemoteAnimationRegistryLookup,
1050 PendingIntentRecord originatingPendingIntent) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001051 // Refuse possible leaked file descriptors
1052 if (intent != null && intent.hasFileDescriptors()) {
1053 throw new IllegalArgumentException("File descriptors passed in Intent");
1054 }
Igor Murashkin212d06c2018-10-22 16:34:39 -07001055 mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001056 boolean componentSpecified = intent.getComponent() != null;
1057
Makoto Onuki1a342742018-04-26 14:56:59 -07001058 final int realCallingPid = Binder.getCallingPid();
1059 final int realCallingUid = Binder.getCallingUid();
1060
Svet Ganovcbcbf662018-05-10 17:25:29 -07001061 int callingPid;
1062 if (callingUid >= 0) {
1063 callingPid = -1;
1064 } else if (caller == null) {
1065 callingPid = realCallingPid;
1066 callingUid = realCallingUid;
1067 } else {
1068 callingPid = callingUid = -1;
1069 }
1070
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001071 // Save a copy in case ephemeral needs it
1072 final Intent ephemeralIntent = new Intent(intent);
1073 // Don't modify the client's object!
1074 intent = new Intent(intent);
Todd Kennedyb21be122017-03-24 14:10:01 -07001075 if (componentSpecified
Patrick Baumann531db462018-02-13 13:01:47 -08001076 && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
Patrick Baumann577d4022018-01-31 16:55:10 +00001077 && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
1078 && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
Wale Ogunwale906f9c62018-07-23 11:23:44 -07001079 && mService.getPackageManagerInternalLocked()
Todd Kennedyb21be122017-03-24 14:10:01 -07001080 .isInstantAppInstallerComponent(intent.getComponent())) {
1081 // intercept intents targeted directly to the ephemeral installer the
Patrick Baumann577d4022018-01-31 16:55:10 +00001082 // ephemeral installer should never be started with a raw Intent; instead
Todd Kennedyb21be122017-03-24 14:10:01 -07001083 // adjust the intent so it looks like a "normal" instant app launch
1084 intent.setComponent(null /*component*/);
1085 componentSpecified = false;
1086 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001087
Makoto Onuki1a342742018-04-26 14:56:59 -07001088 ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001089 0 /* matchFlags */,
1090 computeResolveFilterUid(
1091 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001092 if (rInfo == null) {
1093 UserInfo userInfo = mSupervisor.getUserInfo(userId);
1094 if (userInfo != null && userInfo.isManagedProfile()) {
1095 // Special case for managed profiles, if attempting to launch non-cryto aware
1096 // app in a locked managed profile from an unlocked parent allow it to resolve
1097 // as user will be sent via confirm credentials to unlock the profile.
1098 UserManager userManager = UserManager.get(mService.mContext);
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001099 boolean profileLockedAndParentUnlockingOrUnlocked = false;
Tony Mak13436452016-02-24 11:08:38 +00001100 long token = Binder.clearCallingIdentity();
1101 try {
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001102 UserInfo parent = userManager.getProfileParent(userId);
1103 profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1104 && userManager.isUserUnlockingOrUnlocked(parent.id)
1105 && !userManager.isUserUnlockingOrUnlocked(userId);
Tony Mak13436452016-02-24 11:08:38 +00001106 } finally {
1107 Binder.restoreCallingIdentity(token);
1108 }
Fyodor Kupolovce4db0a2016-05-11 14:21:18 -07001109 if (profileLockedAndParentUnlockingOrUnlocked) {
Kenny Guyb1b30262016-02-09 16:02:35 +00001110 rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001111 PackageManager.MATCH_DIRECT_BOOT_AWARE
Patrick Baumann78380272018-04-04 10:41:01 -07001112 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
Patrick Baumann31426b22018-05-21 13:46:40 -07001113 computeResolveFilterUid(
1114 callingUid, realCallingUid, mRequest.filterCallingUid));
Kenny Guyb1b30262016-02-09 16:02:35 +00001115 }
1116 }
1117 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001118 // Collect information about the target of the Intent.
1119 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1120
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001121 synchronized (mService.mGlobalLock) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001122 final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian8072d112016-09-16 11:11:01 -07001123 stack.mConfigWillChange = globalConfig != null
Wale Ogunwalef6733932018-06-27 05:14:34 -07001124 && mService.getGlobalConfiguration().diff(globalConfig) != 0;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001125 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1126 "Starting activity when config will change = " + stack.mConfigWillChange);
1127
1128 final long origId = Binder.clearCallingIdentity();
1129
1130 if (aInfo != null &&
1131 (aInfo.applicationInfo.privateFlags
Dianne Hackbornc8e4fad2018-05-04 11:31:09 -07001132 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
Wale Ogunwale214f3482018-10-04 11:00:47 -07001133 mService.mHasHeavyWeightFeature) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001134 // This may be a heavy-weight process! Check to see if we already
1135 // have another, different heavy-weight process running.
1136 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
Wale Ogunwale53783742018-09-16 10:21:51 -07001137 final WindowProcessController heavy = mService.mHeavyWeightProcess;
1138 if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
1139 || !heavy.mName.equals(aInfo.processName))) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001140 int appCallingUid = callingUid;
1141 if (caller != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001142 WindowProcessController callerApp =
1143 mService.getProcessController(caller);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001144 if (callerApp != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001145 appCallingUid = callerApp.mInfo.uid;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001146 } else {
1147 Slog.w(TAG, "Unable to find app for caller " + caller
1148 + " (pid=" + callingPid + ") when starting: "
1149 + intent.toString());
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001150 SafeActivityOptions.abort(options);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001151 return ActivityManager.START_PERMISSION_DENIED;
1152 }
1153 }
1154
Wale Ogunwaleee6eca12018-09-19 20:37:53 -07001155 IIntentSender target = mService.getIntentSenderLocked(
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001156 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1157 appCallingUid, userId, null, null, 0, new Intent[] { intent },
1158 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1159 | PendingIntent.FLAG_ONE_SHOT, null);
1160
1161 Intent newIntent = new Intent();
1162 if (requestCode >= 0) {
1163 // Caller is requesting a result.
1164 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1165 }
1166 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1167 new IntentSender(target));
Wale Ogunwale53783742018-09-16 10:21:51 -07001168 heavy.updateIntentForHeavyWeightActivity(newIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001169 newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1170 aInfo.packageName);
1171 newIntent.setFlags(intent.getFlags());
1172 newIntent.setClassName("android",
1173 HeavyWeightSwitcherActivity.class.getName());
1174 intent = newIntent;
1175 resolvedType = null;
1176 caller = null;
1177 callingUid = Binder.getCallingUid();
1178 callingPid = Binder.getCallingPid();
1179 componentSpecified = true;
Makoto Onuki1a342742018-04-26 14:56:59 -07001180 rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
Patrick Baumann31426b22018-05-21 13:46:40 -07001181 0 /* matchFlags */, computeResolveFilterUid(
1182 callingUid, realCallingUid, mRequest.filterCallingUid));
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001183 aInfo = rInfo != null ? rInfo.activityInfo : null;
1184 if (aInfo != null) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001185 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001186 }
1187 }
1188 }
1189 }
1190
Jorim Jaggi275561a2016-02-23 10:11:02 -05001191 final ActivityRecord[] outRecord = new ActivityRecord[1];
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01001192 int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1193 voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1194 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02001195 ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
Michal Karpinski201bc0c2018-07-20 15:32:00 +01001196 allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001197
1198 Binder.restoreCallingIdentity(origId);
1199
1200 if (stack.mConfigWillChange) {
1201 // If the caller also wants to switch to a new configuration,
1202 // do so now. This allows a clean switch, as we are waiting
1203 // for the current activity to pause (so we will not destroy
1204 // it), and have not yet started the next activity.
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001205 mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001206 "updateConfiguration()");
1207 stack.mConfigWillChange = false;
1208 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1209 "Updating to new configuration after starting activity.");
Wale Ogunwalea6191b42018-05-09 07:41:32 -07001210 mService.updateConfigurationLocked(globalConfig, null, false);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001211 }
1212
Vishnu Nair132ee832018-09-28 15:00:05 -07001213 // Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger
1214 // will then wait for the windows to be drawn and populate WaitResult.
1215 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001216 if (outResult != null) {
1217 outResult.result = res;
Bryce Lee4a194382017-04-04 14:32:48 -07001218
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001219 final ActivityRecord r = outRecord[0];
1220
1221 switch(res) {
1222 case START_SUCCESS: {
1223 mSupervisor.mWaitingActivityLaunched.add(outResult);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001224 do {
1225 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001226 mService.mGlobalLock.wait();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001227 } catch (InterruptedException e) {
1228 }
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001229 } while (outResult.result != START_TASK_TO_FRONT
1230 && !outResult.timeout && outResult.who == null);
1231 if (outResult.result == START_TASK_TO_FRONT) {
1232 res = START_TASK_TO_FRONT;
1233 }
1234 break;
1235 }
1236 case START_DELIVERED_TO_TOP: {
1237 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001238 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001239 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001240 break;
1241 }
1242 case START_TASK_TO_FRONT: {
1243 // ActivityRecord may represent a different activity, but it should not be
1244 // in the resumed state.
Bryce Lee7ace3952018-02-16 14:34:32 -08001245 if (r.nowVisible && r.isState(RESUMED)) {
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001246 outResult.timeout = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001247 outResult.who = r.mActivityComponent;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001248 outResult.totalTime = 0;
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001249 } else {
Vishnu Nair132ee832018-09-28 15:00:05 -07001250 final long startTimeMs = SystemClock.uptimeMillis();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001251 mSupervisor.waitActivityVisible(
1252 r.mActivityComponent, outResult, startTimeMs);
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001253 // Note: the timeout variable is not currently not ever set.
1254 do {
1255 try {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07001256 mService.mGlobalLock.wait();
Bryce Lee5f0e28f2018-01-30 16:00:03 -08001257 } catch (InterruptedException e) {
1258 }
1259 } while (!outResult.timeout && outResult.who == null);
1260 }
1261 break;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08001262 }
1263 }
1264 }
1265
1266 return res;
1267 }
1268 }
1269
Svet Ganovcbcbf662018-05-10 17:25:29 -07001270 /**
1271 * Compute the logical UID based on which the package manager would filter
1272 * app components i.e. based on which the instant app policy would be applied
1273 * because it is the logical calling UID.
1274 *
1275 * @param customCallingUid The UID on whose behalf to make the call.
1276 * @param actualCallingUid The UID actually making the call.
Patrick Baumann31426b22018-05-21 13:46:40 -07001277 * @param filterCallingUid The UID to be used to filter for instant apps.
Svet Ganovcbcbf662018-05-10 17:25:29 -07001278 * @return The logical UID making the call.
1279 */
Patrick Baumann31426b22018-05-21 13:46:40 -07001280 static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
1281 int filterCallingUid) {
1282 return filterCallingUid != UserHandle.USER_NULL
1283 ? filterCallingUid
1284 : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
Svet Ganovcbcbf662018-05-10 17:25:29 -07001285 }
1286
Bryce Leedaa91e42017-12-06 14:13:01 -08001287 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1288 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1289 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1290 ActivityRecord[] outActivity) {
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001291 int result = START_CANCELED;
Riddle Hsu16567132018-08-16 21:37:47 +08001292 final ActivityStack startedActivityStack;
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001293 try {
1294 mService.mWindowManager.deferSurfaceLayout();
1295 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001296 startFlags, doResume, options, inTask, outActivity);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001297 } finally {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001298 final ActivityStack currentStack = r.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001299 startedActivityStack = currentStack != null ? currentStack : mTargetStack;
1300
1301 if (ActivityManager.isStartResultSuccessful(result)) {
1302 if (startedActivityStack != null) {
1303 // If there is no state change (e.g. a resumed activity is reparented to
1304 // top of another display) to trigger a visibility/configuration checking,
1305 // we have to update the configuration for changing to different display.
1306 final ActivityRecord currentTop =
1307 startedActivityStack.topRunningActivityLocked();
1308 if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001309 mRootActivityContainer.ensureVisibilityAndConfig(
1310 currentTop, currentTop.getDisplayId(),
Riddle Hsu16567132018-08-16 21:37:47 +08001311 true /* markFrozenIfConfigChanged */, false /* deferResume */);
1312 }
1313 }
1314 } else {
1315 // If we are not able to proceed, disassociate the activity from the task.
1316 // Leaving an activity in an incomplete state can lead to issues, such as
1317 // performing operations without a window container.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001318 final ActivityStack stack = mStartActivity.getActivityStack();
Riddle Hsu16567132018-08-16 21:37:47 +08001319 if (stack != null) {
1320 stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1321 null /* intentResultData */, "startActivity", true /* oomAdj */);
1322 }
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001323 }
1324 mService.mWindowManager.continueSurfaceLayout();
1325 }
1326
Riddle Hsu16567132018-08-16 21:37:47 +08001327 postStartActivityProcessing(r, result, startedActivityStack);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001328
1329 return result;
1330 }
1331
1332 // Note: This method should only be called from {@link startActivity}.
Wale Ogunwale01d66562015-12-29 08:19:19 -08001333 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1334 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
Bryce Lee4a194382017-04-04 14:32:48 -07001335 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1336 ActivityRecord[] outActivity) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001337
1338 setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1339 voiceInteractor);
Louis Chang39ba54b2018-10-18 11:28:57 +08001340 final int preferredWindowingMode = mLaunchParams.mWindowingMode;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001341
Louis Changbd48dca2018-08-29 17:44:34 +08001342 // Do not start home activity if it cannot be launched on preferred display. We are not
1343 // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
1344 // fallback to launch on other displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001345 if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
Louis Changdd3592a2018-11-05 11:04:14 +08001346 mPreferredDisplayId, true /* allowInstrumenting */)) {
Louis Changbd48dca2018-08-29 17:44:34 +08001347 Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
1348 return START_CANCELED;
1349 }
1350
Wale Ogunwale01d66562015-12-29 08:19:19 -08001351 computeLaunchingTaskFlags();
1352
1353 computeSourceStack();
1354
1355 mIntent.setFlags(mLaunchFlags);
1356
Bryce Lee4a194382017-04-04 14:32:48 -07001357 ActivityRecord reusedActivity = getReusableIntentActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001358
Bryce Lee4a194382017-04-04 14:32:48 -07001359 if (reusedActivity != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001360 // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
1361 // still needs to be a lock task mode violation since the task gets cleared out and
1362 // the device would otherwise leave the locked task.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001363 if (mService.getLockTaskController().isLockTaskModeViolation(
1364 reusedActivity.getTaskRecord(),
Wale Ogunwale01d66562015-12-29 08:19:19 -08001365 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1366 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001367 Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
1368 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
1369 }
1370
Bryce Leef65ee7e2018-03-26 16:03:47 -07001371 // True if we are clearing top and resetting of a standard (default) launch mode
1372 // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
1373 final boolean clearTopAndResetStandardLaunchMode =
1374 (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
1375 == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
1376 && mLaunchMode == LAUNCH_MULTIPLE;
1377
1378 // If mStartActivity does not have a task associated with it, associate it with the
1379 // reused activity's task. Do not do so if we're clearing top and resetting for a
1380 // standard launchMode activity.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001381 if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
1382 mStartActivity.setTask(reusedActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001383 }
Bryce Leef65ee7e2018-03-26 16:03:47 -07001384
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001385 if (reusedActivity.getTaskRecord().intent == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001386 // This task was started because of movement of the activity based on affinity...
1387 // Now that we are actually launching it, we can assign the base intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001388 reusedActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001389 }
1390
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001391 // This code path leads to delivering a new intent, we want to make sure we schedule it
1392 // as the first operation, in case the activity will be resumed as a result of later
1393 // operations.
1394 if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Daichi Hirono15a02992016-04-27 18:47:01 +09001395 || isDocumentLaunchesIntoExisting(mLaunchFlags)
Bryce Lee7daee392017-10-12 13:46:18 -07001396 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001397 final TaskRecord task = reusedActivity.getTaskRecord();
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001398
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001399 // In this situation we want to remove all activities from the task up to the one
1400 // being started. In most cases this means we are resetting the task to its initial
1401 // state.
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001402 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
1403 mLaunchFlags);
1404
Bryce Lee4a194382017-04-04 14:32:48 -07001405 // The above code can remove {@code reusedActivity} from the task, leading to the
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001406 // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
1407 // task reference is needed in the call below to
1408 // {@link setTargetStackAndMoveToFrontIfNeeded}.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001409 if (reusedActivity.getTaskRecord() == null) {
Bryce Lee4a194382017-04-04 14:32:48 -07001410 reusedActivity.setTask(task);
Bryce Leeaa5e8c32017-03-01 16:01:06 -08001411 }
1412
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001413 if (top != null) {
1414 if (top.frontOfTask) {
1415 // Activity aliases may mean we use different intents for the top activity,
1416 // so make sure the task now has the identity of the new intent.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001417 top.getTaskRecord().setIntent(mStartActivity);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001418 }
Bryce Lee325e09682017-10-05 17:20:25 -07001419 deliverNewIntent(top);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08001420 }
1421 }
1422
Wale Ogunwaled32da472018-11-16 07:19:28 -08001423 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
1424 (false /* forceSend */, reusedActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001425
Bryce Lee4a194382017-04-04 14:32:48 -07001426 reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001427
Bryce Lee89cd19a2017-05-17 15:18:35 -07001428 final ActivityRecord outResult =
1429 outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
1430
1431 // When there is a reused activity and the current result is a trampoline activity,
1432 // set the reused activity as the result.
1433 if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
1434 outActivity[0] = reusedActivity;
1435 }
1436
Wale Ogunwale01d66562015-12-29 08:19:19 -08001437 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1438 // We don't need to start a new activity, and the client said not to do anything
1439 // if that is the case, so this is it! And for paranoia, make sure we have
1440 // correctly resumed the top activity.
1441 resumeTargetStackIfNeeded();
1442 return START_RETURN_INTENT_TO_CALLER;
1443 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001444
Bryce Leef65ee7e2018-03-26 16:03:47 -07001445 if (reusedActivity != null) {
1446 setTaskFromIntentActivity(reusedActivity);
1447
1448 if (!mAddingToTask && mReuseTask == null) {
1449 // We didn't do anything... but it was needed (a.k.a., client don't use that
1450 // intent!) And for paranoia, make sure we have correctly resumed the top activity.
1451
1452 resumeTargetStackIfNeeded();
1453 if (outActivity != null && outActivity.length > 0) {
1454 outActivity[0] = reusedActivity;
1455 }
1456
1457 return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
Jorim Jaggicdfc04e2017-04-28 19:06:24 +02001458 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001459 }
1460 }
1461
1462 if (mStartActivity.packageName == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001463 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001464 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001465 if (sourceStack != null) {
1466 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1467 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1468 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001469 }
1470 ActivityOptions.abort(mOptions);
1471 return START_CLASS_NOT_FOUND;
1472 }
1473
1474 // If the activity being launched is the same as the one currently at the top, then
1475 // we need to check if it should only be launched once.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001476 final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001477 final ActivityRecord topFocused = topStack.getTopActivity();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001478 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1479 final boolean dontStart = top != null && mStartActivity.resultTo == null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001480 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
1481 && top.mUserId == mStartActivity.mUserId
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001482 && top.attachedToProcess()
Wale Ogunwale01d66562015-12-29 08:19:19 -08001483 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Louis Changbd48dca2018-08-29 17:44:34 +08001484 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
1485 // This allows home activity to automatically launch on secondary display when
1486 // display added, if home was the top activity on default display, instead of
1487 // sending new intent to the home activity on default display.
1488 && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001489 if (dontStart) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001490 // For paranoia, make sure we have correctly resumed the top activity.
1491 topStack.mLastPausedActivity = null;
1492 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001493 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001494 }
1495 ActivityOptions.abort(mOptions);
1496 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1497 // We don't need to start a new activity, and the client said not to do
1498 // anything if that is the case, so this is it!
1499 return START_RETURN_INTENT_TO_CALLER;
1500 }
Bryce Lee325e09682017-10-05 17:20:25 -07001501
1502 deliverNewIntent(top);
Chong Zhangd44063c2016-04-08 11:52:30 -07001503
1504 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1505 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001506 mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
Louis Chang39ba54b2018-10-18 11:28:57 +08001507 mPreferredDisplayId, topStack);
Chong Zhangd44063c2016-04-08 11:52:30 -07001508
Wale Ogunwale01d66562015-12-29 08:19:19 -08001509 return START_DELIVERED_TO_TOP;
1510 }
1511
1512 boolean newTask = false;
1513 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001514 ? mSourceRecord.getTaskRecord() : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001515
1516 // Should this be considered a new task?
Chong Zhang6cda19c2016-06-14 19:07:56 -07001517 int result = START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001518 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1519 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1520 newTask = true;
Louis Changceeb5062018-09-17 18:13:52 +08001521 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001522 } else if (mSourceRecord != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001523 result = setTaskFromSourceRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001524 } else if (mInTask != null) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07001525 result = setTaskFromInTask();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001526 } else {
1527 // This not being started from an existing activity, and not part of a new task...
1528 // just put it in the top task, though these days this case should never happen.
1529 setTaskToCurrentTopOrCreateNewTask();
1530 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07001531 if (result != START_SUCCESS) {
1532 return result;
1533 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001534
Wale Ogunwale6d50dcc2018-07-21 23:00:40 -07001535 mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001536 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001537 mService.getPackageManagerInternalLocked().grantEphemeralAccess(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001538 mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
Wale Ogunwale342fbe92018-10-09 08:44:10 -07001539 UserHandle.getAppId(mCallingUid));
Wale Ogunwale01d66562015-12-29 08:19:19 -08001540 if (newTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001541 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
1542 mStartActivity.getTaskRecord().taskId);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001543 }
1544 ActivityStack.logStartActivity(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001545 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001546 mTargetStack.mLastPausedActivity = null;
Wei Wang98f03f92016-05-18 11:32:52 -07001547
Wale Ogunwaled32da472018-11-16 07:19:28 -08001548 mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
1549 false /* forceSend */, mStartActivity);
Wei Wang98f03f92016-05-18 11:32:52 -07001550
Winson Chungb5c41b72016-12-07 15:00:47 -08001551 mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
1552 mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001553 if (mDoResume) {
Bryce Leeaf691c02017-03-20 14:20:22 -07001554 final ActivityRecord topTaskActivity =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001555 mStartActivity.getTaskRecord().topRunningActivityLocked();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001556 if (!mTargetStack.isFocusable()
Wale Ogunwale68741142016-05-17 09:40:02 -07001557 || (topTaskActivity != null && topTaskActivity.mTaskOverlay
1558 && mStartActivity != topTaskActivity)) {
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001559 // If the activity is not focusable, we can't resume it, but still would like to
1560 // make sure it becomes visible as it starts (this will also trigger entry
1561 // animation). An example of this are PIP activities.
Wale Ogunwale3b232392016-05-13 15:37:13 -07001562 // Also, we don't want to resume activities in a task that currently has an overlay
1563 // as the starting activity just needs to be in the visible paused state until the
1564 // over is removed.
Wale Ogunwale480dca02016-02-06 13:58:29 -08001565 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
Wale Ogunwaleae846f42016-02-22 14:00:56 -08001566 // Go ahead and tell window manager to execute app transition for this activity
1567 // since the app transition will not be triggered through the resume channel.
lumark588a3e82018-07-20 18:53:54 +08001568 mTargetStack.getDisplay().getWindowContainerController().executeAppTransition();
Wale Ogunwale3b232392016-05-13 15:37:13 -07001569 } else {
Winson Chung32066032016-11-04 11:55:21 -07001570 // If the target stack was not previously focusable (previous top running activity
1571 // on that stack was not visible) then any prior calls to move the stack to the
1572 // will not update the focused stack. If starting the new activity now allows the
1573 // task stack to be focusable, then ensure that we now update the focused stack
1574 // accordingly.
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001575 if (mTargetStack.isFocusable()
Wale Ogunwaled32da472018-11-16 07:19:28 -08001576 && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
Winson Chung32066032016-11-04 11:55:21 -07001577 mTargetStack.moveToFront("startActivityUnchecked");
1578 }
Wale Ogunwaled32da472018-11-16 07:19:28 -08001579 mRootActivityContainer.resumeFocusedStacksTopActivities(
1580 mTargetStack, mStartActivity, mOptions);
Filip Gruszczynski3d7fdc12016-01-31 17:33:29 -08001581 }
Winson Chung1dbc8112017-09-28 18:05:31 -07001582 } else if (mStartActivity != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001583 mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001584 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001585 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001586
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001587 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
1588 preferredWindowingMode, mPreferredDisplayId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001589
1590 return START_SUCCESS;
1591 }
1592
Bryce Leedaa91e42017-12-06 14:13:01 -08001593 /**
1594 * Resets the {@link ActivityStarter} state.
1595 * @param clearRequest whether the request should be reset to default values.
1596 */
1597 void reset(boolean clearRequest) {
1598 mStartActivity = null;
1599 mIntent = null;
1600 mCallingUid = -1;
1601 mOptions = null;
1602
1603 mLaunchTaskBehind = false;
1604 mLaunchFlags = 0;
1605 mLaunchMode = INVALID_LAUNCH_MODE;
1606
Bryce Leeec55eb02017-12-05 20:51:27 -08001607 mLaunchParams.reset();
Bryce Leedaa91e42017-12-06 14:13:01 -08001608
1609 mNotTop = null;
1610 mDoResume = false;
1611 mStartFlags = 0;
1612 mSourceRecord = null;
1613 mPreferredDisplayId = INVALID_DISPLAY;
1614
1615 mInTask = null;
1616 mAddingToTask = false;
1617 mReuseTask = null;
1618
1619 mNewTaskInfo = null;
1620 mNewTaskIntent = null;
1621 mSourceStack = null;
1622
1623 mTargetStack = null;
1624 mMovedToFront = false;
1625 mNoAnimation = false;
1626 mKeepCurTransition = false;
1627 mAvoidMoveToFront = false;
1628
1629 mVoiceSession = null;
1630 mVoiceInteractor = null;
1631
1632 mIntentDelivered = false;
1633
1634 if (clearRequest) {
1635 mRequest.reset();
1636 }
1637 }
1638
Wale Ogunwale01d66562015-12-29 08:19:19 -08001639 private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
1640 boolean doResume, int startFlags, ActivityRecord sourceRecord,
1641 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
Bryce Leedaa91e42017-12-06 14:13:01 -08001642 reset(false /* clearRequest */);
1643
Wale Ogunwale01d66562015-12-29 08:19:19 -08001644 mStartActivity = r;
1645 mIntent = r.intent;
1646 mOptions = options;
1647 mCallingUid = r.launchedFromUid;
1648 mSourceRecord = sourceRecord;
1649 mVoiceSession = voiceSession;
1650 mVoiceInteractor = voiceInteractor;
1651
Bryce Leeec55eb02017-12-05 20:51:27 -08001652 mLaunchParams.reset();
Bryce Leedacefc42017-10-10 12:56:02 -07001653
Garfield Tan706dbcb2018-10-15 11:33:02 -07001654 mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
1655 sourceRecord, options, mLaunchParams);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001656
Garfield Tanb5cc09f2018-09-28 10:06:52 -07001657 if (mLaunchParams.hasPreferredDisplay()) {
1658 mPreferredDisplayId = mLaunchParams.mPreferredDisplayId;
1659 } else {
1660 mPreferredDisplayId = DEFAULT_DISPLAY;
1661 }
Garfield Tanb5cc09f2018-09-28 10:06:52 -07001662
Bryce Lee7daee392017-10-12 13:46:18 -07001663 mLaunchMode = r.launchMode;
1664
Wale Ogunwale01d66562015-12-29 08:19:19 -08001665 mLaunchFlags = adjustLaunchFlagsToDocumentMode(
Bryce Lee7daee392017-10-12 13:46:18 -07001666 r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
1667 LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001668 mLaunchTaskBehind = r.mLaunchTaskBehind
Bryce Lee7daee392017-10-12 13:46:18 -07001669 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
Wale Ogunwale01d66562015-12-29 08:19:19 -08001670 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1671
1672 sendNewTaskResultRequestIfNeeded();
1673
1674 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1675 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1676 }
1677
1678 // If we are actually going to launch in to a new task, there are some cases where
1679 // we further want to do multiple task.
1680 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1681 if (mLaunchTaskBehind
1682 || r.info.documentLaunchMode == DOCUMENT_LAUNCH_ALWAYS) {
1683 mLaunchFlags |= FLAG_ACTIVITY_MULTIPLE_TASK;
1684 }
1685 }
1686
1687 // We'll invoke onUserLeaving before onPause only if the launching
1688 // activity did not explicitly state that this is an automated launch.
1689 mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1690 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1691 "startActivity() => mUserLeaving=" + mSupervisor.mUserLeaving);
1692
1693 // If the caller has asked not to resume at this point, we make note
1694 // of this in the record so that we can skip it when trying to find
1695 // the top running activity.
1696 mDoResume = doResume;
Chong Zhang87761972016-08-22 13:53:24 -07001697 if (!doResume || !r.okToShowLocked()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001698 r.delayedResume = true;
1699 mDoResume = false;
1700 }
1701
Winson Chunge2d72172018-01-25 17:46:20 +00001702 if (mOptions != null) {
1703 if (mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) {
1704 r.mTaskOverlay = true;
1705 if (!mOptions.canTaskOverlayResume()) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001706 final TaskRecord task = mRootActivityContainer.anyTaskForId(
Winson Chunge2d72172018-01-25 17:46:20 +00001707 mOptions.getLaunchTaskId());
1708 final ActivityRecord top = task != null ? task.getTopActivity() : null;
Bryce Lee7ace3952018-02-16 14:34:32 -08001709 if (top != null && !top.isState(RESUMED)) {
Jorim Jaggic875ae72016-04-26 22:41:06 -07001710
Winson Chunge2d72172018-01-25 17:46:20 +00001711 // The caller specifies that we'd like to be avoided to be moved to the
1712 // front, so be it!
1713 mDoResume = false;
1714 mAvoidMoveToFront = true;
1715 }
Winson Chungcbcadc92017-01-12 15:54:12 -08001716 }
Winson Chunge2d72172018-01-25 17:46:20 +00001717 } else if (mOptions.getAvoidMoveToFront()) {
Winson Chungba40d3a2018-05-16 09:40:16 -07001718 mDoResume = false;
Winson Chunge2d72172018-01-25 17:46:20 +00001719 mAvoidMoveToFront = true;
Jorim Jaggic875ae72016-04-26 22:41:06 -07001720 }
1721 }
1722
Wale Ogunwale01d66562015-12-29 08:19:19 -08001723 mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1724
1725 mInTask = inTask;
1726 // In some flows in to this function, we retrieve the task record and hold on to it
1727 // without a lock before calling back in to here... so the task at this point may
1728 // not actually be in recents. Check for that, and if it isn't in recents just
1729 // consider it invalid.
1730 if (inTask != null && !inTask.inRecents) {
1731 Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1732 mInTask = null;
1733 }
1734
1735 mStartFlags = startFlags;
1736 // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
1737 // is the same as the one making the call... or, as a special case, if we do not know
1738 // the caller then we count the current top activity as the caller.
1739 if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1740 ActivityRecord checkedCaller = sourceRecord;
1741 if (checkedCaller == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001742 checkedCaller = mRootActivityContainer.getTopDisplayFocusedStack()
Andrii Kulian5f750bc2018-07-17 08:57:23 -07001743 .topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001744 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001745 if (!checkedCaller.mActivityComponent.equals(r.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001746 // Caller is not the same as launcher, so always needed.
1747 mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;
1748 }
1749 }
1750
1751 mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
1752 }
1753
1754 private void sendNewTaskResultRequestIfNeeded() {
Andrii Kulian02b7a832016-10-06 23:11:56 -07001755 final ActivityStack sourceStack = mStartActivity.resultTo != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001756 ? mStartActivity.resultTo.getActivityStack() : null;
Andrii Kulian02b7a832016-10-06 23:11:56 -07001757 if (sourceStack != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001758 // For whatever reason this activity is being launched into a new task...
1759 // yet the caller has requested a result back. Well, that is pretty messed up,
1760 // so instead immediately send back a cancel and let the new task continue launched
1761 // as normal without a dependency on its originator.
1762 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
Andrii Kulian02b7a832016-10-06 23:11:56 -07001763 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1764 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1765 null /* data */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001766 mStartActivity.resultTo = null;
1767 }
1768 }
1769
1770 private void computeLaunchingTaskFlags() {
1771 // If the caller is not coming from another activity, but has given us an explicit task into
1772 // which they would like us to launch the new activity, then let's see about doing that.
Andrii Kulian02b7a832016-10-06 23:11:56 -07001773 if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001774 final Intent baseIntent = mInTask.getBaseIntent();
1775 final ActivityRecord root = mInTask.getRootActivity();
1776 if (baseIntent == null) {
1777 ActivityOptions.abort(mOptions);
1778 throw new IllegalArgumentException("Launching into task without base intent: "
1779 + mInTask);
1780 }
1781
1782 // If this task is empty, then we are adding the first activity -- it
1783 // determines the root, and must be launching as a NEW_TASK.
Bryce Lee7daee392017-10-12 13:46:18 -07001784 if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001785 if (!baseIntent.getComponent().equals(mStartActivity.intent.getComponent())) {
1786 ActivityOptions.abort(mOptions);
1787 throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1788 + mStartActivity + " into different task " + mInTask);
1789 }
1790 if (root != null) {
1791 ActivityOptions.abort(mOptions);
1792 throw new IllegalArgumentException("Caller with mInTask " + mInTask
1793 + " has root " + root + " but target is singleInstance/Task");
1794 }
1795 }
1796
1797 // If task is empty, then adopt the interesting intent launch flags in to the
1798 // activity being started.
1799 if (root == null) {
1800 final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
1801 | FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1802 mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
1803 | (baseIntent.getFlags() & flagsOfInterest);
1804 mIntent.setFlags(mLaunchFlags);
1805 mInTask.setIntent(mStartActivity);
1806 mAddingToTask = true;
1807
1808 // If the task is not empty and the caller is asking to start it as the root of
1809 // a new task, then we don't actually want to start this on the task. We will
1810 // bring the task to the front, and possibly give it a new intent.
1811 } else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1812 mAddingToTask = false;
1813
1814 } else {
1815 mAddingToTask = true;
1816 }
1817
1818 mReuseTask = mInTask;
1819 } else {
1820 mInTask = null;
1821 // Launch ResolverActivity in the source task, so that it stays in the task bounds
1822 // when in freeform workspace.
1823 // Also put noDisplay activities in the source task. These by itself can be placed
1824 // in any task/stack, however it could launch other activities like ResolverActivity,
1825 // and we want those to stay in the original task.
1826 if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001827 && mSourceRecord.inFreeformWindowingMode()) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001828 mAddingToTask = true;
1829 }
1830 }
1831
1832 if (mInTask == null) {
1833 if (mSourceRecord == null) {
1834 // This activity is not being started from another... in this
1835 // case we -always- start a new task.
1836 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
1837 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1838 "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1839 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1840 }
1841 } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
1842 // The original activity who is starting us is running as a single
1843 // instance... this new activity it is starting must go on its
1844 // own task.
1845 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
Bryce Lee7daee392017-10-12 13:46:18 -07001846 } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001847 // The activity being started is a single instance... it always
1848 // gets launched into its own task.
1849 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1850 }
1851 }
1852 }
1853
1854 private void computeSourceStack() {
1855 if (mSourceRecord == null) {
1856 mSourceStack = null;
1857 return;
1858 }
1859 if (!mSourceRecord.finishing) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001860 mSourceStack = mSourceRecord.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001861 return;
1862 }
1863
1864 // If the source is finishing, we can't further count it as our source. This is because the
1865 // task it is associated with may now be empty and on its way out, so we don't want to
1866 // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
1867 // a task for it. But save the task information so it can be used when creating the new task.
1868 if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
1869 Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
1870 + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
1871 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
1872 mNewTaskInfo = mSourceRecord.info;
Bryce Leed9ed45d2017-05-22 15:57:24 -07001873
1874 // It is not guaranteed that the source record will have a task associated with it. For,
1875 // example, if this method is being called for processing a pending activity launch, it
1876 // is possible that the activity has been removed from the task after the launch was
1877 // enqueued.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001878 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
Bryce Leed9ed45d2017-05-22 15:57:24 -07001879 mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
Wale Ogunwale01d66562015-12-29 08:19:19 -08001880 }
1881 mSourceRecord = null;
1882 mSourceStack = null;
1883 }
1884
1885 /**
1886 * Decide whether the new activity should be inserted into an existing task. Returns null
1887 * if not or an ActivityRecord with the task into which the new activity should be added.
1888 */
1889 private ActivityRecord getReusableIntentActivity() {
1890 // We may want to try to place the new activity in to an existing task. We always
1891 // do this if the target activity is singleTask or singleInstance; we will also do
1892 // this if NEW_TASK has been requested, and there is not an additional qualifier telling
1893 // us to still place it in a new task: multi task, always doc mode, or being asked to
1894 // launch this as a new task behind the current one.
1895 boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
1896 (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
Bryce Lee7daee392017-10-12 13:46:18 -07001897 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
Wale Ogunwale01d66562015-12-29 08:19:19 -08001898 // If bring to front is requested, and no result is requested and we have not been given
1899 // an explicit task to launch in to, and we can find a task that was started with this
1900 // same component, then instead of launching bring that one to the front.
1901 putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
1902 ActivityRecord intentActivity = null;
Jorim Jaggi2adba072016-03-03 13:43:39 +01001903 if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08001904 final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
Jorim Jaggi2adba072016-03-03 13:43:39 +01001905 intentActivity = task != null ? task.getTopActivity() : null;
1906 } else if (putIntoExistingTask) {
Bryce Lee7daee392017-10-12 13:46:18 -07001907 if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001908 // There can be one and only one instance of single instance activity in the
1909 // history, and it is always in its own unique task, so we do a special search.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001910 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001911 mStartActivity.isActivityTypeHome());
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001912 } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1913 // For the launch adjacent case we only want to put the activity in an existing
1914 // task if the activity already exists in the history.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001915 intentActivity = mRootActivityContainer.findActivity(mIntent, mStartActivity.info,
Bryce Lee7daee392017-10-12 13:46:18 -07001916 !(LAUNCH_SINGLE_TASK == mLaunchMode));
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001917 } else {
1918 // Otherwise find the best task to put the activity in.
Wale Ogunwaled32da472018-11-16 07:19:28 -08001919 intentActivity =
1920 mRootActivityContainer.findTask(mStartActivity, mPreferredDisplayId);
Wale Ogunwale13dbfff2016-05-20 08:50:15 -07001921 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001922 }
Louis Changbd48dca2018-08-29 17:44:34 +08001923
Louis Chang54506cb2018-11-23 11:03:41 +08001924 if (intentActivity != null
1925 && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
Louis Changbd48dca2018-08-29 17:44:34 +08001926 && intentActivity.getDisplayId() != mPreferredDisplayId) {
1927 // Do not reuse home activity on other displays.
1928 intentActivity = null;
1929 }
1930
Wale Ogunwale01d66562015-12-29 08:19:19 -08001931 return intentActivity;
1932 }
1933
Andrii Kulianfab9cd82017-03-21 19:37:09 -07001934 /**
1935 * Figure out which task and activity to bring to front when we have found an existing matching
1936 * activity record in history. May also clear the task if needed.
1937 * @param intentActivity Existing matching activity.
1938 * @return {@link ActivityRecord} brought to front.
1939 */
Wale Ogunwale01d66562015-12-29 08:19:19 -08001940 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001941 mTargetStack = intentActivity.getActivityStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08001942 mTargetStack.mLastPausedActivity = null;
1943 // If the target task is not in the front, then we need to bring it to the front...
1944 // except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
1945 // the same behavior as if a new instance was being started, which means not bringing it
1946 // to the front if the caller is not itself in the front.
Riddle Hsub70b36d2018-09-11 21:20:02 +08001947 final boolean differentTopTask;
1948 if (mPreferredDisplayId == mTargetStack.mDisplayId) {
1949 final ActivityStack focusStack = mTargetStack.getDisplay().getFocusedStack();
1950 final ActivityRecord curTop = (focusStack == null)
1951 ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001952 final TaskRecord topTask = curTop != null ? curTop.getTaskRecord() : null;
Riddle Hsub70b36d2018-09-11 21:20:02 +08001953 differentTopTask = topTask != null
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001954 && (topTask != intentActivity.getTaskRecord() || topTask != focusStack.topTask());
Riddle Hsub70b36d2018-09-11 21:20:02 +08001955 } else {
1956 // The existing task should always be different from those in other displays.
1957 differentTopTask = true;
1958 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08001959
Riddle Hsub70b36d2018-09-11 21:20:02 +08001960 if (differentTopTask && !mAvoidMoveToFront) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001961 mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
Wale Ogunwale30e441d2017-11-09 08:28:45 -08001962 if (mSourceRecord == null || (mSourceStack.getTopActivity() != null &&
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001963 mSourceStack.getTopActivity().getTaskRecord()
1964 == mSourceRecord.getTaskRecord())) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08001965 // We really do want to push this one into the user's face, right now.
1966 if (mLaunchTaskBehind && mSourceRecord != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001967 intentActivity.setTaskToAffiliateWith(mSourceRecord.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08001968 }
Chong Zhangdea4bd92016-03-15 12:50:03 -07001969
1970 // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
1971 // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
1972 // So no point resuming any of the activities here, it just wastes one extra
1973 // resuming, plus enter AND exit transitions.
1974 // Here we only want to bring the target stack forward. Transition will be applied
1975 // to the new activity that's started after the old ones are gone.
1976 final boolean willClearTask =
1977 (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
1978 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
1979 if (!willClearTask) {
1980 final ActivityStack launchStack = getLaunchStack(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001981 mStartActivity, mLaunchFlags, mStartActivity.getTaskRecord(), mOptions);
1982 final TaskRecord intentTask = intentActivity.getTaskRecord();
Chong Zhangdea4bd92016-03-15 12:50:03 -07001983 if (launchStack == null || launchStack == mTargetStack) {
1984 // We only want to move to the front, if we aren't going to launch on a
1985 // different stack. If we launch on a different stack, we will put the
1986 // task on top there.
chaviw0d562bf2018-03-15 14:24:14 -07001987 mTargetStack.moveTaskToFrontLocked(intentTask, mNoAnimation, mOptions,
1988 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
Chong Zhangdea4bd92016-03-15 12:50:03 -07001989 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001990 } else if (launchStack.inSplitScreenWindowingMode()) {
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001991 if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
1992 // If we want to launch adjacent and mTargetStack is not the computed
1993 // launch stack - move task to top of computed stack.
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07001994 intentTask.reparent(launchStack, ON_TOP,
Winson Chung74666102017-02-22 17:49:24 -08001995 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
1996 "launchToSide");
Andrii Kulianad6f2e52016-06-15 15:27:01 -07001997 } else {
1998 // TODO: This should be reevaluated in MW v2.
1999 // We choose to move task to front instead of launching it adjacent
2000 // when specific stack was requested explicitly and it appeared to be
2001 // adjacent stack, but FLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
chaviw0d562bf2018-03-15 14:24:14 -07002002 mTargetStack.moveTaskToFrontLocked(intentTask,
Bryce Leeaf691c02017-03-20 14:20:22 -07002003 mNoAnimation, mOptions, mStartActivity.appTimeTracker,
Andrii Kulianad6f2e52016-06-15 15:27:01 -07002004 "bringToFrontInsteadOfAdjacentLaunch");
2005 }
Bryce Lee32e09ef2018-03-19 15:29:49 -07002006 mMovedToFront = launchStack != launchStack.getDisplay()
2007 .getTopStackInWindowingMode(launchStack.getWindowingMode());
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002008 } else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
2009 // Target and computed stacks are on different displays and we've
2010 // found a matching task - move the existing instance to that display and
2011 // move it to front.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002012 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Andrii Kulianfab9cd82017-03-21 19:37:09 -07002013 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2014 "reparentToDisplay");
2015 mMovedToFront = true;
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002016 } else if (launchStack.isActivityTypeHome()
2017 && !mTargetStack.isActivityTypeHome()) {
Bryce Lee4ff7da92017-07-17 10:39:24 -07002018 // It is possible for the home activity to be in another stack initially.
2019 // For example, the activity may have been initially started with an intent
2020 // which placed it in the fullscreen stack. To ensure the proper handling of
2021 // the activity based on home stack assumptions, we must move it over.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002022 intentActivity.getTaskRecord().reparent(launchStack, ON_TOP,
Bryce Lee4ff7da92017-07-17 10:39:24 -07002023 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
2024 "reparentingHome");
2025 mMovedToFront = true;
Chong Zhangdea4bd92016-03-15 12:50:03 -07002026 }
2027 mOptions = null;
Jorim Jaggi02886a82016-12-06 09:10:06 -08002028
2029 // We are moving a task to the front, use starting window to hide initial drawn
2030 // delay.
2031 intentActivity.showStartingWindow(null /* prev */, false /* newTask */,
2032 true /* taskSwitch */);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002033 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002034 }
2035 }
Andrii Kulianb850ea52017-12-12 23:49:10 -08002036 // Need to update mTargetStack because if task was moved out of it, the original stack may
2037 // be destroyed.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002038 mTargetStack = intentActivity.getActivityStack();
Winson Chungba40d3a2018-05-16 09:40:16 -07002039 if (!mMovedToFront && mDoResume) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002040 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
2041 + " from " + intentActivity);
2042 mTargetStack.moveToFront("intentActivityFound");
2043 }
2044
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002045 mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTaskRecord(),
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002046 WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, mTargetStack);
Jorim Jaggid53f0922016-04-06 22:16:23 -07002047
Wale Ogunwale01d66562015-12-29 08:19:19 -08002048 // If the caller has requested that the target task be reset, then do so.
2049 if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2050 return mTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
2051 }
2052 return intentActivity;
2053 }
2054
2055 private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
2056 if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2057 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2058 // The caller has requested to completely replace any existing task with its new
2059 // activity. Well that should not be too hard...
Bryce Lee41801b42017-03-02 13:23:12 -08002060 // Note: we must persist the {@link TaskRecord} first as intentActivity could be
2061 // removed from calling performClearTaskLocked (For example, if it is being brought out
Bryce Lee59dad4e2017-03-09 11:54:08 -08002062 // of history or if it is finished immediately), thus disassociating the task. Also note
2063 // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
2064 // launching another activity.
2065 // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
2066 // already launching one.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002067 final TaskRecord task = intentActivity.getTaskRecord();
Bryce Lee59dad4e2017-03-09 11:54:08 -08002068 task.performClearTaskLocked();
2069 mReuseTask = task;
Bryce Lee41801b42017-03-02 13:23:12 -08002070 mReuseTask.setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002071 } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002072 || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002073 final ActivityRecord top = intentActivity.getTaskRecord().performClearTaskLocked(
2074 mStartActivity, mLaunchFlags);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002075 if (top == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002076 // A special case: we need to start the activity because it is not currently
2077 // running, and the caller has asked to clear the current task to have this
2078 // activity at the top.
2079 mAddingToTask = true;
Bryce Lee353112c2017-02-23 09:46:45 -08002080
2081 // We are no longer placing the activity in the task we previously thought we were.
Bryce Leeaf691c02017-03-20 14:20:22 -07002082 mStartActivity.setTask(null);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002083 // Now pretend like this activity is being started by the top of its task, so it
2084 // is put in the right place.
2085 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002086 final TaskRecord task = mSourceRecord.getTaskRecord();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002087 if (task != null && task.getStack() == null) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002088 // Target stack got cleared when we all activities were removed above.
2089 // Go ahead and reset it.
2090 mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
Bryce Leedacefc42017-10-10 12:56:02 -07002091 mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002092 mTargetStack.addTask(task,
2093 !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
2094 }
2095 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002096 } else if (mStartActivity.mActivityComponent.equals(
2097 intentActivity.getTaskRecord().realActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002098 // In this case the top activity on the task is the same as the one being launched,
2099 // so we take that as a request to bring the task to the foreground. If the top
2100 // activity in the task is the root activity, deliver this new intent to it if it
2101 // desires.
Bryce Lee7daee392017-10-12 13:46:18 -07002102 if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
2103 || LAUNCH_SINGLE_TOP == mLaunchMode)
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002104 && intentActivity.mActivityComponent.equals(
2105 mStartActivity.mActivityComponent)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002106 if (intentActivity.frontOfTask) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002107 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002108 }
Bryce Lee325e09682017-10-05 17:20:25 -07002109 deliverNewIntent(intentActivity);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002110 } else if (!intentActivity.getTaskRecord().isSameIntentFilter(mStartActivity)) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002111 // In this case we are launching the root activity of the task, but with a
2112 // different intent. We should start a new instance on top.
2113 mAddingToTask = true;
2114 mSourceRecord = intentActivity;
2115 }
2116 } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2117 // In this case an activity is being launched in to an existing task, without
2118 // resetting that task. This is typically the situation of launching an activity
2119 // from a notification or shortcut. We want to place the new activity on top of the
2120 // current task.
2121 mAddingToTask = true;
2122 mSourceRecord = intentActivity;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002123 } else if (!intentActivity.getTaskRecord().rootWasReset) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002124 // In this case we are launching into an existing task that has not yet been started
2125 // from its front door. The current task has been brought to the front. Ideally,
2126 // we'd probably like to place this new task at the bottom of its stack, but that's
2127 // a little hard to do with the current organization of the code so for now we'll
2128 // just drop it.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002129 intentActivity.getTaskRecord().setIntent(mStartActivity);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002130 }
2131 }
2132
2133 private void resumeTargetStackIfNeeded() {
2134 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002135 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002136 } else {
2137 ActivityOptions.abort(mOptions);
2138 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002139 mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002140 }
2141
Louis Changceeb5062018-09-17 18:13:52 +08002142 private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
Bryce Leedacefc42017-10-10 12:56:02 -07002143 mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
Chong Zhang6cda19c2016-06-14 19:07:56 -07002144
2145 // Do no move the target stack to front yet, as we might bail if
2146 // isLockTaskModeViolation fails below.
Wale Ogunwale01d66562015-12-29 08:19:19 -08002147
2148 if (mReuseTask == null) {
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002149 final TaskRecord task = mTargetStack.createTaskRecord(
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002150 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
Wale Ogunwale01d66562015-12-29 08:19:19 -08002151 mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
Wale Ogunwale72919d22016-12-08 18:58:50 -08002152 mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
Bryce Leeb802ea12017-11-15 21:25:03 -08002153 mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
2154 mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002155 addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002156 updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002157
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002158 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002159 + " in new task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002160 } else {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002161 addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
2162 }
2163
2164 if (taskToAffiliate != null) {
2165 mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002166 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002167
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002168 if (mService.getLockTaskController().isLockTaskModeViolation(
2169 mStartActivity.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002170 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2171 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2172 }
2173
Chong Zhang6cda19c2016-06-14 19:07:56 -07002174 if (mDoResume) {
2175 mTargetStack.moveToFront("reuseOrNewTask");
2176 }
2177 return START_SUCCESS;
Wale Ogunwale01d66562015-12-29 08:19:19 -08002178 }
2179
Bryce Lee325e09682017-10-05 17:20:25 -07002180 private void deliverNewIntent(ActivityRecord activity) {
2181 if (mIntentDelivered) {
2182 return;
2183 }
2184
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002185 ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002186 activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
2187 mStartActivity.launchedFromPackage);
2188 mIntentDelivered = true;
2189 }
2190
Wale Ogunwale01d66562015-12-29 08:19:19 -08002191 private int setTaskFromSourceRecord() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002192 if (mService.getLockTaskController().isLockTaskModeViolation(
2193 mSourceRecord.getTaskRecord())) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002194 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2195 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2196 }
2197
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002198 final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
2199 final ActivityStack sourceStack = mSourceRecord.getActivityStack();
Andrii Kulian02689a72017-07-06 14:28:59 -07002200 // We only want to allow changing stack in two cases:
2201 // 1. If the target task is not the top one. Otherwise we would move the launching task to
2202 // the other side, rather than show two side by side.
2203 // 2. If activity is not allowed on target display.
2204 final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
2205 : sourceStack.mDisplayId;
2206 final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
2207 || !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002208 if (moveStackAllowed) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002209 mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags,
2210 mStartActivity.getTaskRecord(), mOptions);
Andrii Kulian02689a72017-07-06 14:28:59 -07002211 // If target stack is not found now - we can't just rely on the source stack, as it may
2212 // be not suitable. Let's check other displays.
2213 if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
2214 // Can't use target display, lets find a stack on the source display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002215 mTargetStack = mRootActivityContainer.getValidLaunchStackOnDisplay(
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002216 sourceStack.mDisplayId, mStartActivity, mOptions, mLaunchParams);
Andrii Kulian02689a72017-07-06 14:28:59 -07002217 }
2218 if (mTargetStack == null) {
2219 // There are no suitable stacks on the target and source display(s). Look on all
2220 // displays.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002221 mTargetStack = mRootActivityContainer.getNextValidLaunchStack(
Andrii Kulian02689a72017-07-06 14:28:59 -07002222 mStartActivity, -1 /* currentFocus */);
2223 }
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002224 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002225
2226 if (mTargetStack == null) {
Andrii Kulian02b7a832016-10-06 23:11:56 -07002227 mTargetStack = sourceStack;
2228 } else if (mTargetStack != sourceStack) {
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002229 sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
2230 DEFER_RESUME, "launchToSide");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002231 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002232
Wale Ogunwale01d66562015-12-29 08:19:19 -08002233 final TaskRecord topTask = mTargetStack.topTask();
Jorim Jaggic875ae72016-04-26 22:41:06 -07002234 if (topTask != sourceTask && !mAvoidMoveToFront) {
chaviw0d562bf2018-03-15 14:24:14 -07002235 mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
Wale Ogunwale01d66562015-12-29 08:19:19 -08002236 mStartActivity.appTimeTracker, "sourceTaskToFront");
Chong Zhang6cda19c2016-06-14 19:07:56 -07002237 } else if (mDoResume) {
2238 mTargetStack.moveToFront("sourceStackToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002239 }
Chong Zhang6cda19c2016-06-14 19:07:56 -07002240
Wale Ogunwale01d66562015-12-29 08:19:19 -08002241 if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2242 // In this case, we are adding the activity to an existing task, but the caller has
2243 // asked to clear that task if the activity is already running.
2244 ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
2245 mKeepCurTransition = true;
2246 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002247 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTaskRecord());
Bryce Lee325e09682017-10-05 17:20:25 -07002248 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002249 // For paranoia, make sure we have correctly resumed the top activity.
2250 mTargetStack.mLastPausedActivity = null;
2251 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002252 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002253 }
2254 ActivityOptions.abort(mOptions);
2255 return START_DELIVERED_TO_TOP;
2256 }
2257 } else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2258 // In this case, we are launching an activity in our own task that may already be
2259 // running somewhere in the history, and we want to shuffle it to the front of the
2260 // stack if so.
2261 final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
2262 if (top != null) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002263 final TaskRecord task = top.getTaskRecord();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002264 task.moveActivityToFrontLocked(top);
2265 top.updateOptionsLocked(mOptions);
Filip Gruszczynskie826f322016-01-11 17:15:22 -08002266 ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
Bryce Lee325e09682017-10-05 17:20:25 -07002267 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002268 mTargetStack.mLastPausedActivity = null;
2269 if (mDoResume) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002270 mRootActivityContainer.resumeFocusedStacksTopActivities();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002271 }
2272 return START_DELIVERED_TO_TOP;
2273 }
2274 }
2275
2276 // An existing activity is starting this new activity, so we want to keep the new one in
2277 // the same task as the one that is starting it.
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002278 addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002279 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002280 + " in existing task " + mStartActivity.getTaskRecord()
2281 + " from source " + mSourceRecord);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002282 return START_SUCCESS;
2283 }
2284
2285 private int setTaskFromInTask() {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002286 // The caller is asking that the new activity be started in an explicit
2287 // task it has provided to us.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002288 if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Chong Zhang6cda19c2016-06-14 19:07:56 -07002289 Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
2290 return START_RETURN_LOCK_TASK_MODE_VIOLATION;
2291 }
2292
Andrii Kulian02b7a832016-10-06 23:11:56 -07002293 mTargetStack = mInTask.getStack();
Wale Ogunwale01d66562015-12-29 08:19:19 -08002294
2295 // Check whether we should actually launch the new activity in to the task,
2296 // or just reuse the current activity on top.
2297 ActivityRecord top = mInTask.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002298 if (top != null && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
2299 && top.mUserId == mStartActivity.mUserId) {
Wale Ogunwale01d66562015-12-29 08:19:19 -08002300 if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
Bryce Lee7daee392017-10-12 13:46:18 -07002301 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
chaviw0d562bf2018-03-15 14:24:14 -07002302 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002303 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002304 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
2305 // We don't need to start a new activity, and the client said not to do
2306 // anything if that is the case, so this is it!
2307 return START_RETURN_INTENT_TO_CALLER;
2308 }
Bryce Lee325e09682017-10-05 17:20:25 -07002309 deliverNewIntent(top);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002310 return START_DELIVERED_TO_TOP;
2311 }
2312 }
2313
2314 if (!mAddingToTask) {
chaviw0d562bf2018-03-15 14:24:14 -07002315 mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
Yorke Lee64512522017-03-24 13:09:35 -07002316 mStartActivity.appTimeTracker, "inTaskToFront");
Wale Ogunwale01d66562015-12-29 08:19:19 -08002317 // We don't actually want to have this activity added to the task, so just
2318 // stop here but still tell the caller that we consumed the intent.
2319 ActivityOptions.abort(mOptions);
2320 return START_TASK_TO_FRONT;
2321 }
2322
Bryce Leeec55eb02017-12-05 20:51:27 -08002323 if (!mLaunchParams.mBounds.isEmpty()) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002324 // TODO: Shouldn't we already know what stack to use by the time we get here?
Wale Ogunwaled32da472018-11-16 07:19:28 -08002325 ActivityStack stack = mRootActivityContainer.getLaunchStack(
2326 null, null, mInTask, ON_TOP);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002327 if (stack != mInTask.getStack()) {
2328 mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
Yorke Lee64512522017-03-24 13:09:35 -07002329 DEFER_RESUME, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002330 mTargetStack = mInTask.getStack();
2331 }
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002332
Bryce Leeec55eb02017-12-05 20:51:27 -08002333 updateBounds(mInTask, mLaunchParams.mBounds);
Yorke Lee64512522017-03-24 13:09:35 -07002334 }
2335
chaviw0d562bf2018-03-15 14:24:14 -07002336 mTargetStack.moveTaskToFrontLocked(
2337 mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
Yorke Lee64512522017-03-24 13:09:35 -07002338
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002339 addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
2340 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002341 + " in explicit task " + mStartActivity.getTaskRecord());
Wale Ogunwale01d66562015-12-29 08:19:19 -08002342
2343 return START_SUCCESS;
2344 }
2345
Bryce Leed3624e12017-11-30 08:51:45 -08002346 @VisibleForTesting
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002347 void updateBounds(TaskRecord task, Rect bounds) {
Bryce Leedacefc42017-10-10 12:56:02 -07002348 if (bounds.isEmpty()) {
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002349 return;
2350 }
2351
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002352 final ActivityStack stack = task.getStack();
2353 if (stack != null && stack.resizeStackWithLaunchBounds()) {
Wale Ogunwalec9e57de2018-05-08 14:28:07 -07002354 mService.resizeStack(
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002355 stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
Bryce Lee4e4a3ec2017-09-27 08:25:03 -07002356 } else {
2357 task.updateOverrideConfiguration(bounds);
2358 }
2359 }
2360
Wale Ogunwale01d66562015-12-29 08:19:19 -08002361 private void setTaskToCurrentTopOrCreateNewTask() {
Bryce Leedacefc42017-10-10 12:56:02 -07002362 mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions);
Wale Ogunwale01d66562015-12-29 08:19:19 -08002363 if (mDoResume) {
2364 mTargetStack.moveToFront("addingToTopTask");
2365 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -08002366 final ActivityRecord prev = mTargetStack.getTopActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002367 final TaskRecord task = (prev != null)
2368 ? prev.getTaskRecord() : mTargetStack.createTaskRecord(
2369 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info,
Bryce Leeb802ea12017-11-15 21:25:03 -08002370 mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002371 addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
2372 mTargetStack.positionChildWindowContainerAtTop(task);
2373 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002374 + " in new guessed " + mStartActivity.getTaskRecord());
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002375 }
2376
2377 private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002378 if (mStartActivity.getTaskRecord() == null || mStartActivity.getTaskRecord() == parent) {
Wale Ogunwalea0cd15e2017-02-01 15:33:08 -08002379 parent.addActivityToTop(mStartActivity);
2380 } else {
2381 mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
2382 }
Wale Ogunwale01d66562015-12-29 08:19:19 -08002383 }
2384
2385 private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
2386 boolean launchSingleTask, int launchFlags) {
2387 if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2388 (launchSingleInstance || launchSingleTask)) {
2389 // We have a conflict between the Intent and the Activity manifest, manifest wins.
2390 Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
2391 "\"singleInstance\" or \"singleTask\"");
2392 launchFlags &=
2393 ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
2394 } else {
2395 switch (r.info.documentLaunchMode) {
2396 case ActivityInfo.DOCUMENT_LAUNCH_NONE:
2397 break;
2398 case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
2399 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2400 break;
2401 case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
2402 launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
2403 break;
2404 case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
2405 launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
2406 break;
2407 }
2408 }
2409 return launchFlags;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002410 }
2411
Bryce Leedacefc42017-10-10 12:56:02 -07002412 private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
2413 ActivityOptions aOptions) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002414 final TaskRecord task = r.getTaskRecord();
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002415 ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002416 if (stack != null) {
2417 return stack;
2418 }
2419
Andrii Kulian02b7a832016-10-06 23:11:56 -07002420 final ActivityStack currentStack = task != null ? task.getStack() : null;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002421 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulian02b7a832016-10-06 23:11:56 -07002422 if (currentStack != null) {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002423 if (focusedStack != currentStack) {
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002424 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
2425 "computeStackFocus: Setting " + "focused stack to r=" + r
2426 + " task=" + task);
2427 } else {
2428 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002429 "computeStackFocus: Focused stack already=" + focusedStack);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002430 }
Andrii Kulian02b7a832016-10-06 23:11:56 -07002431 return currentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002432 }
2433
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002434 if (canLaunchIntoFocusedStack(r, newTask)) {
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002435 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
Andrii Kulian52d255c2018-07-13 11:32:19 -07002436 "computeStackFocus: Have a focused stack=" + focusedStack);
2437 return focusedStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002438 }
2439
David Stevense5a7b642017-05-22 13:18:23 -07002440 if (mPreferredDisplayId != DEFAULT_DISPLAY) {
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002441 // Try to put the activity in a stack on a secondary display.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002442 stack = mRootActivityContainer.getValidLaunchStackOnDisplay(
2443 mPreferredDisplayId, r, aOptions, mLaunchParams);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002444 if (stack == null) {
2445 // If source display is not suitable - look for topmost valid stack in the system.
2446 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
David Stevense5a7b642017-05-22 13:18:23 -07002447 "computeStackFocus: Can't launch on mPreferredDisplayId="
2448 + mPreferredDisplayId + ", looking on all displays.");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002449 stack = mRootActivityContainer.getNextValidLaunchStack(r, mPreferredDisplayId);
Andrii Kuliana8fe3df2017-06-16 15:29:26 -07002450 }
2451 }
2452 if (stack == null) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002453 stack = mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002454 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002455 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
2456 + r + " stackId=" + stack.mStackId);
2457 return stack;
2458 }
2459
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002460 /** Check if provided activity record can launch in currently focused stack. */
Wale Ogunwale68278562017-09-23 17:13:55 -07002461 // TODO: This method can probably be consolidated into getLaunchStack() below.
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002462 private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
Wale Ogunwaled32da472018-11-16 07:19:28 -08002463 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002464 final boolean canUseFocusedStack;
Wale Ogunwale68278562017-09-23 17:13:55 -07002465 if (focusedStack.isActivityTypeAssistant()) {
2466 canUseFocusedStack = r.isActivityTypeAssistant();
2467 } else {
2468 switch (focusedStack.getWindowingMode()) {
2469 case WINDOWING_MODE_FULLSCREEN:
2470 // The fullscreen stack can contain any task regardless of if the task is
2471 // resizeable or not. So, we let the task go in the fullscreen task if it is the
2472 // focus stack.
2473 canUseFocusedStack = true;
2474 break;
2475 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
2476 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
2477 // Any activity which supports split screen can go in the docked stack.
2478 canUseFocusedStack = r.supportsSplitScreenWindowingMode();
2479 break;
2480 case WINDOWING_MODE_FREEFORM:
2481 // Any activity which supports freeform can go in the freeform stack.
2482 canUseFocusedStack = r.supportsFreeform();
2483 break;
2484 default:
2485 // Dynamic stacks behave similarly to the fullscreen stack and can contain any
2486 // resizeable task.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002487 canUseFocusedStack = !focusedStack.isOnHomeDisplay()
Wale Ogunwale68278562017-09-23 17:13:55 -07002488 && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
2489 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002490 }
Andrii Kulian94e82d9b02017-07-13 15:33:06 -07002491 return canUseFocusedStack && !newTask
Wale Ogunwale68278562017-09-23 17:13:55 -07002492 // Using the focus stack isn't important enough to override the preferred display.
David Stevense5a7b642017-05-22 13:18:23 -07002493 && (mPreferredDisplayId == focusedStack.mDisplayId);
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002494 }
2495
Wale Ogunwale854809c2015-12-27 16:18:19 -08002496 private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
Jorim Jaggi4ad98562016-04-19 20:30:47 -07002497 ActivityOptions aOptions) {
Bryce Leea19b5ad2017-06-07 16:54:11 -07002498 // We are reusing a task, keep the stack!
2499 if (mReuseTask != null) {
2500 return mReuseTask.getStack();
2501 }
Jorim Jaggib8c58762016-04-20 17:58:29 -07002502
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -08002503 if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
David Stevense5a7b642017-05-22 13:18:23 -07002504 || mPreferredDisplayId != DEFAULT_DISPLAY) {
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002505 // We don't pass in the default display id into the get launch stack call so it can do a
2506 // full resolution.
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002507 mLaunchParams.mPreferredDisplayId =
Wale Ogunwaleeb76b762017-11-17 10:08:04 -08002508 mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY;
Wale Ogunwaled32da472018-11-16 07:19:28 -08002509 final ActivityStack stack =
2510 mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP, mLaunchParams);
Garfield Tan20d9e2f2018-11-16 15:42:29 -08002511 mLaunchParams.mPreferredDisplayId = mPreferredDisplayId;
2512 return stack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002513 }
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002514 // Otherwise handle adjacent launch.
Wale Ogunwale854809c2015-12-27 16:18:19 -08002515
Wale Ogunwaled32da472018-11-16 07:19:28 -08002516 final ActivityStack focusedStack = mRootActivityContainer.getTopDisplayFocusedStack();
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002517 // The parent activity doesn't want to launch the activity on top of itself, but
2518 // instead tries to put it onto other side in side-by-side mode.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002519 final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002520
Andrii Kulian52d255c2018-07-13 11:32:19 -07002521 if (parentStack != focusedStack) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002522 // If task's parent stack is not focused - use it during adjacent launch.
2523 return parentStack;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002524 } else {
Andrii Kulian52d255c2018-07-13 11:32:19 -07002525 if (focusedStack != null && task == focusedStack.topTask()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002526 // If task is already on top of focused stack - use it. We don't want to move the
2527 // existing focused task to adjacent stack, just deliver new intent in this case.
Andrii Kulian52d255c2018-07-13 11:32:19 -07002528 return focusedStack;
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002529 }
2530
Wale Ogunwale44f036f2017-09-29 05:09:09 -07002531 if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002532 // If parent was in docked stack, the natural place to launch another activity
2533 // will be fullscreen, so it can appear alongside the docked window.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002534 final int activityType =
2535 mRootActivityContainer.resolveActivityType(r, mOptions, task);
Wale Ogunwale04a05ac2017-09-17 21:35:02 -07002536 return parentStack.getDisplay().getOrCreateStack(
2537 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, activityType, ON_TOP);
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002538 } else {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002539 // If the parent is not in the docked stack, we check if there is docked window
2540 // and if yes, we will launch into that stack. If not, we just put the new
2541 // activity into parent's stack, because we can't find a better place.
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -07002542 final ActivityStack dockedStack =
Wale Ogunwaled32da472018-11-16 07:19:28 -08002543 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack();
Wale Ogunwale9dcf9462017-09-19 15:13:01 -07002544 if (dockedStack != null && !dockedStack.shouldBeVisible(r)) {
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002545 // There is a docked stack, but it isn't visible, so we can't launch into that.
Wale Ogunwaled32da472018-11-16 07:19:28 -08002546 return mRootActivityContainer.getLaunchStack(r, aOptions, task, ON_TOP);
Andrii Kulian4ac2a582016-03-25 00:07:38 -07002547 } else {
2548 return dockedStack;
2549 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002550 }
2551 }
2552 }
2553
Bryce Lee7daee392017-10-12 13:46:18 -07002554 private boolean isLaunchModeOneOf(int mode1, int mode2) {
2555 return mode1 == mLaunchMode || mode2 == mLaunchMode;
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002556 }
2557
Daichi Hirono15a02992016-04-27 18:47:01 +09002558 static boolean isDocumentLaunchesIntoExisting(int flags) {
2559 return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
2560 (flags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0;
2561 }
liulvpingcfa825f2016-09-26 20:00:15 +08002562
Bryce Lee4c9a5972017-12-01 22:14:24 -08002563 ActivityStarter setIntent(Intent intent) {
2564 mRequest.intent = intent;
2565 return this;
2566 }
2567
Bryce Lee32e09ef2018-03-19 15:29:49 -07002568 @VisibleForTesting
2569 Intent getIntent() {
2570 return mRequest.intent;
2571 }
2572
Bryce Lee4c9a5972017-12-01 22:14:24 -08002573 ActivityStarter setReason(String reason) {
2574 mRequest.reason = reason;
2575 return this;
2576 }
2577
2578 ActivityStarter setCaller(IApplicationThread caller) {
2579 mRequest.caller = caller;
2580 return this;
2581 }
2582
2583 ActivityStarter setEphemeralIntent(Intent intent) {
2584 mRequest.ephemeralIntent = intent;
2585 return this;
2586 }
2587
2588
2589 ActivityStarter setResolvedType(String type) {
2590 mRequest.resolvedType = type;
2591 return this;
2592 }
2593
2594 ActivityStarter setActivityInfo(ActivityInfo info) {
2595 mRequest.activityInfo = info;
2596 return this;
2597 }
2598
2599 ActivityStarter setResolveInfo(ResolveInfo info) {
2600 mRequest.resolveInfo = info;
2601 return this;
2602 }
2603
2604 ActivityStarter setVoiceSession(IVoiceInteractionSession voiceSession) {
2605 mRequest.voiceSession = voiceSession;
2606 return this;
2607 }
2608
2609 ActivityStarter setVoiceInteractor(IVoiceInteractor voiceInteractor) {
2610 mRequest.voiceInteractor = voiceInteractor;
2611 return this;
2612 }
2613
2614 ActivityStarter setResultTo(IBinder resultTo) {
2615 mRequest.resultTo = resultTo;
2616 return this;
2617 }
2618
2619 ActivityStarter setResultWho(String resultWho) {
2620 mRequest.resultWho = resultWho;
2621 return this;
2622 }
2623
2624 ActivityStarter setRequestCode(int requestCode) {
2625 mRequest.requestCode = requestCode;
2626 return this;
2627 }
2628
2629 ActivityStarter setCallingPid(int pid) {
2630 mRequest.callingPid = pid;
2631 return this;
2632 }
2633
2634 ActivityStarter setCallingUid(int uid) {
2635 mRequest.callingUid = uid;
2636 return this;
2637 }
2638
2639 ActivityStarter setCallingPackage(String callingPackage) {
2640 mRequest.callingPackage = callingPackage;
2641 return this;
2642 }
2643
2644 ActivityStarter setRealCallingPid(int pid) {
2645 mRequest.realCallingPid = pid;
2646 return this;
2647 }
2648
2649 ActivityStarter setRealCallingUid(int uid) {
2650 mRequest.realCallingUid = uid;
2651 return this;
2652 }
2653
2654 ActivityStarter setStartFlags(int startFlags) {
2655 mRequest.startFlags = startFlags;
2656 return this;
2657 }
2658
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002659 ActivityStarter setActivityOptions(SafeActivityOptions options) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002660 mRequest.activityOptions = options;
2661 return this;
2662 }
2663
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002664 ActivityStarter setActivityOptions(Bundle bOptions) {
2665 return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
2666 }
2667
Bryce Lee4c9a5972017-12-01 22:14:24 -08002668 ActivityStarter setIgnoreTargetSecurity(boolean ignoreTargetSecurity) {
2669 mRequest.ignoreTargetSecurity = ignoreTargetSecurity;
2670 return this;
2671 }
2672
Patrick Baumann31426b22018-05-21 13:46:40 -07002673 ActivityStarter setFilterCallingUid(int filterCallingUid) {
2674 mRequest.filterCallingUid = filterCallingUid;
2675 return this;
2676 }
2677
Bryce Lee4c9a5972017-12-01 22:14:24 -08002678 ActivityStarter setComponentSpecified(boolean componentSpecified) {
2679 mRequest.componentSpecified = componentSpecified;
2680 return this;
2681 }
2682
2683 ActivityStarter setOutActivity(ActivityRecord[] outActivity) {
2684 mRequest.outActivity = outActivity;
2685 return this;
2686 }
2687
2688 ActivityStarter setInTask(TaskRecord inTask) {
2689 mRequest.inTask = inTask;
2690 return this;
2691 }
2692
2693 ActivityStarter setWaitResult(WaitResult result) {
2694 mRequest.waitResult = result;
2695 return this;
2696 }
2697
2698 ActivityStarter setProfilerInfo(ProfilerInfo info) {
2699 mRequest.profilerInfo = info;
2700 return this;
2701 }
2702
2703 ActivityStarter setGlobalConfiguration(Configuration config) {
2704 mRequest.globalConfig = config;
2705 return this;
2706 }
2707
Bryce Lee4c9a5972017-12-01 22:14:24 -08002708 ActivityStarter setUserId(int userId) {
2709 mRequest.userId = userId;
2710 return this;
2711 }
2712
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +01002713 ActivityStarter setMayWait(int userId) {
Bryce Lee4c9a5972017-12-01 22:14:24 -08002714 mRequest.mayWait = true;
Bryce Lee4c9a5972017-12-01 22:14:24 -08002715 mRequest.userId = userId;
2716
2717 return this;
2718 }
2719
Jorim Jaggi6fa41c32018-04-23 18:35:00 +02002720 ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
2721 mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
2722 return this;
2723 }
2724
Michal Karpinski201bc0c2018-07-20 15:32:00 +01002725 ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
2726 mRequest.originatingPendingIntent = originatingPendingIntent;
2727 return this;
2728 }
2729
Bryce Leed3624e12017-11-30 08:51:45 -08002730 void dump(PrintWriter pw, String prefix) {
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002731 prefix = prefix + " ";
Dianne Hackborne676ec72017-07-25 10:55:08 -07002732 pw.print(prefix);
2733 pw.print("mCurrentUser=");
Wale Ogunwaled32da472018-11-16 07:19:28 -08002734 pw.println(mRootActivityContainer.mCurrentUser);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002735 pw.print(prefix);
2736 pw.print("mLastStartReason=");
2737 pw.println(mLastStartReason);
2738 pw.print(prefix);
2739 pw.print("mLastStartActivityTimeMs=");
2740 pw.println(DateFormat.getDateTimeInstance().format(new Date(mLastStartActivityTimeMs)));
2741 pw.print(prefix);
2742 pw.print("mLastStartActivityResult=");
2743 pw.println(mLastStartActivityResult);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002744 ActivityRecord r = mLastStartActivityRecord[0];
2745 if (r != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002746 pw.print(prefix);
2747 pw.println("mLastStartActivityRecord:");
2748 r.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002749 }
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002750 if (mStartActivity != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002751 pw.print(prefix);
2752 pw.println("mStartActivity:");
2753 mStartActivity.dump(pw, prefix + " ");
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002754 }
2755 if (mIntent != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002756 pw.print(prefix);
2757 pw.print("mIntent=");
2758 pw.println(mIntent);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002759 }
2760 if (mOptions != null) {
Dianne Hackborne676ec72017-07-25 10:55:08 -07002761 pw.print(prefix);
2762 pw.print("mOptions=");
2763 pw.println(mOptions);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002764 }
Dianne Hackborne676ec72017-07-25 10:55:08 -07002765 pw.print(prefix);
2766 pw.print("mLaunchSingleTop=");
Bryce Lee7daee392017-10-12 13:46:18 -07002767 pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002768 pw.print(" mLaunchSingleInstance=");
Bryce Lee7daee392017-10-12 13:46:18 -07002769 pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002770 pw.print(" mLaunchSingleTask=");
Bryce Lee7daee392017-10-12 13:46:18 -07002771 pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
Dianne Hackborne676ec72017-07-25 10:55:08 -07002772 pw.print(prefix);
2773 pw.print("mLaunchFlags=0x");
2774 pw.print(Integer.toHexString(mLaunchFlags));
2775 pw.print(" mDoResume=");
2776 pw.print(mDoResume);
2777 pw.print(" mAddingToTask=");
2778 pw.println(mAddingToTask);
Wale Ogunwale692dcd62017-06-20 13:38:14 -07002779 }
Filip Gruszczynski07a0e492015-12-17 14:16:38 -08002780}