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