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