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