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