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