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