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