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