ActivityStackSupervisor.java revision fb81d09d359480f9e43bbf300877b60de05f4816
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                    intent.addCategory(Intent.CATEGORY_VOICE);
1510                    if (!AppGlobals.getPackageManager().activitySupportsIntent(
1511                            intent.getComponent(), intent, resolvedType)) {
1512                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1513                    }
1514                } catch (RemoteException e) {
1515                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1516                }
1517            }
1518        }
1519
1520        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
1521            // If the caller is starting a new voice session, just make sure the target
1522            // is actually allowing it to run this way.
1523            try {
1524                if (!AppGlobals.getPackageManager().activitySupportsIntent(intent.getComponent(),
1525                        intent, resolvedType)) {
1526                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1527                }
1528            } catch (RemoteException e) {
1529                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
1530            }
1531        }
1532
1533        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1534
1535        if (err != ActivityManager.START_SUCCESS) {
1536            if (resultRecord != null) {
1537                resultStack.sendActivityResultLocked(-1,
1538                    resultRecord, resultWho, requestCode,
1539                    Activity.RESULT_CANCELED, null);
1540            }
1541            ActivityOptions.abort(options);
1542            return err;
1543        }
1544
1545        boolean abort = false;
1546
1547        final int startAnyPerm = mService.checkPermission(
1548                START_ANY_ACTIVITY, callingPid, callingUid);
1549
1550        if (startAnyPerm != PERMISSION_GRANTED) {
1551            final int componentRestriction = getComponentRestrictionForCallingPackage(
1552                    aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity);
1553            final int actionRestriction = getActionRestrictionForCallingPackage(
1554                    intent.getAction(), callingPackage, callingPid, callingUid);
1555
1556            if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION
1557                    || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1558                if (resultRecord != null) {
1559                    resultStack.sendActivityResultLocked(-1,
1560                            resultRecord, resultWho, requestCode,
1561                            Activity.RESULT_CANCELED, null);
1562                }
1563                String msg;
1564                if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
1565                    msg = "Permission Denial: starting " + intent.toString()
1566                            + " from " + callerApp + " (pid=" + callingPid
1567                            + ", uid=" + callingUid + ")" + " with revoked permission "
1568                            + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction());
1569                } else if (!aInfo.exported) {
1570                    msg = "Permission Denial: starting " + intent.toString()
1571                            + " from " + callerApp + " (pid=" + callingPid
1572                            + ", uid=" + callingUid + ")"
1573                            + " not exported from uid " + aInfo.applicationInfo.uid;
1574                } else {
1575                    msg = "Permission Denial: starting " + intent.toString()
1576                            + " from " + callerApp + " (pid=" + callingPid
1577                            + ", uid=" + callingUid + ")"
1578                            + " requires " + aInfo.permission;
1579                }
1580                Slog.w(TAG, msg);
1581                throw new SecurityException(msg);
1582            }
1583
1584            if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) {
1585                String message = "Appop Denial: starting " + intent.toString()
1586                        + " from " + callerApp + " (pid=" + callingPid
1587                        + ", uid=" + callingUid + ")"
1588                        + " requires " + AppOpsManager.permissionToOp(
1589                                ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()));
1590                Slog.w(TAG, message);
1591                abort = true;
1592            } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) {
1593                String message = "Appop Denial: starting " + intent.toString()
1594                        + " from " + callerApp + " (pid=" + callingPid
1595                        + ", uid=" + callingUid + ")"
1596                        + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission);
1597                Slog.w(TAG, message);
1598                abort = true;
1599            }
1600        }
1601
1602        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1603                callingPid, resolvedType, aInfo.applicationInfo);
1604
1605        if (mService.mController != null) {
1606            try {
1607                // The Intent we give to the watcher has the extra data
1608                // stripped off, since it can contain private information.
1609                Intent watchIntent = intent.cloneFilter();
1610                abort |= !mService.mController.activityStarting(watchIntent,
1611                        aInfo.applicationInfo.packageName);
1612            } catch (RemoteException e) {
1613                mService.mController = null;
1614            }
1615        }
1616
1617        if (abort) {
1618            if (resultRecord != null) {
1619                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1620                        Activity.RESULT_CANCELED, null);
1621            }
1622            // We pretend to the caller that it was really started, but
1623            // they will just get a cancel result.
1624            ActivityOptions.abort(options);
1625            return ActivityManager.START_SUCCESS;
1626        }
1627
1628        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1629                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1630                requestCode, componentSpecified, voiceSession != null, this, container, options);
1631        if (outActivity != null) {
1632            outActivity[0] = r;
1633        }
1634
1635        if (r.appTimeTracker == null && sourceRecord != null) {
1636            // If the caller didn't specify an explicit time tracker, we want to continue
1637            // tracking under any it has.
1638            r.appTimeTracker = sourceRecord.appTimeTracker;
1639        }
1640
1641        final ActivityStack stack = mFocusedStack;
1642        if (voiceSession == null && (stack.mResumedActivity == null
1643                || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
1644            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
1645                    realCallingPid, realCallingUid, "Activity start")) {
1646                PendingActivityLaunch pal =
1647                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1648                mPendingActivityLaunches.add(pal);
1649                ActivityOptions.abort(options);
1650                return ActivityManager.START_SWITCHES_CANCELED;
1651            }
1652        }
1653
1654        if (mService.mDidAppSwitch) {
1655            // This is the second allowed switch since we stopped switches,
1656            // so now just generally allow switches.  Use case: user presses
1657            // home (switches disabled, switch to home, mDidAppSwitch now true);
1658            // user taps a home icon (coming from home so allowed, we hit here
1659            // and now allow anyone to switch again).
1660            mService.mAppSwitchesAllowedTime = 0;
1661        } else {
1662            mService.mDidAppSwitch = true;
1663        }
1664
1665        doPendingActivityLaunchesLocked(false);
1666
1667        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
1668                startFlags, true, options, inTask);
1669
1670        if (err < 0) {
1671            // If someone asked to have the keyguard dismissed on the next
1672            // activity start, but we are not actually doing an activity
1673            // switch...  just dismiss the keyguard now, because we
1674            // probably want to see whatever is behind it.
1675            notifyActivityDrawnForKeyguard();
1676        }
1677        return err;
1678    }
1679
1680    private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
1681            String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
1682        if (activityInfo.permission == null) {
1683            return ACTIVITY_RESTRICTION_NONE;
1684        }
1685
1686        if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
1687                callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
1688                == PackageManager.PERMISSION_DENIED) {
1689            return ACTIVITY_RESTRICTION_PERMISSION;
1690        }
1691
1692        final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission);
1693        if (opCode == AppOpsManager.OP_NONE) {
1694            return ACTIVITY_RESTRICTION_NONE;
1695        }
1696
1697        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1698                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1699            if (!ignoreTargetSecurity) {
1700                return ACTIVITY_RESTRICTION_APPOP;
1701            }
1702        }
1703
1704        return ACTIVITY_RESTRICTION_NONE;
1705    }
1706
1707    private int getActionRestrictionForCallingPackage(String action,
1708            String callingPackage, int callingPid, int callingUid) {
1709        if (action == null) {
1710            return ACTIVITY_RESTRICTION_NONE;
1711        }
1712
1713        String permission = ACTION_TO_RUNTIME_PERMISSION.get(action);
1714        if (permission == null) {
1715            return ACTIVITY_RESTRICTION_NONE;
1716        }
1717
1718        final PackageInfo packageInfo;
1719        try {
1720            packageInfo = mService.mContext.getPackageManager()
1721                    .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
1722        } catch (PackageManager.NameNotFoundException e) {
1723            Slog.i(TAG, "Cannot find package info for " + callingPackage);
1724            return ACTIVITY_RESTRICTION_NONE;
1725        }
1726
1727        if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) {
1728            return ACTIVITY_RESTRICTION_NONE;
1729        }
1730
1731        if (mService.checkPermission(permission, callingPid, callingUid) ==
1732                PackageManager.PERMISSION_DENIED) {
1733            return ACTIVITY_RESTRICTION_PERMISSION;
1734        }
1735
1736        final int opCode = AppOpsManager.permissionToOpCode(permission);
1737        if (opCode == AppOpsManager.OP_NONE) {
1738            return ACTIVITY_RESTRICTION_NONE;
1739        }
1740
1741        if (mService.mAppOpsService.noteOperation(opCode, callingUid,
1742                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1743            return ACTIVITY_RESTRICTION_APPOP;
1744        }
1745
1746        return ACTIVITY_RESTRICTION_NONE;
1747    }
1748
1749    ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
1750        final TaskRecord task = r.task;
1751
1752        // On leanback only devices we should keep all activities in the same stack.
1753        if (!mLeanbackOnlyDevice &&
1754                (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
1755
1756            ActivityStack stack;
1757
1758            if (task != null && task.stack != null) {
1759                stack = task.stack;
1760                if (stack.isOnHomeDisplay()) {
1761                    if (mFocusedStack != stack) {
1762                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1763                                "computeStackFocus: Setting " + "focused stack to r=" + r
1764                                + " task=" + task);
1765                    } else {
1766                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1767                            "computeStackFocus: Focused stack already=" + mFocusedStack);
1768                    }
1769                }
1770                return stack;
1771            }
1772
1773            final ActivityContainer container = r.mInitialActivityContainer;
1774            if (container != null) {
1775                // The first time put it on the desired stack, after this put on task stack.
1776                r.mInitialActivityContainer = null;
1777                return container.mStack;
1778            }
1779
1780            if (mFocusedStack != mHomeStack && (!newTask ||
1781                    mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
1782                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1783                        "computeStackFocus: Have a focused stack=" + mFocusedStack);
1784                return mFocusedStack;
1785            }
1786
1787            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
1788            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1789                stack = homeDisplayStacks.get(stackNdx);
1790                if (!stack.isHomeStack()) {
1791                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
1792                            "computeStackFocus: Setting focused stack=" + stack);
1793                    return stack;
1794                }
1795            }
1796
1797            // Need to create an app stack for this user.
1798            stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
1799            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
1800                    + r + " stackId=" + stack.mStackId);
1801            return stack;
1802        }
1803        return mHomeStack;
1804    }
1805
1806    boolean setFocusedStack(ActivityRecord r, String reason) {
1807        if (r == null) {
1808            // Not sure what you are trying to do, but it is not going to work...
1809            return false;
1810        }
1811        final TaskRecord task = r.task;
1812        if (task == null || task.stack == null) {
1813            Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task);
1814            return false;
1815        }
1816        task.stack.moveToFront(reason);
1817        return true;
1818    }
1819
1820    final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
1821            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
1822            boolean doResume, Bundle options, TaskRecord inTask) {
1823        final Intent intent = r.intent;
1824        final int callingUid = r.launchedFromUid;
1825
1826        // In some flows in to this function, we retrieve the task record and hold on to it
1827        // without a lock before calling back in to here...  so the task at this point may
1828        // not actually be in recents.  Check for that, and if it isn't in recents just
1829        // consider it invalid.
1830        if (inTask != null && !inTask.inRecents) {
1831            Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
1832            inTask = null;
1833        }
1834
1835        final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
1836        final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
1837        final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
1838
1839        int launchFlags = intent.getFlags();
1840        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
1841                (launchSingleInstance || launchSingleTask)) {
1842            // We have a conflict between the Intent and the Activity manifest, manifest wins.
1843            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
1844                    "\"singleInstance\" or \"singleTask\"");
1845            launchFlags &=
1846                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
1847        } else {
1848            switch (r.info.documentLaunchMode) {
1849                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
1850                    break;
1851                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
1852                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1853                    break;
1854                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
1855                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
1856                    break;
1857                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
1858                    launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1859                    break;
1860            }
1861        }
1862
1863        final boolean launchTaskBehind = r.mLaunchTaskBehind
1864                && !launchSingleTask && !launchSingleInstance
1865                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
1866
1867        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0
1868                && r.resultTo.task.stack != null) {
1869            // For whatever reason this activity is being launched into a new
1870            // task...  yet the caller has requested a result back.  Well, that
1871            // is pretty messed up, so instead immediately send back a cancel
1872            // and let the new task continue launched as normal without a
1873            // dependency on its originator.
1874            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1875            r.resultTo.task.stack.sendActivityResultLocked(-1,
1876                    r.resultTo, r.resultWho, r.requestCode,
1877                    Activity.RESULT_CANCELED, null);
1878            r.resultTo = null;
1879        }
1880
1881        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
1882            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1883        }
1884
1885        // If we are actually going to launch in to a new task, there are some cases where
1886        // we further want to do multiple task.
1887        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1888            if (launchTaskBehind
1889                    || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
1890                launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
1891            }
1892        }
1893
1894        // We'll invoke onUserLeaving before onPause only if the launching
1895        // activity did not explicitly state that this is an automated launch.
1896        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1897        if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
1898                "startActivity() => mUserLeaving=" + mUserLeaving);
1899
1900        // If the caller has asked not to resume at this point, we make note
1901        // of this in the record so that we can skip it when trying to find
1902        // the top running activity.
1903        if (!doResume) {
1904            r.delayedResume = true;
1905        }
1906
1907        ActivityRecord notTop =
1908                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1909
1910        // If the onlyIfNeeded flag is set, then we can do this if the activity
1911        // being launched is the same as the one making the call...  or, as
1912        // a special case, if we do not know the caller then we count the
1913        // current top activity as the caller.
1914        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1915            ActivityRecord checkedCaller = sourceRecord;
1916            if (checkedCaller == null) {
1917                checkedCaller = mFocusedStack.topRunningNonDelayedActivityLocked(notTop);
1918            }
1919            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1920                // Caller is not the same as launcher, so always needed.
1921                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1922            }
1923        }
1924
1925        boolean addingToTask = false;
1926        TaskRecord reuseTask = null;
1927
1928        // If the caller is not coming from another activity, but has given us an
1929        // explicit task into which they would like us to launch the new activity,
1930        // then let's see about doing that.
1931        if (sourceRecord == null && inTask != null && inTask.stack != null) {
1932            final Intent baseIntent = inTask.getBaseIntent();
1933            final ActivityRecord root = inTask.getRootActivity();
1934            if (baseIntent == null) {
1935                ActivityOptions.abort(options);
1936                throw new IllegalArgumentException("Launching into task without base intent: "
1937                        + inTask);
1938            }
1939
1940            // If this task is empty, then we are adding the first activity -- it
1941            // determines the root, and must be launching as a NEW_TASK.
1942            if (launchSingleInstance || launchSingleTask) {
1943                if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
1944                    ActivityOptions.abort(options);
1945                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
1946                            + r + " into different task " + inTask);
1947                }
1948                if (root != null) {
1949                    ActivityOptions.abort(options);
1950                    throw new IllegalArgumentException("Caller with inTask " + inTask
1951                            + " has root " + root + " but target is singleInstance/Task");
1952                }
1953            }
1954
1955            // If task is empty, then adopt the interesting intent launch flags in to the
1956            // activity being started.
1957            if (root == null) {
1958                final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
1959                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
1960                        | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
1961                launchFlags = (launchFlags&~flagsOfInterest)
1962                        | (baseIntent.getFlags()&flagsOfInterest);
1963                intent.setFlags(launchFlags);
1964                inTask.setIntent(r);
1965                addingToTask = true;
1966
1967            // If the task is not empty and the caller is asking to start it as the root
1968            // of a new task, then we don't actually want to start this on the task.  We
1969            // will bring the task to the front, and possibly give it a new intent.
1970            } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1971                addingToTask = false;
1972
1973            } else {
1974                addingToTask = true;
1975            }
1976
1977            reuseTask = inTask;
1978        } else {
1979            inTask = null;
1980        }
1981
1982        if (inTask == null) {
1983            if (sourceRecord == null) {
1984                // This activity is not being started from another...  in this
1985                // case we -always- start a new task.
1986                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
1987                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1988                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1989                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1990                }
1991            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1992                // The original activity who is starting us is running as a single
1993                // instance...  this new activity it is starting must go on its
1994                // own task.
1995                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1996            } else if (launchSingleInstance || launchSingleTask) {
1997                // The activity being started is a single instance...  it always
1998                // gets launched into its own task.
1999                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2000            }
2001        }
2002
2003        ActivityInfo newTaskInfo = null;
2004        Intent newTaskIntent = null;
2005        ActivityStack sourceStack;
2006        if (sourceRecord != null) {
2007            if (sourceRecord.finishing) {
2008                // If the source is finishing, we can't further count it as our source.  This
2009                // is because the task it is associated with may now be empty and on its way out,
2010                // so we don't want to blindly throw it in to that task.  Instead we will take
2011                // the NEW_TASK flow and try to find a task for it. But save the task information
2012                // so it can be used when creating the new task.
2013                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
2014                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
2015                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
2016                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2017                    newTaskInfo = sourceRecord.info;
2018                    newTaskIntent = sourceRecord.task.intent;
2019                }
2020                sourceRecord = null;
2021                sourceStack = null;
2022            } else {
2023                sourceStack = sourceRecord.task.stack;
2024            }
2025        } else {
2026            sourceStack = null;
2027        }
2028
2029        boolean movedHome = false;
2030        ActivityStack targetStack;
2031
2032        intent.setFlags(launchFlags);
2033        final boolean noAnimation = (launchFlags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0;
2034
2035        // We may want to try to place the new activity in to an existing task.  We always
2036        // do this if the target activity is singleTask or singleInstance; we will also do
2037        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
2038        // us to still place it in a new task: multi task, always doc mode, or being asked to
2039        // launch this as a new task behind the current one.
2040        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
2041                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
2042                || launchSingleInstance || launchSingleTask) {
2043            // If bring to front is requested, and no result is requested and we have not
2044            // been given an explicit task to launch in to, and
2045            // we can find a task that was started with this same
2046            // component, then instead of launching bring that one to the front.
2047            if (inTask == null && r.resultTo == null) {
2048                // See if there is a task to bring to the front.  If this is
2049                // a SINGLE_INSTANCE activity, there can be one and only one
2050                // instance of it in the history, and it is always in its own
2051                // unique task, so we do a special search.
2052                ActivityRecord intentActivity = !launchSingleInstance ?
2053                        findTaskLocked(r) : findActivityLocked(intent, r.info);
2054                if (intentActivity != null) {
2055                    // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused
2056                    // but still needs to be a lock task mode violation since the task gets
2057                    // cleared out and the device would otherwise leave the locked task.
2058                    if (isLockTaskModeViolation(intentActivity.task,
2059                            (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2060                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
2061                        showLockTaskToast();
2062                        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
2063                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2064                    }
2065                    if (r.task == null) {
2066                        r.task = intentActivity.task;
2067                    }
2068                    if (intentActivity.task.intent == null) {
2069                        // This task was started because of movement of
2070                        // the activity based on affinity...  now that we
2071                        // are actually launching it, we can assign the
2072                        // base intent.
2073                        intentActivity.task.setIntent(r);
2074                    }
2075                    targetStack = intentActivity.task.stack;
2076                    targetStack.mLastPausedActivity = null;
2077                    // If the target task is not in the front, then we need
2078                    // to bring it to the front...  except...  well, with
2079                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
2080                    // to have the same behavior as if a new instance was
2081                    // being started, which means not bringing it to the front
2082                    // if the caller is not itself in the front.
2083                    final ActivityStack focusStack = getFocusedStack();
2084                    ActivityRecord curTop = (focusStack == null)
2085                            ? null : focusStack.topRunningNonDelayedActivityLocked(notTop);
2086                    boolean movedToFront = false;
2087                    if (curTop != null && (curTop.task != intentActivity.task ||
2088                            curTop.task != focusStack.topTask())) {
2089                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
2090                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
2091                                sourceStack.topActivity().task == sourceRecord.task)) {
2092                            // We really do want to push this one into the user's face, right now.
2093                            if (launchTaskBehind && sourceRecord != null) {
2094                                intentActivity.setTaskToAffiliateWith(sourceRecord.task);
2095                            }
2096                            movedHome = true;
2097                            targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
2098                                    options, r.appTimeTracker, "bringingFoundTaskToFront");
2099                            movedToFront = true;
2100                            if ((launchFlags &
2101                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
2102                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
2103                                // Caller wants to appear on home activity.
2104                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2105                            }
2106                            options = null;
2107                        }
2108                    }
2109                    if (!movedToFront) {
2110                        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + targetStack
2111                                + " from " + intentActivity);
2112                        targetStack.moveToFront("intentActivityFound");
2113                    }
2114
2115                    // If the caller has requested that the target task be
2116                    // reset, then do so.
2117                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2118                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
2119                    }
2120                    if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2121                        // We don't need to start a new activity, and
2122                        // the client said not to do anything if that
2123                        // is the case, so this is it!  And for paranoia, make
2124                        // sure we have correctly resumed the top activity.
2125                        if (doResume) {
2126                            resumeTopActivitiesLocked(targetStack, null, options);
2127
2128                            // Make sure to notify Keyguard as well if we are not running an app
2129                            // transition later.
2130                            if (!movedToFront) {
2131                                notifyActivityDrawnForKeyguard();
2132                            }
2133                        } else {
2134                            ActivityOptions.abort(options);
2135                        }
2136                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2137                    }
2138                    if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
2139                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
2140                        // The caller has requested to completely replace any
2141                        // existing task with its new activity.  Well that should
2142                        // not be too hard...
2143                        reuseTask = intentActivity.task;
2144                        reuseTask.performClearTaskLocked();
2145                        reuseTask.setIntent(r);
2146                    } else if ((launchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
2147                            || launchSingleInstance || launchSingleTask) {
2148                        // In this situation we want to remove all activities
2149                        // from the task up to the one being started.  In most
2150                        // cases this means we are resetting the task to its
2151                        // initial state.
2152                        ActivityRecord top =
2153                                intentActivity.task.performClearTaskLocked(r, launchFlags);
2154                        if (top != null) {
2155                            if (top.frontOfTask) {
2156                                // Activity aliases may mean we use different
2157                                // intents for the top activity, so make sure
2158                                // the task now has the identity of the new
2159                                // intent.
2160                                top.task.setIntent(r);
2161                            }
2162                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
2163                                    r, top.task);
2164                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2165                        } else {
2166                            // A special case: we need to start the activity because it is not
2167                            // currently running, and the caller has asked to clear the current
2168                            // task to have this activity at the top.
2169                            addingToTask = true;
2170                            // Now pretend like this activity is being started by the top of its
2171                            // task, so it is put in the right place.
2172                            sourceRecord = intentActivity;
2173                            TaskRecord task = sourceRecord.task;
2174                            if (task != null && task.stack == null) {
2175                                // Target stack got cleared when we all activities were removed
2176                                // above. Go ahead and reset it.
2177                                targetStack = computeStackFocus(sourceRecord, false /* newTask */);
2178                                targetStack.addTask(
2179                                        task, !launchTaskBehind /* toTop */, false /* moving */);
2180                            }
2181
2182                        }
2183                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
2184                        // In this case the top activity on the task is the
2185                        // same as the one being launched, so we take that
2186                        // as a request to bring the task to the foreground.
2187                        // If the top activity in the task is the root
2188                        // activity, deliver this new intent to it if it
2189                        // desires.
2190                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
2191                                && intentActivity.realActivity.equals(r.realActivity)) {
2192                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
2193                                    intentActivity.task);
2194                            if (intentActivity.frontOfTask) {
2195                                intentActivity.task.setIntent(r);
2196                            }
2197                            intentActivity.deliverNewIntentLocked(callingUid, r.intent,
2198                                    r.launchedFromPackage);
2199                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
2200                            // In this case we are launching the root activity
2201                            // of the task, but with a different intent.  We
2202                            // should start a new instance on top.
2203                            addingToTask = true;
2204                            sourceRecord = intentActivity;
2205                        }
2206                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2207                        // In this case an activity is being launched in to an
2208                        // existing task, without resetting that task.  This
2209                        // is typically the situation of launching an activity
2210                        // from a notification or shortcut.  We want to place
2211                        // the new activity on top of the current task.
2212                        addingToTask = true;
2213                        sourceRecord = intentActivity;
2214                    } else if (!intentActivity.task.rootWasReset) {
2215                        // In this case we are launching in to an existing task
2216                        // that has not yet been started from its front door.
2217                        // The current task has been brought to the front.
2218                        // Ideally, we'd probably like to place this new task
2219                        // at the bottom of its stack, but that's a little hard
2220                        // to do with the current organization of the code so
2221                        // for now we'll just drop it.
2222                        intentActivity.task.setIntent(r);
2223                    }
2224                    if (!addingToTask && reuseTask == null) {
2225                        // We didn't do anything...  but it was needed (a.k.a., client
2226                        // don't use that intent!)  And for paranoia, make
2227                        // sure we have correctly resumed the top activity.
2228                        if (doResume) {
2229                            targetStack.resumeTopActivityLocked(null, options);
2230                            if (!movedToFront) {
2231                                // Make sure to notify Keyguard as well if we are not running an app
2232                                // transition later.
2233                                notifyActivityDrawnForKeyguard();
2234                            }
2235                        } else {
2236                            ActivityOptions.abort(options);
2237                        }
2238                        return ActivityManager.START_TASK_TO_FRONT;
2239                    }
2240                }
2241            }
2242        }
2243
2244        //String uri = r.intent.toURI();
2245        //Intent intent2 = new Intent(uri);
2246        //Slog.i(TAG, "Given intent: " + r.intent);
2247        //Slog.i(TAG, "URI is: " + uri);
2248        //Slog.i(TAG, "To intent: " + intent2);
2249
2250        if (r.packageName != null) {
2251            // If the activity being launched is the same as the one currently
2252            // at the top, then we need to check if it should only be launched
2253            // once.
2254            ActivityStack topStack = mFocusedStack;
2255            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
2256            if (top != null && r.resultTo == null) {
2257                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2258                    if (top.app != null && top.app.thread != null) {
2259                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2260                            || launchSingleTop || launchSingleTask) {
2261                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
2262                                    top.task);
2263                            // For paranoia, make sure we have correctly
2264                            // resumed the top activity.
2265                            topStack.mLastPausedActivity = null;
2266                            if (doResume) {
2267                                resumeTopActivitiesLocked();
2268                            }
2269                            ActivityOptions.abort(options);
2270                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2271                                // We don't need to start a new activity, and
2272                                // the client said not to do anything if that
2273                                // is the case, so this is it!
2274                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2275                            }
2276                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2277                            return ActivityManager.START_DELIVERED_TO_TOP;
2278                        }
2279                    }
2280                }
2281            }
2282
2283        } else {
2284            if (r.resultTo != null && r.resultTo.task.stack != null) {
2285                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
2286                        r.requestCode, Activity.RESULT_CANCELED, null);
2287            }
2288            ActivityOptions.abort(options);
2289            return ActivityManager.START_CLASS_NOT_FOUND;
2290        }
2291
2292        boolean newTask = false;
2293        boolean keepCurTransition = false;
2294
2295        TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
2296                sourceRecord.task : null;
2297
2298        // Should this be considered a new task?
2299        if (r.resultTo == null && inTask == null && !addingToTask
2300                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
2301            newTask = true;
2302            targetStack = computeStackFocus(r, newTask);
2303            targetStack.moveToFront("startingNewTask");
2304
2305            if (reuseTask == null) {
2306                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
2307                        newTaskInfo != null ? newTaskInfo : r.info,
2308                        newTaskIntent != null ? newTaskIntent : intent,
2309                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
2310                        taskToAffiliate);
2311                if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2312                        "Starting new activity " + r + " in new task " + r.task);
2313            } else {
2314                r.setTask(reuseTask, taskToAffiliate);
2315            }
2316            if (isLockTaskModeViolation(r.task)) {
2317                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2318                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2319            }
2320            if (!movedHome) {
2321                if ((launchFlags &
2322                        (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
2323                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
2324                    // Caller wants to appear on home activity, so before starting
2325                    // their own activity we will bring home to the front.
2326                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2327                }
2328            }
2329        } else if (sourceRecord != null) {
2330            final TaskRecord sourceTask = sourceRecord.task;
2331            if (isLockTaskModeViolation(sourceTask)) {
2332                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2333                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2334            }
2335            targetStack = sourceTask.stack;
2336            targetStack.moveToFront("sourceStackToFront");
2337            final TaskRecord topTask = targetStack.topTask();
2338            if (topTask != sourceTask) {
2339                targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
2340                        r.appTimeTracker, "sourceTaskToFront");
2341            }
2342            if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2343                // In this case, we are adding the activity to an existing
2344                // task, but the caller has asked to clear that task if the
2345                // activity is already running.
2346                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
2347                keepCurTransition = true;
2348                if (top != null) {
2349                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
2350                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2351                    // For paranoia, make sure we have correctly
2352                    // resumed the top activity.
2353                    targetStack.mLastPausedActivity = null;
2354                    if (doResume) {
2355                        targetStack.resumeTopActivityLocked(null);
2356                    }
2357                    ActivityOptions.abort(options);
2358                    return ActivityManager.START_DELIVERED_TO_TOP;
2359                }
2360            } else if (!addingToTask &&
2361                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
2362                // In this case, we are launching an activity in our own task
2363                // that may already be running somewhere in the history, and
2364                // we want to shuffle it to the front of the stack if so.
2365                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
2366                if (top != null) {
2367                    final TaskRecord task = top.task;
2368                    task.moveActivityToFrontLocked(top);
2369                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
2370                    top.updateOptionsLocked(options);
2371                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2372                    targetStack.mLastPausedActivity = null;
2373                    if (doResume) {
2374                        targetStack.resumeTopActivityLocked(null);
2375                    }
2376                    return ActivityManager.START_DELIVERED_TO_TOP;
2377                }
2378            }
2379            // An existing activity is starting this new activity, so we want
2380            // to keep the new one in the same task as the one that is starting
2381            // it.
2382            r.setTask(sourceTask, null);
2383            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2384                    + " in existing task " + r.task + " from source " + sourceRecord);
2385
2386        } else if (inTask != null) {
2387            // The caller is asking that the new activity be started in an explicit
2388            // task it has provided to us.
2389            if (isLockTaskModeViolation(inTask)) {
2390                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
2391                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
2392            }
2393            targetStack = inTask.stack;
2394            targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker,
2395                    "inTaskToFront");
2396
2397            // Check whether we should actually launch the new activity in to the task,
2398            // or just reuse the current activity on top.
2399            ActivityRecord top = inTask.getTopActivity();
2400            if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
2401                if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2402                        || launchSingleTop || launchSingleTask) {
2403                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
2404                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
2405                        // We don't need to start a new activity, and
2406                        // the client said not to do anything if that
2407                        // is the case, so this is it!
2408                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
2409                    }
2410                    top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
2411                    return ActivityManager.START_DELIVERED_TO_TOP;
2412                }
2413            }
2414
2415            if (!addingToTask) {
2416                // We don't actually want to have this activity added to the task, so just
2417                // stop here but still tell the caller that we consumed the intent.
2418                ActivityOptions.abort(options);
2419                return ActivityManager.START_TASK_TO_FRONT;
2420            }
2421
2422            r.setTask(inTask, null);
2423            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2424                    + " in explicit task " + r.task);
2425
2426        } else {
2427            // This not being started from an existing activity, and not part
2428            // of a new task...  just put it in the top task, though these days
2429            // this case should never happen.
2430            targetStack = computeStackFocus(r, newTask);
2431            targetStack.moveToFront("addingToTopTask");
2432            ActivityRecord prev = targetStack.topActivity();
2433            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
2434                            r.info, intent, null, null, true), null);
2435            mWindowManager.moveTaskToTop(r.task.taskId);
2436            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
2437                    + " in new guessed " + r.task);
2438        }
2439
2440        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2441                intent, r.getUriPermissionsLocked(), r.userId);
2442
2443        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
2444            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
2445        }
2446        if (newTask) {
2447            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
2448        }
2449        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
2450        targetStack.mLastPausedActivity = null;
2451        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
2452        if (!launchTaskBehind) {
2453            // Don't set focus on an activity that's going to the back.
2454            mService.setFocusedActivityLocked(r, "startedActivity");
2455        }
2456        return ActivityManager.START_SUCCESS;
2457    }
2458
2459    final void doPendingActivityLaunchesLocked(boolean doResume) {
2460        while (!mPendingActivityLaunches.isEmpty()) {
2461            PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
2462            startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
2463                    doResume && mPendingActivityLaunches.isEmpty(), null, null);
2464        }
2465    }
2466
2467    void removePendingActivityLaunchesLocked(ActivityStack stack) {
2468        for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
2469            PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
2470            if (pal.stack == stack) {
2471                mPendingActivityLaunches.remove(palNdx);
2472            }
2473        }
2474    }
2475
2476    void setLaunchSource(int uid) {
2477        mLaunchingActivity.setWorkSource(new WorkSource(uid));
2478    }
2479
2480    void acquireLaunchWakelock() {
2481        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2482            throw new IllegalStateException("Calling must be system uid");
2483        }
2484        mLaunchingActivity.acquire();
2485        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2486            // To be safe, don't allow the wake lock to be held for too long.
2487            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2488        }
2489    }
2490
2491    /**
2492     * Called when the frontmost task is idle.
2493     * @return the state of mService.mBooting before this was called.
2494     */
2495    private boolean checkFinishBootingLocked() {
2496        final boolean booting = mService.mBooting;
2497        boolean enableScreen = false;
2498        mService.mBooting = false;
2499        if (!mService.mBooted) {
2500            mService.mBooted = true;
2501            enableScreen = true;
2502        }
2503        if (booting || enableScreen) {
2504            mService.postFinishBooting(booting, enableScreen);
2505        }
2506        return booting;
2507    }
2508
2509    // Checked.
2510    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
2511            Configuration config) {
2512        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
2513
2514        ArrayList<ActivityRecord> stops = null;
2515        ArrayList<ActivityRecord> finishes = null;
2516        ArrayList<UserState> startingUsers = null;
2517        int NS = 0;
2518        int NF = 0;
2519        boolean booting = false;
2520        boolean activityRemoved = false;
2521
2522        ActivityRecord r = ActivityRecord.forTokenLocked(token);
2523        if (r != null) {
2524            if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
2525                    + Debug.getCallers(4));
2526            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2527            r.finishLaunchTickingLocked();
2528            if (fromTimeout) {
2529                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
2530            }
2531
2532            // This is a hack to semi-deal with a race condition
2533            // in the client where it can be constructed with a
2534            // newer configuration from when we asked it to launch.
2535            // We'll update with whatever configuration it now says
2536            // it used to launch.
2537            if (config != null) {
2538                r.configuration = config;
2539            }
2540
2541            // We are now idle.  If someone is waiting for a thumbnail from
2542            // us, we can now deliver.
2543            r.idle = true;
2544
2545            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
2546            if (isFrontStack(r.task.stack) || fromTimeout) {
2547                booting = checkFinishBootingLocked();
2548            }
2549        }
2550
2551        if (allResumedActivitiesIdle()) {
2552            if (r != null) {
2553                mService.scheduleAppGcsLocked();
2554            }
2555
2556            if (mLaunchingActivity.isHeld()) {
2557                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2558                if (VALIDATE_WAKE_LOCK_CALLER &&
2559                        Binder.getCallingUid() != Process.myUid()) {
2560                    throw new IllegalStateException("Calling must be system uid");
2561                }
2562                mLaunchingActivity.release();
2563            }
2564            ensureActivitiesVisibleLocked(null, 0);
2565        }
2566
2567        // Atomically retrieve all of the other things to do.
2568        stops = processStoppingActivitiesLocked(true);
2569        NS = stops != null ? stops.size() : 0;
2570        if ((NF = mFinishingActivities.size()) > 0) {
2571            finishes = new ArrayList<>(mFinishingActivities);
2572            mFinishingActivities.clear();
2573        }
2574
2575        if (mStartingUsers.size() > 0) {
2576            startingUsers = new ArrayList<>(mStartingUsers);
2577            mStartingUsers.clear();
2578        }
2579
2580        // Stop any activities that are scheduled to do so but have been
2581        // waiting for the next one to start.
2582        for (int i = 0; i < NS; i++) {
2583            r = stops.get(i);
2584            final ActivityStack stack = r.task.stack;
2585            if (stack != null) {
2586                if (r.finishing) {
2587                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
2588                } else {
2589                    stack.stopActivityLocked(r);
2590                }
2591            }
2592        }
2593
2594        // Finish any activities that are scheduled to do so but have been
2595        // waiting for the next one to start.
2596        for (int i = 0; i < NF; i++) {
2597            r = finishes.get(i);
2598            final ActivityStack stack = r.task.stack;
2599            if (stack != null) {
2600                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
2601            }
2602        }
2603
2604        if (!booting) {
2605            // Complete user switch
2606            if (startingUsers != null) {
2607                for (int i = 0; i < startingUsers.size(); i++) {
2608                    mService.finishUserSwitch(startingUsers.get(i));
2609                }
2610            }
2611            // Complete starting up of background users
2612            if (mStartingBackgroundUsers.size() > 0) {
2613                startingUsers = new ArrayList<UserState>(mStartingBackgroundUsers);
2614                mStartingBackgroundUsers.clear();
2615                for (int i = 0; i < startingUsers.size(); i++) {
2616                    mService.finishUserBoot(startingUsers.get(i));
2617                }
2618            }
2619        }
2620
2621        mService.trimApplications();
2622        //dump();
2623        //mWindowManager.dump();
2624
2625        if (activityRemoved) {
2626            resumeTopActivitiesLocked();
2627        }
2628
2629        return r;
2630    }
2631
2632    boolean handleAppDiedLocked(ProcessRecord app) {
2633        boolean hasVisibleActivities = false;
2634        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2635            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2636            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2637                hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app);
2638            }
2639        }
2640        return hasVisibleActivities;
2641    }
2642
2643    void closeSystemDialogsLocked() {
2644        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2645            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2646            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2647                stacks.get(stackNdx).closeSystemDialogsLocked();
2648            }
2649        }
2650    }
2651
2652    void removeUserLocked(int userId) {
2653        mUserStackInFront.delete(userId);
2654    }
2655
2656    /**
2657     * @return true if some activity was finished (or would have finished if doit were true).
2658     */
2659    boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
2660            boolean doit, boolean evenPersistent, int userId) {
2661        boolean didSomething = false;
2662        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2663            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2664            final int numStacks = stacks.size();
2665            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2666                final ActivityStack stack = stacks.get(stackNdx);
2667                if (stack.finishDisabledPackageActivitiesLocked(
2668                        packageName, filterByClasses, doit, evenPersistent, userId)) {
2669                    didSomething = true;
2670                }
2671            }
2672        }
2673        return didSomething;
2674    }
2675
2676    void updatePreviousProcessLocked(ActivityRecord r) {
2677        // Now that this process has stopped, we may want to consider
2678        // it to be the previous app to try to keep around in case
2679        // the user wants to return to it.
2680
2681        // First, found out what is currently the foreground app, so that
2682        // we don't blow away the previous app if this activity is being
2683        // hosted by the process that is actually still the foreground.
2684        ProcessRecord fgApp = null;
2685        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2686            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2687            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2688                final ActivityStack stack = stacks.get(stackNdx);
2689                if (isFrontStack(stack)) {
2690                    if (stack.mResumedActivity != null) {
2691                        fgApp = stack.mResumedActivity.app;
2692                    } else if (stack.mPausingActivity != null) {
2693                        fgApp = stack.mPausingActivity.app;
2694                    }
2695                    break;
2696                }
2697            }
2698        }
2699
2700        // Now set this one as the previous process, only if that really
2701        // makes sense to.
2702        if (r.app != null && fgApp != null && r.app != fgApp
2703                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
2704                && r.app != mService.mHomeProcess) {
2705            mService.mPreviousProcess = r.app;
2706            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
2707        }
2708    }
2709
2710    boolean resumeTopActivitiesLocked() {
2711        return resumeTopActivitiesLocked(null, null, null);
2712    }
2713
2714    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2715            Bundle targetOptions) {
2716        if (targetStack == null) {
2717            targetStack = mFocusedStack;
2718        }
2719        // Do targetStack first.
2720        boolean result = false;
2721        if (isFrontStack(targetStack)) {
2722            result = targetStack.resumeTopActivityLocked(target, targetOptions);
2723        }
2724
2725        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2726            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2727            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2728                final ActivityStack stack = stacks.get(stackNdx);
2729                if (stack == targetStack) {
2730                    // Already started above.
2731                    continue;
2732                }
2733                if (isFrontStack(stack)) {
2734                    stack.resumeTopActivityLocked(null);
2735                }
2736            }
2737        }
2738        return result;
2739    }
2740
2741    void finishTopRunningActivityLocked(ProcessRecord app, String reason) {
2742        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2743            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2744            final int numStacks = stacks.size();
2745            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2746                final ActivityStack stack = stacks.get(stackNdx);
2747                stack.finishTopRunningActivityLocked(app, reason);
2748            }
2749        }
2750    }
2751
2752    void finishVoiceTask(IVoiceInteractionSession session) {
2753        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2754            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2755            final int numStacks = stacks.size();
2756            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2757                final ActivityStack stack = stacks.get(stackNdx);
2758                stack.finishVoiceTask(session);
2759            }
2760        }
2761    }
2762
2763    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options, String reason) {
2764        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
2765            mUserLeaving = true;
2766        }
2767        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
2768            // Caller wants the home activity moved with it.  To accomplish this,
2769            // we'll just indicate that this task returns to the home task.
2770            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
2771        }
2772        if (task.stack == null) {
2773            Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
2774                    + task + " to front. Stack is null");
2775            return;
2776        }
2777        task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
2778                task.getTopActivity() == null ? null : task.getTopActivity().appTimeTracker,
2779                reason);
2780        if (DEBUG_STACK) Slog.d(TAG_STACK,
2781                "findTaskToMoveToFront: moved to front of stack=" + task.stack);
2782    }
2783
2784    ActivityStack getStack(int stackId) {
2785        ActivityContainer activityContainer = mActivityContainers.get(stackId);
2786        if (activityContainer != null) {
2787            return activityContainer.mStack;
2788        }
2789        return null;
2790    }
2791
2792    ArrayList<ActivityStack> getStacks() {
2793        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2794        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2795            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2796        }
2797        return allStacks;
2798    }
2799
2800    IBinder getHomeActivityToken() {
2801        ActivityRecord homeActivity = getHomeActivity();
2802        if (homeActivity != null) {
2803            return homeActivity.appToken;
2804        }
2805        return null;
2806    }
2807
2808    ActivityRecord getHomeActivity() {
2809        return getHomeActivityForUser(mCurrentUser);
2810    }
2811
2812    ActivityRecord getHomeActivityForUser(int userId) {
2813        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2814        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2815            final TaskRecord task = tasks.get(taskNdx);
2816            if (task.isHomeTask()) {
2817                final ArrayList<ActivityRecord> activities = task.mActivities;
2818                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2819                    final ActivityRecord r = activities.get(activityNdx);
2820                    if (r.isHomeActivity()
2821                            && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
2822                        return r;
2823                    }
2824                }
2825            }
2826        }
2827        return null;
2828    }
2829
2830    ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
2831            IActivityContainerCallback callback) {
2832        ActivityContainer activityContainer =
2833                new VirtualActivityContainer(parentActivity, callback);
2834        mActivityContainers.put(activityContainer.mStackId, activityContainer);
2835        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
2836                "createActivityContainer: " + activityContainer);
2837        parentActivity.mChildContainers.add(activityContainer);
2838        return activityContainer;
2839    }
2840
2841    void removeChildActivityContainers(ActivityRecord parentActivity) {
2842        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
2843        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
2844            ActivityContainer container = childStacks.remove(containerNdx);
2845            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
2846                    + container);
2847            container.release();
2848        }
2849    }
2850
2851    void deleteActivityContainer(IActivityContainer container) {
2852        ActivityContainer activityContainer = (ActivityContainer)container;
2853        if (activityContainer != null) {
2854            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
2855                    "deleteActivityContainer: callers=" + Debug.getCallers(4));
2856            final int stackId = activityContainer.mStackId;
2857            mActivityContainers.remove(stackId);
2858            mWindowManager.removeStack(stackId);
2859        }
2860    }
2861
2862    void resizeStackLocked(int stackId, Rect bounds) {
2863        final ActivityStack stack = getStack(stackId);
2864        if (stack == null) {
2865            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
2866            return;
2867        }
2868
2869        final ActivityRecord r = stack.topRunningActivityLocked(null);
2870        if (r != null && !r.task.mResizeable) {
2871            Slog.w(TAG, "resizeStack: top task " + r.task + " not resizeable.");
2872            return;
2873        }
2874
2875        final Configuration overrideConfig = mWindowManager.resizeStack(stackId, bounds);
2876        if (stack.updateOverrideConfiguration(overrideConfig)) {
2877            if (r != null) {
2878                final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
2879                // And we need to make sure at this point that all other activities
2880                // are made visible with the correct configuration.
2881                ensureActivitiesVisibleLocked(r, 0);
2882                if (!updated) {
2883                    resumeTopActivitiesLocked(stack, null, null);
2884                }
2885            }
2886        }
2887    }
2888
2889    /** Makes sure the input task is in a stack with the specified bounds by either resizing the
2890     * current task stack if it only has one entry, moving the task to a stack that matches the
2891     * bounds, or creating a new stack with the required bounds. Also, makes the task resizeable.*/
2892    void resizeTaskLocked(TaskRecord task, Rect bounds) {
2893        task.mResizeable = true;
2894        final ActivityStack currentStack = task.stack;
2895        if (currentStack.isHomeStack()) {
2896            // Can't move task off the home stack. Sorry!
2897            return;
2898        }
2899
2900        final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds);
2901        if (matchingStackId != -1) {
2902            // There is already a stack with the right bounds!
2903            if (currentStack != null && currentStack.mStackId == matchingStackId) {
2904                // Nothing to do here. Already in the right stack...
2905                return;
2906            }
2907            // Move task to stack with matching bounds.
2908            moveTaskToStackLocked(task.taskId, matchingStackId, true);
2909            return;
2910        }
2911
2912        if (currentStack != null && currentStack.numTasks() == 1) {
2913            // Just resize the current stack since this is the task in it.
2914            resizeStackLocked(currentStack.mStackId, bounds);
2915            return;
2916        }
2917
2918        // Create new stack and move the task to it.
2919        final int displayId = (currentStack != null && currentStack.mDisplayId != -1)
2920                ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY;
2921        ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId);
2922
2923        if (newStack == null) {
2924            Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task);
2925            return;
2926        }
2927        moveTaskToStackLocked(task.taskId, newStack.mStackId, true);
2928        resizeStackLocked(newStack.mStackId, bounds);
2929    }
2930
2931    ActivityStack createStackOnDisplay(int stackId, int displayId) {
2932        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2933        if (activityDisplay == null) {
2934            return null;
2935        }
2936
2937        ActivityContainer activityContainer = new ActivityContainer(stackId);
2938        mActivityContainers.put(stackId, activityContainer);
2939        activityContainer.attachToDisplayLocked(activityDisplay);
2940        return activityContainer.mStack;
2941    }
2942
2943    int getNextStackId() {
2944        while (true) {
2945            if (++mLastStackId <= HOME_STACK_ID) {
2946                mLastStackId = HOME_STACK_ID + 1;
2947            }
2948            if (getStack(mLastStackId) == null) {
2949                break;
2950            }
2951        }
2952        return mLastStackId;
2953    }
2954
2955    private boolean restoreRecentTaskLocked(TaskRecord task) {
2956        ActivityStack stack = null;
2957        // Determine stack to restore task to.
2958        if (mLeanbackOnlyDevice) {
2959            // There is only one stack for lean back devices.
2960            stack = mHomeStack;
2961        } else {
2962            // Look for the top stack on the home display that isn't the home stack.
2963            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
2964            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2965                final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx);
2966                if (!tmpStack.isHomeStack() && tmpStack.mFullscreen) {
2967                    stack = tmpStack;
2968                    break;
2969                }
2970            }
2971        }
2972
2973        if (stack == null) {
2974            // We couldn't find a stack to restore the task to. Possible if are restoring recents
2975            // before an application stack is created...Go ahead and create one on the default
2976            // display.
2977            stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
2978            // Restore home stack to top.
2979            moveHomeStack(true, "restoreRecentTask");
2980            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2981                    "Created stack=" + stack + " for recents restoration.");
2982        }
2983
2984        if (stack == null) {
2985            // What does this mean??? Not sure how we would get here...
2986            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2987                    "Unable to find/create stack to restore recent task=" + task);
2988            return false;
2989        }
2990
2991        stack.addTask(task, false, false);
2992        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
2993                "Added restored task=" + task + " to stack=" + stack);
2994        final ArrayList<ActivityRecord> activities = task.mActivities;
2995        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2996            final ActivityRecord r = activities.get(activityNdx);
2997            mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
2998                    r.info.screenOrientation, r.fullscreen,
2999                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
3000                    r.userId, r.info.configChanges, task.voiceSession != null,
3001                    r.mLaunchTaskBehind);
3002        }
3003        return true;
3004    }
3005
3006    void moveTaskToStackLocked(int taskId, int stackId, boolean toTop) {
3007        final TaskRecord task = anyTaskForIdLocked(taskId);
3008        if (task == null) {
3009            Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
3010            return;
3011        }
3012        final ActivityStack stack = getStack(stackId);
3013        if (stack == null) {
3014            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
3015            return;
3016        }
3017        mWindowManager.moveTaskToStack(taskId, stackId, toTop);
3018        if (task.stack != null) {
3019            task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */);
3020        }
3021        stack.addTask(task, toTop, true);
3022        // The task might have already been running and its visibility needs to be synchronized with
3023        // the visibility of the stack / windows.
3024        stack.ensureActivitiesVisibleLocked(null, 0);
3025        resumeTopActivitiesLocked();
3026    }
3027
3028    ActivityRecord findTaskLocked(ActivityRecord r) {
3029        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
3030        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3031            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3032            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3033                final ActivityStack stack = stacks.get(stackNdx);
3034                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
3035                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
3036                    continue;
3037                }
3038                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
3039                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
3040                            "Skipping stack: (new task not allowed) " + stack);
3041                    continue;
3042                }
3043                final ActivityRecord ar = stack.findTaskLocked(r);
3044                if (ar != null) {
3045                    return ar;
3046                }
3047            }
3048        }
3049        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "No task found");
3050        return null;
3051    }
3052
3053    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
3054        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3055            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3056            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3057                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
3058                if (ar != null) {
3059                    return ar;
3060                }
3061            }
3062        }
3063        return null;
3064    }
3065
3066    void goingToSleepLocked() {
3067        scheduleSleepTimeout();
3068        if (!mGoingToSleep.isHeld()) {
3069            mGoingToSleep.acquire();
3070            if (mLaunchingActivity.isHeld()) {
3071                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
3072                    throw new IllegalStateException("Calling must be system uid");
3073                }
3074                mLaunchingActivity.release();
3075                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
3076            }
3077        }
3078        checkReadyForSleepLocked();
3079    }
3080
3081    boolean shutdownLocked(int timeout) {
3082        goingToSleepLocked();
3083
3084        boolean timedout = false;
3085        final long endTime = System.currentTimeMillis() + timeout;
3086        while (true) {
3087            boolean cantShutdown = false;
3088            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3089                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3090                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3091                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
3092                }
3093            }
3094            if (cantShutdown) {
3095                long timeRemaining = endTime - System.currentTimeMillis();
3096                if (timeRemaining > 0) {
3097                    try {
3098                        mService.wait(timeRemaining);
3099                    } catch (InterruptedException e) {
3100                    }
3101                } else {
3102                    Slog.w(TAG, "Activity manager shutdown timed out");
3103                    timedout = true;
3104                    break;
3105                }
3106            } else {
3107                break;
3108            }
3109        }
3110
3111        // Force checkReadyForSleep to complete.
3112        mSleepTimeout = true;
3113        checkReadyForSleepLocked();
3114
3115        return timedout;
3116    }
3117
3118    void comeOutOfSleepIfNeededLocked() {
3119        removeSleepTimeouts();
3120        if (mGoingToSleep.isHeld()) {
3121            mGoingToSleep.release();
3122        }
3123        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3124            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3125            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3126                final ActivityStack stack = stacks.get(stackNdx);
3127                stack.awakeFromSleepingLocked();
3128                if (isFrontStack(stack)) {
3129                    resumeTopActivitiesLocked();
3130                }
3131            }
3132        }
3133        mGoingToSleepActivities.clear();
3134    }
3135
3136    void activitySleptLocked(ActivityRecord r) {
3137        mGoingToSleepActivities.remove(r);
3138        checkReadyForSleepLocked();
3139    }
3140
3141    void checkReadyForSleepLocked() {
3142        if (!mService.isSleepingOrShuttingDown()) {
3143            // Do not care.
3144            return;
3145        }
3146
3147        if (!mSleepTimeout) {
3148            boolean dontSleep = false;
3149            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3150                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3151                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3152                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
3153                }
3154            }
3155
3156            if (mStoppingActivities.size() > 0) {
3157                // Still need to tell some activities to stop; can't sleep yet.
3158                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
3159                        + mStoppingActivities.size() + " activities");
3160                scheduleIdleLocked();
3161                dontSleep = true;
3162            }
3163
3164            if (mGoingToSleepActivities.size() > 0) {
3165                // Still need to tell some activities to sleep; can't sleep yet.
3166                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
3167                        + mGoingToSleepActivities.size() + " activities");
3168                dontSleep = true;
3169            }
3170
3171            if (dontSleep) {
3172                return;
3173            }
3174        }
3175
3176        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3177            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3178            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3179                stacks.get(stackNdx).goToSleep();
3180            }
3181        }
3182
3183        removeSleepTimeouts();
3184
3185        if (mGoingToSleep.isHeld()) {
3186            mGoingToSleep.release();
3187        }
3188        if (mService.mShuttingDown) {
3189            mService.notifyAll();
3190        }
3191    }
3192
3193    boolean reportResumedActivityLocked(ActivityRecord r) {
3194        final ActivityStack stack = r.task.stack;
3195        if (isFrontStack(stack)) {
3196            mService.updateUsageStats(r, true);
3197        }
3198        if (allResumedActivitiesComplete()) {
3199            ensureActivitiesVisibleLocked(null, 0);
3200            mWindowManager.executeAppTransition();
3201            return true;
3202        }
3203        return false;
3204    }
3205
3206    void handleAppCrashLocked(ProcessRecord app) {
3207        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3208            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3209            int stackNdx = stacks.size() - 1;
3210            while (stackNdx >= 0) {
3211                stacks.get(stackNdx).handleAppCrashLocked(app);
3212                stackNdx--;
3213            }
3214        }
3215    }
3216
3217    boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
3218        final ActivityStack stack = r.task.stack;
3219        if (stack == null) {
3220            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3221                    "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
3222            return false;
3223        }
3224        final boolean isVisible = stack.hasVisibleBehindActivity();
3225        if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3226                "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
3227
3228        final ActivityRecord top = topRunningActivityLocked();
3229        if (top == null || top == r || (visible == isVisible)) {
3230            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
3231            stack.setVisibleBehindActivity(visible ? r : null);
3232            return true;
3233        }
3234
3235        // A non-top activity is reporting a visibility change.
3236        if (visible && top.fullscreen) {
3237            // Let the caller know that it can't be seen.
3238            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3239                    "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
3240                    + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
3241                    + top.app.thread);
3242            return false;
3243        } else if (!visible && stack.getVisibleBehindActivity() != r) {
3244            // Only the activity set as currently visible behind should actively reset its
3245            // visible behind state.
3246            if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
3247                    "requestVisibleBehind: returning visible=" + visible
3248                    + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
3249                    + " r=" + r);
3250            return false;
3251        }
3252
3253        stack.setVisibleBehindActivity(visible ? r : null);
3254        if (!visible) {
3255            // Make the activity immediately above r opaque.
3256            final ActivityRecord next = stack.findNextTranslucentActivity(r);
3257            if (next != null) {
3258                mService.convertFromTranslucent(next.appToken);
3259            }
3260        }
3261        if (top.app != null && top.app.thread != null) {
3262            // Notify the top app of the change.
3263            try {
3264                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
3265            } catch (RemoteException e) {
3266            }
3267        }
3268        return true;
3269    }
3270
3271    // Called when WindowManager has finished animating the launchingBehind activity to the back.
3272    void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
3273        r.mLaunchTaskBehind = false;
3274        final TaskRecord task = r.task;
3275        task.setLastThumbnail(task.stack.screenshotActivities(r));
3276        mRecentTasks.addLocked(task);
3277        mService.notifyTaskStackChangedLocked();
3278        mWindowManager.setAppVisibility(r.appToken, false);
3279    }
3280
3281    void scheduleLaunchTaskBehindComplete(IBinder token) {
3282        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
3283    }
3284
3285    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
3286        // First the front stacks. In case any are not fullscreen and are in front of home.
3287        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3288            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3289            final int topStackNdx = stacks.size() - 1;
3290            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
3291                final ActivityStack stack = stacks.get(stackNdx);
3292                stack.ensureActivitiesVisibleLocked(starting, configChanges);
3293            }
3294        }
3295    }
3296
3297    void clearOtherAppTimeTrackers(AppTimeTracker except) {
3298        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3299            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3300            final int topStackNdx = stacks.size() - 1;
3301            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
3302                final ActivityStack stack = stacks.get(stackNdx);
3303                stack.clearOtherAppTimeTrackers(except);
3304            }
3305        }
3306    }
3307
3308    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
3309        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3310            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3311            final int numStacks = stacks.size();
3312            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
3313                final ActivityStack stack = stacks.get(stackNdx);
3314                stack.scheduleDestroyActivities(app, reason);
3315            }
3316        }
3317    }
3318
3319    void releaseSomeActivitiesLocked(ProcessRecord app, String reason) {
3320        // Examine all activities currently running in the process.
3321        TaskRecord firstTask = null;
3322        // Tasks is non-null only if two or more tasks are found.
3323        ArraySet<TaskRecord> tasks = null;
3324        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
3325        for (int i = 0; i < app.activities.size(); i++) {
3326            ActivityRecord r = app.activities.get(i);
3327            // First, if we find an activity that is in the process of being destroyed,
3328            // then we just aren't going to do anything for now; we want things to settle
3329            // down before we try to prune more activities.
3330            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
3331                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
3332                return;
3333            }
3334            // Don't consider any activies that are currently not in a state where they
3335            // can be destroyed.
3336            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
3337                    || r.state == PAUSED || r.state == STOPPING) {
3338                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
3339                continue;
3340            }
3341            if (r.task != null) {
3342                if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task
3343                        + " from " + r);
3344                if (firstTask == null) {
3345                    firstTask = r.task;
3346                } else if (firstTask != r.task) {
3347                    if (tasks == null) {
3348                        tasks = new ArraySet<>();
3349                        tasks.add(firstTask);
3350                    }
3351                    tasks.add(r.task);
3352                }
3353            }
3354        }
3355        if (tasks == null) {
3356            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release");
3357            return;
3358        }
3359        // If we have activities in multiple tasks that are in a position to be destroyed,
3360        // let's iterate through the tasks and release the oldest one.
3361        final int numDisplays = mActivityDisplays.size();
3362        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
3363            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3364            // Step through all stacks starting from behind, to hit the oldest things first.
3365            for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) {
3366                final ActivityStack stack = stacks.get(stackNdx);
3367                // Try to release activities in this stack; if we manage to, we are done.
3368                if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) {
3369                    return;
3370                }
3371            }
3372        }
3373    }
3374
3375    boolean switchUserLocked(int userId, UserState uss) {
3376        mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
3377        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
3378        mCurrentUser = userId;
3379
3380        mStartingUsers.add(uss);
3381        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3382            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3383            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3384                final ActivityStack stack = stacks.get(stackNdx);
3385                stack.switchUserLocked(userId);
3386                TaskRecord task = stack.topTask();
3387                if (task != null) {
3388                    mWindowManager.moveTaskToTop(task.taskId);
3389                }
3390            }
3391        }
3392
3393        ActivityStack stack = getStack(restoreStackId);
3394        if (stack == null) {
3395            stack = mHomeStack;
3396        }
3397        final boolean homeInFront = stack.isHomeStack();
3398        if (stack.isOnHomeDisplay()) {
3399            moveHomeStack(homeInFront, "switchUserOnHomeDisplay");
3400            TaskRecord task = stack.topTask();
3401            if (task != null) {
3402                mWindowManager.moveTaskToTop(task.taskId);
3403            }
3404        } else {
3405            // Stack was moved to another display while user was swapped out.
3406            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
3407        }
3408        return homeInFront;
3409    }
3410
3411    /**
3412     * Add background users to send boot completed events to.
3413     * @param userId The user being started in the background
3414     * @param uss The state object for the user.
3415     */
3416    public void startBackgroundUserLocked(int userId, UserState uss) {
3417        mStartingBackgroundUsers.add(uss);
3418    }
3419
3420    /** Checks whether the userid is a profile of the current user. */
3421    boolean isCurrentProfileLocked(int userId) {
3422        if (userId == mCurrentUser) return true;
3423        for (int i = 0; i < mService.mCurrentProfileIds.length; i++) {
3424            if (mService.mCurrentProfileIds[i] == userId) return true;
3425        }
3426        return false;
3427    }
3428
3429    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
3430        ArrayList<ActivityRecord> stops = null;
3431
3432        final boolean nowVisible = allResumedActivitiesVisible();
3433        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
3434            ActivityRecord s = mStoppingActivities.get(activityNdx);
3435            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
3436            if (DEBUG_ALL) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
3437                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
3438            if (waitingVisible && nowVisible) {
3439                mWaitingVisibleActivities.remove(s);
3440                if (s.finishing) {
3441                    // If this activity is finishing, it is sitting on top of
3442                    // everyone else but we now know it is no longer needed...
3443                    // so get rid of it.  Otherwise, we need to go through the
3444                    // normal flow and hide it once we determine that it is
3445                    // hidden by the activities in front of it.
3446                    if (DEBUG_ALL) Slog.v(TAG, "Before stopping, can hide: " + s);
3447                    mWindowManager.setAppVisibility(s.appToken, false);
3448                }
3449            }
3450            if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
3451                if (DEBUG_ALL) Slog.v(TAG, "Ready to stop: " + s);
3452                if (stops == null) {
3453                    stops = new ArrayList<>();
3454                }
3455                stops.add(s);
3456                mStoppingActivities.remove(activityNdx);
3457            }
3458        }
3459
3460        return stops;
3461    }
3462
3463    void validateTopActivitiesLocked() {
3464        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3465            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3466            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3467                final ActivityStack stack = stacks.get(stackNdx);
3468                final ActivityRecord r = stack.topRunningActivityLocked(null);
3469                final ActivityState state = r == null ? DESTROYED : r.state;
3470                if (isFrontStack(stack)) {
3471                    if (r == null) Slog.e(TAG,
3472                            "validateTop...: null top activity, stack=" + stack);
3473                    else {
3474                        final ActivityRecord pausing = stack.mPausingActivity;
3475                        if (pausing != null && pausing == r) Slog.e(TAG,
3476                                "validateTop...: top stack has pausing activity r=" + r
3477                                + " state=" + state);
3478                        if (state != INITIALIZING && state != RESUMED) Slog.e(TAG,
3479                                "validateTop...: activity in front not resumed r=" + r
3480                                + " state=" + state);
3481                    }
3482                } else {
3483                    final ActivityRecord resumed = stack.mResumedActivity;
3484                    if (resumed != null && resumed == r) Slog.e(TAG,
3485                            "validateTop...: back stack has resumed activity r=" + r
3486                            + " state=" + state);
3487                    if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG,
3488                            "validateTop...: activity in back resumed r=" + r + " state=" + state);
3489                }
3490            }
3491        }
3492    }
3493
3494    private String lockTaskModeToString() {
3495        switch (mLockTaskModeState) {
3496            case LOCK_TASK_MODE_LOCKED:
3497                return "LOCKED";
3498            case LOCK_TASK_MODE_PINNED:
3499                return "PINNED";
3500            case LOCK_TASK_MODE_NONE:
3501                return "NONE";
3502            default: return "unknown=" + mLockTaskModeState;
3503        }
3504    }
3505
3506    public void dump(PrintWriter pw, String prefix) {
3507        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
3508                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
3509        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
3510        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
3511        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
3512        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
3513        pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
3514                final SparseArray<String[]> packages = mService.mLockTaskPackages;
3515                if (packages.size() > 0) {
3516                    pw.println(" mLockTaskPackages (userId:packages)=");
3517                    for (int i = 0; i < packages.size(); ++i) {
3518                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
3519                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
3520                    }
3521                }
3522                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
3523    }
3524
3525    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
3526        return mFocusedStack.getDumpActivitiesLocked(name);
3527    }
3528
3529    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
3530            boolean needSep, String prefix) {
3531        if (activity != null) {
3532            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
3533                if (needSep) {
3534                    pw.println();
3535                }
3536                pw.print(prefix);
3537                pw.println(activity);
3538                return true;
3539            }
3540        }
3541        return false;
3542    }
3543
3544    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
3545            boolean dumpClient, String dumpPackage) {
3546        boolean printed = false;
3547        boolean needSep = false;
3548        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3549            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
3550            pw.print("Display #"); pw.print(activityDisplay.mDisplayId);
3551                    pw.println(" (activities from top to bottom):");
3552            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3553            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3554                final ActivityStack stack = stacks.get(stackNdx);
3555                StringBuilder stackHeader = new StringBuilder(128);
3556                stackHeader.append("  Stack #");
3557                stackHeader.append(stack.mStackId);
3558                stackHeader.append(":");
3559                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
3560                        needSep, stackHeader.toString());
3561                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
3562                        !dumpAll, false, dumpPackage, true,
3563                        "    Running activities (most recent first):", null);
3564
3565                needSep = printed;
3566                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
3567                        "    mPausingActivity: ");
3568                if (pr) {
3569                    printed = true;
3570                    needSep = false;
3571                }
3572                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
3573                        "    mResumedActivity: ");
3574                if (pr) {
3575                    printed = true;
3576                    needSep = false;
3577                }
3578                if (dumpAll) {
3579                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
3580                            "    mLastPausedActivity: ");
3581                    if (pr) {
3582                        printed = true;
3583                        needSep = true;
3584                    }
3585                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
3586                            needSep, "    mLastNoHistoryActivity: ");
3587                }
3588                needSep = printed;
3589            }
3590        }
3591
3592        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
3593                false, dumpPackage, true, "  Activities waiting to finish:", null);
3594        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
3595                false, dumpPackage, true, "  Activities waiting to stop:", null);
3596        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
3597                false, dumpPackage, true, "  Activities waiting for another to become visible:",
3598                null);
3599        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3600                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3601        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
3602                false, dumpPackage, true, "  Activities waiting to sleep:", null);
3603
3604        return printed;
3605    }
3606
3607    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
3608            String prefix, String label, boolean complete, boolean brief, boolean client,
3609            String dumpPackage, boolean needNL, String header1, String header2) {
3610        TaskRecord lastTask = null;
3611        String innerPrefix = null;
3612        String[] args = null;
3613        boolean printed = false;
3614        for (int i=list.size()-1; i>=0; i--) {
3615            final ActivityRecord r = list.get(i);
3616            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
3617                continue;
3618            }
3619            if (innerPrefix == null) {
3620                innerPrefix = prefix + "      ";
3621                args = new String[0];
3622            }
3623            printed = true;
3624            final boolean full = !brief && (complete || !r.isInHistory());
3625            if (needNL) {
3626                pw.println("");
3627                needNL = false;
3628            }
3629            if (header1 != null) {
3630                pw.println(header1);
3631                header1 = null;
3632            }
3633            if (header2 != null) {
3634                pw.println(header2);
3635                header2 = null;
3636            }
3637            if (lastTask != r.task) {
3638                lastTask = r.task;
3639                pw.print(prefix);
3640                pw.print(full ? "* " : "  ");
3641                pw.println(lastTask);
3642                if (full) {
3643                    lastTask.dump(pw, prefix + "  ");
3644                } else if (complete) {
3645                    // Complete + brief == give a summary.  Isn't that obvious?!?
3646                    if (lastTask.intent != null) {
3647                        pw.print(prefix); pw.print("  ");
3648                                pw.println(lastTask.intent.toInsecureStringWithClip());
3649                    }
3650                }
3651            }
3652            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
3653            pw.print(" #"); pw.print(i); pw.print(": ");
3654            pw.println(r);
3655            if (full) {
3656                r.dump(pw, innerPrefix);
3657            } else if (complete) {
3658                // Complete + brief == give a summary.  Isn't that obvious?!?
3659                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
3660                if (r.app != null) {
3661                    pw.print(innerPrefix); pw.println(r.app);
3662                }
3663            }
3664            if (client && r.app != null && r.app.thread != null) {
3665                // flush anything that is already in the PrintWriter since the thread is going
3666                // to write to the file descriptor directly
3667                pw.flush();
3668                try {
3669                    TransferPipe tp = new TransferPipe();
3670                    try {
3671                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
3672                                r.appToken, innerPrefix, args);
3673                        // Short timeout, since blocking here can
3674                        // deadlock with the application.
3675                        tp.go(fd, 2000);
3676                    } finally {
3677                        tp.kill();
3678                    }
3679                } catch (IOException e) {
3680                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
3681                } catch (RemoteException e) {
3682                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
3683                }
3684                needNL = true;
3685            }
3686        }
3687        return printed;
3688    }
3689
3690    void scheduleIdleTimeoutLocked(ActivityRecord next) {
3691        if (DEBUG_IDLE) Slog.d(TAG_IDLE,
3692                "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
3693        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
3694        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
3695    }
3696
3697    final void scheduleIdleLocked() {
3698        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
3699    }
3700
3701    void removeTimeoutsForActivityLocked(ActivityRecord r) {
3702        if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers="
3703                + Debug.getCallers(4));
3704        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3705    }
3706
3707    final void scheduleResumeTopActivities() {
3708        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
3709            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
3710        }
3711    }
3712
3713    void removeSleepTimeouts() {
3714        mSleepTimeout = false;
3715        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
3716    }
3717
3718    final void scheduleSleepTimeout() {
3719        removeSleepTimeouts();
3720        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
3721    }
3722
3723    @Override
3724    public void onDisplayAdded(int displayId) {
3725        if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
3726        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
3727    }
3728
3729    @Override
3730    public void onDisplayRemoved(int displayId) {
3731        if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
3732        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
3733    }
3734
3735    @Override
3736    public void onDisplayChanged(int displayId) {
3737        if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
3738        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
3739    }
3740
3741    private void handleDisplayAdded(int displayId) {
3742        boolean newDisplay;
3743        synchronized (mService) {
3744            newDisplay = mActivityDisplays.get(displayId) == null;
3745            if (newDisplay) {
3746                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
3747                if (activityDisplay.mDisplay == null) {
3748                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
3749                    return;
3750                }
3751                mActivityDisplays.put(displayId, activityDisplay);
3752            }
3753        }
3754        if (newDisplay) {
3755            mWindowManager.onDisplayAdded(displayId);
3756        }
3757    }
3758
3759    private void handleDisplayRemoved(int displayId) {
3760        synchronized (mService) {
3761            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3762            if (activityDisplay != null) {
3763                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
3764                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3765                    stacks.get(stackNdx).mActivityContainer.detachLocked();
3766                }
3767                mActivityDisplays.remove(displayId);
3768            }
3769        }
3770        mWindowManager.onDisplayRemoved(displayId);
3771    }
3772
3773    private void handleDisplayChanged(int displayId) {
3774        synchronized (mService) {
3775            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3776            if (activityDisplay != null) {
3777                // TODO: Update the bounds.
3778            }
3779        }
3780        mWindowManager.onDisplayChanged(displayId);
3781    }
3782
3783    private StackInfo getStackInfoLocked(ActivityStack stack) {
3784        StackInfo info = new StackInfo();
3785        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
3786        info.displayId = Display.DEFAULT_DISPLAY;
3787        info.stackId = stack.mStackId;
3788
3789        ArrayList<TaskRecord> tasks = stack.getAllTasks();
3790        final int numTasks = tasks.size();
3791        int[] taskIds = new int[numTasks];
3792        String[] taskNames = new String[numTasks];
3793        for (int i = 0; i < numTasks; ++i) {
3794            final TaskRecord task = tasks.get(i);
3795            taskIds[i] = task.taskId;
3796            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
3797                    : task.realActivity != null ? task.realActivity.flattenToString()
3798                    : task.getTopActivity() != null ? task.getTopActivity().packageName
3799                    : "unknown";
3800        }
3801        info.taskIds = taskIds;
3802        info.taskNames = taskNames;
3803        return info;
3804    }
3805
3806    StackInfo getStackInfoLocked(int stackId) {
3807        ActivityStack stack = getStack(stackId);
3808        if (stack != null) {
3809            return getStackInfoLocked(stack);
3810        }
3811        return null;
3812    }
3813
3814    ArrayList<StackInfo> getAllStackInfosLocked() {
3815        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
3816        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
3817            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3818            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
3819                list.add(getStackInfoLocked(stacks.get(ndx)));
3820            }
3821        }
3822        return list;
3823    }
3824
3825    TaskRecord getLockedTaskLocked() {
3826        final int top = mLockTaskModeTasks.size() - 1;
3827        if (top >= 0) {
3828            return mLockTaskModeTasks.get(top);
3829        }
3830        return null;
3831    }
3832
3833    boolean isLockedTask(TaskRecord task) {
3834        return mLockTaskModeTasks.contains(task);
3835    }
3836
3837    boolean isLastLockedTask(TaskRecord task) {
3838        return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task);
3839    }
3840
3841    void removeLockedTaskLocked(final TaskRecord task) {
3842        if (!mLockTaskModeTasks.remove(task)) {
3843            return;
3844        }
3845        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
3846        if (mLockTaskModeTasks.isEmpty()) {
3847            // Last one.
3848            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
3849                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
3850            final Message lockTaskMsg = Message.obtain();
3851            lockTaskMsg.arg1 = task.userId;
3852            lockTaskMsg.what = LOCK_TASK_END_MSG;
3853            mHandler.sendMessage(lockTaskMsg);
3854        }
3855    }
3856
3857    void showLockTaskToast() {
3858        mLockTaskNotify.showToast(mLockTaskModeState);
3859    }
3860
3861    void showLockTaskEscapeMessageLocked(TaskRecord task) {
3862        if (mLockTaskModeTasks.contains(task)) {
3863            mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG);
3864        }
3865    }
3866
3867    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
3868            boolean andResume) {
3869        if (task == null) {
3870            // Take out of lock task mode if necessary
3871            final TaskRecord lockedTask = getLockedTaskLocked();
3872            if (lockedTask != null) {
3873                removeLockedTaskLocked(lockedTask);
3874                if (!mLockTaskModeTasks.isEmpty()) {
3875                    // There are locked tasks remaining, can only finish this task, not unlock it.
3876                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3877                            "setLockTaskModeLocked: Tasks remaining, can't unlock");
3878                    lockedTask.performClearTaskLocked();
3879                    resumeTopActivitiesLocked();
3880                    return;
3881                }
3882            }
3883            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3884                    "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
3885            return;
3886        }
3887
3888        // Should have already been checked, but do it again.
3889        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
3890            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
3891                    "setLockTaskModeLocked: Can't lock due to auth");
3892            return;
3893        }
3894        if (isLockTaskModeViolation(task)) {
3895            Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
3896            return;
3897        }
3898
3899        if (mLockTaskModeTasks.isEmpty()) {
3900            // First locktask.
3901            final Message lockTaskMsg = Message.obtain();
3902            lockTaskMsg.obj = task.intent.getComponent().getPackageName();
3903            lockTaskMsg.arg1 = task.userId;
3904            lockTaskMsg.what = LOCK_TASK_START_MSG;
3905            lockTaskMsg.arg2 = lockTaskModeState;
3906            mHandler.sendMessage(lockTaskMsg);
3907        }
3908        // Add it or move it to the top.
3909        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
3910                " Callers=" + Debug.getCallers(4));
3911        mLockTaskModeTasks.remove(task);
3912        mLockTaskModeTasks.add(task);
3913
3914        if (task.mLockTaskUid == -1) {
3915            task.mLockTaskUid = task.mCallingUid;
3916        }
3917
3918        if (andResume) {
3919            findTaskToMoveToFrontLocked(task, 0, null, reason);
3920            resumeTopActivitiesLocked();
3921        }
3922    }
3923
3924    boolean isLockTaskModeViolation(TaskRecord task) {
3925        return isLockTaskModeViolation(task, false);
3926    }
3927
3928    boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
3929        if (getLockedTaskLocked() == task && !isNewClearTask) {
3930            return false;
3931        }
3932        final int lockTaskAuth = task.mLockTaskAuth;
3933        switch (lockTaskAuth) {
3934            case LOCK_TASK_AUTH_DONT_LOCK:
3935                return !mLockTaskModeTasks.isEmpty();
3936            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
3937            case LOCK_TASK_AUTH_LAUNCHABLE:
3938            case LOCK_TASK_AUTH_WHITELISTED:
3939                return false;
3940            case LOCK_TASK_AUTH_PINNABLE:
3941                // Pinnable tasks can't be launched on top of locktask tasks.
3942                return !mLockTaskModeTasks.isEmpty();
3943            default:
3944                Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
3945                return true;
3946        }
3947    }
3948
3949    void onLockTaskPackagesUpdatedLocked() {
3950        boolean didSomething = false;
3951        for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
3952            final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
3953            final boolean wasWhitelisted =
3954                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3955                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3956            lockedTask.setLockTaskAuth();
3957            final boolean isWhitelisted =
3958                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) ||
3959                    (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED);
3960            if (wasWhitelisted && !isWhitelisted) {
3961                // Lost whitelisting authorization. End it now.
3962                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
3963                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
3964                removeLockedTaskLocked(lockedTask);
3965                lockedTask.performClearTaskLocked();
3966                didSomething = true;
3967            }
3968        }
3969        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
3970            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
3971            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
3972                final ActivityStack stack = stacks.get(stackNdx);
3973                stack.onLockTaskPackagesUpdatedLocked();
3974            }
3975        }
3976        final ActivityRecord r = topRunningActivityLocked();
3977        final TaskRecord task = r != null ? r.task : null;
3978        if (mLockTaskModeTasks.isEmpty() && task != null
3979                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
3980            // This task must have just been authorized.
3981            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
3982                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
3983            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
3984                    false);
3985            didSomething = true;
3986        }
3987        if (didSomething) {
3988            resumeTopActivitiesLocked();
3989        }
3990    }
3991
3992    int getLockTaskModeState() {
3993        return mLockTaskModeState;
3994    }
3995
3996    private final class ActivityStackSupervisorHandler extends Handler {
3997
3998        public ActivityStackSupervisorHandler(Looper looper) {
3999            super(looper);
4000        }
4001
4002        void activityIdleInternal(ActivityRecord r) {
4003            synchronized (mService) {
4004                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
4005            }
4006        }
4007
4008        @Override
4009        public void handleMessage(Message msg) {
4010            switch (msg.what) {
4011                case IDLE_TIMEOUT_MSG: {
4012                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
4013                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
4014                    if (mService.mDidDexOpt) {
4015                        mService.mDidDexOpt = false;
4016                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
4017                        nmsg.obj = msg.obj;
4018                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
4019                        return;
4020                    }
4021                    // We don't at this point know if the activity is fullscreen,
4022                    // so we need to be conservative and assume it isn't.
4023                    activityIdleInternal((ActivityRecord)msg.obj);
4024                } break;
4025                case IDLE_NOW_MSG: {
4026                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
4027                    activityIdleInternal((ActivityRecord)msg.obj);
4028                } break;
4029                case RESUME_TOP_ACTIVITY_MSG: {
4030                    synchronized (mService) {
4031                        resumeTopActivitiesLocked();
4032                    }
4033                } break;
4034                case SLEEP_TIMEOUT_MSG: {
4035                    synchronized (mService) {
4036                        if (mService.isSleepingOrShuttingDown()) {
4037                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
4038                            mSleepTimeout = true;
4039                            checkReadyForSleepLocked();
4040                        }
4041                    }
4042                } break;
4043                case LAUNCH_TIMEOUT_MSG: {
4044                    if (mService.mDidDexOpt) {
4045                        mService.mDidDexOpt = false;
4046                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
4047                        return;
4048                    }
4049                    synchronized (mService) {
4050                        if (mLaunchingActivity.isHeld()) {
4051                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
4052                            if (VALIDATE_WAKE_LOCK_CALLER
4053                                    && Binder.getCallingUid() != Process.myUid()) {
4054                                throw new IllegalStateException("Calling must be system uid");
4055                            }
4056                            mLaunchingActivity.release();
4057                        }
4058                    }
4059                } break;
4060                case HANDLE_DISPLAY_ADDED: {
4061                    handleDisplayAdded(msg.arg1);
4062                } break;
4063                case HANDLE_DISPLAY_CHANGED: {
4064                    handleDisplayChanged(msg.arg1);
4065                } break;
4066                case HANDLE_DISPLAY_REMOVED: {
4067                    handleDisplayRemoved(msg.arg1);
4068                } break;
4069                case CONTAINER_CALLBACK_VISIBILITY: {
4070                    final ActivityContainer container = (ActivityContainer) msg.obj;
4071                    final IActivityContainerCallback callback = container.mCallback;
4072                    if (callback != null) {
4073                        try {
4074                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
4075                        } catch (RemoteException e) {
4076                        }
4077                    }
4078                } break;
4079                case LOCK_TASK_START_MSG: {
4080                    // When lock task starts, we disable the status bars.
4081                    try {
4082                        if (mLockTaskNotify == null) {
4083                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
4084                        }
4085                        mLockTaskNotify.show(true);
4086                        mLockTaskModeState = msg.arg2;
4087                        if (getStatusBarService() != null) {
4088                            int flags = 0;
4089                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
4090                                flags = StatusBarManager.DISABLE_MASK
4091                                        & (~StatusBarManager.DISABLE_BACK);
4092                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
4093                                flags = StatusBarManager.DISABLE_MASK
4094                                        & (~StatusBarManager.DISABLE_BACK)
4095                                        & (~StatusBarManager.DISABLE_HOME)
4096                                        & (~StatusBarManager.DISABLE_RECENT);
4097                            }
4098                            getStatusBarService().disable(flags, mToken,
4099                                    mService.mContext.getPackageName());
4100                        }
4101                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
4102                        if (getDevicePolicyManager() != null) {
4103                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
4104                                    (String)msg.obj, msg.arg1);
4105                        }
4106                    } catch (RemoteException ex) {
4107                        throw new RuntimeException(ex);
4108                    }
4109                } break;
4110                case LOCK_TASK_END_MSG: {
4111                    // When lock task ends, we enable the status bars.
4112                    try {
4113                        if (getStatusBarService() != null) {
4114                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
4115                                    mService.mContext.getPackageName());
4116                        }
4117                        mWindowManager.reenableKeyguard(mToken);
4118                        if (getDevicePolicyManager() != null) {
4119                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
4120                                    msg.arg1);
4121                        }
4122                        if (mLockTaskNotify == null) {
4123                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
4124                        }
4125                        mLockTaskNotify.show(false);
4126                        try {
4127                            boolean shouldLockKeyguard = Settings.Secure.getInt(
4128                                    mService.mContext.getContentResolver(),
4129                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
4130                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
4131                                mWindowManager.lockNow(null);
4132                                mWindowManager.dismissKeyguard();
4133                                new LockPatternUtils(mService.mContext)
4134                                        .requireCredentialEntry(UserHandle.USER_ALL);
4135                            }
4136                        } catch (SettingNotFoundException e) {
4137                            // No setting, don't lock.
4138                        }
4139                    } catch (RemoteException ex) {
4140                        throw new RuntimeException(ex);
4141                    } finally {
4142                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
4143                    }
4144                } break;
4145                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
4146                    if (mLockTaskNotify == null) {
4147                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
4148                    }
4149                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
4150                } break;
4151                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
4152                    final ActivityContainer container = (ActivityContainer) msg.obj;
4153                    final IActivityContainerCallback callback = container.mCallback;
4154                    if (callback != null) {
4155                        try {
4156                            callback.onAllActivitiesComplete(container.asBinder());
4157                        } catch (RemoteException e) {
4158                        }
4159                    }
4160                } break;
4161                case LAUNCH_TASK_BEHIND_COMPLETE: {
4162                    synchronized (mService) {
4163                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
4164                        if (r != null) {
4165                            handleLaunchTaskBehindCompleteLocked(r);
4166                        }
4167                    }
4168                } break;
4169            }
4170        }
4171    }
4172
4173    class ActivityContainer extends android.app.IActivityContainer.Stub {
4174        final static int FORCE_NEW_TASK_FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK |
4175                Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
4176        final int mStackId;
4177        IActivityContainerCallback mCallback = null;
4178        final ActivityStack mStack;
4179        ActivityRecord mParentActivity = null;
4180        String mIdString;
4181
4182        boolean mVisible = true;
4183
4184        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
4185        ActivityDisplay mActivityDisplay;
4186
4187        final static int CONTAINER_STATE_HAS_SURFACE = 0;
4188        final static int CONTAINER_STATE_NO_SURFACE = 1;
4189        final static int CONTAINER_STATE_FINISHING = 2;
4190        int mContainerState = CONTAINER_STATE_HAS_SURFACE;
4191
4192        ActivityContainer(int stackId) {
4193            synchronized (mService) {
4194                mStackId = stackId;
4195                mStack = new ActivityStack(this, mRecentTasks);
4196                mIdString = "ActivtyContainer{" + mStackId + "}";
4197                if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
4198            }
4199        }
4200
4201        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
4202            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
4203                    + " to display=" + activityDisplay);
4204            mActivityDisplay = activityDisplay;
4205            mStack.mDisplayId = activityDisplay.mDisplayId;
4206            mStack.mStacks = activityDisplay.mStacks;
4207
4208            activityDisplay.attachActivities(mStack);
4209            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
4210        }
4211
4212        @Override
4213        public void attachToDisplay(int displayId) {
4214            synchronized (mService) {
4215                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
4216                if (activityDisplay == null) {
4217                    return;
4218                }
4219                attachToDisplayLocked(activityDisplay);
4220            }
4221        }
4222
4223        @Override
4224        public int getDisplayId() {
4225            synchronized (mService) {
4226                if (mActivityDisplay != null) {
4227                    return mActivityDisplay.mDisplayId;
4228                }
4229            }
4230            return -1;
4231        }
4232
4233        @Override
4234        public int getStackId() {
4235            synchronized (mService) {
4236                return mStackId;
4237            }
4238        }
4239
4240        @Override
4241        public boolean injectEvent(InputEvent event) {
4242            final long origId = Binder.clearCallingIdentity();
4243            try {
4244                synchronized (mService) {
4245                    if (mActivityDisplay != null) {
4246                        return mInputManagerInternal.injectInputEvent(event,
4247                                mActivityDisplay.mDisplayId,
4248                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
4249                    }
4250                }
4251                return false;
4252            } finally {
4253                Binder.restoreCallingIdentity(origId);
4254            }
4255        }
4256
4257        @Override
4258        public void release() {
4259            synchronized (mService) {
4260                if (mContainerState == CONTAINER_STATE_FINISHING) {
4261                    return;
4262                }
4263                mContainerState = CONTAINER_STATE_FINISHING;
4264
4265                long origId = Binder.clearCallingIdentity();
4266                try {
4267                    mStack.finishAllActivitiesLocked(false);
4268                    removePendingActivityLaunchesLocked(mStack);
4269                } finally {
4270                    Binder.restoreCallingIdentity(origId);
4271                }
4272            }
4273        }
4274
4275        protected void detachLocked() {
4276            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
4277                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
4278            if (mActivityDisplay != null) {
4279                mActivityDisplay.detachActivitiesLocked(mStack);
4280                mActivityDisplay = null;
4281                mStack.mDisplayId = -1;
4282                mStack.mStacks = null;
4283                mWindowManager.detachStack(mStackId);
4284            }
4285        }
4286
4287        @Override
4288        public final int startActivity(Intent intent) {
4289            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
4290            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
4291                    Binder.getCallingUid(), mCurrentUser, false,
4292                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4293
4294            // TODO: Switch to user app stacks here.
4295            String mimeType = intent.getType();
4296            final Uri data = intent.getData();
4297            if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4298                mimeType = mService.getProviderMimeType(data, userId);
4299            }
4300            checkEmbeddedAllowedInner(userId, intent, mimeType);
4301
4302            intent.addFlags(FORCE_NEW_TASK_FLAGS);
4303            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null,
4304                    0, 0, null, null, null, null, false, userId, this, null);
4305        }
4306
4307        @Override
4308        public final int startActivityIntentSender(IIntentSender intentSender)
4309                throws TransactionTooLargeException {
4310            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
4311
4312            if (!(intentSender instanceof PendingIntentRecord)) {
4313                throw new IllegalArgumentException("Bad PendingIntent object");
4314            }
4315
4316            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),
4317                    Binder.getCallingUid(), mCurrentUser, false,
4318                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4319
4320            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
4321            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
4322                    pendingIntent.key.requestResolvedType);
4323
4324            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,
4325                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
4326        }
4327
4328        private void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
4329            ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
4330            if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
4331                throw new SecurityException(
4332                        "Attempt to embed activity that has not set allowEmbedded=\"true\"");
4333            }
4334        }
4335
4336        @Override
4337        public IBinder asBinder() {
4338            return this;
4339        }
4340
4341        @Override
4342        public void setSurface(Surface surface, int width, int height, int density) {
4343            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
4344        }
4345
4346        ActivityStackSupervisor getOuter() {
4347            return ActivityStackSupervisor.this;
4348        }
4349
4350        boolean isAttachedLocked() {
4351            return mActivityDisplay != null;
4352        }
4353
4354        void getBounds(Point outBounds) {
4355            synchronized (mService) {
4356                    if (mActivityDisplay != null) {
4357                    mActivityDisplay.getBounds(outBounds);
4358                } else {
4359                    outBounds.set(0, 0);
4360                }
4361            }
4362        }
4363
4364        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
4365        void setVisible(boolean visible) {
4366            if (mVisible != visible) {
4367                mVisible = visible;
4368                if (mCallback != null) {
4369                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
4370                            0 /* unused */, this).sendToTarget();
4371                }
4372            }
4373        }
4374
4375        void setDrawn() {
4376        }
4377
4378        // You can always start a new task on a regular ActivityStack.
4379        boolean isEligibleForNewTasks() {
4380            return true;
4381        }
4382
4383        void onTaskListEmptyLocked() {
4384            detachLocked();
4385            deleteActivityContainer(this);
4386            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
4387        }
4388
4389        @Override
4390        public String toString() {
4391            return mIdString + (mActivityDisplay == null ? "N" : "A");
4392        }
4393    }
4394
4395    private class VirtualActivityContainer extends ActivityContainer {
4396        Surface mSurface;
4397        boolean mDrawn = false;
4398
4399        VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
4400            super(getNextStackId());
4401            mParentActivity = parent;
4402            mCallback = callback;
4403            mContainerState = CONTAINER_STATE_NO_SURFACE;
4404            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
4405        }
4406
4407        @Override
4408        public void setSurface(Surface surface, int width, int height, int density) {
4409            super.setSurface(surface, width, height, density);
4410
4411            synchronized (mService) {
4412                final long origId = Binder.clearCallingIdentity();
4413                try {
4414                    setSurfaceLocked(surface, width, height, density);
4415                } finally {
4416                    Binder.restoreCallingIdentity(origId);
4417                }
4418            }
4419        }
4420
4421        private void setSurfaceLocked(Surface surface, int width, int height, int density) {
4422            if (mContainerState == CONTAINER_STATE_FINISHING) {
4423                return;
4424            }
4425            VirtualActivityDisplay virtualActivityDisplay =
4426                    (VirtualActivityDisplay) mActivityDisplay;
4427            if (virtualActivityDisplay == null) {
4428                virtualActivityDisplay =
4429                        new VirtualActivityDisplay(width, height, density);
4430                mActivityDisplay = virtualActivityDisplay;
4431                mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
4432                attachToDisplayLocked(virtualActivityDisplay);
4433            }
4434
4435            if (mSurface != null) {
4436                mSurface.release();
4437            }
4438
4439            mSurface = surface;
4440            if (surface != null) {
4441                mStack.resumeTopActivityLocked(null);
4442            } else {
4443                mContainerState = CONTAINER_STATE_NO_SURFACE;
4444                ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
4445                if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
4446                    mStack.startPausingLocked(false, true, false, false);
4447                }
4448            }
4449
4450            setSurfaceIfReadyLocked();
4451
4452            if (DEBUG_STACK) Slog.d(TAG_STACK,
4453                    "setSurface: " + this + " to display=" + virtualActivityDisplay);
4454        }
4455
4456        @Override
4457        boolean isAttachedLocked() {
4458            return mSurface != null && super.isAttachedLocked();
4459        }
4460
4461        @Override
4462        void setDrawn() {
4463            synchronized (mService) {
4464                mDrawn = true;
4465                setSurfaceIfReadyLocked();
4466            }
4467        }
4468
4469        // Never start a new task on an ActivityView if it isn't explicitly specified.
4470        @Override
4471        boolean isEligibleForNewTasks() {
4472            return false;
4473        }
4474
4475        private void setSurfaceIfReadyLocked() {
4476            if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
4477                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
4478            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
4479                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
4480                mContainerState = CONTAINER_STATE_HAS_SURFACE;
4481            }
4482        }
4483    }
4484
4485    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
4486     * attached {@link ActivityStack}s */
4487    class ActivityDisplay {
4488        /** Actual Display this object tracks. */
4489        int mDisplayId;
4490        Display mDisplay;
4491        DisplayInfo mDisplayInfo = new DisplayInfo();
4492
4493        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
4494         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
4495        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
4496
4497        ActivityRecord mVisibleBehindActivity;
4498
4499        ActivityDisplay() {
4500        }
4501
4502        // After instantiation, check that mDisplay is not null before using this. The alternative
4503        // is for this to throw an exception if mDisplayManager.getDisplay() returns null.
4504        ActivityDisplay(int displayId) {
4505            final Display display = mDisplayManager.getDisplay(displayId);
4506            if (display == null) {
4507                return;
4508            }
4509            init(display);
4510        }
4511
4512        void init(Display display) {
4513            mDisplay = display;
4514            mDisplayId = display.getDisplayId();
4515            mDisplay.getDisplayInfo(mDisplayInfo);
4516        }
4517
4518        void attachActivities(ActivityStack stack) {
4519            if (DEBUG_STACK) Slog.v(TAG_STACK,
4520                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId);
4521            mStacks.add(stack);
4522        }
4523
4524        void detachActivitiesLocked(ActivityStack stack) {
4525            if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack
4526                    + " from displayId=" + mDisplayId);
4527            mStacks.remove(stack);
4528        }
4529
4530        void getBounds(Point bounds) {
4531            mDisplay.getDisplayInfo(mDisplayInfo);
4532            bounds.x = mDisplayInfo.appWidth;
4533            bounds.y = mDisplayInfo.appHeight;
4534        }
4535
4536        void setVisibleBehindActivity(ActivityRecord r) {
4537            mVisibleBehindActivity = r;
4538        }
4539
4540        boolean hasVisibleBehindActivity() {
4541            return mVisibleBehindActivity != null;
4542        }
4543
4544        @Override
4545        public String toString() {
4546            return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
4547        }
4548    }
4549
4550    class VirtualActivityDisplay extends ActivityDisplay {
4551        VirtualDisplay mVirtualDisplay;
4552
4553        VirtualActivityDisplay(int width, int height, int density) {
4554            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
4555            mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null,
4556                    VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null,
4557                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
4558                    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null);
4559
4560            init(mVirtualDisplay.getDisplay());
4561
4562            mWindowManager.handleDisplayAdded(mDisplayId);
4563        }
4564
4565        void setSurface(Surface surface) {
4566            if (mVirtualDisplay != null) {
4567                mVirtualDisplay.setSurface(surface);
4568            }
4569        }
4570
4571        @Override
4572        void detachActivitiesLocked(ActivityStack stack) {
4573            super.detachActivitiesLocked(stack);
4574            if (mVirtualDisplay != null) {
4575                mVirtualDisplay.release();
4576                mVirtualDisplay = null;
4577            }
4578        }
4579
4580        @Override
4581        public String toString() {
4582            return "VirtualActivityDisplay={" + mDisplayId + "}";
4583        }
4584    }
4585
4586    private boolean isLeanbackOnlyDevice() {
4587        boolean onLeanbackOnly = false;
4588        try {
4589            onLeanbackOnly = AppGlobals.getPackageManager().hasSystemFeature(
4590                    PackageManager.FEATURE_LEANBACK_ONLY);
4591        } catch (RemoteException e) {
4592            // noop
4593        }
4594
4595        return onLeanbackOnly;
4596    }
4597}
4598