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