1 /*
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 
17 package com.android.server.wm;
18 
19 import static android.app.ActivityManager.START_CANCELED;
20 import static android.app.ActivityManager.START_SUCCESS;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
22 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
23 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
24 import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
25 
26 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
27 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
28 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
29 
30 import android.annotation.NonNull;
31 import android.annotation.Nullable;
32 import android.app.ActivityOptions;
33 import android.app.IApplicationThread;
34 import android.content.ComponentName;
35 import android.content.ContentResolver;
36 import android.content.Intent;
37 import android.content.pm.ActivityInfo;
38 import android.content.pm.ApplicationInfo;
39 import android.content.pm.PackageManager;
40 import android.content.pm.ResolveInfo;
41 import android.os.Binder;
42 import android.os.Bundle;
43 import android.os.IBinder;
44 import android.os.UserHandle;
45 import android.provider.Settings;
46 import android.util.Slog;
47 import android.util.SparseArray;
48 import android.view.RemoteAnimationAdapter;
49 
50 import com.android.internal.annotations.VisibleForTesting;
51 import com.android.internal.util.ArrayUtils;
52 import com.android.server.am.ActivityManagerService;
53 import com.android.server.am.PendingIntentRecord;
54 import com.android.server.uri.NeededUriGrants;
55 import com.android.server.wm.ActivityStarter.DefaultFactory;
56 import com.android.server.wm.ActivityStarter.Factory;
57 
58 import java.io.PrintWriter;
59 import java.util.List;
60 
61 /**
62  * Controller for delegating activity launches.
63  *
64  * This class' main objective is to take external activity start requests and prepare them into
65  * a series of discrete activity launches that can be handled by an {@link ActivityStarter}. It is
66  * also responsible for handling logic that happens around an activity launch, but doesn't
67  * necessarily influence the activity start. Examples include power hint management, processing
68  * through the pending activity list, and recording home activity launches.
69  */
70 public class ActivityStartController {
71     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStartController" : TAG_ATM;
72 
73     private static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 1;
74 
75     private final ActivityTaskManagerService mService;
76     private final ActivityTaskSupervisor mSupervisor;
77 
78     /** Last home activity record we attempted to start. */
79     private ActivityRecord mLastHomeActivityStartRecord;
80 
81     /** Temporary array to capture start activity results */
82     private ActivityRecord[] tmpOutRecord = new ActivityRecord[1];
83 
84     /** The result of the last home activity we attempted to start. */
85     private int mLastHomeActivityStartResult;
86 
87     private final Factory mFactory;
88 
89     private final PendingRemoteAnimationRegistry mPendingRemoteAnimationRegistry;
90 
91     boolean mCheckedForSetup = false;
92 
93     /**
94      * TODO(b/64750076): Capture information necessary for dump and
95      * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object
96      * around
97      */
98     private ActivityStarter mLastStarter;
99 
ActivityStartController(ActivityTaskManagerService service)100     ActivityStartController(ActivityTaskManagerService service) {
101         this(service, service.mTaskSupervisor,
102                 new DefaultFactory(service, service.mTaskSupervisor,
103                     new ActivityStartInterceptor(service, service.mTaskSupervisor)));
104     }
105 
106     @VisibleForTesting
ActivityStartController(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, Factory factory)107     ActivityStartController(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor,
108             Factory factory) {
109         mService = service;
110         mSupervisor = supervisor;
111         mFactory = factory;
112         mFactory.setController(this);
113         mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
114                 service.mH);
115     }
116 
117     /**
118      * @return A starter to configure and execute starting an activity. It is valid until after
119      *         {@link ActivityStarter#execute} is invoked. At that point, the starter should be
120      *         considered invalid and no longer modified or used.
121      */
obtainStarter(Intent intent, String reason)122     ActivityStarter obtainStarter(Intent intent, String reason) {
123         return mFactory.obtain().setIntent(intent).setReason(reason);
124     }
125 
onExecutionComplete(ActivityStarter starter)126     void onExecutionComplete(ActivityStarter starter) {
127         if (mLastStarter == null) {
128             mLastStarter = mFactory.obtain();
129         }
130 
131         mLastStarter.set(starter);
132         mFactory.recycle(starter);
133     }
134 
135     /**
136      * TODO(b/64750076): usage of this doesn't seem right. We're making decisions based off the
137      * last starter for an arbitrary task record. Re-evaluate whether we can remove.
138      */
postStartActivityProcessingForLastStarter(ActivityRecord r, int result, Task targetRootTask)139     void postStartActivityProcessingForLastStarter(ActivityRecord r, int result,
140             Task targetRootTask) {
141         if (mLastStarter == null) {
142             return;
143         }
144 
145         mLastStarter.postStartActivityProcessing(r, result, targetRootTask);
146     }
147 
startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, TaskDisplayArea taskDisplayArea)148     void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
149             TaskDisplayArea taskDisplayArea) {
150         final ActivityOptions options = ActivityOptions.makeBasic();
151         options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
152         if (!ActivityRecord.isResolverActivity(aInfo.name)) {
153             // The resolver activity shouldn't be put in root home task because when the
154             // foreground is standard type activity, the resolver activity should be put on the
155             // top of current foreground instead of bring root home task to front.
156             options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
157         }
158         final int displayId = taskDisplayArea.getDisplayId();
159         options.setLaunchDisplayId(displayId);
160         options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
161                 .toWindowContainerToken());
162 
163         // The home activity will be started later, defer resuming to avoid unnecessary operations
164         // (e.g. start home recursively) when creating root home task.
165         mSupervisor.beginDeferResume();
166         final Task rootHomeTask;
167         try {
168             // Make sure root home task exists on display area.
169             rootHomeTask = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
170         } finally {
171             mSupervisor.endDeferResume();
172         }
173 
174         mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
175                 .setOutActivity(tmpOutRecord)
176                 .setCallingUid(0)
177                 .setActivityInfo(aInfo)
178                 .setActivityOptions(options.toBundle())
179                 .execute();
180         mLastHomeActivityStartRecord = tmpOutRecord[0];
181         if (rootHomeTask.mInResumeTopActivity) {
182             // If we are in resume section already, home activity will be initialized, but not
183             // resumed (to avoid recursive resume) and will stay that way until something pokes it
184             // again. We need to schedule another resume.
185             mSupervisor.scheduleResumeTopActivities();
186         }
187     }
188 
189     /**
190      * Starts the "new version setup screen" if appropriate.
191      */
startSetupActivity()192     void startSetupActivity() {
193         // Only do this once per boot.
194         if (mCheckedForSetup) {
195             return;
196         }
197 
198         // We will show this screen if the current one is a different
199         // version than the last one shown, and we are not running in
200         // low-level factory test mode.
201         final ContentResolver resolver = mService.mContext.getContentResolver();
202         if (mService.mFactoryTest != FACTORY_TEST_LOW_LEVEL
203                 && Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
204             mCheckedForSetup = true;
205 
206             // See if we should be showing the platform update setup UI.
207             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
208             final List<ResolveInfo> ris =
209                     mService.mContext.getPackageManager().queryIntentActivities(intent,
210                             PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA
211                                     | ActivityManagerService.STOCK_PM_FLAGS);
212             if (!ris.isEmpty()) {
213                 final ResolveInfo ri = ris.get(0);
214                 String vers = ri.activityInfo.metaData != null
215                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
216                         : null;
217                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
218                     vers = ri.activityInfo.applicationInfo.metaData.getString(
219                             Intent.METADATA_SETUP_VERSION);
220                 }
221                 String lastVers = Settings.Secure.getString(
222                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
223                 if (vers != null && !vers.equals(lastVers)) {
224                     intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
225                     intent.setComponent(new ComponentName(
226                             ri.activityInfo.packageName, ri.activityInfo.name));
227                     obtainStarter(intent, "startSetupActivity")
228                             .setCallingUid(0)
229                             .setActivityInfo(ri.activityInfo)
230                             .execute();
231                 }
232             }
233         }
234     }
235 
236     /**
237      * If {@code validateIncomingUser} is true, check {@code targetUserId} against the real calling
238      * user ID inferred from {@code realCallingUid}, then return the resolved user-id, taking into
239      * account "current user", etc.
240      *
241      * If {@code validateIncomingUser} is false, it skips the above check, but instead
242      * ensures {@code targetUserId} is a real user ID and not a special user ID such as
243      * {@link android.os.UserHandle#USER_ALL}, etc.
244      */
checkTargetUser(int targetUserId, boolean validateIncomingUser, int realCallingPid, int realCallingUid, String reason)245     int checkTargetUser(int targetUserId, boolean validateIncomingUser,
246             int realCallingPid, int realCallingUid, String reason) {
247         if (validateIncomingUser) {
248             return mService.handleIncomingUser(
249                     realCallingPid, realCallingUid, targetUserId, reason);
250         } else {
251             mService.mAmInternal.ensureNotSpecialUser(targetUserId);
252             return targetUserId;
253         }
254     }
255 
startActivityInPackage(int uid, int realCallingPid, int realCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, SafeActivityOptions options, int userId, Task inTask, String reason, boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)256     final int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
257             String callingPackage, @Nullable String callingFeatureId, Intent intent,
258             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
259             int startFlags, SafeActivityOptions options, int userId, Task inTask, String reason,
260             boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent,
261             boolean allowBackgroundActivityStart) {
262 
263         userId = checkTargetUser(userId, validateIncomingUser, realCallingPid, realCallingUid,
264                 reason);
265 
266         // TODO: Switch to user app stacks here.
267         return obtainStarter(intent, reason)
268                 .setCallingUid(uid)
269                 .setRealCallingPid(realCallingPid)
270                 .setRealCallingUid(realCallingUid)
271                 .setCallingPackage(callingPackage)
272                 .setCallingFeatureId(callingFeatureId)
273                 .setResolvedType(resolvedType)
274                 .setResultTo(resultTo)
275                 .setResultWho(resultWho)
276                 .setRequestCode(requestCode)
277                 .setStartFlags(startFlags)
278                 .setActivityOptions(options)
279                 .setUserId(userId)
280                 .setInTask(inTask)
281                 .setOriginatingPendingIntent(originatingPendingIntent)
282                 .setAllowBackgroundActivityStart(allowBackgroundActivityStart)
283                 .execute();
284     }
285 
286     /**
287      * Start intents as a package.
288      *
289      * @param uid Make a call as if this UID did.
290      * @param callingPackage Make a call as if this package did.
291      * @param callingFeatureId Make a call as if this feature in the package did.
292      * @param intents Intents to start.
293      * @param userId Start the intents on this user.
294      * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
295      * @param originatingPendingIntent PendingIntentRecord that originated this activity start or
296      *        null if not originated by PendingIntent
297      */
startActivitiesInPackage(int uid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)298     final int startActivitiesInPackage(int uid, String callingPackage,
299             @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes,
300             IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser,
301             PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
302         return startActivitiesInPackage(uid, 0 /* realCallingPid */, -1 /* realCallingUid */,
303                 callingPackage, callingFeatureId, intents, resolvedTypes, resultTo, options, userId,
304                 validateIncomingUser, originatingPendingIntent, allowBackgroundActivityStart);
305     }
306 
307     /**
308      * Start intents as a package.
309      *
310      * @param uid Make a call as if this UID did.
311      * @param realCallingPid PID of the real caller.
312      * @param realCallingUid UID of the real caller.
313      * @param callingPackage Make a call as if this package did.
314      * @param intents Intents to start.
315      * @param userId Start the intents on this user.
316      * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
317      * @param originatingPendingIntent PendingIntentRecord that originated this activity start or
318      *        null if not originated by PendingIntent
319      */
startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)320     final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,
321             String callingPackage, @Nullable String callingFeatureId, Intent[] intents,
322             String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
323             boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent,
324             boolean allowBackgroundActivityStart) {
325 
326         final String reason = "startActivityInPackage";
327 
328         userId = checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(),
329                 Binder.getCallingUid(), reason);
330 
331         // TODO: Switch to user app stacks here.
332         return startActivities(null, uid, realCallingPid, realCallingUid, callingPackage,
333                 callingFeatureId, intents, resolvedTypes, resultTo, options, userId, reason,
334                 originatingPendingIntent, allowBackgroundActivityStart);
335     }
336 
startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid, int incomingRealCallingUid, String callingPackage, @Nullable String callingFeatureId, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, String reason, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart)337     int startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid,
338             int incomingRealCallingUid, String callingPackage, @Nullable String callingFeatureId,
339             Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options,
340             int userId, String reason, PendingIntentRecord originatingPendingIntent,
341             boolean allowBackgroundActivityStart) {
342         if (intents == null) {
343             throw new NullPointerException("intents is null");
344         }
345         if (resolvedTypes == null) {
346             throw new NullPointerException("resolvedTypes is null");
347         }
348         if (intents.length != resolvedTypes.length) {
349             throw new IllegalArgumentException("intents are length different than resolvedTypes");
350         }
351 
352         final int realCallingPid = incomingRealCallingPid != 0
353                 ? incomingRealCallingPid
354                 : Binder.getCallingPid();
355         final int realCallingUid = incomingRealCallingUid != -1
356                 ? incomingRealCallingUid
357                 : Binder.getCallingUid();
358 
359         int callingPid;
360         if (callingUid >= 0) {
361             callingPid = -1;
362         } else if (caller == null) {
363             callingPid = realCallingPid;
364             callingUid = realCallingUid;
365         } else {
366             callingPid = callingUid = -1;
367         }
368         final int filterCallingUid = ActivityStarter.computeResolveFilterUid(
369                 callingUid, realCallingUid, UserHandle.USER_NULL);
370         final SparseArray<String> startingUidPkgs = new SparseArray<>();
371         final long origId = Binder.clearCallingIdentity();
372         try {
373             intents = ArrayUtils.filterNotNull(intents, Intent[]::new);
374             final ActivityStarter[] starters = new ActivityStarter[intents.length];
375             // Do not hold WM global lock on this loop because when resolving intent, it may
376             // potentially acquire activity manager lock that leads to deadlock.
377             for (int i = 0; i < intents.length; i++) {
378                 Intent intent = intents[i];
379                 NeededUriGrants intentGrants = null;
380 
381                 // Refuse possible leaked file descriptors.
382                 if (intent.hasFileDescriptors()) {
383                     throw new IllegalArgumentException("File descriptors passed in Intent");
384                 }
385 
386                 // Get the flag earlier because the intent may be modified in resolveActivity below.
387                 final boolean componentSpecified = intent.getComponent() != null;
388                 // Don't modify the client's object!
389                 intent = new Intent(intent);
390 
391                 // Collect information about the target of the Intent.
392                 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i],
393                         0 /* startFlags */, null /* profilerInfo */, userId, filterCallingUid);
394                 aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
395 
396                 if (aInfo != null) {
397                     try {
398                         // Carefully collect grants without holding lock
399                         intentGrants = mSupervisor.mService.mUgmInternal
400                                 .checkGrantUriPermissionFromIntent(intent, filterCallingUid,
401                                         aInfo.applicationInfo.packageName,
402                                         UserHandle.getUserId(aInfo.applicationInfo.uid));
403                     } catch (SecurityException e) {
404                         Slog.d(TAG, "Not allowed to start activity since no uri permission.");
405                         return START_CANCELED;
406                     }
407 
408                     if ((aInfo.applicationInfo.privateFlags
409                             & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
410                         throw new IllegalArgumentException(
411                                 "FLAG_CANT_SAVE_STATE not supported here");
412                     }
413                     startingUidPkgs.put(aInfo.applicationInfo.uid,
414                             aInfo.applicationInfo.packageName);
415                 }
416 
417                 final boolean top = i == intents.length - 1;
418                 final SafeActivityOptions checkedOptions = top
419                         ? options
420                         : null;
421                 starters[i] = obtainStarter(intent, reason)
422                         .setIntentGrants(intentGrants)
423                         .setCaller(caller)
424                         .setResolvedType(resolvedTypes[i])
425                         .setActivityInfo(aInfo)
426                         .setRequestCode(-1)
427                         .setCallingPid(callingPid)
428                         .setCallingUid(callingUid)
429                         .setCallingPackage(callingPackage)
430                         .setCallingFeatureId(callingFeatureId)
431                         .setRealCallingPid(realCallingPid)
432                         .setRealCallingUid(realCallingUid)
433                         .setActivityOptions(checkedOptions)
434                         .setComponentSpecified(componentSpecified)
435 
436                         // Top activity decides on animation being run, so we allow only for the
437                         // top one as otherwise an activity below might consume it.
438                         .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/)
439                         .setOriginatingPendingIntent(originatingPendingIntent)
440                         .setAllowBackgroundActivityStart(allowBackgroundActivityStart);
441             }
442             // Log if the activities to be started have different uids.
443             if (startingUidPkgs.size() > 1) {
444                 final StringBuilder sb = new StringBuilder("startActivities: different apps [");
445                 final int size = startingUidPkgs.size();
446                 for (int i = 0; i < size; i++) {
447                     sb.append(startingUidPkgs.valueAt(i)).append(i == size - 1 ? "]" : ", ");
448                 }
449                 sb.append(" from ").append(callingPackage);
450                 Slog.wtf(TAG, sb.toString());
451             }
452 
453             final IBinder sourceResultTo = resultTo;
454             final ActivityRecord[] outActivity = new ActivityRecord[1];
455             // Lock the loop to ensure the activities launched in a sequence.
456             synchronized (mService.mGlobalLock) {
457                 mService.deferWindowLayout();
458                 try {
459                     for (int i = 0; i < starters.length; i++) {
460                         final int startResult = starters[i].setResultTo(resultTo)
461                                 .setOutActivity(outActivity).execute();
462                         if (startResult < START_SUCCESS) {
463                             // Abort by error result and recycle unused starters.
464                             for (int j = i + 1; j < starters.length; j++) {
465                                 mFactory.recycle(starters[j]);
466                             }
467                             return startResult;
468                         }
469                         final ActivityRecord started = outActivity[0];
470                         if (started != null && started.getUid() == filterCallingUid) {
471                             // Only the started activity which has the same uid as the source caller
472                             // can be the caller of next activity.
473                             resultTo = started.appToken;
474                         } else {
475                             resultTo = sourceResultTo;
476                             // Different apps not adjacent to the caller are forced to be new task.
477                             if (i < starters.length - 1) {
478                                 starters[i + 1].getIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
479                             }
480                         }
481                     }
482                 } finally {
483                     mService.continueWindowLayout();
484                 }
485             }
486         } finally {
487             Binder.restoreCallingIdentity(origId);
488         }
489 
490         return START_SUCCESS;
491     }
492 
493     /**
494      * Starts an activity in the TaskFragment.
495      * @param taskFragment TaskFragment {@link TaskFragment} to start the activity in.
496      * @param activityIntent intent to start the activity.
497      * @param activityOptions ActivityOptions to start the activity with.
498      * @param resultTo the caller activity
499      * @param callingUid the caller uid
500      * @param callingPid the caller pid
501      * @return the start result.
502      */
startActivityInTaskFragment(@onNull TaskFragment taskFragment, @NonNull Intent activityIntent, @Nullable Bundle activityOptions, @Nullable IBinder resultTo, int callingUid, int callingPid)503     int startActivityInTaskFragment(@NonNull TaskFragment taskFragment,
504             @NonNull Intent activityIntent, @Nullable Bundle activityOptions,
505             @Nullable IBinder resultTo, int callingUid, int callingPid) {
506         final ActivityRecord caller =
507                 resultTo != null ? ActivityRecord.forTokenLocked(resultTo) : null;
508         return obtainStarter(activityIntent, "startActivityInTaskFragment")
509                 .setActivityOptions(activityOptions)
510                 .setInTaskFragment(taskFragment)
511                 .setResultTo(resultTo)
512                 .setRequestCode(-1)
513                 .setCallingUid(callingUid)
514                 .setCallingPid(callingPid)
515                 .setUserId(caller != null ? caller.mUserId : mService.getCurrentUserId())
516                 .execute();
517     }
518 
registerRemoteAnimationForNextActivityStart(String packageName, RemoteAnimationAdapter adapter)519     void registerRemoteAnimationForNextActivityStart(String packageName,
520             RemoteAnimationAdapter adapter) {
521         mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter);
522     }
523 
getPendingRemoteAnimationRegistry()524     PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() {
525         return mPendingRemoteAnimationRegistry;
526     }
527 
dumpLastHomeActivityStartResult(PrintWriter pw, String prefix)528     void dumpLastHomeActivityStartResult(PrintWriter pw, String prefix) {
529         pw.print(prefix);
530         pw.print("mLastHomeActivityStartResult=");
531         pw.println(mLastHomeActivityStartResult);
532     }
533 
dump(PrintWriter pw, String prefix, String dumpPackage)534     void dump(PrintWriter pw, String prefix, String dumpPackage) {
535         boolean dumped = false;
536 
537         final boolean dumpPackagePresent = dumpPackage != null;
538 
539         if (mLastHomeActivityStartRecord != null && (!dumpPackagePresent
540                 || dumpPackage.equals(mLastHomeActivityStartRecord.packageName))) {
541             if (!dumped) {
542                 dumped = true;
543                 dumpLastHomeActivityStartResult(pw, prefix);
544             }
545             pw.print(prefix);
546             pw.println("mLastHomeActivityStartRecord:");
547             mLastHomeActivityStartRecord.dump(pw, prefix + "  ", true /* dumpAll */);
548         }
549 
550         if (mLastStarter != null) {
551             final boolean dump = !dumpPackagePresent
552                     || mLastStarter.relatedToPackage(dumpPackage)
553                     || (mLastHomeActivityStartRecord != null
554                             && dumpPackage.equals(mLastHomeActivityStartRecord.packageName));
555 
556             if (dump) {
557                 if (!dumped) {
558                     dumped = true;
559                     dumpLastHomeActivityStartResult(pw, prefix);
560                 }
561                 pw.print(prefix);
562                 mLastStarter.dump(pw, prefix + "  ");
563 
564                 if (dumpPackagePresent) {
565                     return;
566                 }
567             }
568         }
569 
570         if (!dumped) {
571             pw.print(prefix);
572             pw.println("(nothing)");
573         }
574     }
575 }
576