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