blob: 881dc81807f547adc8790b96e9c30b7c153b60f2 [file] [log] [blame]
Bryce Leed3624e12017-11-30 08:51:45 -08001/*
2 * Copyright (C) 2017 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;
Bryce Leed3624e12017-11-30 08:51:45 -080018
19import static android.app.ActivityManager.START_SUCCESS;
Louis Changbd48dca2018-08-29 17:44:34 +080020import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
21import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Bryce Leed3624e12017-11-30 08:51:45 -080022import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
Wale Ogunwale214f3482018-10-04 11:00:47 -070023import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
Louis Chang89f43fc2018-10-05 10:59:14 +080024
Wale Ogunwalefef90a02019-11-06 17:56:33 -080025import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
Wale Ogunwale59507092018-10-29 09:00:30 -070026import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
27import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Bryce Leed3624e12017-11-30 08:51:45 -080028
Philip P. Moltmannee295092020-02-10 08:46:26 -080029import android.annotation.Nullable;
Louis Changbd48dca2018-08-29 17:44:34 +080030import android.app.ActivityOptions;
Bryce Leed3624e12017-11-30 08:51:45 -080031import android.app.IApplicationThread;
Bryce Leed3624e12017-11-30 08:51:45 -080032import android.content.ComponentName;
33import android.content.ContentResolver;
34import android.content.Intent;
35import android.content.pm.ActivityInfo;
36import android.content.pm.ApplicationInfo;
37import android.content.pm.PackageManager;
38import android.content.pm.ResolveInfo;
Bryce Leed3624e12017-11-30 08:51:45 -080039import android.os.Binder;
Bryce Leed3624e12017-11-30 08:51:45 -080040import android.os.Handler;
41import android.os.IBinder;
42import android.os.Looper;
43import android.os.Message;
Patrick Baumann31426b22018-05-21 13:46:40 -070044import android.os.UserHandle;
Bryce Leed3624e12017-11-30 08:51:45 -080045import android.provider.Settings;
Bryce Leed3624e12017-11-30 08:51:45 -080046import android.util.Slog;
Riddle Hsucf2ef0c2019-12-13 14:33:40 +080047import android.util.SparseArray;
wilsonshih468b7c02018-06-29 10:21:40 +080048import android.util.proto.ProtoOutputStream;
Jorim Jaggi04dc5962018-01-29 18:54:13 +010049import android.view.RemoteAnimationAdapter;
Bryce Leed3624e12017-11-30 08:51:45 -080050
51import com.android.internal.annotations.VisibleForTesting;
Riddle Hsu591bf612019-02-14 17:55:31 +080052import com.android.internal.util.ArrayUtils;
Wale Ogunwale59507092018-10-29 09:00:30 -070053import com.android.server.am.ActivityManagerService;
54import com.android.server.am.PendingIntentRecord;
55import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
56import com.android.server.wm.ActivityStarter.DefaultFactory;
57import com.android.server.wm.ActivityStarter.Factory;
Bryce Leed3624e12017-11-30 08:51:45 -080058
59import java.io.PrintWriter;
60import java.util.ArrayList;
61import java.util.List;
62
63/**
64 * Controller for delegating activity launches.
65 *
66 * This class' main objective is to take external activity start requests and prepare them into
67 * a series of discrete activity launches that can be handled by an {@link ActivityStarter}. It is
68 * also responsible for handling logic that happens around an activity launch, but doesn't
69 * necessarily influence the activity start. Examples include power hint management, processing
70 * through the pending activity list, and recording home activity launches.
71 */
72public class ActivityStartController {
Wale Ogunwale98875612018-10-12 07:53:02 -070073 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStartController" : TAG_ATM;
Bryce Leed3624e12017-11-30 08:51:45 -080074
75 private static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 1;
76
Wale Ogunwalec9e57de2018-05-08 14:28:07 -070077 private final ActivityTaskManagerService mService;
Bryce Leed3624e12017-11-30 08:51:45 -080078 private final ActivityStackSupervisor mSupervisor;
Bryce Leed3624e12017-11-30 08:51:45 -080079
80 /** Last home activity record we attempted to start. */
81 private ActivityRecord mLastHomeActivityStartRecord;
82
83 /** Temporary array to capture start activity results */
84 private ActivityRecord[] tmpOutRecord = new ActivityRecord[1];
85
Louis Changbd48dca2018-08-29 17:44:34 +080086 /** The result of the last home activity we attempted to start. */
Bryce Leed3624e12017-11-30 08:51:45 -080087 private int mLastHomeActivityStartResult;
88
89 /** A list of activities that are waiting to launch. */
90 private final ArrayList<ActivityStackSupervisor.PendingActivityLaunch>
91 mPendingActivityLaunches = new ArrayList<>();
92
93 private final Factory mFactory;
94
95 private final Handler mHandler;
96
Jorim Jaggi04dc5962018-01-29 18:54:13 +010097 private final PendingRemoteAnimationRegistry mPendingRemoteAnimationRegistry;
98
Wale Ogunwale342fbe92018-10-09 08:44:10 -070099 boolean mCheckedForSetup = false;
100
Bryce Leed3624e12017-11-30 08:51:45 -0800101 private final class StartHandler extends Handler {
102 public StartHandler(Looper looper) {
103 super(looper, null, true);
104 }
105
106 @Override
107 public void handleMessage(Message msg) {
108 switch(msg.what) {
109 case DO_PENDING_ACTIVITY_LAUNCHES_MSG:
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700110 synchronized (mService.mGlobalLock) {
Bryce Leed3624e12017-11-30 08:51:45 -0800111 doPendingActivityLaunches(true);
112 }
113 break;
114 }
115 }
116 }
117
118 /**
119 * TODO(b/64750076): Capture information necessary for dump and
120 * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object
Bryce Leedaa91e42017-12-06 14:13:01 -0800121 * around
122 */
Bryce Leed3624e12017-11-30 08:51:45 -0800123 private ActivityStarter mLastStarter;
124
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700125 ActivityStartController(ActivityTaskManagerService service) {
Bryce Lee4c9a5972017-12-01 22:14:24 -0800126 this(service, service.mStackSupervisor,
127 new DefaultFactory(service, service.mStackSupervisor,
128 new ActivityStartInterceptor(service, service.mStackSupervisor)));
Bryce Leed3624e12017-11-30 08:51:45 -0800129 }
130
131 @VisibleForTesting
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700132 ActivityStartController(ActivityTaskManagerService service, ActivityStackSupervisor supervisor,
Bryce Leed3624e12017-11-30 08:51:45 -0800133 Factory factory) {
134 mService = service;
135 mSupervisor = supervisor;
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700136 mHandler = new StartHandler(mService.mH.getLooper());
Bryce Leed3624e12017-11-30 08:51:45 -0800137 mFactory = factory;
Bryce Lee4c9a5972017-12-01 22:14:24 -0800138 mFactory.setController(this);
Riddle Hsue459c632020-01-03 22:37:47 +0800139 mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700140 service.mH);
Bryce Leed3624e12017-11-30 08:51:45 -0800141 }
142
143 /**
Bryce Lee4c9a5972017-12-01 22:14:24 -0800144 * @return A starter to configure and execute starting an activity. It is valid until after
145 * {@link ActivityStarter#execute} is invoked. At that point, the starter should be
146 * considered invalid and no longer modified or used.
Bryce Leed3624e12017-11-30 08:51:45 -0800147 */
Bryce Lee4c9a5972017-12-01 22:14:24 -0800148 ActivityStarter obtainStarter(Intent intent, String reason) {
Bryce Leedaa91e42017-12-06 14:13:01 -0800149 return mFactory.obtain().setIntent(intent).setReason(reason);
150 }
Bryce Leed3624e12017-11-30 08:51:45 -0800151
Bryce Leedaa91e42017-12-06 14:13:01 -0800152 void onExecutionComplete(ActivityStarter starter) {
153 if (mLastStarter == null) {
154 mLastStarter = mFactory.obtain();
155 }
156
157 mLastStarter.set(starter);
158 mFactory.recycle(starter);
Bryce Leed3624e12017-11-30 08:51:45 -0800159 }
160
161 /**
162 * TODO(b/64750076): usage of this doesn't seem right. We're making decisions based off the
163 * last starter for an arbitrary task record. Re-evaluate whether we can remove.
164 */
165 void postStartActivityProcessingForLastStarter(ActivityRecord r, int result,
166 ActivityStack targetStack) {
Bryce Leedaa91e42017-12-06 14:13:01 -0800167 if (mLastStarter == null) {
168 return;
169 }
170
Bryce Leed3624e12017-11-30 08:51:45 -0800171 mLastStarter.postStartActivityProcessing(r, result, targetStack);
172 }
173
Louis Changbd48dca2018-08-29 17:44:34 +0800174 void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
Louis Changbd48dca2018-08-29 17:44:34 +0800175 final ActivityOptions options = ActivityOptions.makeBasic();
176 options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
Riddle Hsuff9e8282019-04-24 23:55:11 +0800177 if (!ActivityRecord.isResolverActivity(aInfo.name)) {
178 // The resolver activity shouldn't be put in home stack because when the foreground is
179 // standard type activity, the resolver activity should be put on the top of current
180 // foreground instead of bring home stack to front.
181 options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
182 }
Louis Changbd48dca2018-08-29 17:44:34 +0800183 options.setLaunchDisplayId(displayId);
Wale Ogunwalefef90a02019-11-06 17:56:33 -0800184
Louis Chang677921f2019-12-06 16:44:24 +0800185 final DisplayContent display =
Louis Chang149d5c82019-12-30 09:47:39 +0800186 mService.mRootWindowContainer.getDisplayContent(displayId);
Riddle Hsua0175ab2019-11-12 23:52:32 +0800187 // The home activity will be started later, defer resuming to avoid unneccerary operations
188 // (e.g. start home recursively) when creating home stack.
189 mSupervisor.beginDeferResume();
190 final ActivityStack homeStack;
191 try {
192 // Make sure home stack exist on display.
193 homeStack = display.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME,
194 ON_TOP);
195 } finally {
196 mSupervisor.endDeferResume();
197 }
Wale Ogunwalefef90a02019-11-06 17:56:33 -0800198
Bryce Lee4c9a5972017-12-01 22:14:24 -0800199 mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
200 .setOutActivity(tmpOutRecord)
201 .setCallingUid(0)
202 .setActivityInfo(aInfo)
Louis Changbd48dca2018-08-29 17:44:34 +0800203 .setActivityOptions(options.toBundle())
Bryce Lee4c9a5972017-12-01 22:14:24 -0800204 .execute();
Bryce Leed3624e12017-11-30 08:51:45 -0800205 mLastHomeActivityStartRecord = tmpOutRecord[0];
Wale Ogunwalefef90a02019-11-06 17:56:33 -0800206 if (homeStack.mInResumeTopActivity) {
Bryce Leed3624e12017-11-30 08:51:45 -0800207 // If we are in resume section already, home activity will be initialized, but not
208 // resumed (to avoid recursive resume) and will stay that way until something pokes it
209 // again. We need to schedule another resume.
210 mSupervisor.scheduleResumeTopActivities();
211 }
212 }
213
214 /**
215 * Starts the "new version setup screen" if appropriate.
216 */
217 void startSetupActivity() {
218 // Only do this once per boot.
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700219 if (mCheckedForSetup) {
Bryce Leed3624e12017-11-30 08:51:45 -0800220 return;
221 }
222
223 // We will show this screen if the current one is a different
224 // version than the last one shown, and we are not running in
225 // low-level factory test mode.
226 final ContentResolver resolver = mService.mContext.getContentResolver();
Wale Ogunwale214f3482018-10-04 11:00:47 -0700227 if (mService.mFactoryTest != FACTORY_TEST_LOW_LEVEL
228 && Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700229 mCheckedForSetup = true;
Bryce Leed3624e12017-11-30 08:51:45 -0800230
231 // See if we should be showing the platform update setup UI.
232 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
Philip P. Moltmanncff8f0f2018-03-27 12:51:51 -0700233 final List<ResolveInfo> ris =
234 mService.mContext.getPackageManager().queryIntentActivities(intent,
235 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA
236 | ActivityManagerService.STOCK_PM_FLAGS);
Bryce Leed3624e12017-11-30 08:51:45 -0800237 if (!ris.isEmpty()) {
238 final ResolveInfo ri = ris.get(0);
239 String vers = ri.activityInfo.metaData != null
240 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
241 : null;
242 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
243 vers = ri.activityInfo.applicationInfo.metaData.getString(
244 Intent.METADATA_SETUP_VERSION);
245 }
246 String lastVers = Settings.Secure.getString(
247 resolver, Settings.Secure.LAST_SETUP_SHOWN);
248 if (vers != null && !vers.equals(lastVers)) {
249 intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
250 intent.setComponent(new ComponentName(
251 ri.activityInfo.packageName, ri.activityInfo.name));
Bryce Lee4c9a5972017-12-01 22:14:24 -0800252 obtainStarter(intent, "startSetupActivity")
253 .setCallingUid(0)
254 .setActivityInfo(ri.activityInfo)
255 .execute();
Bryce Leed3624e12017-11-30 08:51:45 -0800256 }
257 }
258 }
259 }
260
Makoto Onukic00ea712018-04-13 12:06:39 -0700261 /**
262 * If {@code validateIncomingUser} is true, check {@code targetUserId} against the real calling
263 * user ID inferred from {@code realCallingUid}, then return the resolved user-id, taking into
264 * account "current user", etc.
265 *
266 * If {@code validateIncomingUser} is false, it skips the above check, but instead
267 * ensures {@code targetUserId} is a real user ID and not a special user ID such as
268 * {@link android.os.UserHandle#USER_ALL}, etc.
269 */
Makoto Onuki1a342742018-04-26 14:56:59 -0700270 int checkTargetUser(int targetUserId, boolean validateIncomingUser,
Makoto Onukic00ea712018-04-13 12:06:39 -0700271 int realCallingPid, int realCallingUid, String reason) {
272 if (validateIncomingUser) {
Wale Ogunwalea6191b42018-05-09 07:41:32 -0700273 return mService.handleIncomingUser(
274 realCallingPid, realCallingUid, targetUserId, reason);
Makoto Onukic00ea712018-04-13 12:06:39 -0700275 } else {
Wale Ogunwale86b74462018-07-02 08:42:43 -0700276 mService.mAmInternal.ensureNotSpecialUser(targetUserId);
Makoto Onukic00ea712018-04-13 12:06:39 -0700277 return targetUserId;
278 }
279 }
280
Tony Mak793e14d2018-01-24 15:11:06 +0000281 final int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
Philip P. Moltmannee295092020-02-10 08:46:26 -0800282 String callingPackage, @Nullable String callingFeatureId, Intent intent,
283 String resolvedType, IBinder resultTo, String resultWho, int requestCode,
284 int startFlags, SafeActivityOptions options, int userId, Task inTask, String reason,
285 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent,
286 boolean allowBackgroundActivityStart) {
Bryce Leed3624e12017-11-30 08:51:45 -0800287
Makoto Onukic00ea712018-04-13 12:06:39 -0700288 userId = checkTargetUser(userId, validateIncomingUser, realCallingPid, realCallingUid,
289 reason);
Bryce Leed3624e12017-11-30 08:51:45 -0800290
291 // TODO: Switch to user app stacks here.
Bryce Lee4c9a5972017-12-01 22:14:24 -0800292 return obtainStarter(intent, reason)
293 .setCallingUid(uid)
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100294 .setRealCallingPid(realCallingPid)
295 .setRealCallingUid(realCallingUid)
Bryce Lee4c9a5972017-12-01 22:14:24 -0800296 .setCallingPackage(callingPackage)
Philip P. Moltmannee295092020-02-10 08:46:26 -0800297 .setCallingFeatureId(callingFeatureId)
Bryce Lee4c9a5972017-12-01 22:14:24 -0800298 .setResolvedType(resolvedType)
299 .setResultTo(resultTo)
300 .setResultWho(resultWho)
301 .setRequestCode(requestCode)
302 .setStartFlags(startFlags)
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100303 .setActivityOptions(options)
Louis Chang54fbb052019-10-16 17:10:17 +0800304 .setUserId(userId)
Bryce Lee4c9a5972017-12-01 22:14:24 -0800305 .setInTask(inTask)
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100306 .setOriginatingPendingIntent(originatingPendingIntent)
Michal Karpinskiac116df2018-12-10 17:51:42 +0000307 .setAllowBackgroundActivityStart(allowBackgroundActivityStart)
Bryce Lee4c9a5972017-12-01 22:14:24 -0800308 .execute();
Bryce Leed3624e12017-11-30 08:51:45 -0800309 }
310
Makoto Onuki7041c4b2018-02-06 13:36:34 -0800311 /**
312 * Start intents as a package.
313 *
Makoto Onuki6895df32018-02-13 08:52:10 -0800314 * @param uid Make a call as if this UID did.
315 * @param callingPackage Make a call as if this package did.
Philip P. Moltmannee295092020-02-10 08:46:26 -0800316 * @param callingFeatureId Make a call as if this feature in the package did.
Makoto Onuki6895df32018-02-13 08:52:10 -0800317 * @param intents Intents to start.
318 * @param userId Start the intents on this user.
319 * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
Michal Karpinski201bc0c2018-07-20 15:32:00 +0100320 * @param originatingPendingIntent PendingIntentRecord that originated this activity start or
321 * null if not originated by PendingIntent
Makoto Onuki7041c4b2018-02-06 13:36:34 -0800322 */
Philip P. Moltmannee295092020-02-10 08:46:26 -0800323 final int startActivitiesInPackage(int uid, String callingPackage,
324 @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes,
325 IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser,
326 PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000327 return startActivitiesInPackage(uid, 0 /* realCallingPid */, -1 /* realCallingUid */,
Philip P. Moltmannee295092020-02-10 08:46:26 -0800328 callingPackage, callingFeatureId, intents, resolvedTypes, resultTo, options, userId,
329 validateIncomingUser, originatingPendingIntent, allowBackgroundActivityStart);
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000330 }
331
332 /**
333 * Start intents as a package.
334 *
335 * @param uid Make a call as if this UID did.
336 * @param realCallingPid PID of the real caller.
337 * @param realCallingUid UID of the real caller.
338 * @param callingPackage Make a call as if this package did.
339 * @param intents Intents to start.
340 * @param userId Start the intents on this user.
341 * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
342 * @param originatingPendingIntent PendingIntentRecord that originated this activity start or
343 * null if not originated by PendingIntent
344 */
345 final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,
Philip P. Moltmannee295092020-02-10 08:46:26 -0800346 String callingPackage, @Nullable String callingFeatureId, Intent[] intents,
347 String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
348 boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent,
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000349 boolean allowBackgroundActivityStart) {
Makoto Onukic00ea712018-04-13 12:06:39 -0700350
Bryce Leed3624e12017-11-30 08:51:45 -0800351 final String reason = "startActivityInPackage";
Makoto Onukic00ea712018-04-13 12:06:39 -0700352
353 userId = checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(),
354 Binder.getCallingUid(), reason);
355
Bryce Leed3624e12017-11-30 08:51:45 -0800356 // TODO: Switch to user app stacks here.
Philip P. Moltmannee295092020-02-10 08:46:26 -0800357 return startActivities(null, uid, realCallingPid, realCallingUid, callingPackage,
358 callingFeatureId, intents, resolvedTypes, resultTo, options, userId, reason,
359 originatingPendingIntent, allowBackgroundActivityStart);
Bryce Leed3624e12017-11-30 08:51:45 -0800360 }
361
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000362 int startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid,
Philip P. Moltmannee295092020-02-10 08:46:26 -0800363 int incomingRealCallingUid, String callingPackage, @Nullable String callingFeatureId,
364 Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options,
Michal Karpinskiac116df2018-12-10 17:51:42 +0000365 int userId, String reason, PendingIntentRecord originatingPendingIntent,
366 boolean allowBackgroundActivityStart) {
Bryce Leed3624e12017-11-30 08:51:45 -0800367 if (intents == null) {
368 throw new NullPointerException("intents is null");
369 }
370 if (resolvedTypes == null) {
371 throw new NullPointerException("resolvedTypes is null");
372 }
373 if (intents.length != resolvedTypes.length) {
374 throw new IllegalArgumentException("intents are length different than resolvedTypes");
375 }
376
Michal Karpinski84d9ebd2019-01-17 18:28:59 +0000377 final int realCallingPid = incomingRealCallingPid != 0
378 ? incomingRealCallingPid
379 : Binder.getCallingPid();
380 final int realCallingUid = incomingRealCallingUid != -1
381 ? incomingRealCallingUid
382 : Binder.getCallingUid();
Bryce Leed3624e12017-11-30 08:51:45 -0800383
384 int callingPid;
385 if (callingUid >= 0) {
386 callingPid = -1;
387 } else if (caller == null) {
388 callingPid = realCallingPid;
389 callingUid = realCallingUid;
390 } else {
391 callingPid = callingUid = -1;
392 }
Riddle Hsua7e69392019-12-07 01:47:11 +0800393 final int filterCallingUid = ActivityStarter.computeResolveFilterUid(
394 callingUid, realCallingUid, UserHandle.USER_NULL);
Riddle Hsucf2ef0c2019-12-13 14:33:40 +0800395 final SparseArray<String> startingUidPkgs = new SparseArray<>();
Bryce Leed3624e12017-11-30 08:51:45 -0800396 final long origId = Binder.clearCallingIdentity();
397 try {
Riddle Hsu591bf612019-02-14 17:55:31 +0800398 intents = ArrayUtils.filterNotNull(intents, Intent[]::new);
399 final ActivityStarter[] starters = new ActivityStarter[intents.length];
400 // Do not hold WM global lock on this loop because when resolving intent, it may
401 // potentially acquire activity manager lock that leads to deadlock.
402 for (int i = 0; i < intents.length; i++) {
403 Intent intent = intents[i];
404
405 // Refuse possible leaked file descriptors.
406 if (intent.hasFileDescriptors()) {
407 throw new IllegalArgumentException("File descriptors passed in Intent");
408 }
409
Riddle Hsuac696e12019-10-01 19:13:48 +0800410 // Get the flag earlier because the intent may be modified in resolveActivity below.
411 final boolean componentSpecified = intent.getComponent() != null;
Riddle Hsu591bf612019-02-14 17:55:31 +0800412 // Don't modify the client's object!
413 intent = new Intent(intent);
414
415 // Collect information about the target of the Intent.
416 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i],
Riddle Hsua7e69392019-12-07 01:47:11 +0800417 0 /* startFlags */, null /* profilerInfo */, userId, filterCallingUid);
Riddle Hsu591bf612019-02-14 17:55:31 +0800418 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
419
Riddle Hsucf2ef0c2019-12-13 14:33:40 +0800420 if (aInfo != null) {
421 if ((aInfo.applicationInfo.privateFlags
422 & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
423 throw new IllegalArgumentException(
424 "FLAG_CANT_SAVE_STATE not supported here");
425 }
426 startingUidPkgs.put(aInfo.applicationInfo.uid,
427 aInfo.applicationInfo.packageName);
Riddle Hsu591bf612019-02-14 17:55:31 +0800428 }
429
430 final boolean top = i == intents.length - 1;
431 final SafeActivityOptions checkedOptions = top
432 ? options
433 : null;
434 starters[i] = obtainStarter(intent, reason)
435 .setCaller(caller)
436 .setResolvedType(resolvedTypes[i])
437 .setActivityInfo(aInfo)
Riddle Hsu591bf612019-02-14 17:55:31 +0800438 .setRequestCode(-1)
439 .setCallingPid(callingPid)
440 .setCallingUid(callingUid)
441 .setCallingPackage(callingPackage)
Philip P. Moltmannee295092020-02-10 08:46:26 -0800442 .setCallingFeatureId(callingFeatureId)
Riddle Hsu591bf612019-02-14 17:55:31 +0800443 .setRealCallingPid(realCallingPid)
444 .setRealCallingUid(realCallingUid)
445 .setActivityOptions(checkedOptions)
Riddle Hsuac696e12019-10-01 19:13:48 +0800446 .setComponentSpecified(componentSpecified)
Riddle Hsu591bf612019-02-14 17:55:31 +0800447
448 // Top activity decides on animation being run, so we allow only for the
449 // top one as otherwise an activity below might consume it.
450 .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/)
451 .setOriginatingPendingIntent(originatingPendingIntent)
452 .setAllowBackgroundActivityStart(allowBackgroundActivityStart);
453 }
Riddle Hsucf2ef0c2019-12-13 14:33:40 +0800454 // Log if the activities to be started have different uids.
455 if (startingUidPkgs.size() > 1) {
456 final StringBuilder sb = new StringBuilder("startActivities: different apps [");
457 final int size = startingUidPkgs.size();
458 for (int i = 0; i < size; i++) {
459 sb.append(startingUidPkgs.valueAt(i)).append(i == size - 1 ? "]" : ", ");
460 }
461 sb.append(" from ").append(callingPackage);
462 Slog.wtf(TAG, sb.toString());
463 }
Riddle Hsu591bf612019-02-14 17:55:31 +0800464
Riddle Hsua7e69392019-12-07 01:47:11 +0800465 final IBinder sourceResultTo = resultTo;
Riddle Hsu591bf612019-02-14 17:55:31 +0800466 final ActivityRecord[] outActivity = new ActivityRecord[1];
467 // Lock the loop to ensure the activities launched in a sequence.
Wale Ogunwalec9e57de2018-05-08 14:28:07 -0700468 synchronized (mService.mGlobalLock) {
Riddle Hsu591bf612019-02-14 17:55:31 +0800469 for (int i = 0; i < starters.length; i++) {
Riddle Hsuac696e12019-10-01 19:13:48 +0800470 final int startResult = starters[i].setResultTo(resultTo)
471 .setOutActivity(outActivity).execute();
Riddle Hsu591bf612019-02-14 17:55:31 +0800472 if (startResult < START_SUCCESS) {
473 // Abort by error result and recycle unused starters.
474 for (int j = i + 1; j < starters.length; j++) {
475 mFactory.recycle(starters[j]);
476 }
477 return startResult;
Bryce Leed3624e12017-11-30 08:51:45 -0800478 }
Riddle Hsua7e69392019-12-07 01:47:11 +0800479 final ActivityRecord started = outActivity[0];
480 if (started != null && started.getUid() == filterCallingUid) {
481 // Only the started activity which has the same uid as the source caller can
482 // be the caller of next activity.
483 resultTo = started.appToken;
484 } else {
485 resultTo = sourceResultTo;
486 // Different apps not adjacent to the caller are forced to be new task.
487 if (i < starters.length - 1) {
488 starters[i + 1].getIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
489 }
490 }
Bryce Leed3624e12017-11-30 08:51:45 -0800491 }
492 }
493 } finally {
494 Binder.restoreCallingIdentity(origId);
495 }
496
497 return START_SUCCESS;
498 }
499
500 void schedulePendingActivityLaunches(long delayMs) {
501 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
502 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
503 mHandler.sendMessageDelayed(msg, delayMs);
504 }
505
506 void doPendingActivityLaunches(boolean doResume) {
507 while (!mPendingActivityLaunches.isEmpty()) {
508 final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
509 final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
Bryce Lee4c9a5972017-12-01 22:14:24 -0800510 final ActivityStarter starter = obtainStarter(null /* intent */,
511 "pendingActivityLaunch");
Bryce Leed3624e12017-11-30 08:51:45 -0800512 try {
Bryce Lee4c9a5972017-12-01 22:14:24 -0800513 starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000514 resume, pal.r.pendingOptions, null);
Bryce Leed3624e12017-11-30 08:51:45 -0800515 } catch (Exception e) {
516 Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
517 pal.sendErrorResult(e.getMessage());
518 }
519 }
520 }
521
522 void addPendingActivityLaunch(PendingActivityLaunch launch) {
523 mPendingActivityLaunches.add(launch);
524 }
525
526 boolean clearPendingActivityLaunches(String packageName) {
527 final int pendingLaunches = mPendingActivityLaunches.size();
528
529 for (int palNdx = pendingLaunches - 1; palNdx >= 0; --palNdx) {
530 final PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
531 final ActivityRecord r = pal.r;
532 if (r != null && r.packageName.equals(packageName)) {
533 mPendingActivityLaunches.remove(palNdx);
534 }
535 }
536 return mPendingActivityLaunches.size() < pendingLaunches;
537 }
538
Jorim Jaggi04dc5962018-01-29 18:54:13 +0100539 void registerRemoteAnimationForNextActivityStart(String packageName,
540 RemoteAnimationAdapter adapter) {
541 mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter);
542 }
543
544 PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() {
545 return mPendingRemoteAnimationRegistry;
546 }
547
Bryce Leed3624e12017-11-30 08:51:45 -0800548 void dump(PrintWriter pw, String prefix, String dumpPackage) {
549 pw.print(prefix);
550 pw.print("mLastHomeActivityStartResult=");
551 pw.println(mLastHomeActivityStartResult);
552
553 if (mLastHomeActivityStartRecord != null) {
554 pw.print(prefix);
555 pw.println("mLastHomeActivityStartRecord:");
Garfield Tane8d84ab2019-10-11 09:49:40 -0700556 mLastHomeActivityStartRecord.dump(pw, prefix + " ", true /* dumpAll */);
Bryce Leed3624e12017-11-30 08:51:45 -0800557 }
558
559 final boolean dumpPackagePresent = dumpPackage != null;
560
561 if (mLastStarter != null) {
562 final boolean dump = !dumpPackagePresent
563 || mLastStarter.relatedToPackage(dumpPackage)
564 || (mLastHomeActivityStartRecord != null
565 && dumpPackage.equals(mLastHomeActivityStartRecord.packageName));
566
567 if (dump) {
568 pw.print(prefix);
569 mLastStarter.dump(pw, prefix + " ");
570
571 if (dumpPackagePresent) {
572 return;
573 }
574 }
575 }
576
577 if (dumpPackagePresent) {
578 pw.print(prefix);
579 pw.println("(nothing)");
580 }
581 }
wilsonshih468b7c02018-06-29 10:21:40 +0800582
Jeffrey Huangcb782852019-12-05 11:28:11 -0800583 public void dumpDebug(ProtoOutputStream proto, long fieldId) {
wilsonshih468b7c02018-06-29 10:21:40 +0800584 for (PendingActivityLaunch activity: mPendingActivityLaunches) {
585 activity.r.writeIdentifierToProto(proto, fieldId);
586 }
587 }
Bryce Leed3624e12017-11-30 08:51:45 -0800588}