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