ActivityStackSupervisor.java revision e3a00d745fad479f560e96cec23e957f37d1c043
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.lang.ref.WeakReference;
99import java.util.ArrayList;
100import java.util.List;
101
102public final class ActivityStackSupervisor implements DisplayListener {
103    static final boolean DEBUG = ActivityManagerService.DEBUG || false;
104    static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
105    static final boolean DEBUG_APP = DEBUG || false;
106    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
107    static final boolean DEBUG_STATES = DEBUG || false;
108    static final boolean DEBUG_IDLE = DEBUG || false;
109
110    public static final int HOME_STACK_ID = 0;
111
112    /** How long we wait until giving up on the last activity telling us it is idle. */
113    static final int IDLE_TIMEOUT = 10*1000;
114
115    /** How long we can hold the sleep wake lock before giving up. */
116    static final int SLEEP_TIMEOUT = 5*1000;
117
118    // How long we can hold the launch wake lock before giving up.
119    static final int LAUNCH_TIMEOUT = 10*1000;
120
121    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
122    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
123    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
124    static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
125    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
126    static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
127    static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
128    static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
129    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
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<WeakReference<ActivityContainer>> mActivityContainers =
228            new SparseArray<WeakReference<ActivityContainer>>();
229
230    /** Mapping from displayId to display current state */
231    private SparseArray<ActivityDisplay> mActivityDisplays = 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(null, 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(
1199                    sourceRecord, resultWho, requestCode);
1200            }
1201            if (sourceRecord.launchedFromUid == callingUid) {
1202                // The new activity is being launched from the same uid as the previous
1203                // activity in the flow, and asking to forward its result back to the
1204                // previous.  In this case the activity is serving as a trampoline between
1205                // the two, so we also want to update its launchedFromPackage to be the
1206                // same as the previous activity.  Note that this is safe, since we know
1207                // these two packages come from the same uid; the caller could just as
1208                // well have supplied that same package name itself.  This specifially
1209                // deals with the case of an intent picker/chooser being launched in the app
1210                // flow to redirect to an activity picked by the user, where we want the final
1211                // activity to consider it to have been launched by the previous app activity.
1212                callingPackage = sourceRecord.launchedFromPackage;
1213            }
1214        }
1215
1216        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1217            // We couldn't find a class that can handle the given Intent.
1218            // That's the end of that!
1219            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1220        }
1221
1222        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1223            // We couldn't find the specific class specified in the Intent.
1224            // Also the end of the line.
1225            err = ActivityManager.START_CLASS_NOT_FOUND;
1226        }
1227
1228        if (err != ActivityManager.START_SUCCESS) {
1229            if (resultRecord != null) {
1230                resultStack.sendActivityResultLocked(-1,
1231                    resultRecord, resultWho, requestCode,
1232                    Activity.RESULT_CANCELED, null);
1233            }
1234            setDismissKeyguard(false);
1235            ActivityOptions.abort(options);
1236            return err;
1237        }
1238
1239        final int startAnyPerm = mService.checkPermission(
1240                START_ANY_ACTIVITY, callingPid, callingUid);
1241        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1242                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1243        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1244            if (resultRecord != null) {
1245                resultStack.sendActivityResultLocked(-1,
1246                    resultRecord, resultWho, requestCode,
1247                    Activity.RESULT_CANCELED, null);
1248            }
1249            setDismissKeyguard(false);
1250            String msg;
1251            if (!aInfo.exported) {
1252                msg = "Permission Denial: starting " + intent.toString()
1253                        + " from " + callerApp + " (pid=" + callingPid
1254                        + ", uid=" + callingUid + ")"
1255                        + " not exported from uid " + aInfo.applicationInfo.uid;
1256            } else {
1257                msg = "Permission Denial: starting " + intent.toString()
1258                        + " from " + callerApp + " (pid=" + callingPid
1259                        + ", uid=" + callingUid + ")"
1260                        + " requires " + aInfo.permission;
1261            }
1262            Slog.w(TAG, msg);
1263            throw new SecurityException(msg);
1264        }
1265
1266        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
1267                callingPid, resolvedType, aInfo.applicationInfo);
1268
1269        if (mService.mController != null) {
1270            try {
1271                // The Intent we give to the watcher has the extra data
1272                // stripped off, since it can contain private information.
1273                Intent watchIntent = intent.cloneFilter();
1274                abort |= !mService.mController.activityStarting(watchIntent,
1275                        aInfo.applicationInfo.packageName);
1276            } catch (RemoteException e) {
1277                mService.mController = null;
1278            }
1279        }
1280
1281        if (abort) {
1282            if (resultRecord != null) {
1283                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1284                        Activity.RESULT_CANCELED, null);
1285            }
1286            // We pretend to the caller that it was really started, but
1287            // they will just get a cancel result.
1288            setDismissKeyguard(false);
1289            ActivityOptions.abort(options);
1290            return ActivityManager.START_SUCCESS;
1291        }
1292
1293        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1294                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
1295                requestCode, componentSpecified, this, container);
1296        if (outActivity != null) {
1297            outActivity[0] = r;
1298        }
1299
1300        final ActivityStack stack = getFocusedStack();
1301        if (stack.mResumedActivity == null
1302                || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
1303            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1304                PendingActivityLaunch pal =
1305                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1306                mService.mPendingActivityLaunches.add(pal);
1307                setDismissKeyguard(false);
1308                ActivityOptions.abort(options);
1309                return ActivityManager.START_SWITCHES_CANCELED;
1310            }
1311        }
1312
1313        if (mService.mDidAppSwitch) {
1314            // This is the second allowed switch since we stopped switches,
1315            // so now just generally allow switches.  Use case: user presses
1316            // home (switches disabled, switch to home, mDidAppSwitch now true);
1317            // user taps a home icon (coming from home so allowed, we hit here
1318            // and now allow anyone to switch again).
1319            mService.mAppSwitchesAllowedTime = 0;
1320        } else {
1321            mService.mDidAppSwitch = true;
1322        }
1323
1324        mService.doPendingActivityLaunchesLocked(false);
1325
1326        err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
1327
1328        if (allPausedActivitiesComplete()) {
1329            // If someone asked to have the keyguard dismissed on the next
1330            // activity start, but we are not actually doing an activity
1331            // switch...  just dismiss the keyguard now, because we
1332            // probably want to see whatever is behind it.
1333            dismissKeyguard();
1334        }
1335        return err;
1336    }
1337
1338    ActivityStack adjustStackFocus(ActivityRecord r) {
1339        final TaskRecord task = r.task;
1340        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
1341            if (task != null) {
1342                final ActivityStack taskStack = task.stack;
1343                if (taskStack.isOnHomeDisplay()) {
1344                    if (mFocusedStack != taskStack) {
1345                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
1346                                "focused stack to r=" + r + " task=" + task);
1347                        mFocusedStack = taskStack;
1348                    } else {
1349                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
1350                            "adjustStackFocus: Focused stack already=" + mFocusedStack);
1351                    }
1352                }
1353                return taskStack;
1354            }
1355
1356            final ActivityContainer container = r.mInitialActivityContainer;
1357            if (container != null) {
1358                // The first time put it on the desired stack, after this put on task stack.
1359                r.mInitialActivityContainer = null;
1360                return container.mStack;
1361            }
1362
1363            if (mFocusedStack != mHomeStack) {
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(null, 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            targetStack = adjustStackFocus(r);
1732            targetStack.moveToFront();
1733            if (reuseTask == null) {
1734                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
1735                        newTaskInfo != null ? newTaskInfo : r.info,
1736                        newTaskIntent != null ? newTaskIntent : intent,
1737                        true), null, true);
1738                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1739                        r.task);
1740            } else {
1741                r.setTask(reuseTask, reuseTask, true);
1742            }
1743            newTask = true;
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);
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        WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId);
2131        if (weakReference != null) {
2132            ActivityContainer activityContainer = weakReference.get();
2133            if (activityContainer != null) {
2134                return activityContainer.mStack;
2135            } else {
2136                mActivityContainers.remove(stackId);
2137            }
2138        }
2139        return null;
2140    }
2141
2142    ArrayList<ActivityStack> getStacks() {
2143        ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>();
2144        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2145            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
2146        }
2147        return allStacks;
2148    }
2149
2150    IBinder getHomeActivityToken() {
2151        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
2152        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
2153            final TaskRecord task = tasks.get(taskNdx);
2154            if (task.isHomeTask()) {
2155                final ArrayList<ActivityRecord> activities = task.mActivities;
2156                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2157                    final ActivityRecord r = activities.get(activityNdx);
2158                    if (r.isHomeActivity()) {
2159                        return r.appToken;
2160                    }
2161                }
2162            }
2163        }
2164        return null;
2165    }
2166
2167    ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId,
2168            IActivityContainerCallback callback) {
2169        ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId,
2170                callback);
2171        mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer));
2172        if (parentActivity != null) {
2173            parentActivity.mChildContainers.add(activityContainer.mStack);
2174        }
2175        return activityContainer;
2176    }
2177
2178    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
2179            IActivityContainerCallback callback) {
2180        return createActivityContainer(parentActivity, getNextStackId(), callback);
2181    }
2182
2183    void removeChildActivityContainers(ActivityRecord parentActivity) {
2184        for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) {
2185            final ActivityContainer container = mActivityContainers.valueAt(ndx).get();
2186            if (container == null) {
2187                mActivityContainers.removeAt(ndx);
2188                continue;
2189            }
2190            if (container.mParentActivity != parentActivity) {
2191                continue;
2192            }
2193
2194            ActivityStack stack = container.mStack;
2195            ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
2196            if (top != null) {
2197                // TODO: Make sure the next activity doesn't start up when top is destroyed.
2198                stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
2199            }
2200            mActivityContainers.removeAt(ndx);
2201            container.detachLocked();
2202        }
2203    }
2204
2205    void deleteActivityContainer(IActivityContainer container) {
2206        ActivityContainer activityContainer = (ActivityContainer)container;
2207        if (activityContainer != null) {
2208            activityContainer.mStack.destroyActivitiesLocked(null, true,
2209                    "deleteActivityContainer");
2210            final ActivityRecord parent = activityContainer.mParentActivity;
2211            if (parent != null) {
2212                parent.mChildContainers.remove(activityContainer);
2213            }
2214            final int stackId = activityContainer.mStackId;
2215            mActivityContainers.remove(stackId);
2216            mWindowManager.removeStack(stackId);
2217        }
2218    }
2219
2220    private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
2221        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2222        if (activityDisplay == null) {
2223            return -1;
2224        }
2225
2226        ActivityContainer activityContainer =
2227                createActivityContainer(parentActivity, stackId, null);
2228        activityContainer.attachToDisplayLocked(activityDisplay);
2229        return stackId;
2230    }
2231
2232    int getNextStackId() {
2233        while (true) {
2234            if (++mLastStackId <= HOME_STACK_ID) {
2235                mLastStackId = HOME_STACK_ID + 1;
2236            }
2237            if (getStack(mLastStackId) == null) {
2238                break;
2239            }
2240        }
2241        return mLastStackId;
2242    }
2243
2244    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
2245        final TaskRecord task = anyTaskForIdLocked(taskId);
2246        if (task == null) {
2247            return;
2248        }
2249        final ActivityStack stack = getStack(stackId);
2250        if (stack == null) {
2251            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
2252            return;
2253        }
2254        task.stack.removeTask(task);
2255        stack.addTask(task, toTop);
2256        mWindowManager.addTask(taskId, stackId, toTop);
2257        resumeTopActivitiesLocked();
2258    }
2259
2260    ActivityRecord findTaskLocked(ActivityRecord r) {
2261        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
2262        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2263            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2264            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2265                final ActivityStack stack = stacks.get(stackNdx);
2266                if (!r.isApplicationActivity() && !stack.isHomeStack()) {
2267                    if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
2268                    continue;
2269                }
2270                final ActivityRecord ar = stack.findTaskLocked(r);
2271                if (ar != null) {
2272                    return ar;
2273                }
2274            }
2275        }
2276        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
2277        return null;
2278    }
2279
2280    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
2281        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2282            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2283            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2284                final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info);
2285                if (ar != null) {
2286                    return ar;
2287                }
2288            }
2289        }
2290        return null;
2291    }
2292
2293    void goingToSleepLocked() {
2294        scheduleSleepTimeout();
2295        if (!mGoingToSleep.isHeld()) {
2296            mGoingToSleep.acquire();
2297            if (mLaunchingActivity.isHeld()) {
2298                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
2299                    throw new IllegalStateException("Calling must be system uid");
2300                }
2301                mLaunchingActivity.release();
2302                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
2303            }
2304        }
2305        checkReadyForSleepLocked();
2306    }
2307
2308    boolean shutdownLocked(int timeout) {
2309        boolean timedout = false;
2310        goingToSleepLocked();
2311
2312        final long endTime = System.currentTimeMillis() + timeout;
2313        while (true) {
2314            boolean cantShutdown = false;
2315            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2316                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2317                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2318                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
2319                }
2320            }
2321            if (cantShutdown) {
2322                long timeRemaining = endTime - System.currentTimeMillis();
2323                if (timeRemaining > 0) {
2324                    try {
2325                        mService.wait(timeRemaining);
2326                    } catch (InterruptedException e) {
2327                    }
2328                } else {
2329                    Slog.w(TAG, "Activity manager shutdown timed out");
2330                    timedout = true;
2331                    break;
2332                }
2333            } else {
2334                break;
2335            }
2336        }
2337
2338        // Force checkReadyForSleep to complete.
2339        mSleepTimeout = true;
2340        checkReadyForSleepLocked();
2341
2342        return timedout;
2343    }
2344
2345    void comeOutOfSleepIfNeededLocked() {
2346        removeSleepTimeouts();
2347        if (mGoingToSleep.isHeld()) {
2348            mGoingToSleep.release();
2349        }
2350        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2351            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2352            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2353                final ActivityStack stack = stacks.get(stackNdx);
2354                stack.awakeFromSleepingLocked();
2355                if (isFrontStack(stack)) {
2356                    resumeTopActivitiesLocked();
2357                }
2358            }
2359        }
2360        mGoingToSleepActivities.clear();
2361    }
2362
2363    void activitySleptLocked(ActivityRecord r) {
2364        mGoingToSleepActivities.remove(r);
2365        checkReadyForSleepLocked();
2366    }
2367
2368    void checkReadyForSleepLocked() {
2369        if (!mService.isSleepingOrShuttingDown()) {
2370            // Do not care.
2371            return;
2372        }
2373
2374        if (!mSleepTimeout) {
2375            boolean dontSleep = false;
2376            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2377                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2378                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2379                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
2380                }
2381            }
2382
2383            if (mStoppingActivities.size() > 0) {
2384                // Still need to tell some activities to stop; can't sleep yet.
2385                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2386                        + mStoppingActivities.size() + " activities");
2387                scheduleIdleLocked();
2388                dontSleep = true;
2389            }
2390
2391            if (mGoingToSleepActivities.size() > 0) {
2392                // Still need to tell some activities to sleep; can't sleep yet.
2393                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2394                        + mGoingToSleepActivities.size() + " activities");
2395                dontSleep = true;
2396            }
2397
2398            if (dontSleep) {
2399                return;
2400            }
2401        }
2402
2403        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2404            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2405            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2406                stacks.get(stackNdx).goToSleep();
2407            }
2408        }
2409
2410        removeSleepTimeouts();
2411
2412        if (mGoingToSleep.isHeld()) {
2413            mGoingToSleep.release();
2414        }
2415        if (mService.mShuttingDown) {
2416            mService.notifyAll();
2417        }
2418    }
2419
2420    boolean reportResumedActivityLocked(ActivityRecord r) {
2421        final ActivityStack stack = r.task.stack;
2422        if (isFrontStack(stack)) {
2423            mService.updateUsageStats(r, true);
2424        }
2425        if (allResumedActivitiesComplete()) {
2426            ensureActivitiesVisibleLocked(null, 0);
2427            mWindowManager.executeAppTransition();
2428            return true;
2429        }
2430        return false;
2431    }
2432
2433    void handleAppCrashLocked(ProcessRecord app) {
2434        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2435            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2436            final int numStacks = stacks.size();
2437            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2438                final ActivityStack stack = stacks.get(stackNdx);
2439                stack.handleAppCrashLocked(app);
2440            }
2441        }
2442    }
2443
2444    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2445        // First the front stacks. In case any are not fullscreen and are in front of home.
2446        boolean showHomeBehindStack = false;
2447        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2448            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2449            final int topStackNdx = stacks.size() - 1;
2450            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
2451                final ActivityStack stack = stacks.get(stackNdx);
2452                if (stackNdx == topStackNdx) {
2453                    // Top stack.
2454                    showHomeBehindStack =
2455                            stack.ensureActivitiesVisibleLocked(starting, configChanges);
2456                } else {
2457                    // Back stack.
2458                    stack.ensureActivitiesVisibleLocked(starting, configChanges,
2459                            showHomeBehindStack);
2460                }
2461            }
2462        }
2463    }
2464
2465    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2466        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2467            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2468            final int numStacks = stacks.size();
2469            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2470                final ActivityStack stack = stacks.get(stackNdx);
2471                stack.scheduleDestroyActivities(app, false, reason);
2472            }
2473        }
2474    }
2475
2476    boolean switchUserLocked(int userId, UserStartedState uss) {
2477        mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId());
2478        final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
2479        mCurrentUser = userId;
2480
2481        mStartingUsers.add(uss);
2482        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2483            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2484            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2485                final ActivityStack stack = stacks.get(stackNdx);
2486                stack.switchUserLocked(userId);
2487                mWindowManager.moveTaskToTop(stack.topTask().taskId);
2488            }
2489        }
2490
2491        ActivityStack stack = getStack(restoreStackId);
2492        if (stack == null) {
2493            stack = mHomeStack;
2494        }
2495        final boolean homeInFront = stack.isHomeStack();
2496        if (stack.isOnHomeDisplay()) {
2497            moveHomeStack(homeInFront);
2498            mWindowManager.moveTaskToTop(stack.topTask().taskId);
2499        } else {
2500            // Stack was moved to another display while user was swapped out.
2501            resumeHomeActivity(null);
2502        }
2503        return homeInFront;
2504    }
2505
2506    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2507        int N = mStoppingActivities.size();
2508        if (N <= 0) return null;
2509
2510        ArrayList<ActivityRecord> stops = null;
2511
2512        final boolean nowVisible = allResumedActivitiesVisible();
2513        for (int i=0; i<N; i++) {
2514            ActivityRecord s = mStoppingActivities.get(i);
2515            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2516                    + nowVisible + " waitingVisible=" + s.waitingVisible
2517                    + " finishing=" + s.finishing);
2518            if (s.waitingVisible && nowVisible) {
2519                mWaitingVisibleActivities.remove(s);
2520                s.waitingVisible = false;
2521                if (s.finishing) {
2522                    // If this activity is finishing, it is sitting on top of
2523                    // everyone else but we now know it is no longer needed...
2524                    // so get rid of it.  Otherwise, we need to go through the
2525                    // normal flow and hide it once we determine that it is
2526                    // hidden by the activities in front of it.
2527                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2528                    mWindowManager.setAppVisibility(s.appToken, false);
2529                }
2530            }
2531            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2532                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2533                if (stops == null) {
2534                    stops = new ArrayList<ActivityRecord>();
2535                }
2536                stops.add(s);
2537                mStoppingActivities.remove(i);
2538                N--;
2539                i--;
2540            }
2541        }
2542
2543        return stops;
2544    }
2545
2546    void validateTopActivitiesLocked() {
2547        // FIXME
2548/*        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2549            final ActivityStack stack = stacks.get(stackNdx);
2550            final ActivityRecord r = stack.topRunningActivityLocked(null);
2551            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2552            if (isFrontStack(stack)) {
2553                if (r == null) {
2554                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2555                } else {
2556                    final ActivityRecord pausing = stack.mPausingActivity;
2557                    if (pausing != null && pausing == r) {
2558                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2559                            " state=" + state);
2560                    }
2561                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2562                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2563                                " state=" + state);
2564                    }
2565                }
2566            } else {
2567                final ActivityRecord resumed = stack.mResumedActivity;
2568                if (resumed != null && resumed == r) {
2569                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2570                        " state=" + state);
2571                }
2572                if (r != null && (state == ActivityState.INITIALIZING
2573                        || state == ActivityState.RESUMED)) {
2574                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2575                            " state=" + state);
2576                }
2577            }
2578        }
2579*/
2580    }
2581
2582    public void dump(PrintWriter pw, String prefix) {
2583        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity=");
2584                pw.println(mDismissKeyguardOnNextActivity);
2585        pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
2586                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
2587        pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
2588        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
2589        pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
2590        pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
2591    }
2592
2593    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2594        return getFocusedStack().getDumpActivitiesLocked(name);
2595    }
2596
2597    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2598            boolean needSep, String prefix) {
2599        if (activity != null) {
2600            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2601                if (needSep) {
2602                    pw.println();
2603                }
2604                pw.print(prefix);
2605                pw.println(activity);
2606                return true;
2607            }
2608        }
2609        return false;
2610    }
2611
2612    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2613            boolean dumpClient, String dumpPackage) {
2614        boolean printed = false;
2615        boolean needSep = false;
2616        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2617            ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
2618            pw.print("Display #"); pw.println(activityDisplay.mDisplayId);
2619            ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2620            final int numStacks = stacks.size();
2621            for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2622                final ActivityStack stack = stacks.get(stackNdx);
2623                StringBuilder stackHeader = new StringBuilder(128);
2624                stackHeader.append("  Stack #");
2625                stackHeader.append(stack.mStackId);
2626                stackHeader.append(":");
2627                printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage,
2628                        needSep, stackHeader.toString());
2629                printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false,
2630                        !dumpAll, false, dumpPackage, true,
2631                        "    Running activities (most recent first):", null);
2632
2633                needSep = printed;
2634                boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2635                        "    mPausingActivity: ");
2636                if (pr) {
2637                    printed = true;
2638                    needSep = false;
2639                }
2640                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2641                        "    mResumedActivity: ");
2642                if (pr) {
2643                    printed = true;
2644                    needSep = false;
2645                }
2646                if (dumpAll) {
2647                    pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2648                            "    mLastPausedActivity: ");
2649                    if (pr) {
2650                        printed = true;
2651                        needSep = true;
2652                    }
2653                    printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
2654                            needSep, "    mLastNoHistoryActivity: ");
2655                }
2656                needSep = printed;
2657            }
2658        }
2659
2660        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2661                false, dumpPackage, true, "  Activities waiting to finish:", null);
2662        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2663                false, dumpPackage, true, "  Activities waiting to stop:", null);
2664        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2665                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2666                null);
2667        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2668                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2669        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2670                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2671
2672        return printed;
2673    }
2674
2675    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2676            String prefix, String label, boolean complete, boolean brief, boolean client,
2677            String dumpPackage, boolean needNL, String header1, String header2) {
2678        TaskRecord lastTask = null;
2679        String innerPrefix = null;
2680        String[] args = null;
2681        boolean printed = false;
2682        for (int i=list.size()-1; i>=0; i--) {
2683            final ActivityRecord r = list.get(i);
2684            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2685                continue;
2686            }
2687            if (innerPrefix == null) {
2688                innerPrefix = prefix + "      ";
2689                args = new String[0];
2690            }
2691            printed = true;
2692            final boolean full = !brief && (complete || !r.isInHistory());
2693            if (needNL) {
2694                pw.println("");
2695                needNL = false;
2696            }
2697            if (header1 != null) {
2698                pw.println(header1);
2699                header1 = null;
2700            }
2701            if (header2 != null) {
2702                pw.println(header2);
2703                header2 = null;
2704            }
2705            if (lastTask != r.task) {
2706                lastTask = r.task;
2707                pw.print(prefix);
2708                pw.print(full ? "* " : "  ");
2709                pw.println(lastTask);
2710                if (full) {
2711                    lastTask.dump(pw, prefix + "  ");
2712                } else if (complete) {
2713                    // Complete + brief == give a summary.  Isn't that obvious?!?
2714                    if (lastTask.intent != null) {
2715                        pw.print(prefix); pw.print("  ");
2716                                pw.println(lastTask.intent.toInsecureStringWithClip());
2717                    }
2718                }
2719            }
2720            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2721            pw.print(" #"); pw.print(i); pw.print(": ");
2722            pw.println(r);
2723            if (full) {
2724                r.dump(pw, innerPrefix);
2725            } else if (complete) {
2726                // Complete + brief == give a summary.  Isn't that obvious?!?
2727                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2728                if (r.app != null) {
2729                    pw.print(innerPrefix); pw.println(r.app);
2730                }
2731            }
2732            if (client && r.app != null && r.app.thread != null) {
2733                // flush anything that is already in the PrintWriter since the thread is going
2734                // to write to the file descriptor directly
2735                pw.flush();
2736                try {
2737                    TransferPipe tp = new TransferPipe();
2738                    try {
2739                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2740                                r.appToken, innerPrefix, args);
2741                        // Short timeout, since blocking here can
2742                        // deadlock with the application.
2743                        tp.go(fd, 2000);
2744                    } finally {
2745                        tp.kill();
2746                    }
2747                } catch (IOException e) {
2748                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2749                } catch (RemoteException e) {
2750                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2751                }
2752                needNL = true;
2753            }
2754        }
2755        return printed;
2756    }
2757
2758    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2759        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2760        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2761        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2762    }
2763
2764    final void scheduleIdleLocked() {
2765        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2766    }
2767
2768    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2769        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2770        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2771    }
2772
2773    final void scheduleResumeTopActivities() {
2774        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
2775            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2776        }
2777    }
2778
2779    void removeSleepTimeouts() {
2780        mSleepTimeout = false;
2781        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2782    }
2783
2784    final void scheduleSleepTimeout() {
2785        removeSleepTimeouts();
2786        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2787    }
2788
2789    @Override
2790    public void onDisplayAdded(int displayId) {
2791        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
2792    }
2793
2794    @Override
2795    public void onDisplayRemoved(int displayId) {
2796        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
2797    }
2798
2799    @Override
2800    public void onDisplayChanged(int displayId) {
2801        mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
2802    }
2803
2804    public void handleDisplayAddedLocked(int displayId) {
2805        boolean newDisplay;
2806        synchronized (mService) {
2807            newDisplay = mActivityDisplays.get(displayId) == null;
2808            if (newDisplay) {
2809                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
2810                mActivityDisplays.put(displayId, activityDisplay);
2811            }
2812        }
2813        if (newDisplay) {
2814            mWindowManager.onDisplayAdded(displayId);
2815        }
2816    }
2817
2818    public void handleDisplayRemovedLocked(int displayId) {
2819        synchronized (mService) {
2820            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2821            if (activityDisplay != null) {
2822                ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
2823                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2824                    stacks.get(stackNdx).mActivityContainer.detachLocked();
2825                }
2826                mActivityDisplays.remove(displayId);
2827            }
2828        }
2829        mWindowManager.onDisplayRemoved(displayId);
2830    }
2831
2832    public void handleDisplayChangedLocked(int displayId) {
2833        synchronized (mService) {
2834            ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
2835            if (activityDisplay != null) {
2836                // TODO: Update the bounds.
2837            }
2838        }
2839        mWindowManager.onDisplayChanged(displayId);
2840    }
2841
2842    StackInfo getStackInfo(ActivityStack stack) {
2843        StackInfo info = new StackInfo();
2844        mWindowManager.getStackBounds(stack.mStackId, info.bounds);
2845        info.displayId = Display.DEFAULT_DISPLAY;
2846        info.stackId = stack.mStackId;
2847
2848        ArrayList<TaskRecord> tasks = stack.getAllTasks();
2849        final int numTasks = tasks.size();
2850        int[] taskIds = new int[numTasks];
2851        String[] taskNames = new String[numTasks];
2852        for (int i = 0; i < numTasks; ++i) {
2853            final TaskRecord task = tasks.get(i);
2854            taskIds[i] = task.taskId;
2855            taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
2856                    : task.realActivity != null ? task.realActivity.flattenToString()
2857                    : task.getTopActivity() != null ? task.getTopActivity().packageName
2858                    : "unknown";
2859        }
2860        info.taskIds = taskIds;
2861        info.taskNames = taskNames;
2862        return info;
2863    }
2864
2865    StackInfo getStackInfoLocked(int stackId) {
2866        ActivityStack stack = getStack(stackId);
2867        if (stack != null) {
2868            return getStackInfo(stack);
2869        }
2870        return null;
2871    }
2872
2873    ArrayList<StackInfo> getAllStackInfosLocked() {
2874        ArrayList<StackInfo> list = new ArrayList<StackInfo>();
2875        for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
2876            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2877            for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
2878                list.add(getStackInfo(stacks.get(ndx)));
2879            }
2880        }
2881        return list;
2882    }
2883
2884    private final class ActivityStackSupervisorHandler extends Handler {
2885
2886        public ActivityStackSupervisorHandler(Looper looper) {
2887            super(looper);
2888        }
2889
2890        void activityIdleInternal(ActivityRecord r) {
2891            synchronized (mService) {
2892                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2893            }
2894        }
2895
2896        @Override
2897        public void handleMessage(Message msg) {
2898            switch (msg.what) {
2899                case IDLE_TIMEOUT_MSG: {
2900                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
2901                    if (mService.mDidDexOpt) {
2902                        mService.mDidDexOpt = false;
2903                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2904                        nmsg.obj = msg.obj;
2905                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2906                        return;
2907                    }
2908                    // We don't at this point know if the activity is fullscreen,
2909                    // so we need to be conservative and assume it isn't.
2910                    activityIdleInternal((ActivityRecord)msg.obj);
2911                } break;
2912                case IDLE_NOW_MSG: {
2913                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
2914                    activityIdleInternal((ActivityRecord)msg.obj);
2915                } break;
2916                case RESUME_TOP_ACTIVITY_MSG: {
2917                    synchronized (mService) {
2918                        resumeTopActivitiesLocked();
2919                    }
2920                } break;
2921                case SLEEP_TIMEOUT_MSG: {
2922                    synchronized (mService) {
2923                        if (mService.isSleepingOrShuttingDown()) {
2924                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2925                            mSleepTimeout = true;
2926                            checkReadyForSleepLocked();
2927                        }
2928                    }
2929                } break;
2930                case LAUNCH_TIMEOUT_MSG: {
2931                    if (mService.mDidDexOpt) {
2932                        mService.mDidDexOpt = false;
2933                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
2934                        return;
2935                    }
2936                    synchronized (mService) {
2937                        if (mLaunchingActivity.isHeld()) {
2938                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
2939                            if (VALIDATE_WAKE_LOCK_CALLER
2940                                    && Binder.getCallingUid() != Process.myUid()) {
2941                                throw new IllegalStateException("Calling must be system uid");
2942                            }
2943                            mLaunchingActivity.release();
2944                        }
2945                    }
2946                } break;
2947                case HANDLE_DISPLAY_ADDED: {
2948                    handleDisplayAddedLocked(msg.arg1);
2949                } break;
2950                case HANDLE_DISPLAY_CHANGED: {
2951                    handleDisplayChangedLocked(msg.arg1);
2952                } break;
2953                case HANDLE_DISPLAY_REMOVED: {
2954                    handleDisplayRemovedLocked(msg.arg1);
2955                } break;
2956                case CONTAINER_CALLBACK_VISIBILITY: {
2957                    final ActivityContainer container = (ActivityContainer) msg.obj;
2958                    try {
2959                        // We only send this message if mCallback is non-null.
2960                        container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1);
2961                    } catch (RemoteException e) {
2962                    }
2963                }
2964            }
2965        }
2966    }
2967
2968    class ActivityContainer extends IActivityContainer.Stub {
2969        final int mStackId;
2970        final IActivityContainerCallback mCallback;
2971        final ActivityStack mStack;
2972        final ActivityRecord mParentActivity;
2973        final String mIdString;
2974
2975        boolean mVisible = true;
2976
2977        /** Display this ActivityStack is currently on. Null if not attached to a Display. */
2978        ActivityDisplay mActivityDisplay;
2979
2980        ActivityContainer(ActivityRecord parentActivity, int stackId,
2981                IActivityContainerCallback callback) {
2982            synchronized (mService) {
2983                mStackId = stackId;
2984                mStack = new ActivityStack(this);
2985                mParentActivity = parentActivity;
2986                mCallback = callback;
2987                mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
2988                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this);
2989            }
2990        }
2991
2992        void attachToDisplayLocked(ActivityDisplay activityDisplay) {
2993            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this
2994                    + " to display=" + activityDisplay);
2995            mActivityDisplay = activityDisplay;
2996            mStack.mDisplayId = activityDisplay.mDisplayId;
2997            mStack.mStacks = activityDisplay.mStacks;
2998
2999            activityDisplay.attachActivities(mStack);
3000            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
3001        }
3002
3003        @Override
3004        public void attachToDisplay(int displayId) {
3005            synchronized (mService) {
3006                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
3007                if (activityDisplay == null) {
3008                    return;
3009                }
3010                attachToDisplayLocked(activityDisplay);
3011            }
3012        }
3013
3014        @Override
3015        public int getDisplayId() {
3016            if (mActivityDisplay != null) {
3017                return mActivityDisplay.mDisplayId;
3018            }
3019            return -1;
3020        }
3021
3022        @Override
3023        public boolean injectEvent(InputEvent event) {
3024            final long origId = Binder.clearCallingIdentity();
3025            try {
3026                if (mActivityDisplay != null) {
3027                    return mInputManagerInternal.injectInputEvent(event,
3028                            mActivityDisplay.mDisplayId,
3029                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
3030                }
3031                return false;
3032            } finally {
3033                Binder.restoreCallingIdentity(origId);
3034            }
3035        }
3036
3037        private void detachLocked() {
3038            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display="
3039                    + mActivityDisplay + " Callers=" + Debug.getCallers(2));
3040            if (mActivityDisplay != null) {
3041                mActivityDisplay.detachActivitiesLocked(mStack);
3042                mActivityDisplay = null;
3043                mStack.mDisplayId = -1;
3044                mStack.mStacks = null;
3045                mWindowManager.detachStack(mStackId);
3046            }
3047        }
3048
3049        @Override
3050        public void detachFromDisplay() {
3051            synchronized (mService) {
3052                detachLocked();
3053            }
3054        }
3055
3056        @Override
3057        public final int startActivity(Intent intent) {
3058            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");
3059            int userId = mService.handleIncomingUser(Binder.getCallingPid(),
3060                    Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null);
3061            // TODO: Switch to user app stacks here.
3062            String mimeType = intent.getType();
3063            if (mimeType == null && intent.getData() != null
3064                    && "content".equals(intent.getData().getScheme())) {
3065                mimeType = mService.getProviderMimeType(intent.getData(), userId);
3066            }
3067            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null,
3068                    null, null, null, null, userId, this);
3069        }
3070
3071        @Override
3072        public final int startActivityIntentSender(IIntentSender intentSender) {
3073            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
3074
3075            if (!(intentSender instanceof PendingIntentRecord)) {
3076                throw new IllegalArgumentException("Bad PendingIntent object");
3077            }
3078
3079            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null,
3080                    null, 0, 0, 0, null, this);
3081        }
3082
3083        @Override
3084        public IBinder asBinder() {
3085            return this;
3086        }
3087
3088        @Override
3089        public void attachToSurface(Surface surface, int width, int height, int density) {
3090            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
3091
3092            final long origId = Binder.clearCallingIdentity();
3093            try {
3094                synchronized (mService) {
3095                    ActivityDisplay activityDisplay =
3096                            new ActivityDisplay(surface, width, height, density);
3097                    mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay);
3098                    attachToDisplayLocked(activityDisplay);
3099                    mStack.resumeTopActivityLocked(null);
3100                }
3101                if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display="
3102                        + mActivityDisplay);
3103            } finally {
3104                Binder.restoreCallingIdentity(origId);
3105            }
3106        }
3107
3108        ActivityStackSupervisor getOuter() {
3109            return ActivityStackSupervisor.this;
3110        }
3111
3112        boolean isAttached() {
3113            return mActivityDisplay != null;
3114        }
3115
3116        void getBounds(Point outBounds) {
3117            if (mActivityDisplay != null) {
3118                mActivityDisplay.getBounds(outBounds);
3119            } else {
3120                outBounds.set(0, 0);
3121            }
3122        }
3123
3124        void setVisible(boolean visible) {
3125            if (mVisible != visible) {
3126                mVisible = visible;
3127                if (mCallback != null) {
3128                    mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
3129                            0 /* unused */, this).sendToTarget();
3130                }
3131            }
3132        }
3133
3134        @Override
3135        public String toString() {
3136            return mIdString + (mActivityDisplay == null ? "N" : "A");
3137        }
3138    }
3139
3140    /** Exactly one of these classes per Display in the system. Capable of holding zero or more
3141     * attached {@link ActivityStack}s */
3142    final class ActivityDisplay {
3143        /** Actual Display this object tracks. */
3144        int mDisplayId;
3145        Display mDisplay;
3146        DisplayInfo mDisplayInfo = new DisplayInfo();
3147        Surface mSurface;
3148
3149        /** All of the stacks on this display. Order matters, topmost stack is in front of all other
3150         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
3151        final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
3152
3153        /** If this display is for an ActivityView then the VirtualDisplay created for it is stored
3154         * here. */
3155        VirtualDisplay mVirtualDisplay;
3156
3157        ActivityDisplay(int displayId) {
3158            init(mDisplayManager.getDisplay(displayId));
3159        }
3160
3161        ActivityDisplay(Surface surface, int width, int height, int density) {
3162            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
3163            long ident = Binder.clearCallingIdentity();
3164            try {
3165                mVirtualDisplay = dm.createVirtualDisplay(mService.mContext,
3166                        VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface,
3167                        DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
3168                        DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
3169            } finally {
3170                Binder.restoreCallingIdentity(ident);
3171            }
3172
3173            init(mVirtualDisplay.getDisplay());
3174            mSurface = surface;
3175
3176            mWindowManager.handleDisplayAdded(mDisplayId);
3177        }
3178
3179        private void init(Display display) {
3180            mDisplay = display;
3181            mDisplayId = display.getDisplayId();
3182            mDisplay.getDisplayInfo(mDisplayInfo);
3183        }
3184
3185        void attachActivities(ActivityStack stack) {
3186            if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId="
3187                    + mDisplayId);
3188            mStacks.add(stack);
3189        }
3190
3191        void detachActivitiesLocked(ActivityStack stack) {
3192            if (DEBUG_STACK) Slog.v(TAG, "detachActivitiesLocked: detaching " + stack
3193                    + " from displayId=" + mDisplayId);
3194            mStacks.remove(stack);
3195            if (mStacks.isEmpty() && mVirtualDisplay != null) {
3196                mVirtualDisplay.release();
3197                mVirtualDisplay = null;
3198            }
3199            mSurface.release();
3200        }
3201
3202        void getBounds(Point bounds) {
3203            mDisplay.getDisplayInfo(mDisplayInfo);
3204            bounds.x = mDisplayInfo.appWidth;
3205            bounds.y = mDisplayInfo.appHeight;
3206        }
3207
3208        @Override
3209        public String toString() {
3210            return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V")
3211                    + " numStacks=" + mStacks.size() + "}";
3212        }
3213    }
3214}
3215