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