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