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