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