ActivityStackSupervisor.java revision a7cfbe0e548ac76f20915b65851b8bc9095aa541
1/*
2 * Copyright (C) 2013 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
17package com.android.server.am;
18
19import static android.Manifest.permission.START_ANY_ACTIVITY;
20import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
21import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
22import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
23import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
24import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
25import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
26import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
27import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
28import static android.content.pm.PackageManager.PERMISSION_GRANTED;
29import static com.android.server.am.ActivityManagerDebugConfig.*;
30import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
31import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
32import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
33import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
34import static com.android.server.am.ActivityStack.ActivityState.*;
35import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
36import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
37import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
38import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
39import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
40
41import android.Manifest;
42import android.app.Activity;
43import android.app.ActivityManager;
44import android.app.ActivityManager.StackInfo;
45import android.app.ActivityOptions;
46import android.app.AppGlobals;
47import android.app.AppOpsManager;
48import android.app.IActivityContainer;
49import android.app.IActivityContainerCallback;
50import android.app.IActivityManager;
51import android.app.IApplicationThread;
52import android.app.PendingIntent;
53import android.app.ProfilerInfo;
54import android.app.ActivityManager.RunningTaskInfo;
55import android.app.IActivityManager.WaitResult;
56import android.app.ResultInfo;
57import android.app.StatusBarManager;
58import android.app.admin.IDevicePolicyManager;
59import android.content.ComponentName;
60import android.content.Context;
61import android.content.IIntentSender;
62import android.content.Intent;
63import android.content.IntentSender;
64import android.content.pm.ActivityInfo;
65import android.content.pm.ApplicationInfo;
66import android.content.pm.PackageInfo;
67import android.content.pm.PackageManager;
68import android.content.pm.ResolveInfo;
69import android.content.res.Configuration;
70import android.graphics.Point;
71import android.graphics.Rect;
72import android.hardware.display.DisplayManager;
73import android.hardware.display.DisplayManager.DisplayListener;
74import android.hardware.display.DisplayManagerGlobal;
75import android.hardware.display.VirtualDisplay;
76import android.hardware.input.InputManager;
77import android.hardware.input.InputManagerInternal;
78import android.net.Uri;
79import android.os.Binder;
80import android.os.Bundle;
81import android.os.Debug;
82import android.os.Handler;
83import android.os.IBinder;
84import android.os.Looper;
85import android.os.Message;
86import android.os.ParcelFileDescriptor;
87import android.os.PowerManager;
88import android.os.Process;
89import android.os.RemoteException;
90import android.os.ServiceManager;
91import android.os.SystemClock;
92import android.os.TransactionTooLargeException;
93import android.os.UserHandle;
94import android.os.WorkSource;
95import android.provider.MediaStore;
96import android.provider.Settings;
97import android.provider.Settings.SettingNotFoundException;
98import android.service.voice.IVoiceInteractionSession;
99import android.util.ArrayMap;
100import android.util.ArraySet;
101import android.util.EventLog;
102import android.util.Slog;
103import android.util.SparseArray;
104
105import android.util.SparseIntArray;
106import android.view.Display;
107import android.view.DisplayInfo;
108import android.view.InputEvent;
109import android.view.Surface;
110import com.android.internal.app.HeavyWeightSwitcherActivity;
111import com.android.internal.app.IVoiceInteractor;
112import com.android.internal.content.ReferrerIntent;
113import com.android.internal.os.TransferPipe;
114import com.android.internal.statusbar.IStatusBarService;
115import com.android.internal.util.ArrayUtils;
116import com.android.internal.widget.LockPatternUtils;
117import com.android.server.LocalServices;
118import com.android.server.am.ActivityStack.ActivityState;
119import com.android.server.wm.WindowManagerService;
120
121
122import java.io.FileDescriptor;
123import java.io.IOException;
124import java.io.PrintWriter;
125import java.util.ArrayList;
126import java.util.Arrays;
127import java.util.List;
128import java.util.Set;
129
130public final class ActivityStackSupervisor implements DisplayListener {
131    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
132    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
133    private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
134    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
135    private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
136    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
137    private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
138    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
139    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
140    private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
141    private static final String TAG_STACK = TAG + POSTFIX_STACK;
142    private static final String TAG_STATES = TAG + POSTFIX_STATES;
143    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
144    private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
145    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
146    private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
147
148    public static final int HOME_STACK_ID = 0;
149
150    /** How long we wait until giving up on the last activity telling us it is idle. */
151    static final int IDLE_TIMEOUT = 10 * 1000;
152
153    /** How long we can hold the sleep wake lock before giving up. */
154    static final int SLEEP_TIMEOUT = 5 * 1000;
155
156    // How long we can hold the launch wake lock before giving up.
157    static final int LAUNCH_TIMEOUT = 10 * 1000;
158
159    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
160    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
161    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
162    static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
163    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
164    static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
165    static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
166    static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
167    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
168    static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
169    static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
170    static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
171    static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
172    static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
173
174    private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
175
176    private static final String LOCK_TASK_TAG = "Lock-to-App";
177
178    // Activity actions an app cannot start if it uses a permission which is not granted.
179    private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
180            new ArrayMap<>();
181    static {
182        ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE,
183                Manifest.permission.CAMERA);
184        ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE,
185                Manifest.permission.CAMERA);
186        ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL,
187                Manifest.permission.CALL_PHONE);
188    }
189
190    /** Action restriction: launching the activity is not restricted. */
191    private static final int ACTIVITY_RESTRICTION_NONE = 0;
192    /** Action restriction: launching the activity is restricted by a permission. */
193    private static final int ACTIVITY_RESTRICTION_PERMISSION = 1;
194    /** Action restriction: launching the activity is restricted by an app op. */
195    private static final int ACTIVITY_RESTRICTION_APPOP = 2;
196
197    /** Status Bar Service **/
198    private IBinder mToken = new Binder();
199    private IStatusBarService mStatusBarService;
200    private IDevicePolicyManager mDevicePolicyManager;
201
202    // For debugging to make sure the caller when acquiring/releasing our
203    // wake lock is the system process.
204    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
205
206    final ActivityManagerService mService;
207
208    private final RecentTasks mRecentTasks;
209
210    final ActivityStackSupervisorHandler mHandler;
211
212    /** Short cut */
213    WindowManagerService mWindowManager;
214    DisplayManager mDisplayManager;
215
216    /** Identifier counter for all ActivityStacks */
217    private int mLastStackId = HOME_STACK_ID;
218
219    /** Task identifier that activities are currently being started in.  Incremented each time a
220     * new task is created. */
221    private int mCurTaskId = 0;
222
223    /** The current user */
224    private int mCurrentUser;
225
226    /** The stack containing the launcher app. Assumed to always be attached to
227     * Display.DEFAULT_DISPLAY. */
228    private ActivityStack mHomeStack;
229
230    /** The stack currently receiving input or launching the next activity. */
231    private ActivityStack mFocusedStack;
232
233    /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
234     * been resumed. If stacks are changing position this will hold the old stack until the new
235     * stack becomes resumed after which it will be set to mFocusedStack. */
236    private ActivityStack mLastFocusedStack;
237
238    /** List of activities that are waiting for a new activity to become visible before completing
239     * whatever operation they are supposed to do. */
240    final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
241
242    /** List of processes waiting to find out about the next visible activity. */
243    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>();
244
245    /** List of processes waiting to find out about the next launched activity. */
246    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>();
247
248    /** List of activities that are ready to be stopped, but waiting for the next activity to
249     * settle down before doing so. */
250    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
251
252    /** List of activities that are ready to be finished, but waiting for the previous activity to
253     * settle down before doing so.  It contains ActivityRecord objects. */
254    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
255
256    /** List of activities that are in the process of going to sleep. */
257    final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
258
259    /** Used on user changes */
260    final ArrayList<UserState> mStartingUsers = new ArrayList<>();
261
262    /** Used to queue up any background users being started */
263    final ArrayList<UserState> mStartingBackgroundUsers = new ArrayList<>();
264
265    /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
266     * is being brought in front of us. */
267    boolean mUserLeaving = false;
268
269    /** Set when we have taken too long waiting to go to sleep. */
270    boolean mSleepTimeout = false;
271
272    /** Indicates if we are running on a Leanback-only (TV) device. Only initialized after
273     * setWindowManager is called. **/
274    private boolean mLeanbackOnlyDevice;
275
276    /**
277     * We don't want to allow the device to go to sleep while in the process
278     * of launching an activity.  This is primarily to allow alarm intent
279     * receivers to launch an activity and get that to run before the device
280     * goes back to sleep.
281     */
282    PowerManager.WakeLock mLaunchingActivity;
283
284    /**
285     * Set when the system is going to sleep, until we have
286     * successfully paused the current activity and released our wake lock.
287     * At that point the system is allowed to actually sleep.
288     */
289    PowerManager.WakeLock mGoingToSleep;
290
291    /** Stack id of the front stack when user switched, indexed by userId. */
292    SparseIntArray mUserStackInFront = new SparseIntArray(2);
293
294    // TODO: Add listener for removal of references.
295    /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
296    private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>();
297
298    /** Mapping from displayId to display current state */
299    private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>();
300
301    InputManagerInternal mInputManagerInternal;
302
303    /** The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks
304     * may be finished until there is only one entry left. If this is empty the system is not
305     * in lockTask mode. */
306    ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>();
307    /** Store the current lock task mode. Possible values:
308     * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
309     * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
310     */
311    private int mLockTaskModeState;
312    /**
313     * Notifies the user when entering/exiting lock-task.
314     */
315    private LockTaskNotify mLockTaskNotify;
316
317    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<>();
318
319    /** Used to keep resumeTopActivityLocked() from being entered recursively */
320    boolean inResumeTopActivity;
321
322    /**
323     * Description of a request to start a new activity, which has been held
324     * due to app switches being disabled.
325     */
326    static class PendingActivityLaunch {
327        final ActivityRecord r;
328        final ActivityRecord sourceRecord;
329        final int startFlags;
330        final ActivityStack stack;
331
332        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
333                int _startFlags, ActivityStack _stack) {
334            r = _r;
335            sourceRecord = _sourceRecord;
336            startFlags = _startFlags;
337            stack = _stack;
338        }
339    }
340
341    public ActivityStackSupervisor(ActivityManagerService service, RecentTasks recentTasks) {
342        mService = service;
343        mRecentTasks = recentTasks;
344        mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
345    }
346
347    /**
348     * At the time when the constructor runs, the power manager has not yet been
349     * initialized.  So we initialize our wakelocks afterwards.
350     */
351    void initPowerManagement() {
352        PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
353        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
354        mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*launch*");
355        mLaunchingActivity.setReferenceCounted(false);
356    }
357
358    // This function returns a IStatusBarService. The value is from ServiceManager.
359    // getService and is cached.
360    private IStatusBarService getStatusBarService() {
361        synchronized (mService) {
362            if (mStatusBarService == null) {
363                mStatusBarService = IStatusBarService.Stub.asInterface(
364                    ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
365                if (mStatusBarService == null) {
366                    Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
367                }
368            }
369            return mStatusBarService;
370        }
371    }
372
373    private IDevicePolicyManager getDevicePolicyManager() {
374        synchronized (mService) {
375            if (mDevicePolicyManager == null) {
376                mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
377                    ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE));
378                if (mDevicePolicyManager == null) {
379                    Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
380                }
381            }
382            return mDevicePolicyManager;
383        }
384    }
385
386    void setWindowManager(WindowManagerService wm) {
387        synchronized (mService) {
388            mWindowManager = wm;
389
390            mDisplayManager =
391                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
392            mDisplayManager.registerDisplayListener(this, null);
393
394            Display[] displays = mDisplayManager.getDisplays();
395            for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
396                final int displayId = displays[displayNdx].getDisplayId();
397                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
398                if (activityDisplay.mDisplay == null) {
399                    throw new IllegalStateException("Default Display does not exist");
400                }
401                mActivityDisplays.put(displayId, activityDisplay);
402            }
403
404            createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
405            mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
406
407            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
408
409            // Initialize this here, now that we can get a valid reference to PackageManager.
410            mLeanbackOnlyDevice = isLeanbackOnlyDevice();
411        }
412    }
413
414    void notifyActivityDrawnForKeyguard() {
415        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
416        mWindowManager.notifyActivityDrawnForKeyguard();
417    }
418
419    ActivityStack getFocusedStack() {
420        return mFocusedStack;
421    }
422
423    ActivityStack getLastStack() {
424        return mLastFocusedStack;
425    }
426
427    /** Top of all visible stacks is/should always be equal to the focused stack.
428     * Use {@link ActivityStack#isStackVisibleLocked} to determine if a specific
429     * stack is visible or not. */
430    boolean isFrontStack(ActivityStack stack) {
431        if (stack == null) {
432            return false;
433        }
434
435        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
436        if (parent != null) {
437            stack = parent.task.stack;
438        }
439        return stack == mFocusedStack;
440    }
441
442    void moveHomeStack(boolean toFront, String reason) {
443        moveHomeStack(toFront, reason, null);
444    }
445
446    void moveHomeStack(boolean toFront, String reason, ActivityStack lastFocusedStack) {
447        ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
448        final int topNdx = stacks.size() - 1;
449        if (topNdx <= 0) {
450            return;
451        }
452
453        // The home stack should either be at the top or bottom of the stack list.
454        if ((toFront && (stacks.get(topNdx) != mHomeStack))
455                || (!toFront && (stacks.get(0) != mHomeStack))) {
456            if (DEBUG_STACK) Slog.d(TAG_STACK, "moveHomeTask: topStack old="
457                    + ((lastFocusedStack != null) ? lastFocusedStack : stacks.get(topNdx))
458                    + " new=" + mFocusedStack);
459            stacks.remove(mHomeStack);
460            stacks.add(toFront ? topNdx : 0, mHomeStack);
461        }
462
463        if (lastFocusedStack != null) {
464            mLastFocusedStack = lastFocusedStack;
465        }
466        mFocusedStack = stacks.get(topNdx);
467
468        EventLog.writeEvent(EventLogTags.AM_HOME_STACK_MOVED,
469                mCurrentUser, toFront ? 1 : 0, stacks.get(topNdx).getStackId(),
470                mFocusedStack == null ? -1 : mFocusedStack.getStackId(), reason);
471
472        if (mService.mBooting || !mService.mBooted) {
473            final ActivityRecord r = topRunningActivityLocked();
474            if (r != null && r.idle) {
475                checkFinishBootingLocked();
476            }
477        }
478    }
479
480    /** Returns true if the focus activity was adjusted to the home stack top activity. */
481    boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
482        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
483            mWindowManager.showRecentApps();
484            return false;
485        }
486
487        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
488
489        final ActivityRecord top = getHomeActivity();
490        if (top == null) {
491            return false;
492        }
493        mService.setFocusedActivityLocked(top, reason);
494        return true;
495    }
496
497    boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
498        if (!mService.mBooting && !mService.mBooted) {
499            // Not ready yet!
500            return false;
501        }
502
503        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
504            mWindowManager.showRecentApps();
505            return false;
506        }
507
508        if (prev != null) {
509            prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
510        }
511
512        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
513        ActivityRecord r = getHomeActivity();
514        if (r != null) {
515            mService.setFocusedActivityLocked(r, reason);
516            return resumeTopActivitiesLocked(mHomeStack, prev, null);
517        }
518        return mService.startHomeActivityLocked(mCurrentUser, reason);
519    }
520
521    TaskRecord anyTaskForIdLocked(int id) {
522        return anyTaskForIdLocked(id, true);
523    }
524
525    /**
526     * Returns a {@link TaskRecord} for the input id if available. Null otherwise.
527     * @param id Id of the task we would like returned.
528     * @param restoreFromRecents If the id was not in the active list, but was found in recents,
529     *                           restore the task from recents to the active list.
530     */
531    TaskRecord anyTaskForIdLocked(int id, boolean restoreFromRecents) {
532        int numDisplays = mActivityDisplays.size();
533        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
534            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
535            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
536                ActivityStack stack = stacks.get(stackNdx);
537                TaskRecord task = stack.taskForIdLocked(id);
538                if (task != null) {
539                    return task;
540                }
541            }
542        }
543
544        // Don't give up! Look in recents.
545        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
546        TaskRecord task = mRecentTasks.taskForIdLocked(id);
547        if (task == null) {
548            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
549            return null;
550        }
551
552        if (!restoreFromRecents) {
553            return task;
554        }
555
556        if (!restoreRecentTaskLocked(task)) {
557            if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
558                    "Couldn't restore task id=" + id + " found in recents");
559            return null;
560        }
561        if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
562        return task;
563    }
564
565    ActivityRecord isInAnyStackLocked(IBinder token) {
566        int numDisplays = mActivityDisplays.size();
567        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
568            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
569            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
570                final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token);
571                if (r != null) {
572                    return r;
573                }
574            }
575        }
576        return null;
577    }
578
579    void setNextTaskId(int taskId) {
580        if (taskId > mCurTaskId) {
581            mCurTaskId = taskId;
582        }
583    }
584
585    int getNextTaskId() {
586        do {
587            mCurTaskId++;
588            if (mCurTaskId <= 0) {
589                mCurTaskId = 1;
590            }
591        } while (anyTaskForIdLocked(mCurTaskId, false) != null);
592        return mCurTaskId;
593    }
594
595    ActivityRecord resumedAppLocked() {
596        ActivityStack stack = mFocusedStack;
597        if (stack == null) {
598            return null;
599        }
600        ActivityRecord resumedActivity = stack.mResumedActivity;
601        if (resumedActivity == null || resumedActivity.app == null) {
602            resumedActivity = stack.mPausingActivity;
603            if (resumedActivity == null || resumedActivity.app == null) {
604                resumedActivity = stack.topRunningActivityLocked(null);
605            }
606        }
607        return resumedActivity;
608    }
609
610    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
611        final String processName = app.processName;
612        boolean didSomething = false;
613        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
614            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
615            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
616                final ActivityStack stack = stacks.get(stackNdx);
617                if (!isFrontStack(stack)) {
618                    continue;
619                }
620                ActivityRecord hr = stack.topRunningActivityLocked(null);
621                if (hr != null) {
622                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
623                            && processName.equals(hr.processName)) {
624                        try {
625                            if (realStartActivityLocked(hr, app, true, true)) {
626                                didSomething = true;
627                            }
628                        } catch (RemoteException e) {
629                            Slog.w(TAG, "Exception in new application when starting activity "
630                                  + hr.intent.getComponent().flattenToShortString(), e);
631                            throw e;
632                        }
633                    }
634                }
635            }
636        }
637        if (!didSomething) {
638            ensureActivitiesVisibleLocked(null, 0);
639        }
640        return didSomething;
641    }
642
643    boolean allResumedActivitiesIdle() {
644        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
645            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
646            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
647                final ActivityStack stack = stacks.get(stackNdx);
648                if (!isFrontStack(stack) || stack.numActivities() == 0) {
649                    continue;
650                }
651                final ActivityRecord resumedActivity = stack.mResumedActivity;
652                if (resumedActivity == null || !resumedActivity.idle) {
653                    if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
654                             + stack.mStackId + " " + resumedActivity + " not idle");
655                    return false;
656                }
657            }
658        }
659        return true;
660    }
661
662    boolean allResumedActivitiesComplete() {
663        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
664            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
665            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
666                final ActivityStack stack = stacks.get(stackNdx);
667                if (isFrontStack(stack)) {
668                    final ActivityRecord r = stack.mResumedActivity;
669                    if (r != null && r.state != RESUMED) {
670                        return false;
671                    }
672                }
673            }
674        }
675        // TODO: Not sure if this should check if all Paused are complete too.
676        if (DEBUG_STACK) Slog.d(TAG_STACK,
677                "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
678                mLastFocusedStack + " to=" + mFocusedStack);
679        mLastFocusedStack = mFocusedStack;
680        return true;
681    }
682
683    boolean allResumedActivitiesVisible() {
684        boolean foundResumed = false;
685        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
686            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
687            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
688                final ActivityStack stack = stacks.get(stackNdx);
689                final ActivityRecord r = stack.mResumedActivity;
690                if (r != null) {
691                    if (!r.nowVisible || mWaitingVisibleActivities.contains(r)) {
692                        return false;
693                    }
694                    foundResumed = true;
695                }
696            }
697        }
698        return foundResumed;
699    }
700
701    /**
702     * Pause all activities in either all of the stacks or just the back stacks.
703     * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
704     * @return true if any activity was paused as a result of this call.
705     */
706    boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
707        boolean someActivityPaused = false;
708        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
709            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
710            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
711                final ActivityStack stack = stacks.get(stackNdx);
712                if (!isFrontStack(stack) && stack.mResumedActivity != null) {
713                    if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
714                            " mResumedActivity=" + stack.mResumedActivity);
715                    someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
716                            dontWait);
717                }
718            }
719        }
720        return someActivityPaused;
721    }
722
723    boolean allPausedActivitiesComplete() {
724        boolean pausing = true;
725        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
726            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
727            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
728                final ActivityStack stack = stacks.get(stackNdx);
729                final ActivityRecord r = stack.mPausingActivity;
730                if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) {
731                    if (DEBUG_STATES) {
732                        Slog.d(TAG_STATES,
733                                "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
734                        pausing = false;
735                    } else {
736                        return false;
737                    }
738                }
739            }
740        }
741        return pausing;
742    }
743
744    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
745            boolean resuming, boolean dontWait) {
746        // TODO: Put all stacks in supervisor and iterate through them instead.
747        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
748            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
749            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
750                final ActivityStack stack = stacks.get(stackNdx);
751                if (stack.mResumedActivity != null &&
752                        stack.mActivityContainer.mParentActivity == parent) {
753                    stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
754                }
755            }
756        }
757    }
758
759    void reportActivityVisibleLocked(ActivityRecord r) {
760        sendWaitingVisibleReportLocked(r);
761    }
762
763    void sendWaitingVisibleReportLocked(ActivityRecord r) {
764        boolean changed = false;
765        for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
766            WaitResult w = mWaitingActivityVisible.get(i);
767            if (w.who == null) {
768                changed = true;
769                w.timeout = false;
770                if (r != null) {
771                    w.who = new ComponentName(r.info.packageName, r.info.name);
772                }
773                w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
774                w.thisTime = w.totalTime;
775            }
776        }
777        if (changed) {
778            mService.notifyAll();
779        }
780    }
781
782    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
783            long thisTime, long totalTime) {
784        boolean changed = false;
785        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
786            WaitResult w = mWaitingActivityLaunched.remove(i);
787            if (w.who == null) {
788                changed = true;
789                w.timeout = timeout;
790                if (r != null) {
791                    w.who = new ComponentName(r.info.packageName, r.info.name);
792                }
793                w.thisTime = thisTime;
794                w.totalTime = totalTime;
795            }
796        }
797        if (changed) {
798            mService.notifyAll();
799        }
800    }
801
802    ActivityRecord topRunningActivityLocked() {
803        final ActivityStack focusedStack = mFocusedStack;
804        ActivityRecord r = focusedStack.topRunningActivityLocked(null);
805        if (r != null) {
806            return r;
807        }
808
809        // Return to the home stack.
810        final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
811        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
812            final ActivityStack stack = stacks.get(stackNdx);
813            if (stack != focusedStack && isFrontStack(stack)) {
814                r = stack.topRunningActivityLocked(null);
815                if (r != null) {
816                    return r;
817                }
818            }
819        }
820        return null;
821    }
822
823    void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) {
824        // Gather all of the running tasks for each stack into runningTaskLists.
825        ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists =
826                new ArrayList<ArrayList<RunningTaskInfo>>();
827        final int numDisplays = mActivityDisplays.size();
828        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
829            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
830            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
831                final ActivityStack stack = stacks.get(stackNdx);
832                ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>();
833                runningTaskLists.add(stackTaskList);
834                stack.getTasksLocked(stackTaskList, callingUid, allowed);
835            }
836        }
837
838        // The lists are already sorted from most recent to oldest. Just pull the most recent off
839        // each list and add it to list. Stop when all lists are empty or maxNum reached.
840        while (maxNum > 0) {
841            long mostRecentActiveTime = Long.MIN_VALUE;
842            ArrayList<RunningTaskInfo> selectedStackList = null;
843            final int numTaskLists = runningTaskLists.size();
844            for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) {
845                ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx);
846                if (!stackTaskList.isEmpty()) {
847                    final long lastActiveTime = stackTaskList.get(0).lastActiveTime;
848                    if (lastActiveTime > mostRecentActiveTime) {
849                        mostRecentActiveTime = lastActiveTime;
850                        selectedStackList = stackTaskList;
851                    }
852                }
853            }
854            if (selectedStackList != null) {
855                list.add(selectedStackList.remove(0));
856                --maxNum;
857            } else {
858                break;
859            }
860        }
861    }
862
863    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
864            ProfilerInfo profilerInfo, int userId) {
865        // Collect information about the target of the Intent.
866        ActivityInfo aInfo;
867        try {
868            ResolveInfo rInfo =
869                AppGlobals.getPackageManager().resolveIntent(
870                        intent, resolvedType,
871                        PackageManager.MATCH_DEFAULT_ONLY
872                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
873            aInfo = rInfo != null ? rInfo.activityInfo : null;
874        } catch (RemoteException e) {
875            aInfo = null;
876        }
877
878        if (aInfo != null) {
879            // Store the found target back into the intent, because now that
880            // we have it we never want to do this again.  For example, if the
881            // user navigates back to this point in the history, we should
882            // always restart the exact same activity.
883            intent.setComponent(new ComponentName(
884                    aInfo.applicationInfo.packageName, aInfo.name));
885
886            // Don't debug things in the system process
887            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
888                if (!aInfo.processName.equals("system")) {
889                    mService.setDebugApp(aInfo.processName, true, false);
890                }
891            }
892
893            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
894                if (!aInfo.processName.equals("system")) {
895                    mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
896                }
897            }
898
899            if (profilerInfo != null) {
900                if (!aInfo.processName.equals("system")) {
901                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
902                }
903            }
904        }
905        return aInfo;
906    }
907
908    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
909        moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
910        startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
911                null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
912                null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
913                null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
914                0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */,
915                false /* componentSpecified */,
916                null /* outActivity */, null /* container */,  null /* inTask */);
917        if (inResumeTopActivity) {
918            // If we are in resume section already, home activity will be initialized, but not
919            // resumed (to avoid recursive resume) and will stay that way until something pokes it
920            // again. We need to schedule another resume.
921            scheduleResumeTopActivities();
922        }
923    }
924
925    final int startActivityMayWait(IApplicationThread caller, int callingUid,
926            String callingPackage, Intent intent, String resolvedType,
927            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
928            IBinder resultTo, String resultWho, int requestCode, int startFlags,
929            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
930            Bundle options, boolean ignoreTargetSecurity, int userId,
931            IActivityContainer iContainer, TaskRecord inTask) {
932        // Refuse possible leaked file descriptors
933        if (intent != null && intent.hasFileDescriptors()) {
934            throw new IllegalArgumentException("File descriptors passed in Intent");
935        }
936        boolean componentSpecified = intent.getComponent() != null;
937
938        // Don't modify the client's object!
939        intent = new Intent(intent);
940
941        // Collect information about the target of the Intent.
942        ActivityInfo aInfo =
943                resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
944
945        ActivityContainer container = (ActivityContainer)iContainer;
946        synchronized (mService) {
947            if (container != null && container.mParentActivity != null &&
948                    container.mParentActivity.state != RESUMED) {
949                // Cannot start a child activity if the parent is not resumed.
950                return ActivityManager.START_CANCELED;
951            }
952            final int realCallingPid = Binder.getCallingPid();
953            final int realCallingUid = Binder.getCallingUid();
954            int callingPid;
955            if (callingUid >= 0) {
956                callingPid = -1;
957            } else if (caller == null) {
958                callingPid = realCallingPid;
959                callingUid = realCallingUid;
960            } else {
961                callingPid = callingUid = -1;
962            }
963
964            final ActivityStack stack;
965            if (container == null || container.mStack.isOnHomeDisplay()) {
966                stack = mFocusedStack;
967            } else {
968                stack = container.mStack;
969            }
970            stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
971            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
972                    "Starting activity when config will change = " + stack.mConfigWillChange);
973
974            final long origId = Binder.clearCallingIdentity();
975
976            if (aInfo != null &&
977                    (aInfo.applicationInfo.privateFlags
978                            &ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
979                // This may be a heavy-weight process!  Check to see if we already
980                // have another, different heavy-weight process running.
981                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
982                    if (mService.mHeavyWeightProcess != null &&
983                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
984                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
985                        int appCallingUid = callingUid;
986                        if (caller != null) {
987                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
988                            if (callerApp != null) {
989                                appCallingUid = callerApp.info.uid;
990                            } else {
991                                Slog.w(TAG, "Unable to find app for caller " + caller
992                                      + " (pid=" + callingPid + ") when starting: "
993                                      + intent.toString());
994                                ActivityOptions.abort(options);
995                                return ActivityManager.START_PERMISSION_DENIED;
996                            }
997                        }
998
999                        IIntentSender target = mService.getIntentSenderLocked(
1000                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1001                                appCallingUid, userId, null, null, 0, new Intent[] { intent },
1002                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1003                                | PendingIntent.FLAG_ONE_SHOT, null);
1004
1005                        Intent newIntent = new Intent();
1006                        if (requestCode >= 0) {
1007                            // Caller is requesting a result.
1008                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1009                        }
1010                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1011                                new IntentSender(target));
1012                        if (mService.mHeavyWeightProcess.activities.size() > 0) {
1013                            ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
1014                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
1015                                    hist.packageName);
1016                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
1017                                    hist.task.taskId);
1018                        }
1019                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1020                                aInfo.packageName);
1021                        newIntent.setFlags(intent.getFlags());
1022                        newIntent.setClassName("android",
1023                                HeavyWeightSwitcherActivity.class.getName());
1024                        intent = newIntent;
1025                        resolvedType = null;
1026                        caller = null;
1027                        callingUid = Binder.getCallingUid();
1028                        callingPid = Binder.getCallingPid();
1029                        componentSpecified = true;
1030                        try {
1031                            ResolveInfo rInfo =
1032                                AppGlobals.getPackageManager().resolveIntent(
1033                                        intent, null,
1034                                        PackageManager.MATCH_DEFAULT_ONLY
1035                                        | ActivityManagerService.STOCK_PM_FLAGS, userId);
1036                            aInfo = rInfo != null ? rInfo.activityInfo : null;
1037                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
1038                        } catch (RemoteException e) {
1039                            aInfo = null;
1040                        }
1041                    }
1042                }
1043            }
1044
1045            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
1046                    voiceSession, voiceInteractor, resultTo, resultWho,
1047                    requestCode, callingPid, callingUid, callingPackage,
1048                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
1049                    componentSpecified, null, container, inTask);
1050
1051            Binder.restoreCallingIdentity(origId);
1052
1053            if (stack.mConfigWillChange) {
1054                // If the caller also wants to switch to a new configuration,
1055                // do so now.  This allows a clean switch, as we are waiting
1056                // for the current activity to pause (so we will not destroy
1057                // it), and have not yet started the next activity.
1058                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
1059                        "updateConfiguration()");
1060                stack.mConfigWillChange = false;
1061                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1062                        "Updating to new configuration after starting activity.");
1063                mService.updateConfigurationLocked(config, null, false, false);
1064            }
1065
1066            if (outResult != null) {
1067                outResult.result = res;
1068                if (res == ActivityManager.START_SUCCESS) {
1069                    mWaitingActivityLaunched.add(outResult);
1070                    do {
1071                        try {
1072                            mService.wait();
1073                        } catch (InterruptedException e) {
1074                        }
1075                    } while (!outResult.timeout && outResult.who == null);
1076                } else if (res == ActivityManager.START_TASK_TO_FRONT) {
1077                    ActivityRecord r = stack.topRunningActivityLocked(null);
1078                    if (r.nowVisible && r.state == RESUMED) {
1079                        outResult.timeout = false;
1080                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
1081                        outResult.totalTime = 0;
1082                        outResult.thisTime = 0;
1083                    } else {
1084                        outResult.thisTime = SystemClock.uptimeMillis();
1085                        mWaitingActivityVisible.add(outResult);
1086                        do {
1087                            try {
1088                                mService.wait();
1089                            } catch (InterruptedException e) {
1090                            }
1091                        } while (!outResult.timeout && outResult.who == null);
1092                    }
1093                }
1094            }
1095
1096            return res;
1097        }
1098    }
1099
1100    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
1101            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
1102            Bundle options, int userId) {
1103        if (intents == null) {
1104            throw new NullPointerException("intents is null");
1105        }
1106        if (resolvedTypes == null) {
1107            throw new NullPointerException("resolvedTypes is null");
1108        }
1109        if (intents.length != resolvedTypes.length) {
1110            throw new IllegalArgumentException("intents are length different than resolvedTypes");
1111        }
1112
1113
1114        int callingPid;
1115        if (callingUid >= 0) {
1116            callingPid = -1;
1117        } else if (caller == null) {
1118            callingPid = Binder.getCallingPid();
1119            callingUid = Binder.getCallingUid();
1120        } else {
1121            callingPid = callingUid = -1;
1122        }
1123        final long origId = Binder.clearCallingIdentity();
1124        try {
1125            synchronized (mService) {
1126                ActivityRecord[] outActivity = new ActivityRecord[1];
1127                for (int i=0; i<intents.length; i++) {
1128                    Intent intent = intents[i];
1129                    if (intent == null) {
1130                        continue;
1131                    }
1132
1133                    // Refuse possible leaked file descriptors
1134                    if (intent != null && intent.hasFileDescriptors()) {
1135                        throw new IllegalArgumentException("File descriptors passed in Intent");
1136                    }
1137
1138                    boolean componentSpecified = intent.getComponent() != null;
1139
1140                    // Don't modify the client's object!
1141                    intent = new Intent(intent);
1142
1143                    // Collect information about the target of the Intent.
1144                    ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i], 0, null, userId);
1145                    // TODO: New, check if this is correct
1146                    aInfo = mService.getActivityInfoForUser(aInfo, userId);
1147
1148                    if (aInfo != null &&
1149                            (aInfo.applicationInfo.privateFlags
1150                                    & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)  != 0) {
1151                        throw new IllegalArgumentException(
1152                                "FLAG_CANT_SAVE_STATE not supported here");
1153                    }
1154
1155                    Bundle theseOptions;
1156                    if (options != null && i == intents.length-1) {
1157                        theseOptions = options;
1158                    } else {
1159                        theseOptions = null;
1160                    }
1161                    int res = startActivityLocked(caller, intent, resolvedTypes[i],
1162                            aInfo, null, null, resultTo, null, -1, callingPid, callingUid,
1163                            callingPackage, callingPid, callingUid,
1164                            0, theseOptions, false, componentSpecified, outActivity, null, null);
1165                    if (res < 0) {
1166                        return res;
1167                    }
1168
1169                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
1170                }
1171            }
1172        } finally {
1173            Binder.restoreCallingIdentity(origId);
1174        }
1175
1176        return ActivityManager.START_SUCCESS;
1177    }
1178
1179    final boolean realStartActivityLocked(ActivityRecord r,
1180            ProcessRecord app, boolean andResume, boolean checkConfig)
1181            throws RemoteException {
1182
1183        if (andResume) {
1184            r.startFreezingScreenLocked(app, 0);
1185            mWindowManager.setAppVisibility(r.appToken, true);
1186
1187            // schedule launch ticks to collect information about slow apps.
1188            r.startLaunchTickingLocked();
1189        }
1190
1191        // Have the window manager re-evaluate the orientation of
1192        // the screen based on the new activity order.  Note that
1193        // as a result of this, it can call back into the activity
1194        // manager with a new orientation.  We don't care about that,
1195        // because the activity is not currently running so we are
1196        // just restarting it anyway.
1197        if (checkConfig) {
1198            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1199                    mService.mConfiguration,
1200                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
1201            mService.updateConfigurationLocked(config, r, false, false);
1202        }
1203
1204        r.app = app;
1205        app.waitingToKill = null;
1206        r.launchCount++;
1207        r.lastLaunchTime = SystemClock.uptimeMillis();
1208
1209        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
1210
1211        int idx = app.activities.indexOf(r);
1212        if (idx < 0) {
1213            app.activities.add(r);
1214        }
1215        mService.updateLruProcessLocked(app, true, null);
1216        mService.updateOomAdjLocked();
1217
1218        final TaskRecord task = r.task;
1219        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
1220                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
1221            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
1222        }
1223
1224        final ActivityStack stack = task.stack;
1225        try {
1226            if (app.thread == null) {
1227                throw new RemoteException();
1228            }
1229            List<ResultInfo> results = null;
1230            List<ReferrerIntent> newIntents = null;
1231            if (andResume) {
1232                results = r.results;
1233                newIntents = r.newIntents;
1234            }
1235            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1236                    "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
1237                    + " newIntents=" + newIntents + " andResume=" + andResume);
1238            if (andResume) {
1239                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
1240                        r.userId, System.identityHashCode(r),
1241                        task.taskId, r.shortComponentName);
1242            }
1243            if (r.isHomeActivity() && r.isNotResolverActivity()) {
1244                // Home process is the root process of the task.
1245                mService.mHomeProcess = task.mActivities.get(0).app;
1246            }
1247            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1248            r.sleeping = false;
1249            r.forceNewConfig = false;
1250            mService.showAskCompatModeDialogLocked(r);
1251            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
1252            ProfilerInfo profilerInfo = null;
1253            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
1254                if (mService.mProfileProc == null || mService.mProfileProc == app) {
1255                    mService.mProfileProc = app;
1256                    final String profileFile = mService.mProfileFile;
1257                    if (profileFile != null) {
1258                        ParcelFileDescriptor profileFd = mService.mProfileFd;
1259                        if (profileFd != null) {
1260                            try {
1261                                profileFd = profileFd.dup();
1262                            } catch (IOException e) {
1263                                if (profileFd != null) {
1264                                    try {
1265                                        profileFd.close();
1266                                    } catch (IOException o) {
1267                                    }
1268                                    profileFd = null;
1269                                }
1270                            }
1271                        }
1272
1273                        profilerInfo = new ProfilerInfo(profileFile, profileFd,
1274                                mService.mSamplingInterval, mService.mAutoStopProfiler);
1275                    }
1276                }
1277            }
1278
1279            if (andResume) {
1280                app.hasShownUi = true;
1281                app.pendingUiClean = true;
1282            }
1283            app.forceProcessStateUpTo(mService.mTopProcessState);
1284            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1285                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
1286                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
1287                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
1288                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
1289
1290            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
1291                // This may be a heavy-weight process!  Note that the package
1292                // manager will ensure that only activity can run in the main
1293                // process of the .apk, which is the only thing that will be
1294                // considered heavy-weight.
1295                if (app.processName.equals(app.info.packageName)) {
1296                    if (mService.mHeavyWeightProcess != null
1297                            && mService.mHeavyWeightProcess != app) {
1298                        Slog.w(TAG, "Starting new heavy weight process " + app
1299                                + " when already running "
1300                                + mService.mHeavyWeightProcess);
1301                    }
1302                    mService.mHeavyWeightProcess = app;
1303                    Message msg = mService.mHandler.obtainMessage(
1304                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
1305                    msg.obj = r;
1306                    mService.mHandler.sendMessage(msg);
1307                }
1308            }
1309
1310        } catch (RemoteException e) {
1311            if (r.launchFailed) {
1312                // This is the second time we failed -- finish activity
1313                // and give up.
1314                Slog.e(TAG, "Second failure launching "
1315                      + r.intent.getComponent().flattenToShortString()
1316                      + ", giving up", e);
1317                mService.appDiedLocked(app);
1318                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
1319                        "2nd-crash", false);
1320                return false;
1321            }
1322
1323            // This is the first time we failed -- restart process and
1324            // retry.
1325            app.activities.remove(r);
1326            throw e;
1327        }
1328
1329        r.launchFailed = false;
1330        if (stack.updateLRUListLocked(r)) {
1331            Slog.w(TAG, "Activity " + r
1332                  + " being launched, but already in LRU list");
1333        }
1334
1335        if (andResume) {
1336            // As part of the process of launching, ActivityThread also performs
1337            // a resume.
1338            stack.minimalResumeActivityLocked(r);
1339        } else {
1340            // This activity is not starting in the resumed state... which
1341            // should look like we asked it to pause+stop (but remain visible),
1342            // and it has done so and reported back the current icicle and
1343            // other state.
1344            if (DEBUG_STATES) Slog.v(TAG_STATES,
1345                    "Moving to STOPPED: " + r + " (starting in stopped state)");
1346            r.state = STOPPED;
1347            r.stopped = true;
1348        }
1349
1350        // Launch the new version setup screen if needed.  We do this -after-
1351        // launching the initial activity (that is, home), so that it can have
1352        // a chance to initialize itself while in the background, making the
1353        // switch back to it faster and look better.
1354        if (isFrontStack(stack)) {
1355            mService.startSetupActivityLocked();
1356        }
1357
1358        // Update any services we are bound to that might care about whether
1359        // their client may have activities.
1360        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
1361
1362        return true;
1363    }
1364
1365    void startSpecificActivityLocked(ActivityRecord r,
1366            boolean andResume, boolean checkConfig) {
1367        // Is this activity's application already running?
1368        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1369                r.info.applicationInfo.uid, true);
1370
1371        r.task.stack.setLaunchTime(r);
1372
1373        if (app != null && app.thread != null) {
1374            try {
1375                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1376                        || !"android".equals(r.info.packageName)) {
1377                    // Don't add this if it is a platform component that is marked
1378                    // to run in multiple processes, because this is actually
1379                    // part of the framework so doesn't make sense to track as a
1380                    // separate apk in the process.
1381                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
1382                            mService.mProcessStats);
1383                }
1384                realStartActivityLocked(r, app, andResume, checkConfig);
1385                return;
1386            } catch (RemoteException e) {
1387                Slog.w(TAG, "Exception when starting activity "
1388                        + r.intent.getComponent().flattenToShortString(), e);
1389            }
1390
1391            // If a dead object exception was thrown -- fall through to
1392            // restart the application.
1393        }
1394
1395        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1396                "activity", r.intent.getComponent(), false, false, true);
1397    }
1398
1399    final int startActivityLocked(IApplicationThread caller,
1400            Intent intent, String resolvedType, ActivityInfo aInfo,
1401            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1402            IBinder resultTo, String resultWho, int requestCode,
1403            int callingPid, int callingUid, String callingPackage,
1404            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
1405            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
1406            ActivityContainer container, TaskRecord inTask) {
1407        int err = ActivityManager.START_SUCCESS;
1408
1409        ProcessRecord callerApp = null;
1410        if (caller != null) {
1411            callerApp = mService.getRecordForAppLocked(caller);
1412            if (callerApp != null) {
1413                callingPid = callerApp.pid;
1414                callingUid = callerApp.info.uid;
1415            } else {
1416                Slog.w(TAG, "Unable to find app for caller " + caller
1417                      + " (pid=" + callingPid + ") when starting: "
1418                      + intent.toString());
1419                err = ActivityManager.START_PERMISSION_DENIED;
1420            }
1421        }
1422
1423        final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1424
1425        if (err == ActivityManager.START_SUCCESS) {
1426            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1427                    + "} from uid " + callingUid
1428                    + " on display " + (container == null ? (mFocusedStack == null ?
1429                            Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
1430                            (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
1431                                    container.mActivityDisplay.mDisplayId)));
1432        }
1433
1434        ActivityRecord sourceRecord = null;
1435        ActivityRecord resultRecord = null;
1436        if (resultTo != null) {
1437            sourceRecord = isInAnyStackLocked(resultTo);
1438            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
1439                    "Will send result to " + resultTo + " " + sourceRecord);
1440            if (sourceRecord != null) {
1441                if (requestCode >= 0 && !sourceRecord.finishing) {
1442                    resultRecord = sourceRecord;
1443                }
1444            }
1445        }
1446
1447        final int launchFlags = intent.getFlags();
1448
1449        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
1450            // Transfer the result target from the source activity to the new
1451            // one being started, including any failures.
1452            if (requestCode >= 0) {
1453                ActivityOptions.abort(options);
1454                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1455            }
1456            resultRecord = sourceRecord.resultTo;
1457            if (resultRecord != null && !resultRecord.isInStackLocked()) {
1458                resultRecord = null;
1459            }
1460            resultWho = sourceRecord.resultWho;
1461            requestCode = sourceRecord.requestCode;
1462            sourceRecord.resultTo = null;
1463            if (resultRecord != null) {
1464                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
1465            }
1466            if (sourceRecord.launchedFromUid == callingUid) {
1467                // The new activity is being launched from the same uid as the previous
1468                // activity in the flow, and asking to forward its result back to the
1469                // previous.  In this case the activity is serving as a trampoline between
1470                // the two, so we also want to update its launchedFromPackage to be the
1471                // same as the previous activity.  Note that this is safe, since we know
1472                // these two packages come from the same uid; the caller could just as
1473                // well have supplied that same package name itself.  This specifially
1474                // deals with the case of an intent picker/chooser being launched in the app
1475                // flow to redirect to an activity picked by the user, where we want the final
1476                // activity to consider it to have been launched by the previous app activity.
1477                callingPackage = sourceRecord.launchedFromPackage;
1478            }
1479        }
1480
1481        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1482            // We couldn't find a class that can handle the given Intent.
1483            // That's the end of that!
1484            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1485        }
1486
1487        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1488            // We couldn't find the specific class specified in the Intent.
1489            // Also the end of the line.
1490            err = ActivityManager.START_CLASS_NOT_FOUND;
1491        }
1492
1493        if (err == ActivityManager.START_SUCCESS
1494                && !isCurrentProfileLocked(userId)
1495                && (aInfo.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
1496            // Trying to launch a background activity that doesn't show for all users.
1497            err = ActivityManager.START_NOT_CURRENT_USER_ACTIVITY;
1498        }
1499
1500        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
1501                && sourceRecord.task.voiceSession != null) {
1502            // If this activity is being launched as part of a voice session, we need
1503            // to ensure that it is safe to do so.  If the upcoming activity will also
1504            // be part of the voice session, we can only launch it if it has explicitly
1505            // said it supports the VOICE category, or it is a part of the calling app.
1506            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
1507                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
1508                try {
1509                    if (!AppGlobals.getPackageManager().activitySupportsIntent(
1510                            intent.getComponent(), intent, resolvedType)) {
1511                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1512                    }
1513                } catch (RemoteException e) {
1514                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1515                }
1516            }
1517        }
1518
1519        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
1520            // If the caller is starting a new voice session, just make sure the target
1521            // is actually allowing it to run this way.
1522            try {
1523                if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1524                        intent, resolvedType)) {
1525                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1526                }
1527            } catch (RemoteException e) {
1528                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1529            }
1530        }
1531
1532        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1533
1534        if (err != ActivityManager.START_SUCCESS) {
1535            if (resultRecord != null) {
1536                resultStack.sendActivityResultLocked(-1,
1537                    resultRecord, resultWho, requestCode,
1538                    Activity.RESULT_CANCELED, null);
1539            }
1540            ActivityOptions.abort(options);
1541            return err;
1542        }
1543
1544        boolean abort = false;
1545
1546        final int startAnyPerm = mService.checkPermission(
1547                START_ANY_ACTIVITY, callingPid, callingUid);
1548
1549        if (startAnyPerm != PERMISSION_GRANTED) {
1550            final int componentRestriction = getComponentRestrictionForCallingPackage(
1551                    aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity);
1552            final int actionRestriction = getActionRestrictionForCallingPackage(
1553                    intent.getAction(), callingPackage, callingPid, callingUid);
1554
1555            if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
1556                    || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1557                if (resultRecord != null) {
1558                    resultStack.sendActivityResultLocked(-1,
1559                            resultRecord, resultWho, requestCode,
1560                            Activity.RESULT_CANCELED, null);
1561                }
1562                String msg;
1563                if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1564                    msg = "Permission Denial: starting " + intent.toString()
1565                            + " from " + callerApp + " (pid=" + callingPid
1566                            + ", uid=" + callingUid + ")" + " with revoked permission "
1567                            + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
1568                } else if (!aInfo.exported) {
1569                    msg = "Permission Denial: starting " + intent.toString()
1570                            + " from " + callerApp + " (pid=" + callingPid
1571                            + ", uid=" + callingUid + ")"
1572                            + " not exported from uid " + aInfo.applicationInfo.uid;
1573                } else {
1574                    msg = "Permission Denial: starting " + intent.toString()
1575                            + " from " + callerApp + " (pid=" + callingPid
1576                            + ", uid=" + callingUid + ")"
1577                            + " requires " + aInfo.permission;
1578                }
1579                Slog.w(TAG, msg);
1580                throw new SecurityException(msg);
1581            }
1582
1583            if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
1584                String message = "Appop Denial: starting " + intent.toString()
1585                        + " from " + callerApp + " (pid=" + callingPid
1586                        + ", uid=" + callingUid + ")"
1587                        + " requires " + AppOpsManager.permissionToOp(
1588                                ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
1589                Slog.w(TAG, message);
1590                abort = true;
1591            } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
1592                String message = "Appop Denial: starting " + intent.toString()
1593                        + " from " + callerApp + " (pid=" + callingPid
1594                        + ", uid=" + callingUid + ")"
1595                        + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
1596                Slog.w(TAG, message);
1597                abort = true;
1598            }
1599        }
1600
1601        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1602                callingPid, resolvedType, aInfo.applicationInfo);
1603
1604        if (mService.mController != null) {
1605            try {
1606                // The Intent we give to the watcher has the extra data
1607                // stripped off, since it can contain private information.
1608                Intent watchIntent = intent.cloneFilter();
1609                abort |= !mService.mController.activityStarting(watchIntent,
1610                        aInfo.applicationInfo.packageName);
1611            } catch (RemoteException e) {
1612                mService.mController = null;
1613            }
1614        }
1615
1616        if (abort) {
1617            if (resultRecord != null) {
1618                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1619                        Activity.RESULT_CANCELED, null);
1620            }
1621            // We pretend to the caller that it was really started, but
1622            // they will just get a cancel result.
1623            ActivityOptions.abort(options);
1624            return ActivityManager.START_SUCCESS;
1625        }
1626
1627        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1628                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1629                requestCode, componentSpecified, this, container, options);
1630        if (outActivity != null) {
1631            outActivity[0] = r;
1632        }
1633
1634        if (r.appTimeTracker == null && sourceRecord != null) {
1635            // If the caller didn't specify an explicit time tracker, we want to continue
1636            // tracking under any it has.
1637            r.appTimeTracker = sourceRecord.appTimeTracker;
1638        }
1639
1640        final ActivityStack stack = mFocusedStack;
1641        if (voiceSession == null && (stack.mResumedActivity == null
1642                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
1643            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
1644                    realCallingPid, realCallingUid, "Activity start")) {
1645                PendingActivityLaunch pal =
1646                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1647                mPendingActivityLaunches.add(pal);
1648                ActivityOptions.abort(options);
1649                return ActivityManager.START_SWITCHES_CANCELED;
1650            }
1651        }
1652
1653        if (mService.mDidAppSwitch) {
1654            // This is the second allowed switch since we stopped switches,
1655            // so now just generally allow switches.  Use case: user presses
1656            // home (switches disabled, switch to home, mDidAppSwitch now true);
1657            // user taps a home icon (coming from home so allowed, we hit here
1658            // and now allow anyone to switch again).
1659            mService.mAppSwitchesAllowedTime = 0;
1660        } else {
1661            mService.mDidAppSwitch = true;
1662        }
1663
1664        doPendingActivityLaunchesLocked(false);
1665
1666        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
1667                startFlags, true, options, inTask);
1668
1669        if (err < 0) {
1670            // If someone asked to have the keyguard dismissed on the next
1671            // activity start, but we are not actually doing an activity
1672            // switch...  just dismiss the keyguard now, because we
1673            // probably want to see whatever is behind it.
1674            notifyActivityDrawnForKeyguard();
1675        }
1676        return err;
1677    }
1678
1679    private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
1680            String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
1681        if (activityInfo.permission == null) {
1682            return ACTIVITY_RESTRICTION_NONE;
1683        }
1684
1685        if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
1686                callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
1687                == PackageManager.PERMISSION_DENIED) {
1688            return ACTIVITY_RESTRICTION_PERMISSION;
1689        }
1690
1691        final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
1692        if (opCode == AppOpsManager.OP_NONE) {
1693            return ACTIVITY_RESTRICTION_NONE;
1694        }
1695
1696        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1697                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1698            if (!ignoreTargetSecurity) {
1699                return ACTIVITY_RESTRICTION_APPOP;
1700            }
1701        }
1702
1703        return ACTIVITY_RESTRICTION_NONE;
1704    }
1705
1706    private int getActionRestrictionForCallingPackage(String action,
1707            String callingPackage, int callingPid, int callingUid) {
1708        if (action == null) {
1709            return ACTIVITY_RESTRICTION_NONE;
1710        }
1711
1712        String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
1713        if (permission == null) {
1714            return ACTIVITY_RESTRICTION_NONE;
1715        }
1716
1717        final PackageInfo packageInfo;
1718        try {
1719            packageInfo = mService.mContext.getPackageManager()
1720                    .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
1721        } catch (PackageManager.NameNotFoundException e) {
1722            Slog.i(TAG, "Cannot find package info for " + callingPackage);
1723            return ACTIVITY_RESTRICTION_NONE;
1724        }
1725
1726        if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
1727            return ACTIVITY_RESTRICTION_NONE;
1728        }
1729
1730        if (mService.checkPermission(permission, callingPid, callingUid) ==
1731                PackageManager.PERMISSION_DENIED) {
1732            return ACTIVITY_RESTRICTION_PERMISSION;
1733        }
1734
1735        final int opCode = AppOpsManager.permissionToOpCode(permission);
1736        if (opCode == AppOpsManager.OP_NONE) {
1737            return ACTIVITY_RESTRICTION_NONE;
1738        }
1739
1740        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1741                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1742            return ACTIVITY_RESTRICTION_APPOP;
1743        }
1744
1745        return ACTIVITY_RESTRICTION_NONE;
1746    }
1747
1748    ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
1749        final TaskRecord task = r.task;
1750
1751        // On leanback only devices we should keep all activities in the same stack.
1752        if (!mLeanbackOnlyDevice &&
1753                (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
1754
1755            ActivityStack stack;
1756
1757            if (task != null && task.stack != null) {
1758                stack = task.stack;
1759                if (stack.isOnHomeDisplay()) {
1760                    if (mFocusedStack != stack) {
1761                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1762                                "computeStackFocus: Setting " + "focused stack to r=" + r
1763                                + " task=" + task);
1764                    } else {
1765                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1766                            "computeStackFocus: Focused stack already=" + mFocusedStack);
1767                    }
1768                }
1769                return stack;
1770            }
1771
1772            final ActivityContainer container = r.mInitialActivityContainer;
1773            if (container != null) {
1774                // The first time put it on the desired stack, after this put on task stack.
1775                r.mInitialActivityContainer = null;
1776                return container.mStack;
1777            }
1778
1779            if (mFocusedStack != mHomeStack && (!newTask ||
1780                    mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
1781                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1782                        "computeStackFocus: Have a focused stack=" + mFocusedStack);
1783                return mFocusedStack;
1784            }
1785
1786            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1787            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1788                stack = homeDisplayStacks.get(stackNdx);
1789                if (!stack.isHomeStack()) {
1790                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1791                            "computeStackFocus: Setting focused stack=" + stack);
1792                    return stack;
1793                }
1794            }
1795
1796            // Need to create an app stack for this user.
1797            stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
1798            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
1799                    + r + " stackId=" + stack.mStackId);
1800            return stack;
1801        }
1802        return mHomeStack;
1803    }
1804
1805    boolean setFocusedStack(ActivityRecord r, String reason) {
1806        if (r == null) {
1807            // Not sure what you are trying to do, but it is not going to work...
1808            return false;
1809        }
1810        final TaskRecord task = r.task;
1811        if (task == null || task.stack == null) {
1812            Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task);
1813            return false;
1814        }
1815        task.stack.moveToFront(reason);
1816        return true;
1817    }
1818
1819    final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
1820            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
1821            boolean doResume, Bundle options, TaskRecord inTask) {
1822        final Intent intent = r.intent;
1823        final int callingUid = r.launchedFromUid;
1824
1825        // In some flows in to this function, we retrieve the task record and hold on to it
1826        // without a lock before calling back in to here...  so the task at this point may
1827        // not actually be in recents.  Check for that, and if it isn't in recents just
1828        // consider it invalid.
1829        if (inTask != null && !inTask.inRecents) {
1830            Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1831            inTask = null;
1832        }
1833
1834        final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
1835        final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
1836        final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
1837
1838        int launchFlags = intent.getFlags();
1839        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1840                (launchSingleInstance || launchSingleTask)) {
1841            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1842            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1843                    "\"singleInstance\" or \"singleTask\"");
1844            launchFlags &=
1845                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
1846        } else {
1847            switch (r.info.documentLaunchMode) {
1848                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1849                    break;
1850                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1851                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1852                    break;
1853                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1854                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1855                    break;
1856                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1857                    launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1858                    break;
1859            }
1860        }
1861
1862        final boolean launchTaskBehind = r.mLaunchTaskBehind
1863                && !launchSingleTask && !launchSingleInstance
1864                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1865
1866        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0
1867                && r.resultTo.task.stack != null) {
1868            // For whatever reason this activity is being launched into a new
1869            // task...  yet the caller has requested a result back.  Well, that
1870            // is pretty messed up, so instead immediately send back a cancel
1871            // and let the new task continue launched as normal without a
1872            // dependency on its originator.
1873            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1874            r.resultTo.task.stack.sendActivityResultLocked(-1,
1875                    r.resultTo, r.resultWho, r.requestCode,
1876                    Activity.RESULT_CANCELED, null);
1877            r.resultTo = null;
1878        }
1879
1880        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1881            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1882        }
1883
1884        // If we are actually going to launch in to a new task, there are some cases where
1885        // we further want to do multiple task.
1886        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1887            if (launchTaskBehind
1888                    || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
1889                launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1890            }
1891        }
1892
1893        // We'll invoke onUserLeaving before onPause only if the launching
1894        // activity did not explicitly state that this is an automated launch.
1895        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1896        if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1897                "startActivity() => mUserLeaving=" + mUserLeaving);
1898
1899        // If the caller has asked not to resume at this point, we make note
1900        // of this in the record so that we can skip it when trying to find
1901        // the top running activity.
1902        if (!doResume) {
1903            r.delayedResume = true;
1904        }
1905
1906        ActivityRecord notTop =
1907                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1908
1909        // If the onlyIfNeeded flag is set, then we can do this if the activity
1910        // being launched is the same as the one making the call...  or, as
1911        // a special case, if we do not know the caller then we count the
1912        // current top activity as the caller.
1913        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1914            ActivityRecord checkedCaller = sourceRecord;
1915            if (checkedCaller == null) {
1916                checkedCaller = mFocusedStack.topRunningNonDelayedActivityLocked(notTop);
1917            }
1918            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1919                // Caller is not the same as launcher, so always needed.
1920                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1921            }
1922        }
1923
1924        boolean addingToTask = false;
1925        TaskRecord reuseTask = null;
1926
1927        // If the caller is not coming from another activity, but has given us an
1928        // explicit task into which they would like us to launch the new activity,
1929        // then let's see about doing that.
1930        if (sourceRecord == null && inTask != null && inTask.stack != null) {
1931            final Intent baseIntent = inTask.getBaseIntent();
1932            final ActivityRecord root = inTask.getRootActivity();
1933            if (baseIntent == null) {
1934                ActivityOptions.abort(options);
1935                throw new IllegalArgumentException("Launching into task without base intent: "
1936                        + inTask);
1937            }
1938
1939            // If this task is empty, then we are adding the first activity -- it
1940            // determines the root, and must be launching as a NEW_TASK.
1941            if (launchSingleInstance || launchSingleTask) {
1942                if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
1943                    ActivityOptions.abort(options);
1944                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1945                            + r + " into different task " + inTask);
1946                }
1947                if (root != null) {
1948                    ActivityOptions.abort(options);
1949                    throw new IllegalArgumentException("Caller with inTask " + inTask
1950                            + " has root " + root + " but target is singleInstance/Task");
1951                }
1952            }
1953
1954            // If task is empty, then adopt the interesting intent launch flags in to the
1955            // activity being started.
1956            if (root == null) {
1957                final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
1958                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
1959                        | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1960                launchFlags = (launchFlags&~flagsOfInterest)
1961                        | (baseIntent.getFlags()&flagsOfInterest);
1962                intent.setFlags(launchFlags);
1963                inTask.setIntent(r);
1964                addingToTask = true;
1965
1966            // If the task is not empty and the caller is asking to start it as the root
1967            // of a new task, then we don't actually want to start this on the task.  We
1968            // will bring the task to the front, and possibly give it a new intent.
1969            } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1970                addingToTask = false;
1971
1972            } else {
1973                addingToTask = true;
1974            }
1975
1976            reuseTask = inTask;
1977        } else {
1978            inTask = null;
1979        }
1980
1981        if (inTask == null) {
1982            if (sourceRecord == null) {
1983                // This activity is not being started from another...  in this
1984                // case we -always- start a new task.
1985                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
1986                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1987                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1988                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1989                }
1990            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1991                // The original activity who is starting us is running as a single
1992                // instance...  this new activity it is starting must go on its
1993                // own task.
1994                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1995            } else if (launchSingleInstance || launchSingleTask) {
1996                // The activity being started is a single instance...  it always
1997                // gets launched into its own task.
1998                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1999            }
2000        }
2001
2002        ActivityInfo newTaskInfo = null;
2003        Intent newTaskIntent = null;
2004        ActivityStack sourceStack;
2005        if (sourceRecord != null) {
2006            if (sourceRecord.finishing) {
2007                // If the source is finishing, we can't further count it as our source.  This
2008                // is because the task it is associated with may now be empty and on its way out,
2009                // so we don't want to blindly throw it in to that task.  Instead we will take
2010                // the NEW_TASK flow and try to find a task for it. But save the task information
2011                // so it can be used when creating the new task.
2012                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
2013                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
2014                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
2015                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2016                    newTaskInfo = sourceRecord.info;
2017                    newTaskIntent = sourceRecord.task.intent;
2018                }
2019                sourceRecord = null;
2020                sourceStack = null;
2021            } else {
2022                sourceStack = sourceRecord.task.stack;
2023            }
2024        } else {
2025            sourceStack = null;
2026        }
2027
2028        boolean movedHome = false;
2029        ActivityStack targetStack;
2030
2031        intent.setFlags(launchFlags);
2032        final boolean noAnimation = (launchFlags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0;
2033
2034        // We may want to try to place the new activity in to an existing task.  We always
2035        // do this if the target activity is singleTask or singleInstance; we will also do
2036        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2037        // us to still place it in a new task: multi task, always doc mode, or being asked to
2038        // launch this as a new task behind the current one.
2039        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
2040                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
2041                || launchSingleInstance || launchSingleTask) {
2042            // If bring to front is requested, and no result is requested and we have not
2043            // been given an explicit task to launch in to, and
2044            // we can find a task that was started with this same
2045            // component, then instead of launching bring that one to the front.
2046            if (inTask == null && r.resultTo == null) {
2047                // See if there is a task to bring to the front.  If this is
2048                // a SINGLE_INSTANCE activity, there can be one and only one
2049                // instance of it in the history, and it is always in its own
2050                // unique task, so we do a special search.
2051                ActivityRecord intentActivity = !launchSingleInstance ?
2052                        findTaskLocked(r) : findActivityLocked(intent, r.info);
2053                if (intentActivity != null) {
2054                    // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused
2055                    // but still needs to be a lock task mode violation since the task gets
2056                    // cleared out and the device would otherwise leave the locked task.
2057                    if (isLockTaskModeViolation(intentActivity.task,
2058                            (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2059                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
2060                        showLockTaskToast();
2061                        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
2062                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2063                    }
2064                    if (r.task == null) {
2065                        r.task = intentActivity.task;
2066                    }
2067                    if (intentActivity.task.intent == null) {
2068                        // This task was started because of movement of
2069                        // the activity based on affinity...  now that we
2070                        // are actually launching it, we can assign the
2071                        // base intent.
2072                        intentActivity.task.setIntent(r);
2073                    }
2074                    targetStack = intentActivity.task.stack;
2075                    targetStack.mLastPausedActivity = null;
2076                    // If the target task is not in the front, then we need
2077                    // to bring it to the front...  except...  well, with
2078                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
2079                    // to have the same behavior as if a new instance was
2080                    // being started, which means not bringing it to the front
2081                    // if the caller is not itself in the front.
2082                    final ActivityStack focusStack = getFocusedStack();
2083                    ActivityRecord curTop = (focusStack == null)
2084                            ? null : focusStack.topRunningNonDelayedActivityLocked(notTop);
2085                    boolean movedToFront = false;
2086                    if (curTop != null && (curTop.task != intentActivity.task ||
2087                            curTop.task != focusStack.topTask())) {
2088                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
2089                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
2090                                sourceStack.topActivity().task == sourceRecord.task)) {
2091                            // We really do want to push this one into the user's face, right now.
2092                            if (launchTaskBehind && sourceRecord != null) {
2093                                intentActivity.setTaskToAffiliateWith(sourceRecord.task);
2094                            }
2095                            movedHome = true;
2096                            targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
2097                                    options, r.appTimeTracker, "bringingFoundTaskToFront");
2098                            movedToFront = true;
2099                            if ((launchFlags &
2100                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
2101                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
2102                                // Caller wants to appear on home activity.
2103                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2104                            }
2105                            options = null;
2106                        }
2107                    }
2108                    if (!movedToFront) {
2109                        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + targetStack
2110                                + " from " + intentActivity);
2111                        targetStack.moveToFront("intentActivityFound");
2112                    }
2113
2114                    // If the caller has requested that the target task be
2115                    // reset, then do so.
2116                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2117                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
2118                    }
2119                    if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2120                        // We don't need to start a new activity, and
2121                        // the client said not to do anything if that
2122                        // is the case, so this is it!  And for paranoia, make
2123                        // sure we have correctly resumed the top activity.
2124                        if (doResume) {
2125                            resumeTopActivitiesLocked(targetStack, null, options);
2126
2127                            // Make sure to notify Keyguard as well if we are not running an app
2128                            // transition later.
2129                            if (!movedToFront) {
2130                                notifyActivityDrawnForKeyguard();
2131                            }
2132                        } else {
2133                            ActivityOptions.abort(options);
2134                        }
2135                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2136                    }
2137                    if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2138                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2139                        // The caller has requested to completely replace any
2140                        // existing task with its new activity.  Well that should
2141                        // not be too hard...
2142                        reuseTask = intentActivity.task;
2143                        reuseTask.performClearTaskLocked();
2144                        reuseTask.setIntent(r);
2145                    } else if ((launchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2146                            || launchSingleInstance || launchSingleTask) {
2147                        // In this situation we want to remove all activities
2148                        // from the task up to the one being started.  In most
2149                        // cases this means we are resetting the task to its
2150                        // initial state.
2151                        ActivityRecord top =
2152                                intentActivity.task.performClearTaskLocked(r, launchFlags);
2153                        if (top != null) {
2154                            if (top.frontOfTask) {
2155                                // Activity aliases may mean we use different
2156                                // intents for the top activity, so make sure
2157                                // the task now has the identity of the new
2158                                // intent.
2159                                top.task.setIntent(r);
2160                            }
2161                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
2162                                    r, top.task);
2163                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2164                        } else {
2165                            // A special case: we need to start the activity because it is not
2166                            // currently running, and the caller has asked to clear the current
2167                            // task to have this activity at the top.
2168                            addingToTask = true;
2169                            // Now pretend like this activity is being started by the top of its
2170                            // task, so it is put in the right place.
2171                            sourceRecord = intentActivity;
2172                            TaskRecord task = sourceRecord.task;
2173                            if (task != null && task.stack == null) {
2174                                // Target stack got cleared when we all activities were removed
2175                                // above. Go ahead and reset it.
2176                                targetStack = computeStackFocus(sourceRecord, false /* newTask */);
2177                                targetStack.addTask(
2178                                        task, !launchTaskBehind /* toTop */, false /* moving */);
2179                            }
2180
2181                        }
2182                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
2183                        // In this case the top activity on the task is the
2184                        // same as the one being launched, so we take that
2185                        // as a request to bring the task to the foreground.
2186                        // If the top activity in the task is the root
2187                        // activity, deliver this new intent to it if it
2188                        // desires.
2189                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
2190                                && intentActivity.realActivity.equals(r.realActivity)) {
2191                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
2192                                    intentActivity.task);
2193                            if (intentActivity.frontOfTask) {
2194                                intentActivity.task.setIntent(r);
2195                            }
2196                            intentActivity.deliverNewIntentLocked(callingUid, r.intent,
2197                                    r.launchedFromPackage);
2198                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
2199                            // In this case we are launching the root activity
2200                            // of the task, but with a different intent.  We
2201                            // should start a new instance on top.
2202                            addingToTask = true;
2203                            sourceRecord = intentActivity;
2204                        }
2205                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2206                        // In this case an activity is being launched in to an
2207                        // existing task, without resetting that task.  This
2208                        // is typically the situation of launching an activity
2209                        // from a notification or shortcut.  We want to place
2210                        // the new activity on top of the current task.
2211                        addingToTask = true;
2212                        sourceRecord = intentActivity;
2213                    } else if (!intentActivity.task.rootWasReset) {
2214                        // In this case we are launching in to an existing task
2215                        // that has not yet been started from its front door.
2216                        // The current task has been brought to the front.
2217                        // Ideally, we'd probably like to place this new task
2218                        // at the bottom of its stack, but that's a little hard
2219                        // to do with the current organization of the code so
2220                        // for now we'll just drop it.
2221                        intentActivity.task.setIntent(r);
2222                    }
2223                    if (!addingToTask && reuseTask == null) {
2224                        // We didn't do anything...  but it was needed (a.k.a., client
2225                        // don't use that intent!)  And for paranoia, make
2226                        // sure we have correctly resumed the top activity.
2227                        if (doResume) {
2228                            targetStack.resumeTopActivityLocked(null, options);
2229                            if (!movedToFront) {
2230                                // Make sure to notify Keyguard as well if we are not running an app
2231                                // transition later.
2232                                notifyActivityDrawnForKeyguard();
2233                            }
2234                        } else {
2235                            ActivityOptions.abort(options);
2236                        }
2237                        return ActivityManager.START_TASK_TO_FRONT;
2238                    }
2239                }
2240            }
2241        }
2242
2243        //String uri = r.intent.toURI();
2244        //Intent intent2 = new Intent(uri);
2245        //Slog.i(TAG, "Given intent: " + r.intent);
2246        //Slog.i(TAG, "URI is: " + uri);
2247        //Slog.i(TAG, "To intent: " + intent2);
2248
2249        if (r.packageName != null) {
2250            // If the activity being launched is the same as the one currently
2251            // at the top, then we need to check if it should only be launched
2252            // once.
2253            ActivityStack topStack = mFocusedStack;
2254            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
2255            if (top != null && r.resultTo == null) {
2256                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2257                    if (top.app != null && top.app.thread != null) {
2258                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2259                            || launchSingleTop || launchSingleTask) {
2260                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
2261                                    top.task);
2262                            // For paranoia, make sure we have correctly
2263                            // resumed the top activity.
2264                            topStack.mLastPausedActivity = null;
2265                            if (doResume) {
2266                                resumeTopActivitiesLocked();
2267                            }
2268                            ActivityOptions.abort(options);
2269                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2270                                // We don't need to start a new activity, and
2271                                // the client said not to do anything if that
2272                                // is the case, so this is it!
2273                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2274                            }
2275                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2276                            return ActivityManager.START_DELIVERED_TO_TOP;
2277                        }
2278                    }
2279                }
2280            }
2281
2282        } else {
2283            if (r.resultTo != null && r.resultTo.task.stack != null) {
2284                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
2285                        r.requestCode, Activity.RESULT_CANCELED, null);
2286            }
2287            ActivityOptions.abort(options);
2288            return ActivityManager.START_CLASS_NOT_FOUND;
2289        }
2290
2291        boolean newTask = false;
2292        boolean keepCurTransition = false;
2293
2294        TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
2295                sourceRecord.task : null;
2296
2297        // Should this be considered a new task?
2298        if (r.resultTo == null && inTask == null && !addingToTask
2299                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
2300            newTask = true;
2301            targetStack = computeStackFocus(r, newTask);
2302            targetStack.moveToFront("startingNewTask");
2303
2304            if (reuseTask == null) {
2305                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
2306                        newTaskInfo != null ? newTaskInfo : r.info,
2307                        newTaskIntent != null ? newTaskIntent : intent,
2308                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
2309                        taskToAffiliate);
2310                if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2311                        "Starting new activity " + r + " in new task " + r.task);
2312            } else {
2313                r.setTask(reuseTask, taskToAffiliate);
2314            }
2315            if (isLockTaskModeViolation(r.task)) {
2316                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2317                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2318            }
2319            if (!movedHome) {
2320                if ((launchFlags &
2321                        (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
2322                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
2323                    // Caller wants to appear on home activity, so before starting
2324                    // their own activity we will bring home to the front.
2325                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2326                }
2327            }
2328        } else if (sourceRecord != null) {
2329            final TaskRecord sourceTask = sourceRecord.task;
2330            if (isLockTaskModeViolation(sourceTask)) {
2331                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2332                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2333            }
2334            targetStack = sourceTask.stack;
2335            targetStack.moveToFront("sourceStackToFront");
2336            final TaskRecord topTask = targetStack.topTask();
2337            if (topTask != sourceTask) {
2338                targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
2339                        r.appTimeTracker, "sourceTaskToFront");
2340            }
2341            if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2342                // In this case, we are adding the activity to an existing
2343                // task, but the caller has asked to clear that task if the
2344                // activity is already running.
2345                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
2346                keepCurTransition = true;
2347                if (top != null) {
2348                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
2349                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2350                    // For paranoia, make sure we have correctly
2351                    // resumed the top activity.
2352                    targetStack.mLastPausedActivity = null;
2353                    if (doResume) {
2354                        targetStack.resumeTopActivityLocked(null);
2355                    }
2356                    ActivityOptions.abort(options);
2357                    return ActivityManager.START_DELIVERED_TO_TOP;
2358                }
2359            } else if (!addingToTask &&
2360                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2361                // In this case, we are launching an activity in our own task
2362                // that may already be running somewhere in the history, and
2363                // we want to shuffle it to the front of the stack if so.
2364                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
2365                if (top != null) {
2366                    final TaskRecord task = top.task;
2367                    task.moveActivityToFrontLocked(top);
2368                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
2369                    top.updateOptionsLocked(options);
2370                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2371                    targetStack.mLastPausedActivity = null;
2372                    if (doResume) {
2373                        targetStack.resumeTopActivityLocked(null);
2374                    }
2375                    return ActivityManager.START_DELIVERED_TO_TOP;
2376                }
2377            }
2378            // An existing activity is starting this new activity, so we want
2379            // to keep the new one in the same task as the one that is starting
2380            // it.
2381            r.setTask(sourceTask, null);
2382            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2383                    + " in existing task " + r.task + " from source " + sourceRecord);
2384
2385        } else if (inTask != null) {
2386            // The caller is asking that the new activity be started in an explicit
2387            // task it has provided to us.
2388            if (isLockTaskModeViolation(inTask)) {
2389                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2390                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2391            }
2392            targetStack = inTask.stack;
2393            targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker,
2394                    "inTaskToFront");
2395
2396            // Check whether we should actually launch the new activity in to the task,
2397            // or just reuse the current activity on top.
2398            ActivityRecord top = inTask.getTopActivity();
2399            if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2400                if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2401                        || launchSingleTop || launchSingleTask) {
2402                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
2403                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2404                        // We don't need to start a new activity, and
2405                        // the client said not to do anything if that
2406                        // is the case, so this is it!
2407                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2408                    }
2409                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2410                    return ActivityManager.START_DELIVERED_TO_TOP;
2411                }
2412            }
2413
2414            if (!addingToTask) {
2415                // We don't actually want to have this activity added to the task, so just
2416                // stop here but still tell the caller that we consumed the intent.
2417                ActivityOptions.abort(options);
2418                return ActivityManager.START_TASK_TO_FRONT;
2419            }
2420
2421            r.setTask(inTask, null);
2422            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2423                    + " in explicit task " + r.task);
2424
2425        } else {
2426            // This not being started from an existing activity, and not part
2427            // of a new task...  just put it in the top task, though these days
2428            // this case should never happen.
2429            targetStack = computeStackFocus(r, newTask);
2430            targetStack.moveToFront("addingToTopTask");
2431            ActivityRecord prev = targetStack.topActivity();
2432            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
2433                            r.info, intent, null, null, true), null);
2434            mWindowManager.moveTaskToTop(r.task.taskId);
2435            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2436                    + " in new guessed " + r.task);
2437        }
2438
2439        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2440                intent, r.getUriPermissionsLocked(), r.userId);
2441
2442        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
2443            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
2444        }
2445        if (newTask) {
2446            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
2447        }
2448        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
2449        targetStack.mLastPausedActivity = null;
2450        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
2451        if (!launchTaskBehind) {
2452            // Don't set focus on an activity that's going to the back.
2453            mService.setFocusedActivityLocked(r, "startedActivity");
2454        }
2455        return ActivityManager.START_SUCCESS;
2456    }
2457
2458    final void doPendingActivityLaunchesLocked(boolean doResume) {
2459        while (!mPendingActivityLaunches.isEmpty()) {
2460            PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
2461            startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
2462                    doResume && mPendingActivityLaunches.isEmpty(), null, null);
2463        }
2464    }
2465
2466    void removePendingActivityLaunchesLocked(ActivityStack stack) {
2467        for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
2468            PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
2469            if (pal.stack == stack) {
2470                mPendingActivityLaunches.remove(palNdx);
2471            }
2472        }
2473    }
2474
2475    void setLaunchSource(int uid) {
2476        mLaunchingActivity.setWorkSource(new WorkSource(uid));
2477    }
2478
2479    void acquireLaunchWakelock() {
2480        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2481            throw new IllegalStateException("Calling must be system uid");
2482        }
2483        mLaunchingActivity.acquire();
2484        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2485            // To be safe, don't allow the wake lock to be held for too long.
2486            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2487        }
2488    }
2489
2490    /**
2491     * Called when the frontmost task is idle.
2492     * @return the state of mService.mBooting before this was called.
2493     */
2494    private boolean checkFinishBootingLocked() {
2495        final boolean booting = mService.mBooting;
2496        boolean enableScreen = false;
2497        mService.mBooting = false;
2498        if (!mService.mBooted) {
2499            mService.mBooted = true;
2500            enableScreen = true;
2501        }
2502        if (booting || enableScreen) {
2503            mService.postFinishBooting(booting, enableScreen);
2504        }
2505        return booting;
2506    }
2507
2508    // Checked.
2509    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2510            Configuration config) {
2511        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
2512
2513        ArrayList<ActivityRecord> stops = null;
2514        ArrayList<ActivityRecord> finishes = null;
2515        ArrayList<UserState> startingUsers = null;
2516        int NS = 0;
2517        int NF = 0;
2518        boolean booting = false;
2519        boolean activityRemoved = false;
2520
2521        ActivityRecord r = ActivityRecord.forTokenLocked(token);
2522        if (r != null) {
2523            if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
2524                    + Debug.getCallers(4));
2525            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2526            r.finishLaunchTickingLocked();
2527            if (fromTimeout) {
2528                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2529            }
2530
2531            // This is a hack to semi-deal with a race condition
2532            // in the client where it can be constructed with a
2533            // newer configuration from when we asked it to launch.
2534            // We'll update with whatever configuration it now says
2535            // it used to launch.
2536            if (config != null) {
2537                r.configuration = config;
2538            }
2539
2540            // We are now idle.  If someone is waiting for a thumbnail from
2541            // us, we can now deliver.
2542            r.idle = true;
2543
2544            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2545            if (isFrontStack(r.task.stack) || fromTimeout) {
2546                booting = checkFinishBootingLocked();
2547            }
2548        }
2549
2550        if (allResumedActivitiesIdle()) {
2551            if (r != null) {
2552                mService.scheduleAppGcsLocked();
2553            }
2554
2555            if (mLaunchingActivity.isHeld()) {
2556                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2557                if (VALIDATE_WAKE_LOCK_CALLER &&
2558                        Binder.getCallingUid() != Process.myUid()) {
2559                    throw new IllegalStateException("Calling must be system uid");
2560                }
2561                mLaunchingActivity.release();
2562            }
2563            ensureActivitiesVisibleLocked(null, 0);
2564        }
2565
2566        // Atomically retrieve all of the other things to do.
2567        stops = processStoppingActivitiesLocked(true);
2568        NS = stops != null ? stops.size() : 0;
2569        if ((NF = mFinishingActivities.size()) > 0) {
2570            finishes = new ArrayList<>(mFinishingActivities);
2571            mFinishingActivities.clear();
2572        }
2573
2574        if (mStartingUsers.size() > 0) {
2575            startingUsers = new ArrayList<>(mStartingUsers);
2576            mStartingUsers.clear();
2577        }
2578
2579        // Stop any activities that are scheduled to do so but have been
2580        // waiting for the next one to start.
2581        for (int i = 0; i < NS; i++) {
2582            r = stops.get(i);
2583            final ActivityStack stack = r.task.stack;
2584            if (stack != null) {
2585                if (r.finishing) {
2586                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2587                } else {
2588                    stack.stopActivityLocked(r);
2589                }
2590            }
2591        }
2592
2593        // Finish any activities that are scheduled to do so but have been
2594        // waiting for the next one to start.
2595        for (int i = 0; i < NF; i++) {
2596            r = finishes.get(i);
2597            final ActivityStack stack = r.task.stack;
2598            if (stack != null) {
2599                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
2600            }
2601        }
2602
2603        if (!booting) {
2604            // Complete user switch
2605            if (startingUsers != null) {
2606                for (int i = 0; i < startingUsers.size(); i++) {
2607                    mService.finishUserSwitch(startingUsers.get(i));
2608                }
2609            }
2610            // Complete starting up of background users
2611            if (mStartingBackgroundUsers.size() > 0) {
2612                startingUsers = new ArrayList<UserState>(mStartingBackgroundUsers);
2613                mStartingBackgroundUsers.clear();
2614                for (int i = 0; i < startingUsers.size(); i++) {
2615                    mService.finishUserBoot(startingUsers.get(i));
2616                }
2617            }
2618        }
2619
2620        mService.trimApplications();
2621        //dump();
2622        //mWindowManager.dump();
2623
2624        if (activityRemoved) {
2625            resumeTopActivitiesLocked();
2626        }
2627
2628        return r;
2629    }
2630
2631    boolean handleAppDiedLocked(ProcessRecord app) {
2632        boolean hasVisibleActivities = false;
2633        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2634            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2635            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2636                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2637            }
2638        }
2639        return hasVisibleActivities;
2640    }
2641
2642    void closeSystemDialogsLocked() {
2643        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2644            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2645            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2646                stacks.get(stackNdx).closeSystemDialogsLocked();
2647            }
2648        }
2649    }
2650
2651    void removeUserLocked(int userId) {
2652        mUserStackInFront.delete(userId);
2653    }
2654
2655    /**
2656     * @return true if some activity was finished (or would have finished if doit were true).
2657     */
2658    boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
2659            boolean doit, boolean evenPersistent, int userId) {
2660        boolean didSomething = false;
2661        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2662            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2663            final int numStacks = stacks.size();
2664            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2665                final ActivityStack stack = stacks.get(stackNdx);
2666                if (stack.finishDisabledPackageActivitiesLocked(
2667                        packageName, filterByClasses, doit, evenPersistent, userId)) {
2668                    didSomething = true;
2669                }
2670            }
2671        }
2672        return didSomething;
2673    }
2674
2675    void updatePreviousProcessLocked(ActivityRecord r) {
2676        // Now that this process has stopped, we may want to consider
2677        // it to be the previous app to try to keep around in case
2678        // the user wants to return to it.
2679
2680        // First, found out what is currently the foreground app, so that
2681        // we don't blow away the previous app if this activity is being
2682        // hosted by the process that is actually still the foreground.
2683        ProcessRecord fgApp = null;
2684        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2685            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2686            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2687                final ActivityStack stack = stacks.get(stackNdx);
2688                if (isFrontStack(stack)) {
2689                    if (stack.mResumedActivity != null) {
2690                        fgApp = stack.mResumedActivity.app;
2691                    } else if (stack.mPausingActivity != null) {
2692                        fgApp = stack.mPausingActivity.app;
2693                    }
2694                    break;
2695                }
2696            }
2697        }
2698
2699        // Now set this one as the previous process, only if that really
2700        // makes sense to.
2701        if (r.app != null && fgApp != null && r.app != fgApp
2702                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2703                && r.app != mService.mHomeProcess) {
2704            mService.mPreviousProcess = r.app;
2705            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2706        }
2707    }
2708
2709    boolean resumeTopActivitiesLocked() {
2710        return resumeTopActivitiesLocked(null, null, null);
2711    }
2712
2713    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2714            Bundle targetOptions) {
2715        if (targetStack == null) {
2716            targetStack = mFocusedStack;
2717        }
2718        // Do targetStack first.
2719        boolean result = false;
2720        if (isFrontStack(targetStack)) {
2721            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2722        }
2723
2724        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2725            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2726            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2727                final ActivityStack stack = stacks.get(stackNdx);
2728                if (stack == targetStack) {
2729                    // Already started above.
2730                    continue;
2731                }
2732                if (isFrontStack(stack)) {
2733                    stack.resumeTopActivityLocked(null);
2734                }
2735            }
2736        }
2737        return result;
2738    }
2739
2740    void finishTopRunningActivityLocked(ProcessRecord app, String reason) {
2741        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2742            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2743            final int numStacks = stacks.size();
2744            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2745                final ActivityStack stack = stacks.get(stackNdx);
2746                stack.finishTopRunningActivityLocked(app, reason);
2747            }
2748        }
2749    }
2750
2751    void finishVoiceTask(IVoiceInteractionSession session) {
2752        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2753            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2754            final int numStacks = stacks.size();
2755            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2756                final ActivityStack stack = stacks.get(stackNdx);
2757                stack.finishVoiceTask(session);
2758            }
2759        }
2760    }
2761
2762    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options, String reason) {
2763        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2764            mUserLeaving = true;
2765        }
2766        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2767            // Caller wants the home activity moved with it.  To accomplish this,
2768            // we'll just indicate that this task returns to the home task.
2769            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2770        }
2771        if (task.stack == null) {
2772            Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
2773                    + task + " to front. Stack is null");
2774            return;
2775        }
2776        task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
2777                task.getTopActivity() == null ? null : task.getTopActivity().appTimeTracker,
2778                reason);
2779        if (DEBUG_STACK) Slog.d(TAG_STACK,
2780                "findTaskToMoveToFront: moved to front of stack=" + task.stack);
2781    }
2782
2783    ActivityStack getStack(int stackId) {
2784        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2785        if (activityContainer != null) {
2786            return activityContainer.mStack;
2787        }
2788        return null;
2789    }
2790
2791    ArrayList<ActivityStack> getStacks() {
2792        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2793        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2794            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2795        }
2796        return allStacks;
2797    }
2798
2799    IBinder getHomeActivityToken() {
2800        ActivityRecord homeActivity = getHomeActivity();
2801        if (homeActivity != null) {
2802            return homeActivity.appToken;
2803        }
2804        return null;
2805    }
2806
2807    ActivityRecord getHomeActivity() {
2808        return getHomeActivityForUser(mCurrentUser);
2809    }
2810
2811    ActivityRecord getHomeActivityForUser(int userId) {
2812        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2813        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2814            final TaskRecord task = tasks.get(taskNdx);
2815            if (task.isHomeTask()) {
2816                final ArrayList<ActivityRecord> activities = task.mActivities;
2817                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2818                    final ActivityRecord r = activities.get(activityNdx);
2819                    if (r.isHomeActivity()
2820                            && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
2821                        return r;
2822                    }
2823                }
2824            }
2825        }
2826        return null;
2827    }
2828
2829    ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
2830            IActivityContainerCallback callback) {
2831        ActivityContainer activityContainer =
2832                new VirtualActivityContainer(parentActivity, callback);
2833        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2834        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
2835                "createActivityContainer: " + activityContainer);
2836        parentActivity.mChildContainers.add(activityContainer);
2837        return activityContainer;
2838    }
2839
2840    void removeChildActivityContainers(ActivityRecord parentActivity) {
2841        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2842        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2843            ActivityContainer container = childStacks.remove(containerNdx);
2844            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
2845                    + container);
2846            container.release();
2847        }
2848    }
2849
2850    void deleteActivityContainer(IActivityContainer container) {
2851        ActivityContainer activityContainer = (ActivityContainer)container;
2852        if (activityContainer != null) {
2853            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
2854                    "deleteActivityContainer: callers=" + Debug.getCallers(4));
2855            final int stackId = activityContainer.mStackId;
2856            mActivityContainers.remove(stackId);
2857            mWindowManager.removeStack(stackId);
2858        }
2859    }
2860
2861    void resizeStackLocked(int stackId, Rect bounds) {
2862        final ActivityStack stack = getStack(stackId);
2863        if (stack == null) {
2864            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2865            return;
2866        }
2867
2868        final ActivityRecord r = stack.topRunningActivityLocked(null);
2869        if (r != null && !r.task.mResizeable) {
2870            Slog.w(TAG, "resizeStack: top task " + r.task + " not resizeable.");
2871            return;
2872        }
2873
2874        final Configuration overrideConfig = mWindowManager.resizeStack(stackId, bounds);
2875        if (stack.updateOverrideConfiguration(overrideConfig)) {
2876            if (r != null) {
2877                final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
2878                // And we need to make sure at this point that all other activities
2879                // are made visible with the correct configuration.
2880                ensureActivitiesVisibleLocked(r, 0);
2881                if (!updated) {
2882                    resumeTopActivitiesLocked(stack, null, null);
2883                }
2884            }
2885        }
2886    }
2887
2888    /** Makes sure the input task is in a stack with the specified bounds by either resizing the
2889     * current task stack if it only has one entry, moving the task to a stack that matches the
2890     * bounds, or creating a new stack with the required bounds. Also, makes the task resizeable.*/
2891    void resizeTaskLocked(TaskRecord task, Rect bounds) {
2892        task.mResizeable = true;
2893        final ActivityStack currentStack = task.stack;
2894        if (currentStack.isHomeStack()) {
2895            // Can't move task off the home stack. Sorry!
2896            return;
2897        }
2898
2899        final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds);
2900        if (matchingStackId != -1) {
2901            // There is already a stack with the right bounds!
2902            if (currentStack != null && currentStack.mStackId == matchingStackId) {
2903                // Nothing to do here. Already in the right stack...
2904                return;
2905            }
2906            // Move task to stack with matching bounds.
2907            moveTaskToStackLocked(task.taskId, matchingStackId, true);
2908            return;
2909        }
2910
2911        if (currentStack != null && currentStack.numTasks() == 1) {
2912            // Just resize the current stack since this is the task in it.
2913            resizeStackLocked(currentStack.mStackId, bounds);
2914            return;
2915        }
2916
2917        // Create new stack and move the task to it.
2918        final int displayId = (currentStack != null && currentStack.mDisplayId != -1)
2919                ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY;
2920        ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId);
2921
2922        if (newStack == null) {
2923            Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task);
2924            return;
2925        }
2926        moveTaskToStackLocked(task.taskId, newStack.mStackId, true);
2927        resizeStackLocked(newStack.mStackId, bounds);
2928    }
2929
2930    ActivityStack createStackOnDisplay(int stackId, int displayId) {
2931        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2932        if (activityDisplay == null) {
2933            return null;
2934        }
2935
2936        ActivityContainer activityContainer = new ActivityContainer(stackId);
2937        mActivityContainers.put(stackId, activityContainer);
2938        activityContainer.attachToDisplayLocked(activityDisplay);
2939        return activityContainer.mStack;
2940    }
2941
2942    int getNextStackId() {
2943        while (true) {
2944            if (++mLastStackId <= HOME_STACK_ID) {
2945                mLastStackId = HOME_STACK_ID + 1;
2946            }
2947            if (getStack(mLastStackId) == null) {
2948                break;
2949            }
2950        }
2951        return mLastStackId;
2952    }
2953
2954    private boolean restoreRecentTaskLocked(TaskRecord task) {
2955        ActivityStack stack = null;
2956        // Determine stack to restore task to.
2957        if (mLeanbackOnlyDevice) {
2958            // There is only one stack for lean back devices.
2959            stack = mHomeStack;
2960        } else {
2961            // Look for the top stack on the home display that isn't the home stack.
2962            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
2963            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2964                final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx);
2965                if (!tmpStack.isHomeStack() && tmpStack.mFullscreen) {
2966                    stack = tmpStack;
2967                    break;
2968                }
2969            }
2970        }
2971
2972        if (stack == null) {
2973            // We couldn't find a stack to restore the task to. Possible if are restoring recents
2974            // before an application stack is created...Go ahead and create one on the default
2975            // display.
2976            stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2977            // Restore home stack to top.
2978            moveHomeStack(true, "restoreRecentTask");
2979            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2980                    "Created stack=" + stack + " for recents restoration.");
2981        }
2982
2983        if (stack == null) {
2984            // What does this mean??? Not sure how we would get here...
2985            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2986                    "Unable to find/create stack to restore recent task=" + task);
2987            return false;
2988        }
2989
2990        stack.addTask(task, false, false);
2991        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2992                "Added restored task=" + task + " to stack=" + stack);
2993        final ArrayList<ActivityRecord> activities = task.mActivities;
2994        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2995            final ActivityRecord r = activities.get(activityNdx);
2996            mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
2997                    r.info.screenOrientation, r.fullscreen,
2998                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
2999                    r.userId, r.info.configChanges, task.voiceSession != null,
3000                    r.mLaunchTaskBehind);
3001        }
3002        return true;
3003    }
3004
3005    void moveTaskToStackLocked(int taskId, int stackId, boolean toTop) {
3006        final TaskRecord task = anyTaskForIdLocked(taskId);
3007        if (task == null) {
3008            Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
3009            return;
3010        }
3011        final ActivityStack stack = getStack(stackId);
3012        if (stack == null) {
3013            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
3014            return;
3015        }
3016        mWindowManager.moveTaskToStack(taskId, stackId, toTop);
3017        if (task.stack != null) {
3018            task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */);
3019        }
3020        stack.addTask(task, toTop, true);
3021        // The task might have already been running and its visibility needs to be synchronized with
3022        // the visibility of the stack / windows.
3023        stack.ensureActivitiesVisibleLocked(null, 0);
3024        resumeTopActivitiesLocked();
3025    }
3026
3027    ActivityRecord findTaskLocked(ActivityRecord r) {
3028        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
3029        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3030            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3031            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3032                final ActivityStack stack = stacks.get(stackNdx);
3033                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
3034                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
3035                    continue;
3036                }
3037                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
3038                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
3039                            "Skipping stack: (new task not allowed) " + stack);
3040                    continue;
3041                }
3042                final ActivityRecord ar = stack.findTaskLocked(r);
3043                if (ar != null) {
3044                    return ar;
3045                }
3046            }
3047        }
3048        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "No task found");
3049        return null;
3050    }
3051
3052    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
3053        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3054            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3055            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3056                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
3057                if (ar != null) {
3058                    return ar;
3059                }
3060            }
3061        }
3062        return null;
3063    }
3064
3065    void goingToSleepLocked() {
3066        scheduleSleepTimeout();
3067        if (!mGoingToSleep.isHeld()) {
3068            mGoingToSleep.acquire();
3069            if (mLaunchingActivity.isHeld()) {
3070                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
3071                    throw new IllegalStateException("Calling must be system uid");
3072                }
3073                mLaunchingActivity.release();
3074                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
3075            }
3076        }
3077        checkReadyForSleepLocked();
3078    }
3079
3080    boolean shutdownLocked(int timeout) {
3081        goingToSleepLocked();
3082
3083        boolean timedout = false;
3084        final long endTime = System.currentTimeMillis() + timeout;
3085        while (true) {
3086            boolean cantShutdown = false;
3087            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3088                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3089                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3090                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
3091                }
3092            }
3093            if (cantShutdown) {
3094                long timeRemaining = endTime - System.currentTimeMillis();
3095                if (timeRemaining > 0) {
3096                    try {
3097                        mService.wait(timeRemaining);
3098                    } catch (InterruptedException e) {
3099                    }
3100                } else {
3101                    Slog.w(TAG, "Activity manager shutdown timed out");
3102                    timedout = true;
3103                    break;
3104                }
3105            } else {
3106                break;
3107            }
3108        }
3109
3110        // Force checkReadyForSleep to complete.
3111        mSleepTimeout = true;
3112        checkReadyForSleepLocked();
3113
3114        return timedout;
3115    }
3116
3117    void comeOutOfSleepIfNeededLocked() {
3118        removeSleepTimeouts();
3119        if (mGoingToSleep.isHeld()) {
3120            mGoingToSleep.release();
3121        }
3122        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3123            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3124            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3125                final ActivityStack stack = stacks.get(stackNdx);
3126                stack.awakeFromSleepingLocked();
3127                if (isFrontStack(stack)) {
3128                    resumeTopActivitiesLocked();
3129                }
3130            }
3131        }
3132        mGoingToSleepActivities.clear();
3133    }
3134
3135    void activitySleptLocked(ActivityRecord r) {
3136        mGoingToSleepActivities.remove(r);
3137        checkReadyForSleepLocked();
3138    }
3139
3140    void checkReadyForSleepLocked() {
3141        if (!mService.isSleepingOrShuttingDown()) {
3142            // Do not care.
3143            return;
3144        }
3145
3146        if (!mSleepTimeout) {
3147            boolean dontSleep = false;
3148            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3149                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3150                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3151                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
3152                }
3153            }
3154
3155            if (mStoppingActivities.size() > 0) {
3156                // Still need to tell some activities to stop; can't sleep yet.
3157                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
3158                        + mStoppingActivities.size() + " activities");
3159                scheduleIdleLocked();
3160                dontSleep = true;
3161            }
3162
3163            if (mGoingToSleepActivities.size() > 0) {
3164                // Still need to tell some activities to sleep; can't sleep yet.
3165                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
3166                        + mGoingToSleepActivities.size() + " activities");
3167                dontSleep = true;
3168            }
3169
3170            if (dontSleep) {
3171                return;
3172            }
3173        }
3174
3175        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3176            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3177            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3178                stacks.get(stackNdx).goToSleep();
3179            }
3180        }
3181
3182        removeSleepTimeouts();
3183
3184        if (mGoingToSleep.isHeld()) {
3185            mGoingToSleep.release();
3186        }
3187        if (mService.mShuttingDown) {
3188            mService.notifyAll();
3189        }
3190    }
3191
3192    boolean reportResumedActivityLocked(ActivityRecord r) {
3193        final ActivityStack stack = r.task.stack;
3194        if (isFrontStack(stack)) {
3195            mService.updateUsageStats(r, true);
3196        }
3197        if (allResumedActivitiesComplete()) {
3198            ensureActivitiesVisibleLocked(null, 0);
3199            mWindowManager.executeAppTransition();
3200            return true;
3201        }
3202        return false;
3203    }
3204
3205    void handleAppCrashLocked(ProcessRecord app) {
3206        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3207            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3208            final int numStacks = stacks.size();
3209            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
3210                final ActivityStack stack = stacks.get(stackNdx);
3211                stack.handleAppCrashLocked(app);
3212            }
3213        }
3214    }
3215
3216    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
3217        final ActivityStack stack = r.task.stack;
3218        if (stack == null) {
3219            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3220                    "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
3221            return false;
3222        }
3223        final boolean isVisible = stack.hasVisibleBehindActivity();
3224        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3225                "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
3226
3227        final ActivityRecord top = topRunningActivityLocked();
3228        if (top == null || top == r || (visible == isVisible)) {
3229            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
3230            stack.setVisibleBehindActivity(visible ? r : null);
3231            return true;
3232        }
3233
3234        // A non-top activity is reporting a visibility change.
3235        if (visible && top.fullscreen) {
3236            // Let the caller know that it can't be seen.
3237            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3238                    "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
3239                    + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
3240                    + top.app.thread);
3241            return false;
3242        } else if (!visible && stack.getVisibleBehindActivity() != r) {
3243            // Only the activity set as currently visible behind should actively reset its
3244            // visible behind state.
3245            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3246                    "requestVisibleBehind: returning visible=" + visible
3247                    + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
3248                    + " r=" + r);
3249            return false;
3250        }
3251
3252        stack.setVisibleBehindActivity(visible ? r : null);
3253        if (!visible) {
3254            // Make the activity immediately above r opaque.
3255            final ActivityRecord next = stack.findNextTranslucentActivity(r);
3256            if (next != null) {
3257                mService.convertFromTranslucent(next.appToken);
3258            }
3259        }
3260        if (top.app != null && top.app.thread != null) {
3261            // Notify the top app of the change.
3262            try {
3263                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
3264            } catch (RemoteException e) {
3265            }
3266        }
3267        return true;
3268    }
3269
3270    // Called when WindowManager has finished animating the launchingBehind activity to the back.
3271    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
3272        r.mLaunchTaskBehind = false;
3273        final TaskRecord task = r.task;
3274        task.setLastThumbnail(task.stack.screenshotActivities(r));
3275        mRecentTasks.addLocked(task);
3276        mService.notifyTaskStackChangedLocked();
3277        mWindowManager.setAppVisibility(r.appToken, false);
3278    }
3279
3280    void scheduleLaunchTaskBehindComplete(IBinder token) {
3281        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
3282    }
3283
3284    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
3285        // First the front stacks. In case any are not fullscreen and are in front of home.
3286        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3287            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3288            final int topStackNdx = stacks.size() - 1;
3289            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
3290                final ActivityStack stack = stacks.get(stackNdx);
3291                stack.ensureActivitiesVisibleLocked(starting, configChanges);
3292            }
3293        }
3294    }
3295
3296    void clearOtherAppTimeTrackers(AppTimeTracker except) {
3297        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3298            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3299            final int topStackNdx = stacks.size() - 1;
3300            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
3301                final ActivityStack stack = stacks.get(stackNdx);
3302                stack.clearOtherAppTimeTrackers(except);
3303            }
3304        }
3305    }
3306
3307    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
3308        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3309            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3310            final int numStacks = stacks.size();
3311            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
3312                final ActivityStack stack = stacks.get(stackNdx);
3313                stack.scheduleDestroyActivities(app, reason);
3314            }
3315        }
3316    }
3317
3318    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
3319        // Examine all activities currently running in the process.
3320        TaskRecord firstTask = null;
3321        // Tasks is non-null only if two or more tasks are found.
3322        ArraySet<TaskRecord> tasks = null;
3323        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
3324        for (int i = 0; i < app.activities.size(); i++) {
3325            ActivityRecord r = app.activities.get(i);
3326            // First, if we find an activity that is in the process of being destroyed,
3327            // then we just aren't going to do anything for now; we want things to settle
3328            // down before we try to prune more activities.
3329            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
3330                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
3331                return;
3332            }
3333            // Don't consider any activies that are currently not in a state where they
3334            // can be destroyed.
3335            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
3336                    || r.state == PAUSED || r.state == STOPPING) {
3337                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
3338                continue;
3339            }
3340            if (r.task != null) {
3341                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task
3342                        + " from " + r);
3343                if (firstTask == null) {
3344                    firstTask = r.task;
3345                } else if (firstTask != r.task) {
3346                    if (tasks == null) {
3347                        tasks = new ArraySet<>();
3348                        tasks.add(firstTask);
3349                    }
3350                    tasks.add(r.task);
3351                }
3352            }
3353        }
3354        if (tasks == null) {
3355            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
3356            return;
3357        }
3358        // If we have activities in multiple tasks that are in a position to be destroyed,
3359        // let's iterate through the tasks and release the oldest one.
3360        final int numDisplays = mActivityDisplays.size();
3361        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
3362            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3363            // Step through all stacks starting from behind, to hit the oldest things first.
3364            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
3365                final ActivityStack stack = stacks.get(stackNdx);
3366                // Try to release activities in this stack; if we manage to, we are done.
3367                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
3368                    return;
3369                }
3370            }
3371        }
3372    }
3373
3374    boolean switchUserLocked(int userId, UserState uss) {
3375        mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
3376        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
3377        mCurrentUser = userId;
3378
3379        mStartingUsers.add(uss);
3380        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3381            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3382            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3383                final ActivityStack stack = stacks.get(stackNdx);
3384                stack.switchUserLocked(userId);
3385                TaskRecord task = stack.topTask();
3386                if (task != null) {
3387                    mWindowManager.moveTaskToTop(task.taskId);
3388                }
3389            }
3390        }
3391
3392        ActivityStack stack = getStack(restoreStackId);
3393        if (stack == null) {
3394            stack = mHomeStack;
3395        }
3396        final boolean homeInFront = stack.isHomeStack();
3397        if (stack.isOnHomeDisplay()) {
3398            moveHomeStack(homeInFront, "switchUserOnHomeDisplay");
3399            TaskRecord task = stack.topTask();
3400            if (task != null) {
3401                mWindowManager.moveTaskToTop(task.taskId);
3402            }
3403        } else {
3404            // Stack was moved to another display while user was swapped out.
3405            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
3406        }
3407        return homeInFront;
3408    }
3409
3410    /**
3411     * Add background users to send boot completed events to.
3412     * @param userId The user being started in the background
3413     * @param uss The state object for the user.
3414     */
3415    public void startBackgroundUserLocked(int userId, UserState uss) {
3416        mStartingBackgroundUsers.add(uss);
3417    }
3418
3419    /** Checks whether the userid is a profile of the current user. */
3420    boolean isCurrentProfileLocked(int userId) {
3421        if (userId == mCurrentUser) return true;
3422        for (int i = 0; i < mService.mCurrentProfileIds.length; i++) {
3423            if (mService.mCurrentProfileIds[i] == userId) return true;
3424        }
3425        return false;
3426    }
3427
3428    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
3429        ArrayList<ActivityRecord> stops = null;
3430
3431        final boolean nowVisible = allResumedActivitiesVisible();
3432        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3433            ActivityRecord s = mStoppingActivities.get(activityNdx);
3434            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
3435            if (DEBUG_ALL) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
3436                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
3437            if (waitingVisible && nowVisible) {
3438                mWaitingVisibleActivities.remove(s);
3439                if (s.finishing) {
3440                    // If this activity is finishing, it is sitting on top of
3441                    // everyone else but we now know it is no longer needed...
3442                    // so get rid of it.  Otherwise, we need to go through the
3443                    // normal flow and hide it once we determine that it is
3444                    // hidden by the activities in front of it.
3445                    if (DEBUG_ALL) Slog.v(TAG, "Before stopping, can hide: " + s);
3446                    mWindowManager.setAppVisibility(s.appToken, false);
3447                }
3448            }
3449            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
3450                if (DEBUG_ALL) Slog.v(TAG, "Ready to stop: " + s);
3451                if (stops == null) {
3452                    stops = new ArrayList<>();
3453                }
3454                stops.add(s);
3455                mStoppingActivities.remove(activityNdx);
3456            }
3457        }
3458
3459        return stops;
3460    }
3461
3462    void validateTopActivitiesLocked() {
3463        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3464            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3465            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3466                final ActivityStack stack = stacks.get(stackNdx);
3467                final ActivityRecord r = stack.topRunningActivityLocked(null);
3468                final ActivityState state = r == null ? DESTROYED : r.state;
3469                if (isFrontStack(stack)) {
3470                    if (r == null) Slog.e(TAG,
3471                            "validateTop...: null top activity, stack=" + stack);
3472                    else {
3473                        final ActivityRecord pausing = stack.mPausingActivity;
3474                        if (pausing != null && pausing == r) Slog.e(TAG,
3475                                "validateTop...: top stack has pausing activity r=" + r
3476                                + " state=" + state);
3477                        if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
3478                                "validateTop...: activity in front not resumed r=" + r
3479                                + " state=" + state);
3480                    }
3481                } else {
3482                    final ActivityRecord resumed = stack.mResumedActivity;
3483                    if (resumed != null && resumed == r) Slog.e(TAG,
3484                            "validateTop...: back stack has resumed activity r=" + r
3485                            + " state=" + state);
3486                    if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
3487                            "validateTop...: activity in back resumed r=" + r + " state=" + state);
3488                }
3489            }
3490        }
3491    }
3492
3493    private String lockTaskModeToString() {
3494        switch (mLockTaskModeState) {
3495            case LOCK_TASK_MODE_LOCKED:
3496                return "LOCKED";
3497            case LOCK_TASK_MODE_PINNED:
3498                return "PINNED";
3499            case LOCK_TASK_MODE_NONE:
3500                return "NONE";
3501            default: return "unknown=" + mLockTaskModeState;
3502        }
3503    }
3504
3505    public void dump(PrintWriter pw, String prefix) {
3506        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3507                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3508        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3509        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
3510        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3511        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3512        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
3513                final SparseArray<String[]> packages = mService.mLockTaskPackages;
3514                if (packages.size() > 0) {
3515                    pw.println(" mLockTaskPackages (userId:packages)=");
3516                    for (int i = 0; i < packages.size(); ++i) {
3517                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
3518                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
3519                    }
3520                }
3521                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
3522    }
3523
3524    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3525        return mFocusedStack.getDumpActivitiesLocked(name);
3526    }
3527
3528    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3529            boolean needSep, String prefix) {
3530        if (activity != null) {
3531            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3532                if (needSep) {
3533                    pw.println();
3534                }
3535                pw.print(prefix);
3536                pw.println(activity);
3537                return true;
3538            }
3539        }
3540        return false;
3541    }
3542
3543    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3544            boolean dumpClient, String dumpPackage) {
3545        boolean printed = false;
3546        boolean needSep = false;
3547        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3548            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3549            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3550                    pw.println(" (activities from top to bottom):");
3551            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3552            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3553                final ActivityStack stack = stacks.get(stackNdx);
3554                StringBuilder stackHeader = new StringBuilder(128);
3555                stackHeader.append("  Stack #");
3556                stackHeader.append(stack.mStackId);
3557                stackHeader.append(":");
3558                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3559                        needSep, stackHeader.toString());
3560                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3561                        !dumpAll, false, dumpPackage, true,
3562                        "    Running activities (most recent first):", null);
3563
3564                needSep = printed;
3565                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3566                        "    mPausingActivity: ");
3567                if (pr) {
3568                    printed = true;
3569                    needSep = false;
3570                }
3571                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3572                        "    mResumedActivity: ");
3573                if (pr) {
3574                    printed = true;
3575                    needSep = false;
3576                }
3577                if (dumpAll) {
3578                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3579                            "    mLastPausedActivity: ");
3580                    if (pr) {
3581                        printed = true;
3582                        needSep = true;
3583                    }
3584                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3585                            needSep, "    mLastNoHistoryActivity: ");
3586                }
3587                needSep = printed;
3588            }
3589        }
3590
3591        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3592                false, dumpPackage, true, "  Activities waiting to finish:", null);
3593        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3594                false, dumpPackage, true, "  Activities waiting to stop:", null);
3595        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3596                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3597                null);
3598        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3599                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3600        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3601                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3602
3603        return printed;
3604    }
3605
3606    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3607            String prefix, String label, boolean complete, boolean brief, boolean client,
3608            String dumpPackage, boolean needNL, String header1, String header2) {
3609        TaskRecord lastTask = null;
3610        String innerPrefix = null;
3611        String[] args = null;
3612        boolean printed = false;
3613        for (int i=list.size()-1; i>=0; i--) {
3614            final ActivityRecord r = list.get(i);
3615            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3616                continue;
3617            }
3618            if (innerPrefix == null) {
3619                innerPrefix = prefix + "      ";
3620                args = new String[0];
3621            }
3622            printed = true;
3623            final boolean full = !brief && (complete || !r.isInHistory());
3624            if (needNL) {
3625                pw.println("");
3626                needNL = false;
3627            }
3628            if (header1 != null) {
3629                pw.println(header1);
3630                header1 = null;
3631            }
3632            if (header2 != null) {
3633                pw.println(header2);
3634                header2 = null;
3635            }
3636            if (lastTask != r.task) {
3637                lastTask = r.task;
3638                pw.print(prefix);
3639                pw.print(full ? "* " : "  ");
3640                pw.println(lastTask);
3641                if (full) {
3642                    lastTask.dump(pw, prefix + "  ");
3643                } else if (complete) {
3644                    // Complete + brief == give a summary.  Isn't that obvious?!?
3645                    if (lastTask.intent != null) {
3646                        pw.print(prefix); pw.print("  ");
3647                                pw.println(lastTask.intent.toInsecureStringWithClip());
3648                    }
3649                }
3650            }
3651            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3652            pw.print(" #"); pw.print(i); pw.print(": ");
3653            pw.println(r);
3654            if (full) {
3655                r.dump(pw, innerPrefix);
3656            } else if (complete) {
3657                // Complete + brief == give a summary.  Isn't that obvious?!?
3658                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3659                if (r.app != null) {
3660                    pw.print(innerPrefix); pw.println(r.app);
3661                }
3662            }
3663            if (client && r.app != null && r.app.thread != null) {
3664                // flush anything that is already in the PrintWriter since the thread is going
3665                // to write to the file descriptor directly
3666                pw.flush();
3667                try {
3668                    TransferPipe tp = new TransferPipe();
3669                    try {
3670                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3671                                r.appToken, innerPrefix, args);
3672                        // Short timeout, since blocking here can
3673                        // deadlock with the application.
3674                        tp.go(fd, 2000);
3675                    } finally {
3676                        tp.kill();
3677                    }
3678                } catch (IOException e) {
3679                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3680                } catch (RemoteException e) {
3681                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3682                }
3683                needNL = true;
3684            }
3685        }
3686        return printed;
3687    }
3688
3689    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3690        if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3691                "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3692        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3693        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3694    }
3695
3696    final void scheduleIdleLocked() {
3697        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3698    }
3699
3700    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3701        if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
3702                + Debug.getCallers(4));
3703        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3704    }
3705
3706    final void scheduleResumeTopActivities() {
3707        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3708            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3709        }
3710    }
3711
3712    void removeSleepTimeouts() {
3713        mSleepTimeout = false;
3714        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3715    }
3716
3717    final void scheduleSleepTimeout() {
3718        removeSleepTimeouts();
3719        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3720    }
3721
3722    @Override
3723    public void onDisplayAdded(int displayId) {
3724        Slog.v(TAG, "Display added displayId=" + displayId);
3725        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3726    }
3727
3728    @Override
3729    public void onDisplayRemoved(int displayId) {
3730        Slog.v(TAG, "Display removed displayId=" + displayId);
3731        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3732    }
3733
3734    @Override
3735    public void onDisplayChanged(int displayId) {
3736        Slog.v(TAG, "Display changed displayId=" + displayId);
3737        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3738    }
3739
3740    private void handleDisplayAdded(int displayId) {
3741        boolean newDisplay;
3742        synchronized (mService) {
3743            newDisplay = mActivityDisplays.get(displayId) == null;
3744            if (newDisplay) {
3745                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3746                if (activityDisplay.mDisplay == null) {
3747                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3748                    return;
3749                }
3750                mActivityDisplays.put(displayId, activityDisplay);
3751            }
3752        }
3753        if (newDisplay) {
3754            mWindowManager.onDisplayAdded(displayId);
3755        }
3756    }
3757
3758    private void handleDisplayRemoved(int displayId) {
3759        synchronized (mService) {
3760            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3761            if (activityDisplay != null) {
3762                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3763                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3764                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3765                }
3766                mActivityDisplays.remove(displayId);
3767            }
3768        }
3769        mWindowManager.onDisplayRemoved(displayId);
3770    }
3771
3772    private void handleDisplayChanged(int displayId) {
3773        synchronized (mService) {
3774            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3775            if (activityDisplay != null) {
3776                // TODO: Update the bounds.
3777            }
3778        }
3779        mWindowManager.onDisplayChanged(displayId);
3780    }
3781
3782    private StackInfo getStackInfoLocked(ActivityStack stack) {
3783        StackInfo info = new StackInfo();
3784        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3785        info.displayId = Display.DEFAULT_DISPLAY;
3786        info.stackId = stack.mStackId;
3787
3788        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3789        final int numTasks = tasks.size();
3790        int[] taskIds = new int[numTasks];
3791        String[] taskNames = new String[numTasks];
3792        for (int i = 0; i < numTasks; ++i) {
3793            final TaskRecord task = tasks.get(i);
3794            taskIds[i] = task.taskId;
3795            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3796                    : task.realActivity != null ? task.realActivity.flattenToString()
3797                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3798                    : "unknown";
3799        }
3800        info.taskIds = taskIds;
3801        info.taskNames = taskNames;
3802        return info;
3803    }
3804
3805    StackInfo getStackInfoLocked(int stackId) {
3806        ActivityStack stack = getStack(stackId);
3807        if (stack != null) {
3808            return getStackInfoLocked(stack);
3809        }
3810        return null;
3811    }
3812
3813    ArrayList<StackInfo> getAllStackInfosLocked() {
3814        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3815        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3816            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3817            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3818                list.add(getStackInfoLocked(stacks.get(ndx)));
3819            }
3820        }
3821        return list;
3822    }
3823
3824    TaskRecord getLockedTaskLocked() {
3825        final int top = mLockTaskModeTasks.size() - 1;
3826        if (top >= 0) {
3827            return mLockTaskModeTasks.get(top);
3828        }
3829        return null;
3830    }
3831
3832    boolean isLockedTask(TaskRecord task) {
3833        return mLockTaskModeTasks.contains(task);
3834    }
3835
3836    boolean isLastLockedTask(TaskRecord task) {
3837        return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
3838    }
3839
3840    void removeLockedTaskLocked(final TaskRecord task) {
3841        if (!mLockTaskModeTasks.remove(task)) {
3842            return;
3843        }
3844        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
3845        if (mLockTaskModeTasks.isEmpty()) {
3846            // Last one.
3847            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
3848                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
3849            final Message lockTaskMsg = Message.obtain();
3850            lockTaskMsg.arg1 = task.userId;
3851            lockTaskMsg.what = LOCK_TASK_END_MSG;
3852            mHandler.sendMessage(lockTaskMsg);
3853        }
3854    }
3855
3856    void showLockTaskToast() {
3857        mLockTaskNotify.showToast(mLockTaskModeState);
3858    }
3859
3860    void showLockTaskEscapeMessageLocked(TaskRecord task) {
3861        if (mLockTaskModeTasks.contains(task)) {
3862            mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
3863        }
3864    }
3865
3866    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
3867            boolean andResume) {
3868        if (task == null) {
3869            // Take out of lock task mode if necessary
3870            final TaskRecord lockedTask = getLockedTaskLocked();
3871            if (lockedTask != null) {
3872                removeLockedTaskLocked(lockedTask);
3873                if (!mLockTaskModeTasks.isEmpty()) {
3874                    // There are locked tasks remaining, can only finish this task, not unlock it.
3875                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3876                            "setLockTaskModeLocked: Tasks remaining, can't unlock");
3877                    lockedTask.performClearTaskLocked();
3878                    resumeTopActivitiesLocked();
3879                    return;
3880                }
3881            }
3882            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3883                    "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
3884            return;
3885        }
3886
3887        // Should have already been checked, but do it again.
3888        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
3889            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3890                    "setLockTaskModeLocked: Can't lock due to auth");
3891            return;
3892        }
3893        if (isLockTaskModeViolation(task)) {
3894            Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
3895            return;
3896        }
3897
3898        if (mLockTaskModeTasks.isEmpty()) {
3899            // First locktask.
3900            final Message lockTaskMsg = Message.obtain();
3901            lockTaskMsg.obj = task.intent.getComponent().getPackageName();
3902            lockTaskMsg.arg1 = task.userId;
3903            lockTaskMsg.what = LOCK_TASK_START_MSG;
3904            lockTaskMsg.arg2 = lockTaskModeState;
3905            mHandler.sendMessage(lockTaskMsg);
3906        }
3907        // Add it or move it to the top.
3908        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
3909                " Callers=" + Debug.getCallers(4));
3910        mLockTaskModeTasks.remove(task);
3911        mLockTaskModeTasks.add(task);
3912
3913        if (task.mLockTaskUid == -1) {
3914            task.mLockTaskUid = task.mCallingUid;
3915        }
3916
3917        if (andResume) {
3918            findTaskToMoveToFrontLocked(task, 0, null, reason);
3919            resumeTopActivitiesLocked();
3920        }
3921    }
3922
3923    boolean isLockTaskModeViolation(TaskRecord task) {
3924        return isLockTaskModeViolation(task, false);
3925    }
3926
3927    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
3928        if (getLockedTaskLocked() == task && !isNewClearTask) {
3929            return false;
3930        }
3931        final int lockTaskAuth = task.mLockTaskAuth;
3932        switch (lockTaskAuth) {
3933            case LOCK_TASK_AUTH_DONT_LOCK:
3934                return !mLockTaskModeTasks.isEmpty();
3935            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
3936            case LOCK_TASK_AUTH_LAUNCHABLE:
3937            case LOCK_TASK_AUTH_WHITELISTED:
3938                return false;
3939            case LOCK_TASK_AUTH_PINNABLE:
3940                // Pinnable tasks can't be launched on top of locktask tasks.
3941                return !mLockTaskModeTasks.isEmpty();
3942            default:
3943                Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
3944                return true;
3945        }
3946    }
3947
3948    void onLockTaskPackagesUpdatedLocked() {
3949        boolean didSomething = false;
3950        for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
3951            final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
3952            final boolean wasWhitelisted =
3953                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3954                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3955            lockedTask.setLockTaskAuth();
3956            final boolean isWhitelisted =
3957                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3958                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3959            if (wasWhitelisted && !isWhitelisted) {
3960                // Lost whitelisting authorization. End it now.
3961                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
3962                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
3963                removeLockedTaskLocked(lockedTask);
3964                lockedTask.performClearTaskLocked();
3965                didSomething = true;
3966            }
3967        }
3968        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3969            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3970            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3971                final ActivityStack stack = stacks.get(stackNdx);
3972                stack.onLockTaskPackagesUpdatedLocked();
3973            }
3974        }
3975        final ActivityRecord r = topRunningActivityLocked();
3976        final TaskRecord task = r != null ? r.task : null;
3977        if (mLockTaskModeTasks.isEmpty() && task != null
3978                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
3979            // This task must have just been authorized.
3980            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
3981                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
3982            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
3983                    false);
3984            didSomething = true;
3985        }
3986        if (didSomething) {
3987            resumeTopActivitiesLocked();
3988        }
3989    }
3990
3991    int getLockTaskModeState() {
3992        return mLockTaskModeState;
3993    }
3994
3995    private final class ActivityStackSupervisorHandler extends Handler {
3996
3997        public ActivityStackSupervisorHandler(Looper looper) {
3998            super(looper);
3999        }
4000
4001        void activityIdleInternal(ActivityRecord r) {
4002            synchronized (mService) {
4003                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
4004            }
4005        }
4006
4007        @Override
4008        public void handleMessage(Message msg) {
4009            switch (msg.what) {
4010                case IDLE_TIMEOUT_MSG: {
4011                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
4012                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
4013                    if (mService.mDidDexOpt) {
4014                        mService.mDidDexOpt = false;
4015                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
4016                        nmsg.obj = msg.obj;
4017                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
4018                        return;
4019                    }
4020                    // We don't at this point know if the activity is fullscreen,
4021                    // so we need to be conservative and assume it isn't.
4022                    activityIdleInternal((ActivityRecord)msg.obj);
4023                } break;
4024                case IDLE_NOW_MSG: {
4025                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
4026                    activityIdleInternal((ActivityRecord)msg.obj);
4027                } break;
4028                case RESUME_TOP_ACTIVITY_MSG: {
4029                    synchronized (mService) {
4030                        resumeTopActivitiesLocked();
4031                    }
4032                } break;
4033                case SLEEP_TIMEOUT_MSG: {
4034                    synchronized (mService) {
4035                        if (mService.isSleepingOrShuttingDown()) {
4036                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
4037                            mSleepTimeout = true;
4038                            checkReadyForSleepLocked();
4039                        }
4040                    }
4041                } break;
4042                case LAUNCH_TIMEOUT_MSG: {
4043                    if (mService.mDidDexOpt) {
4044                        mService.mDidDexOpt = false;
4045                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
4046                        return;
4047                    }
4048                    synchronized (mService) {
4049                        if (mLaunchingActivity.isHeld()) {
4050                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
4051                            if (VALIDATE_WAKE_LOCK_CALLER
4052                                    && Binder.getCallingUid() != Process.myUid()) {
4053                                throw new IllegalStateException("Calling must be system uid");
4054                            }
4055                            mLaunchingActivity.release();
4056                        }
4057                    }
4058                } break;
4059                case HANDLE_DISPLAY_ADDED: {
4060                    handleDisplayAdded(msg.arg1);
4061                } break;
4062                case HANDLE_DISPLAY_CHANGED: {
4063                    handleDisplayChanged(msg.arg1);
4064                } break;
4065                case HANDLE_DISPLAY_REMOVED: {
4066                    handleDisplayRemoved(msg.arg1);
4067                } break;
4068                case CONTAINER_CALLBACK_VISIBILITY: {
4069                    final ActivityContainer container = (ActivityContainer) msg.obj;
4070                    final IActivityContainerCallback callback = container.mCallback;
4071                    if (callback != null) {
4072                        try {
4073                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
4074                        } catch (RemoteException e) {
4075                        }
4076                    }
4077                } break;
4078                case LOCK_TASK_START_MSG: {
4079                    // When lock task starts, we disable the status bars.
4080                    try {
4081                        if (mLockTaskNotify == null) {
4082                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
4083                        }
4084                        mLockTaskNotify.show(true);
4085                        mLockTaskModeState = msg.arg2;
4086                        if (getStatusBarService() != null) {
4087                            int flags = 0;
4088                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
4089                                flags = StatusBarManager.DISABLE_MASK
4090                                        & (~StatusBarManager.DISABLE_BACK);
4091                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
4092                                flags = StatusBarManager.DISABLE_MASK
4093                                        & (~StatusBarManager.DISABLE_BACK)
4094                                        & (~StatusBarManager.DISABLE_HOME)
4095                                        & (~StatusBarManager.DISABLE_RECENT);
4096                            }
4097                            getStatusBarService().disable(flags, mToken,
4098                                    mService.mContext.getPackageName());
4099                        }
4100                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
4101                        if (getDevicePolicyManager() != null) {
4102                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
4103                                    (String)msg.obj, msg.arg1);
4104                        }
4105                    } catch (RemoteException ex) {
4106                        throw new RuntimeException(ex);
4107                    }
4108                } break;
4109                case LOCK_TASK_END_MSG: {
4110                    // When lock task ends, we enable the status bars.
4111                    try {
4112                        if (getStatusBarService() != null) {
4113                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
4114                                    mService.mContext.getPackageName());
4115                        }
4116                        mWindowManager.reenableKeyguard(mToken);
4117                        if (getDevicePolicyManager() != null) {
4118                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
4119                                    msg.arg1);
4120                        }
4121                        if (mLockTaskNotify == null) {
4122                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
4123                        }
4124                        mLockTaskNotify.show(false);
4125                        try {
4126                            boolean shouldLockKeyguard = Settings.Secure.getInt(
4127                                    mService.mContext.getContentResolver(),
4128                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
4129                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
4130                                mWindowManager.lockNow(null);
4131                                mWindowManager.dismissKeyguard();
4132                                new LockPatternUtils(mService.mContext)
4133                                        .requireCredentialEntry(UserHandle.USER_ALL);
4134                            }
4135                        } catch (SettingNotFoundException e) {
4136                            // No setting, don't lock.
4137                        }
4138                    } catch (RemoteException ex) {
4139                        throw new RuntimeException(ex);
4140                    } finally {
4141                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
4142                    }
4143                } break;
4144                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
4145                    if (mLockTaskNotify == null) {
4146                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
4147                    }
4148                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
4149                } break;
4150                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
4151                    final ActivityContainer container = (ActivityContainer) msg.obj;
4152                    final IActivityContainerCallback callback = container.mCallback;
4153                    if (callback != null) {
4154                        try {
4155                            callback.onAllActivitiesComplete(container.asBinder());
4156                        } catch (RemoteException e) {
4157                        }
4158                    }
4159                } break;
4160                case LAUNCH_TASK_BEHIND_COMPLETE: {
4161                    synchronized (mService) {
4162                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
4163                        if (r != null) {
4164                            handleLaunchTaskBehindCompleteLocked(r);
4165                        }
4166                    }
4167                } break;
4168            }
4169        }
4170    }
4171
4172    class ActivityContainer extends android.app.IActivityContainer.Stub {
4173        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
4174                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
4175        final int mStackId;
4176        IActivityContainerCallback mCallback = null;
4177        final ActivityStack mStack;
4178        ActivityRecord mParentActivity = null;
4179        String mIdString;
4180
4181        boolean mVisible = true;
4182
4183        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
4184        ActivityDisplay mActivityDisplay;
4185
4186        final static int CONTAINER_STATE_HAS_SURFACE = 0;
4187        final static int CONTAINER_STATE_NO_SURFACE = 1;
4188        final static int CONTAINER_STATE_FINISHING = 2;
4189        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
4190
4191        ActivityContainer(int stackId) {
4192            synchronized (mService) {
4193                mStackId = stackId;
4194                mStack = new ActivityStack(this, mRecentTasks);
4195                mIdString = "ActivtyContainer{" + mStackId + "}";
4196                if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
4197            }
4198        }
4199
4200        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
4201            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
4202                    + " to display=" + activityDisplay);
4203            mActivityDisplay = activityDisplay;
4204            mStack.mDisplayId = activityDisplay.mDisplayId;
4205            mStack.mStacks = activityDisplay.mStacks;
4206
4207            activityDisplay.attachActivities(mStack);
4208            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
4209        }
4210
4211        @Override
4212        public void attachToDisplay(int displayId) {
4213            synchronized (mService) {
4214                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
4215                if (activityDisplay == null) {
4216                    return;
4217                }
4218                attachToDisplayLocked(activityDisplay);
4219            }
4220        }
4221
4222        @Override
4223        public int getDisplayId() {
4224            synchronized (mService) {
4225                if (mActivityDisplay != null) {
4226                    return mActivityDisplay.mDisplayId;
4227                }
4228            }
4229            return -1;
4230        }
4231
4232        @Override
4233        public int getStackId() {
4234            synchronized (mService) {
4235                return mStackId;
4236            }
4237        }
4238
4239        @Override
4240        public boolean injectEvent(InputEvent event) {
4241            final long origId = Binder.clearCallingIdentity();
4242            try {
4243                synchronized (mService) {
4244                    if (mActivityDisplay != null) {
4245                        return mInputManagerInternal.injectInputEvent(event,
4246                                mActivityDisplay.mDisplayId,
4247                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
4248                    }
4249                }
4250                return false;
4251            } finally {
4252                Binder.restoreCallingIdentity(origId);
4253            }
4254        }
4255
4256        @Override
4257        public void release() {
4258            synchronized (mService) {
4259                if (mContainerState == CONTAINER_STATE_FINISHING) {
4260                    return;
4261                }
4262                mContainerState = CONTAINER_STATE_FINISHING;
4263
4264                long origId = Binder.clearCallingIdentity();
4265                try {
4266                    mStack.finishAllActivitiesLocked(false);
4267                    removePendingActivityLaunchesLocked(mStack);
4268                } finally {
4269                    Binder.restoreCallingIdentity(origId);
4270                }
4271            }
4272        }
4273
4274        protected void detachLocked() {
4275            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
4276                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
4277            if (mActivityDisplay != null) {
4278                mActivityDisplay.detachActivitiesLocked(mStack);
4279                mActivityDisplay = null;
4280                mStack.mDisplayId = -1;
4281                mStack.mStacks = null;
4282                mWindowManager.detachStack(mStackId);
4283            }
4284        }
4285
4286        @Override
4287        public final int startActivity(Intent intent) {
4288            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
4289            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
4290                    Binder.getCallingUid(), mCurrentUser, false,
4291                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4292
4293            // TODO: Switch to user app stacks here.
4294            String mimeType = intent.getType();
4295            final Uri data = intent.getData();
4296            if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4297                mimeType = mService.getProviderMimeType(data, userId);
4298            }
4299            checkEmbeddedAllowedInner(userId, intent, mimeType);
4300
4301            intent.addFlags(FORCE_NEW_TASK_FLAGS);
4302            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null,
4303                    0, 0, null, null, null, null, false, userId, this, null);
4304        }
4305
4306        @Override
4307        public final int startActivityIntentSender(IIntentSender intentSender)
4308                throws TransactionTooLargeException {
4309            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
4310
4311            if (!(intentSender instanceof PendingIntentRecord)) {
4312                throw new IllegalArgumentException("Bad PendingIntent object");
4313            }
4314
4315            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
4316                    Binder.getCallingUid(), mCurrentUser, false,
4317                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4318
4319            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
4320            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
4321                    pendingIntent.key.requestResolvedType);
4322
4323            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
4324                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
4325        }
4326
4327        private void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
4328            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
4329            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
4330                throw new SecurityException(
4331                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
4332            }
4333        }
4334
4335        @Override
4336        public IBinder asBinder() {
4337            return this;
4338        }
4339
4340        @Override
4341        public void setSurface(Surface surface, int width, int height, int density) {
4342            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
4343        }
4344
4345        ActivityStackSupervisor getOuter() {
4346            return ActivityStackSupervisor.this;
4347        }
4348
4349        boolean isAttachedLocked() {
4350            return mActivityDisplay != null;
4351        }
4352
4353        void getBounds(Point outBounds) {
4354            synchronized (mService) {
4355                    if (mActivityDisplay != null) {
4356                    mActivityDisplay.getBounds(outBounds);
4357                } else {
4358                    outBounds.set(0, 0);
4359                }
4360            }
4361        }
4362
4363        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
4364        void setVisible(boolean visible) {
4365            if (mVisible != visible) {
4366                mVisible = visible;
4367                if (mCallback != null) {
4368                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
4369                            0 /* unused */, this).sendToTarget();
4370                }
4371            }
4372        }
4373
4374        void setDrawn() {
4375        }
4376
4377        // You can always start a new task on a regular ActivityStack.
4378        boolean isEligibleForNewTasks() {
4379            return true;
4380        }
4381
4382        void onTaskListEmptyLocked() {
4383            detachLocked();
4384            deleteActivityContainer(this);
4385            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
4386        }
4387
4388        @Override
4389        public String toString() {
4390            return mIdString + (mActivityDisplay == null ? "N" : "A");
4391        }
4392    }
4393
4394    private class VirtualActivityContainer extends ActivityContainer {
4395        Surface mSurface;
4396        boolean mDrawn = false;
4397
4398        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
4399            super(getNextStackId());
4400            mParentActivity = parent;
4401            mCallback = callback;
4402            mContainerState = CONTAINER_STATE_NO_SURFACE;
4403            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
4404        }
4405
4406        @Override
4407        public void setSurface(Surface surface, int width, int height, int density) {
4408            super.setSurface(surface, width, height, density);
4409
4410            synchronized (mService) {
4411                final long origId = Binder.clearCallingIdentity();
4412                try {
4413                    setSurfaceLocked(surface, width, height, density);
4414                } finally {
4415                    Binder.restoreCallingIdentity(origId);
4416                }
4417            }
4418        }
4419
4420        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
4421            if (mContainerState == CONTAINER_STATE_FINISHING) {
4422                return;
4423            }
4424            VirtualActivityDisplay virtualActivityDisplay =
4425                    (VirtualActivityDisplay) mActivityDisplay;
4426            if (virtualActivityDisplay == null) {
4427                virtualActivityDisplay =
4428                        new VirtualActivityDisplay(width, height, density);
4429                mActivityDisplay = virtualActivityDisplay;
4430                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
4431                attachToDisplayLocked(virtualActivityDisplay);
4432            }
4433
4434            if (mSurface != null) {
4435                mSurface.release();
4436            }
4437
4438            mSurface = surface;
4439            if (surface != null) {
4440                mStack.resumeTopActivityLocked(null);
4441            } else {
4442                mContainerState = CONTAINER_STATE_NO_SURFACE;
4443                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
4444                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
4445                    mStack.startPausingLocked(false, true, false, false);
4446                }
4447            }
4448
4449            setSurfaceIfReadyLocked();
4450
4451            if (DEBUG_STACK) Slog.d(TAG_STACK,
4452                    "setSurface: " + this + " to display=" + virtualActivityDisplay);
4453        }
4454
4455        @Override
4456        boolean isAttachedLocked() {
4457            return mSurface != null && super.isAttachedLocked();
4458        }
4459
4460        @Override
4461        void setDrawn() {
4462            synchronized (mService) {
4463                mDrawn = true;
4464                setSurfaceIfReadyLocked();
4465            }
4466        }
4467
4468        // Never start a new task on an ActivityView if it isn't explicitly specified.
4469        @Override
4470        boolean isEligibleForNewTasks() {
4471            return false;
4472        }
4473
4474        private void setSurfaceIfReadyLocked() {
4475            if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
4476                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
4477            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
4478                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
4479                mContainerState = CONTAINER_STATE_HAS_SURFACE;
4480            }
4481        }
4482    }
4483
4484    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
4485     * attached {@link ActivityStack}s */
4486    class ActivityDisplay {
4487        /** Actual Display this object tracks. */
4488        int mDisplayId;
4489        Display mDisplay;
4490        DisplayInfo mDisplayInfo = new DisplayInfo();
4491
4492        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
4493         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
4494        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
4495
4496        ActivityRecord mVisibleBehindActivity;
4497
4498        ActivityDisplay() {
4499        }
4500
4501        // After instantiation, check that mDisplay is not null before using this. The alternative
4502        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
4503        ActivityDisplay(int displayId) {
4504            final Display display = mDisplayManager.getDisplay(displayId);
4505            if (display == null) {
4506                return;
4507            }
4508            init(display);
4509        }
4510
4511        void init(Display display) {
4512            mDisplay = display;
4513            mDisplayId = display.getDisplayId();
4514            mDisplay.getDisplayInfo(mDisplayInfo);
4515        }
4516
4517        void attachActivities(ActivityStack stack) {
4518            if (DEBUG_STACK) Slog.v(TAG_STACK,
4519                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId);
4520            mStacks.add(stack);
4521        }
4522
4523        void detachActivitiesLocked(ActivityStack stack) {
4524            if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
4525                    + " from displayId=" + mDisplayId);
4526            mStacks.remove(stack);
4527        }
4528
4529        void getBounds(Point bounds) {
4530            mDisplay.getDisplayInfo(mDisplayInfo);
4531            bounds.x = mDisplayInfo.appWidth;
4532            bounds.y = mDisplayInfo.appHeight;
4533        }
4534
4535        void setVisibleBehindActivity(ActivityRecord r) {
4536            mVisibleBehindActivity = r;
4537        }
4538
4539        boolean hasVisibleBehindActivity() {
4540            return mVisibleBehindActivity != null;
4541        }
4542
4543        @Override
4544        public String toString() {
4545            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4546        }
4547    }
4548
4549    class VirtualActivityDisplay extends ActivityDisplay {
4550        VirtualDisplay mVirtualDisplay;
4551
4552        VirtualActivityDisplay(int width, int height, int density) {
4553            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4554            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4555                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4556                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4557                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4558
4559            init(mVirtualDisplay.getDisplay());
4560
4561            mWindowManager.handleDisplayAdded(mDisplayId);
4562        }
4563
4564        void setSurface(Surface surface) {
4565            if (mVirtualDisplay != null) {
4566                mVirtualDisplay.setSurface(surface);
4567            }
4568        }
4569
4570        @Override
4571        void detachActivitiesLocked(ActivityStack stack) {
4572            super.detachActivitiesLocked(stack);
4573            if (mVirtualDisplay != null) {
4574                mVirtualDisplay.release();
4575                mVirtualDisplay = null;
4576            }
4577        }
4578
4579        @Override
4580        public String toString() {
4581            return "VirtualActivityDisplay={" + mDisplayId + "}";
4582        }
4583    }
4584
4585    private boolean isLeanbackOnlyDevice() {
4586        boolean onLeanbackOnly = false;
4587        try {
4588            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
4589                    PackageManager.FEATURE_LEANBACK_ONLY);
4590        } catch (RemoteException e) {
4591            // noop
4592        }
4593
4594        return onLeanbackOnly;
4595    }
4596}
4597