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