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