ActivityStackSupervisor.java revision e7c58b6d7d761b93e785b0a399e5b00fdb82f4ce
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.ActivityOptions;
38import android.app.AppGlobals;
39import android.app.IActivityManager;
40import android.app.IApplicationThread;
41import android.app.IThumbnailReceiver;
42import android.app.PendingIntent;
43import android.app.ActivityManager.RunningTaskInfo;
44import android.app.IActivityManager.WaitResult;
45import android.app.ResultInfo;
46import android.content.ComponentName;
47import android.content.Context;
48import android.content.IIntentSender;
49import android.content.Intent;
50import android.content.IntentSender;
51import android.content.pm.ActivityInfo;
52import android.content.pm.ApplicationInfo;
53import android.content.pm.PackageManager;
54import android.content.pm.ResolveInfo;
55import android.content.res.Configuration;
56import android.os.Binder;
57import android.os.Bundle;
58import android.os.Debug;
59import android.os.Handler;
60import android.os.IBinder;
61import android.os.Looper;
62import android.os.Message;
63import android.os.ParcelFileDescriptor;
64import android.os.PowerManager;
65import android.os.RemoteException;
66import android.os.SystemClock;
67import android.os.UserHandle;
68import android.util.EventLog;
69import android.util.Slog;
70import android.util.SparseArray;
71
72import com.android.internal.app.HeavyWeightSwitcherActivity;
73import com.android.internal.os.TransferPipe;
74import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.wm.StackBox;
77import com.android.server.wm.WindowManagerService;
78
79import java.io.FileDescriptor;
80import java.io.IOException;
81import java.io.PrintWriter;
82import java.util.ArrayList;
83import java.util.List;
84
85public final class ActivityStackSupervisor {
86    static final boolean DEBUG = ActivityManagerService.DEBUG || false;
87    static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
88    static final boolean DEBUG_APP = DEBUG || false;
89    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
90    static final boolean DEBUG_STATES = DEBUG || false;
91    static final boolean DEBUG_IDLE = DEBUG || false;
92
93    public static final int HOME_STACK_ID = 0;
94
95    /** How long we wait until giving up on the last activity telling us it is idle. */
96    static final int IDLE_TIMEOUT = 10*1000;
97
98    /** How long we can hold the sleep wake lock before giving up. */
99    static final int SLEEP_TIMEOUT = 5*1000;
100
101    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
102    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
103    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
104    static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
105
106    final ActivityManagerService mService;
107    final Context mContext;
108    final Looper mLooper;
109
110    final ActivityStackSupervisorHandler mHandler;
111
112    /** Short cut */
113    WindowManagerService mWindowManager;
114
115    /** Dismiss the keyguard after the next activity is displayed? */
116    private boolean mDismissKeyguardOnNextActivity = false;
117
118    /** Identifier counter for all ActivityStacks */
119    private int mLastStackId = HOME_STACK_ID;
120
121    /** Task identifier that activities are currently being started in.  Incremented each time a
122     * new task is created. */
123    private int mCurTaskId = 0;
124
125    /** The current user */
126    private int mCurrentUser;
127
128    /** The stack containing the launcher app */
129    private ActivityStack mHomeStack;
130
131    /** The non-home stack currently receiving input or launching the next activity. If home is
132     * in front then mHomeStack overrides mFocusedStack.
133     * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
134    private ActivityStack mFocusedStack;
135
136    /** All the non-launcher stacks */
137    private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
138
139    private static final int STACK_STATE_HOME_IN_FRONT = 0;
140    private static final int STACK_STATE_HOME_TO_BACK = 1;
141    private static final int STACK_STATE_HOME_IN_BACK = 2;
142    private static final int STACK_STATE_HOME_TO_FRONT = 3;
143    private int mStackState = STACK_STATE_HOME_IN_FRONT;
144
145    /** List of activities that are waiting for a new activity to become visible before completing
146     * whatever operation they are supposed to do. */
147    final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
148
149    /** List of processes waiting to find out about the next visible activity. */
150    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
151            new ArrayList<IActivityManager.WaitResult>();
152
153    /** List of processes waiting to find out about the next launched activity. */
154    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
155            new ArrayList<IActivityManager.WaitResult>();
156
157    /** List of activities that are ready to be stopped, but waiting for the next activity to
158     * settle down before doing so. */
159    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
160
161    /** List of activities that are ready to be finished, but waiting for the previous activity to
162     * settle down before doing so.  It contains ActivityRecord objects. */
163    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
164
165    /** List of activities that are in the process of going to sleep. */
166    final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
167
168    /** List of ActivityRecord objects that have been finished and must still report back to a
169     * pending thumbnail receiver. */
170    final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
171
172    /** Used on user changes */
173    final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
174
175    /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
176     * is being brought in front of us. */
177    boolean mUserLeaving = false;
178
179    /** Stacks belonging to users other than mCurrentUser. Indexed by userId. */
180    final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
181
182    /** Set when we have taken too long waiting to go to sleep. */
183    boolean mSleepTimeout = false;
184
185    /**
186     * Set when the system is going to sleep, until we have
187     * successfully paused the current activity and released our wake lock.
188     * At that point the system is allowed to actually sleep.
189     */
190    final PowerManager.WakeLock mGoingToSleep;
191
192    public ActivityStackSupervisor(ActivityManagerService service, Context context,
193            Looper looper) {
194        mService = service;
195        mContext = context;
196        mLooper = looper;
197        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
198        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
199        mHandler = new ActivityStackSupervisorHandler(looper);
200    }
201
202    void setWindowManager(WindowManagerService wm) {
203        mWindowManager = wm;
204        mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
205        mStacks.add(mHomeStack);
206    }
207
208    void dismissKeyguard() {
209        if (mDismissKeyguardOnNextActivity) {
210            mDismissKeyguardOnNextActivity = false;
211            mWindowManager.dismissKeyguard();
212        }
213    }
214
215    ActivityStack getFocusedStack() {
216        if (mFocusedStack == null) {
217            return mHomeStack;
218        }
219        switch (mStackState) {
220            case STACK_STATE_HOME_IN_FRONT:
221            case STACK_STATE_HOME_TO_FRONT:
222                return mHomeStack;
223            case STACK_STATE_HOME_IN_BACK:
224            case STACK_STATE_HOME_TO_BACK:
225            default:
226                return mFocusedStack;
227        }
228    }
229
230    ActivityStack getLastStack() {
231        switch (mStackState) {
232            case STACK_STATE_HOME_IN_FRONT:
233            case STACK_STATE_HOME_TO_BACK:
234                return mHomeStack;
235            case STACK_STATE_HOME_TO_FRONT:
236            case STACK_STATE_HOME_IN_BACK:
237            default:
238                return mFocusedStack;
239        }
240    }
241
242    boolean isFrontStack(ActivityStack stack) {
243        return (stack.mCurrentUser == mCurrentUser) &&
244                !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
245    }
246
247    void moveHomeStack(boolean toFront) {
248        final boolean homeInFront = isFrontStack(mHomeStack);
249        if (homeInFront ^ toFront) {
250            if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
251                    stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
252                    STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
253            mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
254        }
255    }
256
257    boolean resumeHomeActivity(ActivityRecord prev) {
258        moveHomeStack(true);
259        if (prev != null) {
260            prev.mLaunchHomeTaskNext = false;
261        }
262        if (mHomeStack.topRunningActivityLocked(null) != null) {
263            return resumeTopActivitiesLocked(mHomeStack, prev, null);
264        }
265        return mService.startHomeActivityLocked(mCurrentUser);
266    }
267
268    final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r,
269            ActivityStack stack) {
270        if (stack == mHomeStack) {
271            return;
272        }
273        if ((sourceRecord == null && getLastStack() == mHomeStack) ||
274                (sourceRecord != null && sourceRecord.isHomeActivity())) {
275            if (r == null) {
276                r = stack.topRunningActivityLocked(null);
277            }
278            if (r != null && !r.isHomeActivity() && r.isRootActivity()) {
279                r.mLaunchHomeTaskNext = true;
280            }
281        }
282    }
283
284    void setDismissKeyguard(boolean dismiss) {
285        mDismissKeyguardOnNextActivity = dismiss;
286    }
287
288    TaskRecord anyTaskForIdLocked(int id) {
289        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
290            ActivityStack stack = mStacks.get(stackNdx);
291            TaskRecord task = stack.taskForIdLocked(id);
292            if (task != null) {
293                return task;
294            }
295        }
296        return null;
297    }
298
299    ActivityRecord isInAnyStackLocked(IBinder token) {
300        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
301            final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
302            if (r != null) {
303                return r;
304            }
305        }
306        return null;
307    }
308
309    int getNextTaskId() {
310        do {
311            mCurTaskId++;
312            if (mCurTaskId <= 0) {
313                mCurTaskId = 1;
314            }
315        } while (anyTaskForIdLocked(mCurTaskId) != null);
316        return mCurTaskId;
317    }
318
319    void removeTask(TaskRecord task) {
320        mWindowManager.removeTask(task.taskId);
321        final ActivityStack stack = task.stack;
322        final ActivityRecord r = stack.mResumedActivity;
323        if (r != null && r.task == task) {
324            stack.mResumedActivity = null;
325        }
326        if (stack.removeTask(task) && !stack.isHomeStack()) {
327            if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
328            mStacks.remove(stack);
329            final int stackId = stack.mStackId;
330            final int nextStackId = mWindowManager.removeStack(stackId);
331            // TODO: Perhaps we need to let the ActivityManager determine the next focus...
332            if (getFocusedStack().mStackId == stackId) {
333                // If this is the last app stack, set mFocusedStack to null.
334                mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
335            }
336        }
337    }
338
339    ActivityRecord resumedAppLocked() {
340        ActivityStack stack = getFocusedStack();
341        if (stack == null) {
342            return null;
343        }
344        ActivityRecord resumedActivity = stack.mResumedActivity;
345        if (resumedActivity == null || resumedActivity.app == null) {
346            resumedActivity = stack.mPausingActivity;
347            if (resumedActivity == null || resumedActivity.app == null) {
348                resumedActivity = stack.topRunningActivityLocked(null);
349            }
350        }
351        return resumedActivity;
352    }
353
354    boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
355        boolean didSomething = false;
356        final String processName = app.processName;
357        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
358            final ActivityStack stack = mStacks.get(stackNdx);
359            if (!isFrontStack(stack)) {
360                continue;
361            }
362            ActivityRecord hr = stack.topRunningActivityLocked(null);
363            if (hr != null) {
364                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
365                        && processName.equals(hr.processName)) {
366                    try {
367                        if (headless) {
368                            Slog.e(TAG, "Starting activities not supported on headless device: "
369                                    + hr);
370                        } else if (realStartActivityLocked(hr, app, true, true)) {
371                            didSomething = true;
372                        }
373                    } catch (Exception e) {
374                        Slog.w(TAG, "Exception in new application when starting activity "
375                              + hr.intent.getComponent().flattenToShortString(), e);
376                        throw e;
377                    }
378                }
379            }
380        }
381        if (!didSomething) {
382            ensureActivitiesVisibleLocked(null, 0);
383        }
384        return didSomething;
385    }
386
387    boolean allResumedActivitiesIdle() {
388        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
389            final ActivityRecord resumedActivity = mStacks.get(stackNdx).mResumedActivity;
390            if (resumedActivity == null || !resumedActivity.idle) {
391                return false;
392            }
393        }
394        return true;
395    }
396
397    boolean allResumedActivitiesComplete() {
398        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
399            final ActivityStack stack = mStacks.get(stackNdx);
400            if (isFrontStack(stack)) {
401                final ActivityRecord r = stack.mResumedActivity;
402                if (r != null && r.state != ActivityState.RESUMED) {
403                    return false;
404                }
405            }
406        }
407        // TODO: Not sure if this should check if all Paused are complete too.
408        switch (mStackState) {
409            case STACK_STATE_HOME_TO_BACK:
410                if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
411                        stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
412                        stackStateToString(STACK_STATE_HOME_IN_BACK));
413                mStackState = STACK_STATE_HOME_IN_BACK;
414                break;
415            case STACK_STATE_HOME_TO_FRONT:
416                if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
417                        stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
418                        stackStateToString(STACK_STATE_HOME_IN_FRONT));
419                mStackState = STACK_STATE_HOME_IN_FRONT;
420                break;
421        }
422        return true;
423    }
424
425    boolean allResumedActivitiesVisible() {
426        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
427            final ActivityStack stack = mStacks.get(stackNdx);
428            final ActivityRecord r = stack.mResumedActivity;
429            if (r != null && (!r.nowVisible || r.waitingVisible)) {
430                return false;
431            }
432        }
433        return true;
434    }
435
436    boolean pauseBackStacks(boolean userLeaving) {
437        boolean someActivityPaused = false;
438        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
439            final ActivityStack stack = mStacks.get(stackNdx);
440            if (!isFrontStack(stack) && stack.mResumedActivity != null) {
441                stack.startPausingLocked(userLeaving, false);
442                someActivityPaused = true;
443            }
444        }
445        return someActivityPaused;
446    }
447
448    boolean allPausedActivitiesComplete() {
449        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
450            final ActivityStack stack = mStacks.get(stackNdx);
451            final ActivityRecord r = stack.mPausingActivity;
452            if (r != null && r.state != ActivityState.PAUSED
453                    && r.state != ActivityState.STOPPED
454                    && r.state != ActivityState.STOPPING) {
455                return false;
456            }
457        }
458        return true;
459    }
460
461    void reportActivityVisibleLocked(ActivityRecord r) {
462        for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
463            WaitResult w = mWaitingActivityVisible.get(i);
464            w.timeout = false;
465            if (r != null) {
466                w.who = new ComponentName(r.info.packageName, r.info.name);
467            }
468            w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
469            w.thisTime = w.totalTime;
470        }
471        mService.notifyAll();
472        dismissKeyguard();
473    }
474
475    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
476            long thisTime, long totalTime) {
477        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
478            WaitResult w = mWaitingActivityLaunched.remove(i);
479            w.timeout = timeout;
480            if (r != null) {
481                w.who = new ComponentName(r.info.packageName, r.info.name);
482            }
483            w.thisTime = thisTime;
484            w.totalTime = totalTime;
485        }
486        mService.notifyAll();
487    }
488
489    ActivityRecord topRunningActivityLocked() {
490        final ActivityStack focusedStack = getFocusedStack();
491        ActivityRecord r = focusedStack.topRunningActivityLocked(null);
492        if (r != null) {
493            return r;
494        }
495
496        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
497            final ActivityStack stack = mStacks.get(stackNdx);
498            if (stack.mCurrentUser == mCurrentUser && stack != focusedStack &&
499                    isFrontStack(stack)) {
500                r = stack.topRunningActivityLocked(null);
501                if (r != null) {
502                    return r;
503                }
504            }
505        }
506        return null;
507    }
508
509    ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
510            PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
511        ActivityRecord r = null;
512        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
513            final ActivityStack stack = mStacks.get(stackNdx);
514            final ActivityRecord ar =
515                    stack.getTasksLocked(maxNum - list.size(), receiver, pending, list);
516            if (isFrontStack(stack)) {
517                r = ar;
518            }
519        }
520        return r;
521    }
522
523    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
524            String profileFile, ParcelFileDescriptor profileFd, int userId) {
525        // Collect information about the target of the Intent.
526        ActivityInfo aInfo;
527        try {
528            ResolveInfo rInfo =
529                AppGlobals.getPackageManager().resolveIntent(
530                        intent, resolvedType,
531                        PackageManager.MATCH_DEFAULT_ONLY
532                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
533            aInfo = rInfo != null ? rInfo.activityInfo : null;
534        } catch (RemoteException e) {
535            aInfo = null;
536        }
537
538        if (aInfo != null) {
539            // Store the found target back into the intent, because now that
540            // we have it we never want to do this again.  For example, if the
541            // user navigates back to this point in the history, we should
542            // always restart the exact same activity.
543            intent.setComponent(new ComponentName(
544                    aInfo.applicationInfo.packageName, aInfo.name));
545
546            // Don't debug things in the system process
547            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
548                if (!aInfo.processName.equals("system")) {
549                    mService.setDebugApp(aInfo.processName, true, false);
550                }
551            }
552
553            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
554                if (!aInfo.processName.equals("system")) {
555                    mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
556                }
557            }
558
559            if (profileFile != null) {
560                if (!aInfo.processName.equals("system")) {
561                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
562                            profileFile, profileFd,
563                            (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
564                }
565            }
566        }
567        return aInfo;
568    }
569
570    void startHomeActivity(Intent intent, ActivityInfo aInfo) {
571        moveHomeStack(true);
572        startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
573                null, false, null);
574    }
575
576    final int startActivityMayWait(IApplicationThread caller, int callingUid,
577            String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
578            String resultWho, int requestCode, int startFlags, String profileFile,
579            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
580            Bundle options, int userId) {
581        // Refuse possible leaked file descriptors
582        if (intent != null && intent.hasFileDescriptors()) {
583            throw new IllegalArgumentException("File descriptors passed in Intent");
584        }
585        boolean componentSpecified = intent.getComponent() != null;
586
587        // Don't modify the client's object!
588        intent = new Intent(intent);
589
590        // Collect information about the target of the Intent.
591        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
592                profileFile, profileFd, userId);
593
594        synchronized (mService) {
595            int callingPid;
596            if (callingUid >= 0) {
597                callingPid = -1;
598            } else if (caller == null) {
599                callingPid = Binder.getCallingPid();
600                callingUid = Binder.getCallingUid();
601            } else {
602                callingPid = callingUid = -1;
603            }
604
605            final ActivityStack stack = getFocusedStack();
606            stack.mConfigWillChange = config != null
607                    && mService.mConfiguration.diff(config) != 0;
608            if (DEBUG_CONFIGURATION) Slog.v(TAG,
609                    "Starting activity when config will change = " + stack.mConfigWillChange);
610
611            final long origId = Binder.clearCallingIdentity();
612
613            if (aInfo != null &&
614                    (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
615                // This may be a heavy-weight process!  Check to see if we already
616                // have another, different heavy-weight process running.
617                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
618                    if (mService.mHeavyWeightProcess != null &&
619                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
620                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
621                        int realCallingUid = callingUid;
622                        if (caller != null) {
623                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
624                            if (callerApp != null) {
625                                realCallingUid = callerApp.info.uid;
626                            } else {
627                                Slog.w(TAG, "Unable to find app for caller " + caller
628                                      + " (pid=" + callingPid + ") when starting: "
629                                      + intent.toString());
630                                ActivityOptions.abort(options);
631                                return ActivityManager.START_PERMISSION_DENIED;
632                            }
633                        }
634
635                        IIntentSender target = mService.getIntentSenderLocked(
636                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
637                                realCallingUid, userId, null, null, 0, new Intent[] { intent },
638                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
639                                | PendingIntent.FLAG_ONE_SHOT, null);
640
641                        Intent newIntent = new Intent();
642                        if (requestCode >= 0) {
643                            // Caller is requesting a result.
644                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
645                        }
646                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
647                                new IntentSender(target));
648                        if (mService.mHeavyWeightProcess.activities.size() > 0) {
649                            ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
650                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
651                                    hist.packageName);
652                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
653                                    hist.task.taskId);
654                        }
655                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
656                                aInfo.packageName);
657                        newIntent.setFlags(intent.getFlags());
658                        newIntent.setClassName("android",
659                                HeavyWeightSwitcherActivity.class.getName());
660                        intent = newIntent;
661                        resolvedType = null;
662                        caller = null;
663                        callingUid = Binder.getCallingUid();
664                        callingPid = Binder.getCallingPid();
665                        componentSpecified = true;
666                        try {
667                            ResolveInfo rInfo =
668                                AppGlobals.getPackageManager().resolveIntent(
669                                        intent, null,
670                                        PackageManager.MATCH_DEFAULT_ONLY
671                                        | ActivityManagerService.STOCK_PM_FLAGS, userId);
672                            aInfo = rInfo != null ? rInfo.activityInfo : null;
673                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
674                        } catch (RemoteException e) {
675                            aInfo = null;
676                        }
677                    }
678                }
679            }
680
681            int res = startActivityLocked(caller, intent, resolvedType,
682                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
683                    callingPackage, startFlags, options, componentSpecified, null);
684
685            if (stack.mConfigWillChange) {
686                // If the caller also wants to switch to a new configuration,
687                // do so now.  This allows a clean switch, as we are waiting
688                // for the current activity to pause (so we will not destroy
689                // it), and have not yet started the next activity.
690                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
691                        "updateConfiguration()");
692                stack.mConfigWillChange = false;
693                if (DEBUG_CONFIGURATION) Slog.v(TAG,
694                        "Updating to new configuration after starting activity.");
695                mService.updateConfigurationLocked(config, null, false, false);
696            }
697
698            Binder.restoreCallingIdentity(origId);
699
700            if (outResult != null) {
701                outResult.result = res;
702                if (res == ActivityManager.START_SUCCESS) {
703                    mWaitingActivityLaunched.add(outResult);
704                    do {
705                        try {
706                            mService.wait();
707                        } catch (InterruptedException e) {
708                        }
709                    } while (!outResult.timeout && outResult.who == null);
710                } else if (res == ActivityManager.START_TASK_TO_FRONT) {
711                    ActivityRecord r = stack.topRunningActivityLocked(null);
712                    if (r.nowVisible) {
713                        outResult.timeout = false;
714                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
715                        outResult.totalTime = 0;
716                        outResult.thisTime = 0;
717                    } else {
718                        outResult.thisTime = SystemClock.uptimeMillis();
719                        mWaitingActivityVisible.add(outResult);
720                        do {
721                            try {
722                                mService.wait();
723                            } catch (InterruptedException e) {
724                            }
725                        } while (!outResult.timeout && outResult.who == null);
726                    }
727                }
728            }
729
730            return res;
731        }
732    }
733
734    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
735            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
736            Bundle options, int userId) {
737        if (intents == null) {
738            throw new NullPointerException("intents is null");
739        }
740        if (resolvedTypes == null) {
741            throw new NullPointerException("resolvedTypes is null");
742        }
743        if (intents.length != resolvedTypes.length) {
744            throw new IllegalArgumentException("intents are length different than resolvedTypes");
745        }
746
747
748        int callingPid;
749        if (callingUid >= 0) {
750            callingPid = -1;
751        } else if (caller == null) {
752            callingPid = Binder.getCallingPid();
753            callingUid = Binder.getCallingUid();
754        } else {
755            callingPid = callingUid = -1;
756        }
757        final long origId = Binder.clearCallingIdentity();
758        try {
759            synchronized (mService) {
760                ActivityRecord[] outActivity = new ActivityRecord[1];
761                for (int i=0; i<intents.length; i++) {
762                    Intent intent = intents[i];
763                    if (intent == null) {
764                        continue;
765                    }
766
767                    // Refuse possible leaked file descriptors
768                    if (intent != null && intent.hasFileDescriptors()) {
769                        throw new IllegalArgumentException("File descriptors passed in Intent");
770                    }
771
772                    boolean componentSpecified = intent.getComponent() != null;
773
774                    // Don't modify the client's object!
775                    intent = new Intent(intent);
776
777                    // Collect information about the target of the Intent.
778                    ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
779                            0, null, null, userId);
780                    // TODO: New, check if this is correct
781                    aInfo = mService.getActivityInfoForUser(aInfo, userId);
782
783                    if (aInfo != null &&
784                            (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
785                                    != 0) {
786                        throw new IllegalArgumentException(
787                                "FLAG_CANT_SAVE_STATE not supported here");
788                    }
789
790                    Bundle theseOptions;
791                    if (options != null && i == intents.length-1) {
792                        theseOptions = options;
793                    } else {
794                        theseOptions = null;
795                    }
796                    int res = startActivityLocked(caller, intent, resolvedTypes[i],
797                            aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
798                            0, theseOptions, componentSpecified, outActivity);
799                    if (res < 0) {
800                        return res;
801                    }
802
803                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
804                }
805            }
806        } finally {
807            Binder.restoreCallingIdentity(origId);
808        }
809
810        return ActivityManager.START_SUCCESS;
811    }
812
813    final boolean realStartActivityLocked(ActivityRecord r,
814            ProcessRecord app, boolean andResume, boolean checkConfig)
815            throws RemoteException {
816
817        r.startFreezingScreenLocked(app, 0);
818        mWindowManager.setAppVisibility(r.appToken, true);
819
820        // schedule launch ticks to collect information about slow apps.
821        r.startLaunchTickingLocked();
822
823        // Have the window manager re-evaluate the orientation of
824        // the screen based on the new activity order.  Note that
825        // as a result of this, it can call back into the activity
826        // manager with a new orientation.  We don't care about that,
827        // because the activity is not currently running so we are
828        // just restarting it anyway.
829        if (checkConfig) {
830            Configuration config = mWindowManager.updateOrientationFromAppTokens(
831                    mService.mConfiguration,
832                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
833            mService.updateConfigurationLocked(config, r, false, false);
834        }
835
836        r.app = app;
837        app.waitingToKill = null;
838        r.launchCount++;
839        r.lastLaunchTime = SystemClock.uptimeMillis();
840
841        if (localLOGV) Slog.v(TAG, "Launching: " + r);
842
843        int idx = app.activities.indexOf(r);
844        if (idx < 0) {
845            app.activities.add(r);
846        }
847        mService.updateLruProcessLocked(app, true);
848
849        final ActivityStack stack = r.task.stack;
850        try {
851            if (app.thread == null) {
852                throw new RemoteException();
853            }
854            List<ResultInfo> results = null;
855            List<Intent> newIntents = null;
856            if (andResume) {
857                results = r.results;
858                newIntents = r.newIntents;
859            }
860            if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
861                    + " icicle=" + r.icicle
862                    + " with results=" + results + " newIntents=" + newIntents
863                    + " andResume=" + andResume);
864            if (andResume) {
865                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
866                        r.userId, System.identityHashCode(r),
867                        r.task.taskId, r.shortComponentName);
868            }
869            if (r.isHomeActivity()) {
870                mService.mHomeProcess = app;
871            }
872            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
873            r.sleeping = false;
874            r.forceNewConfig = false;
875            mService.showAskCompatModeDialogLocked(r);
876            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
877            String profileFile = null;
878            ParcelFileDescriptor profileFd = null;
879            boolean profileAutoStop = false;
880            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
881                if (mService.mProfileProc == null || mService.mProfileProc == app) {
882                    mService.mProfileProc = app;
883                    profileFile = mService.mProfileFile;
884                    profileFd = mService.mProfileFd;
885                    profileAutoStop = mService.mAutoStopProfiler;
886                }
887            }
888            app.hasShownUi = true;
889            app.pendingUiClean = true;
890            if (profileFd != null) {
891                try {
892                    profileFd = profileFd.dup();
893                } catch (IOException e) {
894                    if (profileFd != null) {
895                        try {
896                            profileFd.close();
897                        } catch (IOException o) {
898                        }
899                        profileFd = null;
900                    }
901                }
902            }
903            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
904                    System.identityHashCode(r), r.info,
905                    new Configuration(mService.mConfiguration),
906                    r.compat, r.icicle, results, newIntents, !andResume,
907                    mService.isNextTransitionForward(), profileFile, profileFd,
908                    profileAutoStop);
909
910            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
911                // This may be a heavy-weight process!  Note that the package
912                // manager will ensure that only activity can run in the main
913                // process of the .apk, which is the only thing that will be
914                // considered heavy-weight.
915                if (app.processName.equals(app.info.packageName)) {
916                    if (mService.mHeavyWeightProcess != null
917                            && mService.mHeavyWeightProcess != app) {
918                        Slog.w(TAG, "Starting new heavy weight process " + app
919                                + " when already running "
920                                + mService.mHeavyWeightProcess);
921                    }
922                    mService.mHeavyWeightProcess = app;
923                    Message msg = mService.mHandler.obtainMessage(
924                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
925                    msg.obj = r;
926                    mService.mHandler.sendMessage(msg);
927                }
928            }
929
930        } catch (RemoteException e) {
931            if (r.launchFailed) {
932                // This is the second time we failed -- finish activity
933                // and give up.
934                Slog.e(TAG, "Second failure launching "
935                      + r.intent.getComponent().flattenToShortString()
936                      + ", giving up", e);
937                mService.appDiedLocked(app, app.pid, app.thread);
938                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
939                        "2nd-crash", false);
940                return false;
941            }
942
943            // This is the first time we failed -- restart process and
944            // retry.
945            app.activities.remove(r);
946            throw e;
947        }
948
949        r.launchFailed = false;
950        if (stack.updateLRUListLocked(r)) {
951            Slog.w(TAG, "Activity " + r
952                  + " being launched, but already in LRU list");
953        }
954
955        if (andResume) {
956            // As part of the process of launching, ActivityThread also performs
957            // a resume.
958            stack.minimalResumeActivityLocked(r);
959        } else {
960            // This activity is not starting in the resumed state... which
961            // should look like we asked it to pause+stop (but remain visible),
962            // and it has done so and reported back the current icicle and
963            // other state.
964            if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
965                    + " (starting in stopped state)");
966            r.state = ActivityState.STOPPED;
967            r.stopped = true;
968        }
969
970        // Launch the new version setup screen if needed.  We do this -after-
971        // launching the initial activity (that is, home), so that it can have
972        // a chance to initialize itself while in the background, making the
973        // switch back to it faster and look better.
974        if (isFrontStack(stack)) {
975            mService.startSetupActivityLocked();
976        }
977
978        return true;
979    }
980
981    void startSpecificActivityLocked(ActivityRecord r,
982            boolean andResume, boolean checkConfig) {
983        // Is this activity's application already running?
984        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
985                r.info.applicationInfo.uid);
986
987        r.task.stack.setLaunchTime(r);
988
989        if (app != null && app.thread != null) {
990            try {
991                app.addPackage(r.info.packageName, mService.mProcessTracker);
992                realStartActivityLocked(r, app, andResume, checkConfig);
993                return;
994            } catch (RemoteException e) {
995                Slog.w(TAG, "Exception when starting activity "
996                        + r.intent.getComponent().flattenToShortString(), e);
997            }
998
999            // If a dead object exception was thrown -- fall through to
1000            // restart the application.
1001        }
1002
1003        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1004                "activity", r.intent.getComponent(), false, false);
1005    }
1006
1007    final int startActivityLocked(IApplicationThread caller,
1008            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
1009            String resultWho, int requestCode,
1010            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
1011            boolean componentSpecified, ActivityRecord[] outActivity) {
1012        int err = ActivityManager.START_SUCCESS;
1013
1014        ProcessRecord callerApp = null;
1015        if (caller != null) {
1016            callerApp = mService.getRecordForAppLocked(caller);
1017            if (callerApp != null) {
1018                callingPid = callerApp.pid;
1019                callingUid = callerApp.info.uid;
1020            } else {
1021                Slog.w(TAG, "Unable to find app for caller " + caller
1022                      + " (pid=" + callingPid + ") when starting: "
1023                      + intent.toString());
1024                err = ActivityManager.START_PERMISSION_DENIED;
1025            }
1026        }
1027
1028        if (err == ActivityManager.START_SUCCESS) {
1029            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
1030            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
1031                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
1032        }
1033
1034        ActivityRecord sourceRecord = null;
1035        ActivityRecord resultRecord = null;
1036        if (resultTo != null) {
1037            sourceRecord = isInAnyStackLocked(resultTo);
1038            if (DEBUG_RESULTS) Slog.v(
1039                TAG, "Will send result to " + resultTo + " " + sourceRecord);
1040            if (sourceRecord != null) {
1041                if (requestCode >= 0 && !sourceRecord.finishing) {
1042                    resultRecord = sourceRecord;
1043                }
1044            }
1045        }
1046        ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
1047
1048        int launchFlags = intent.getFlags();
1049
1050        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
1051                && sourceRecord != null) {
1052            // Transfer the result target from the source activity to the new
1053            // one being started, including any failures.
1054            if (requestCode >= 0) {
1055                ActivityOptions.abort(options);
1056                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
1057            }
1058            resultRecord = sourceRecord.resultTo;
1059            resultWho = sourceRecord.resultWho;
1060            requestCode = sourceRecord.requestCode;
1061            sourceRecord.resultTo = null;
1062            if (resultRecord != null) {
1063                resultRecord.removeResultsLocked(
1064                    sourceRecord, resultWho, requestCode);
1065            }
1066        }
1067
1068        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
1069            // We couldn't find a class that can handle the given Intent.
1070            // That's the end of that!
1071            err = ActivityManager.START_INTENT_NOT_RESOLVED;
1072        }
1073
1074        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
1075            // We couldn't find the specific class specified in the Intent.
1076            // Also the end of the line.
1077            err = ActivityManager.START_CLASS_NOT_FOUND;
1078        }
1079
1080        if (err != ActivityManager.START_SUCCESS) {
1081            if (resultRecord != null) {
1082                resultStack.sendActivityResultLocked(-1,
1083                    resultRecord, resultWho, requestCode,
1084                    Activity.RESULT_CANCELED, null);
1085            }
1086            setDismissKeyguard(false);
1087            ActivityOptions.abort(options);
1088            return err;
1089        }
1090
1091        final int startAnyPerm = mService.checkPermission(
1092                START_ANY_ACTIVITY, callingPid, callingUid);
1093        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
1094                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
1095        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
1096            if (resultRecord != null) {
1097                resultStack.sendActivityResultLocked(-1,
1098                    resultRecord, resultWho, requestCode,
1099                    Activity.RESULT_CANCELED, null);
1100            }
1101            setDismissKeyguard(false);
1102            String msg;
1103            if (!aInfo.exported) {
1104                msg = "Permission Denial: starting " + intent.toString()
1105                        + " from " + callerApp + " (pid=" + callingPid
1106                        + ", uid=" + callingUid + ")"
1107                        + " not exported from uid " + aInfo.applicationInfo.uid;
1108            } else {
1109                msg = "Permission Denial: starting " + intent.toString()
1110                        + " from " + callerApp + " (pid=" + callingPid
1111                        + ", uid=" + callingUid + ")"
1112                        + " requires " + aInfo.permission;
1113            }
1114            Slog.w(TAG, msg);
1115            throw new SecurityException(msg);
1116        }
1117
1118        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent,
1119                callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo);
1120
1121        if (mService.mController != null) {
1122            try {
1123                // The Intent we give to the watcher has the extra data
1124                // stripped off, since it can contain private information.
1125                Intent watchIntent = intent.cloneFilter();
1126                abort |= !mService.mController.activityStarting(watchIntent,
1127                        aInfo.applicationInfo.packageName);
1128            } catch (RemoteException e) {
1129                mService.mController = null;
1130            }
1131        }
1132
1133        if (abort) {
1134            if (resultRecord != null) {
1135                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
1136                        Activity.RESULT_CANCELED, null);
1137            }
1138            // We pretend to the caller that it was really started, but
1139            // they will just get a cancel result.
1140            setDismissKeyguard(false);
1141            ActivityOptions.abort(options);
1142            return ActivityManager.START_SUCCESS;
1143        }
1144
1145        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
1146                intent, resolvedType, aInfo, mService.mConfiguration,
1147                resultRecord, resultWho, requestCode, componentSpecified, this);
1148        if (outActivity != null) {
1149            outActivity[0] = r;
1150        }
1151
1152        final ActivityStack stack = getFocusedStack();
1153        if (stack.mResumedActivity == null
1154                || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
1155            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
1156                PendingActivityLaunch pal =
1157                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
1158                mService.mPendingActivityLaunches.add(pal);
1159                setDismissKeyguard(false);
1160                ActivityOptions.abort(options);
1161                return ActivityManager.START_SWITCHES_CANCELED;
1162            }
1163        }
1164
1165        if (mService.mDidAppSwitch) {
1166            // This is the second allowed switch since we stopped switches,
1167            // so now just generally allow switches.  Use case: user presses
1168            // home (switches disabled, switch to home, mDidAppSwitch now true);
1169            // user taps a home icon (coming from home so allowed, we hit here
1170            // and now allow anyone to switch again).
1171            mService.mAppSwitchesAllowedTime = 0;
1172        } else {
1173            mService.mDidAppSwitch = true;
1174        }
1175
1176        mService.doPendingActivityLaunchesLocked(false);
1177
1178        err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
1179        if (stack.mPausingActivity == null) {
1180            // Someone asked to have the keyguard dismissed on the next
1181            // activity start, but we are not actually doing an activity
1182            // switch...  just dismiss the keyguard now, because we
1183            // probably want to see whatever is behind it.
1184            dismissKeyguard();
1185        }
1186        return err;
1187    }
1188
1189    ActivityStack getCorrectStack(ActivityRecord r) {
1190        final TaskRecord task = r.task;
1191        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
1192            int stackNdx;
1193            for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
1194                if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) {
1195                    break;
1196                }
1197            }
1198            if (stackNdx == 0) {
1199                // Time to create the first app stack for this user.
1200                int stackId = mService.createStack(-1, HOME_STACK_ID,
1201                        StackBox.TASK_STACK_GOES_OVER, 1.0f);
1202                if (DEBUG_FOCUS) Slog.d(TAG, "getCorrectStack: New stack r=" + r + " stackId="
1203                        + stackId);
1204                mFocusedStack = getStack(stackId);
1205            }
1206            if (task != null) {
1207                if (DEBUG_FOCUS) Slog.d(TAG, "getCorrectStack: Setting focused stack to r=" +
1208                        r + " task=" + task);
1209                mFocusedStack = task.stack;
1210            }
1211            return mFocusedStack;
1212        }
1213        return mHomeStack;
1214    }
1215
1216    void setFocusedStack(ActivityRecord r) {
1217        if (r == null) {
1218            return;
1219        }
1220        if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
1221            if (mStackState != STACK_STATE_HOME_IN_FRONT) {
1222                if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1223                        stackStateToString(mStackState) + " new=" +
1224                        stackStateToString(STACK_STATE_HOME_TO_FRONT) +
1225                        " Callers=" + Debug.getCallers(3));
1226                mStackState = STACK_STATE_HOME_TO_FRONT;
1227            }
1228        } else {
1229            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: Setting focused stack to r=" +
1230                    r + " task=" + r.task + " Callers=" + Debug.getCallers(3));
1231            mFocusedStack = r.task.stack;
1232            if (mStackState != STACK_STATE_HOME_IN_BACK) {
1233                if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
1234                        stackStateToString(mStackState) + " new=" +
1235                        stackStateToString(STACK_STATE_HOME_TO_BACK) +
1236                        " Callers=" + Debug.getCallers(3));
1237                mStackState = STACK_STATE_HOME_TO_BACK;
1238            }
1239        }
1240    }
1241
1242    final int startActivityUncheckedLocked(ActivityRecord r,
1243            ActivityRecord sourceRecord, int startFlags, boolean doResume,
1244            Bundle options) {
1245        final Intent intent = r.intent;
1246        final int callingUid = r.launchedFromUid;
1247
1248        int launchFlags = intent.getFlags();
1249
1250        // We'll invoke onUserLeaving before onPause only if the launching
1251        // activity did not explicitly state that this is an automated launch.
1252        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
1253        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
1254
1255        // If the caller has asked not to resume at this point, we make note
1256        // of this in the record so that we can skip it when trying to find
1257        // the top running activity.
1258        if (!doResume) {
1259            r.delayedResume = true;
1260        }
1261
1262        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
1263
1264        // If the onlyIfNeeded flag is set, then we can do this if the activity
1265        // being launched is the same as the one making the call...  or, as
1266        // a special case, if we do not know the caller then we count the
1267        // current top activity as the caller.
1268        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1269            ActivityRecord checkedCaller = sourceRecord;
1270            if (checkedCaller == null) {
1271                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
1272            }
1273            if (!checkedCaller.realActivity.equals(r.realActivity)) {
1274                // Caller is not the same as launcher, so always needed.
1275                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
1276            }
1277        }
1278
1279        if (sourceRecord == null) {
1280            // This activity is not being started from another...  in this
1281            // case we -always- start a new task.
1282            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1283                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
1284                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
1285                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1286            }
1287        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1288            // The original activity who is starting us is running as a single
1289            // instance...  this new activity it is starting must go on its
1290            // own task.
1291            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1292        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
1293                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1294            // The activity being started is a single instance...  it always
1295            // gets launched into its own task.
1296            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
1297        }
1298
1299        final ActivityStack sourceStack;
1300        TaskRecord sourceTask;
1301        if (sourceRecord != null) {
1302            sourceTask = sourceRecord.task;
1303            sourceStack = sourceTask.stack;
1304        } else {
1305            sourceTask = null;
1306            sourceStack = null;
1307        }
1308
1309        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1310            // For whatever reason this activity is being launched into a new
1311            // task...  yet the caller has requested a result back.  Well, that
1312            // is pretty messed up, so instead immediately send back a cancel
1313            // and let the new task continue launched as normal without a
1314            // dependency on its originator.
1315            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
1316            r.resultTo.task.stack.sendActivityResultLocked(-1,
1317                    r.resultTo, r.resultWho, r.requestCode,
1318                Activity.RESULT_CANCELED, null);
1319            r.resultTo = null;
1320        }
1321
1322        boolean addingToTask = false;
1323        boolean movedHome = false;
1324        TaskRecord reuseTask = null;
1325        ActivityStack targetStack;
1326        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
1327                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
1328                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1329                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1330            // If bring to front is requested, and no result is requested, and
1331            // we can find a task that was started with this same
1332            // component, then instead of launching bring that one to the front.
1333            if (r.resultTo == null) {
1334                // See if there is a task to bring to the front.  If this is
1335                // a SINGLE_INSTANCE activity, there can be one and only one
1336                // instance of it in the history, and it is always in its own
1337                // unique task, so we do a special search.
1338                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
1339                        ? findTaskLocked(intent, r.info)
1340                        : findActivityLocked(intent, r.info);
1341                if (intentActivity != null) {
1342                    if (r.task == null) {
1343                        r.task = intentActivity.task;
1344                    }
1345                    targetStack = intentActivity.task.stack;
1346                    moveHomeStack(targetStack.isHomeStack());
1347                    if (intentActivity.task.intent == null) {
1348                        // This task was started because of movement of
1349                        // the activity based on affinity...  now that we
1350                        // are actually launching it, we can assign the
1351                        // base intent.
1352                        intentActivity.task.setIntent(intent, r.info);
1353                    }
1354                    // If the target task is not in the front, then we need
1355                    // to bring it to the front...  except...  well, with
1356                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
1357                    // to have the same behavior as if a new instance was
1358                    // being started, which means not bringing it to the front
1359                    // if the caller is not itself in the front.
1360                    final ActivityStack lastStack = getLastStack();
1361                    ActivityRecord curTop = lastStack == null?
1362                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
1363                    if (curTop != null && curTop.task != intentActivity.task) {
1364                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
1365                        if (sourceRecord == null || sourceStack.topActivity() == sourceRecord) {
1366                            // We really do want to push this one into the
1367                            // user's face, right now.
1368                            movedHome = true;
1369                            if ((launchFlags &
1370                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
1371                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
1372                                // Caller wants to appear on home activity, so before starting
1373                                // their own activity we will bring home to the front.
1374                                r.mLaunchHomeTaskNext = true;
1375                            }
1376                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
1377                            options = null;
1378                        }
1379                    }
1380                    // If the caller has requested that the target task be
1381                    // reset, then do so.
1382                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
1383                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
1384                    }
1385                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1386                        // We don't need to start a new activity, and
1387                        // the client said not to do anything if that
1388                        // is the case, so this is it!  And for paranoia, make
1389                        // sure we have correctly resumed the top activity.
1390                        if (doResume) {
1391                            setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
1392                            resumeTopActivitiesLocked(targetStack, null, options);
1393                        } else {
1394                            ActivityOptions.abort(options);
1395                        }
1396                        if (r.task == null)  Slog.v(TAG,
1397                                "startActivityUncheckedLocked: task left null",
1398                                new RuntimeException("here").fillInStackTrace());
1399                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1400                    }
1401                    if ((launchFlags &
1402                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
1403                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
1404                        // The caller has requested to completely replace any
1405                        // existing task with its new activity.  Well that should
1406                        // not be too hard...
1407                        reuseTask = intentActivity.task;
1408                        reuseTask.performClearTaskLocked();
1409                        reuseTask.setIntent(r.intent, r.info);
1410                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
1411                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
1412                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
1413                        // In this situation we want to remove all activities
1414                        // from the task up to the one being started.  In most
1415                        // cases this means we are resetting the task to its
1416                        // initial state.
1417                        ActivityRecord top =
1418                                intentActivity.task.performClearTaskLocked(r, launchFlags);
1419                        if (top != null) {
1420                            if (top.frontOfTask) {
1421                                // Activity aliases may mean we use different
1422                                // intents for the top activity, so make sure
1423                                // the task now has the identity of the new
1424                                // intent.
1425                                top.task.setIntent(r.intent, r.info);
1426                            }
1427                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
1428                                    r, top.task);
1429                            top.deliverNewIntentLocked(callingUid, r.intent);
1430                        } else {
1431                            // A special case: we need to
1432                            // start the activity because it is not currently
1433                            // running, and the caller has asked to clear the
1434                            // current task to have this activity at the top.
1435                            addingToTask = true;
1436                            // Now pretend like this activity is being started
1437                            // by the top of its task, so it is put in the
1438                            // right place.
1439                            sourceRecord = intentActivity;
1440                        }
1441                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
1442                        // In this case the top activity on the task is the
1443                        // same as the one being launched, so we take that
1444                        // as a request to bring the task to the foreground.
1445                        // If the top activity in the task is the root
1446                        // activity, deliver this new intent to it if it
1447                        // desires.
1448                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1449                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
1450                                && intentActivity.realActivity.equals(r.realActivity)) {
1451                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
1452                                    intentActivity.task);
1453                            if (intentActivity.frontOfTask) {
1454                                intentActivity.task.setIntent(r.intent, r.info);
1455                            }
1456                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
1457                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
1458                            // In this case we are launching the root activity
1459                            // of the task, but with a different intent.  We
1460                            // should start a new instance on top.
1461                            addingToTask = true;
1462                            sourceRecord = intentActivity;
1463                        }
1464                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
1465                        // In this case an activity is being launched in to an
1466                        // existing task, without resetting that task.  This
1467                        // is typically the situation of launching an activity
1468                        // from a notification or shortcut.  We want to place
1469                        // the new activity on top of the current task.
1470                        addingToTask = true;
1471                        sourceRecord = intentActivity;
1472                    } else if (!intentActivity.task.rootWasReset) {
1473                        // In this case we are launching in to an existing task
1474                        // that has not yet been started from its front door.
1475                        // The current task has been brought to the front.
1476                        // Ideally, we'd probably like to place this new task
1477                        // at the bottom of its stack, but that's a little hard
1478                        // to do with the current organization of the code so
1479                        // for now we'll just drop it.
1480                        intentActivity.task.setIntent(r.intent, r.info);
1481                    }
1482                    if (!addingToTask && reuseTask == null) {
1483                        // We didn't do anything...  but it was needed (a.k.a., client
1484                        // don't use that intent!)  And for paranoia, make
1485                        // sure we have correctly resumed the top activity.
1486                        if (doResume) {
1487                            setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
1488                            targetStack.resumeTopActivityLocked(null, options);
1489                        } else {
1490                            ActivityOptions.abort(options);
1491                        }
1492                        if (r.task == null)  Slog.v(TAG,
1493                            "startActivityUncheckedLocked: task left null",
1494                            new RuntimeException("here").fillInStackTrace());
1495                        return ActivityManager.START_TASK_TO_FRONT;
1496                    }
1497                }
1498            }
1499        }
1500
1501        //String uri = r.intent.toURI();
1502        //Intent intent2 = new Intent(uri);
1503        //Slog.i(TAG, "Given intent: " + r.intent);
1504        //Slog.i(TAG, "URI is: " + uri);
1505        //Slog.i(TAG, "To intent: " + intent2);
1506
1507        if (r.packageName != null) {
1508            // If the activity being launched is the same as the one currently
1509            // at the top, then we need to check if it should only be launched
1510            // once.
1511            ActivityStack topStack = getFocusedStack();
1512            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
1513            if (top != null && r.resultTo == null) {
1514                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
1515                    if (top.app != null && top.app.thread != null) {
1516                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
1517                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
1518                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
1519                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
1520                                    top.task);
1521                            // For paranoia, make sure we have correctly
1522                            // resumed the top activity.
1523                            if (doResume) {
1524                                setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
1525                                resumeTopActivitiesLocked();
1526                            }
1527                            ActivityOptions.abort(options);
1528                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
1529                                // We don't need to start a new activity, and
1530                                // the client said not to do anything if that
1531                                // is the case, so this is it!
1532                                if (r.task == null)  Slog.v(TAG,
1533                                    "startActivityUncheckedLocked: task left null",
1534                                    new RuntimeException("here").fillInStackTrace());
1535                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
1536                            }
1537                            top.deliverNewIntentLocked(callingUid, r.intent);
1538                            if (r.task == null)  Slog.v(TAG,
1539                                "startActivityUncheckedLocked: task left null",
1540                                new RuntimeException("here").fillInStackTrace());
1541                            return ActivityManager.START_DELIVERED_TO_TOP;
1542                        }
1543                    }
1544                }
1545            }
1546
1547        } else {
1548            if (r.resultTo != null) {
1549                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
1550                        r.requestCode, Activity.RESULT_CANCELED, null);
1551            }
1552            ActivityOptions.abort(options);
1553            if (r.task == null)  Slog.v(TAG,
1554                "startActivityUncheckedLocked: task left null",
1555                new RuntimeException("here").fillInStackTrace());
1556            return ActivityManager.START_CLASS_NOT_FOUND;
1557        }
1558
1559        boolean newTask = false;
1560        boolean keepCurTransition = false;
1561
1562        // Should this be considered a new task?
1563        if (r.resultTo == null && !addingToTask
1564                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
1565            targetStack = getCorrectStack(r);
1566            moveHomeStack(targetStack.isHomeStack());
1567            if (reuseTask == null) {
1568                r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1569                        null, true);
1570                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
1571                        r.task);
1572            } else {
1573                r.setTask(reuseTask, reuseTask, true);
1574            }
1575            newTask = true;
1576            if (!movedHome) {
1577                if ((launchFlags &
1578                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
1579                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
1580                    // Caller wants to appear on home activity, so before starting
1581                    // their own activity we will bring home to the front.
1582                    r.mLaunchHomeTaskNext = true;
1583                }
1584            }
1585        } else if (sourceRecord != null) {
1586            sourceTask = sourceRecord.task;
1587            targetStack = sourceTask.stack;
1588            moveHomeStack(targetStack.isHomeStack());
1589            if (!addingToTask &&
1590                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
1591                // In this case, we are adding the activity to an existing
1592                // task, but the caller has asked to clear that task if the
1593                // activity is already running.
1594                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
1595                keepCurTransition = true;
1596                if (top != null) {
1597                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
1598                    top.deliverNewIntentLocked(callingUid, r.intent);
1599                    // For paranoia, make sure we have correctly
1600                    // resumed the top activity.
1601                    if (doResume) {
1602                        setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
1603                        targetStack.resumeTopActivityLocked(null);
1604                    }
1605                    ActivityOptions.abort(options);
1606                    if (r.task == null)  Slog.v(TAG,
1607                        "startActivityUncheckedLocked: task left null",
1608                        new RuntimeException("here").fillInStackTrace());
1609                    return ActivityManager.START_DELIVERED_TO_TOP;
1610                }
1611            } else if (!addingToTask &&
1612                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
1613                // In this case, we are launching an activity in our own task
1614                // that may already be running somewhere in the history, and
1615                // we want to shuffle it to the front of the stack if so.
1616                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
1617                if (top != null) {
1618                    final TaskRecord task = top.task;
1619                    task.moveActivityToFrontLocked(top);
1620                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
1621                    top.updateOptionsLocked(options);
1622                    top.deliverNewIntentLocked(callingUid, r.intent);
1623                    if (doResume) {
1624                        setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
1625                        targetStack.resumeTopActivityLocked(null);
1626                    }
1627                    if (r.task == null)  Slog.v(TAG,
1628                        "startActivityUncheckedLocked: task left null",
1629                        new RuntimeException("here").fillInStackTrace());
1630                    return ActivityManager.START_DELIVERED_TO_TOP;
1631                }
1632            }
1633            // An existing activity is starting this new activity, so we want
1634            // to keep the new one in the same task as the one that is starting
1635            // it.
1636            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
1637            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1638                    + " in existing task " + r.task);
1639
1640        } else {
1641            // This not being started from an existing activity, and not part
1642            // of a new task...  just put it in the top task, though these days
1643            // this case should never happen.
1644            targetStack = getCorrectStack(r);
1645            moveHomeStack(targetStack.isHomeStack());
1646            ActivityRecord prev = targetStack.topActivity();
1647            r.setTask(prev != null ? prev.task
1648                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
1649                    null, true);
1650            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
1651                    + " in new guessed " + r.task);
1652        }
1653
1654        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
1655                intent, r.getUriPermissionsLocked());
1656
1657        if (newTask) {
1658            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
1659        }
1660        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
1661        setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
1662        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
1663        mService.setFocusedActivityLocked(r);
1664        return ActivityManager.START_SUCCESS;
1665    }
1666
1667    // Checked.
1668    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
1669            Configuration config) {
1670        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
1671
1672        ActivityRecord res = null;
1673
1674        ArrayList<ActivityRecord> stops = null;
1675        ArrayList<ActivityRecord> finishes = null;
1676        ArrayList<UserStartedState> startingUsers = null;
1677        int NS = 0;
1678        int NF = 0;
1679        IApplicationThread sendThumbnail = null;
1680        boolean booting = false;
1681        boolean enableScreen = false;
1682        boolean activityRemoved = false;
1683
1684        ActivityRecord r = ActivityRecord.forToken(token);
1685        if (r != null) {
1686            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
1687                    Debug.getCallers(4));
1688            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1689            r.finishLaunchTickingLocked();
1690            res = r.task.stack.activityIdleInternalLocked(token);
1691            if (res != null) {
1692                if (fromTimeout) {
1693                    reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
1694                }
1695
1696                // This is a hack to semi-deal with a race condition
1697                // in the client where it can be constructed with a
1698                // newer configuration from when we asked it to launch.
1699                // We'll update with whatever configuration it now says
1700                // it used to launch.
1701                if (config != null) {
1702                    r.configuration = config;
1703                }
1704
1705                // We are now idle.  If someone is waiting for a thumbnail from
1706                // us, we can now deliver.
1707                r.idle = true;
1708                if (allResumedActivitiesIdle()) {
1709                    mService.scheduleAppGcsLocked();
1710                }
1711                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
1712                    sendThumbnail = r.app.thread;
1713                    r.thumbnailNeeded = false;
1714                }
1715
1716                //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
1717                if (!mService.mBooted && isFrontStack(r.task.stack)) {
1718                    mService.mBooted = true;
1719                    enableScreen = true;
1720                }
1721            } else if (fromTimeout) {
1722                reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
1723            }
1724        }
1725
1726        // Atomically retrieve all of the other things to do.
1727        stops = processStoppingActivitiesLocked(true);
1728        NS = stops != null ? stops.size() : 0;
1729        if ((NF=mFinishingActivities.size()) > 0) {
1730            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
1731            mFinishingActivities.clear();
1732        }
1733
1734        final ArrayList<ActivityRecord> thumbnails;
1735        final int NT = mCancelledThumbnails.size();
1736        if (NT > 0) {
1737            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
1738            mCancelledThumbnails.clear();
1739        } else {
1740            thumbnails = null;
1741        }
1742
1743        if (isFrontStack(mHomeStack)) {
1744            booting = mService.mBooting;
1745            mService.mBooting = false;
1746        }
1747
1748        if (mStartingUsers.size() > 0) {
1749            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
1750            mStartingUsers.clear();
1751        }
1752
1753        // Perform the following actions from unsynchronized state.
1754        final IApplicationThread thumbnailThread = sendThumbnail;
1755        mHandler.post(new Runnable() {
1756            @Override
1757            public void run() {
1758                if (thumbnailThread != null) {
1759                    try {
1760                        thumbnailThread.requestThumbnail(token);
1761                    } catch (Exception e) {
1762                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
1763                        mService.sendPendingThumbnail(null, token, null, null, true);
1764                    }
1765                }
1766
1767                // Report back to any thumbnail receivers.
1768                for (int i = 0; i < NT; i++) {
1769                    ActivityRecord r = thumbnails.get(i);
1770                    mService.sendPendingThumbnail(r, null, null, null, true);
1771                }
1772            }
1773        });
1774
1775        // Stop any activities that are scheduled to do so but have been
1776        // waiting for the next one to start.
1777        for (int i = 0; i < NS; i++) {
1778            r = stops.get(i);
1779            final ActivityStack stack = r.task.stack;
1780            if (r.finishing) {
1781                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
1782            } else {
1783                stack.stopActivityLocked(r);
1784            }
1785        }
1786
1787        // Finish any activities that are scheduled to do so but have been
1788        // waiting for the next one to start.
1789        for (int i = 0; i < NF; i++) {
1790            r = finishes.get(i);
1791            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
1792        }
1793
1794        if (booting) {
1795            mService.finishBooting();
1796        } else if (startingUsers != null) {
1797            for (int i = 0; i < startingUsers.size(); i++) {
1798                mService.finishUserSwitch(startingUsers.get(i));
1799            }
1800        }
1801
1802        mService.trimApplications();
1803        //dump();
1804        //mWindowManager.dump();
1805
1806        if (enableScreen) {
1807            mService.enableScreenAfterBoot();
1808        }
1809
1810        if (activityRemoved) {
1811            resumeTopActivitiesLocked();
1812        }
1813
1814        return res;
1815    }
1816
1817    void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
1818        // Just in case.
1819        final int numStacks = mStacks.size();
1820        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1821            mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
1822        }
1823    }
1824
1825    void closeSystemDialogsLocked() {
1826        final int numStacks = mStacks.size();
1827        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1828            final ActivityStack stack = mStacks.get(stackNdx);
1829            stack.closeSystemDialogsLocked();
1830        }
1831    }
1832
1833    /**
1834     * @return true if some activity was finished (or would have finished if doit were true).
1835     */
1836    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
1837        boolean didSomething = false;
1838        final int numStacks = mStacks.size();
1839        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1840            final ActivityStack stack = mStacks.get(stackNdx);
1841            if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
1842                didSomething = true;
1843            }
1844        }
1845        return didSomething;
1846    }
1847
1848    boolean resumeTopActivitiesLocked() {
1849        return resumeTopActivitiesLocked(null, null, null);
1850    }
1851
1852    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
1853            Bundle targetOptions) {
1854        if (targetStack == null) {
1855            targetStack = getFocusedStack();
1856        }
1857        boolean result = false;
1858        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1859            final ActivityStack stack = mStacks.get(stackNdx);
1860            if (isFrontStack(stack)) {
1861                if (stack == targetStack) {
1862                    result = stack.resumeTopActivityLocked(target, targetOptions);
1863                } else {
1864                    stack.resumeTopActivityLocked(null);
1865                }
1866            }
1867        }
1868        return result;
1869    }
1870
1871    void finishTopRunningActivityLocked(ProcessRecord app) {
1872        final int numStacks = mStacks.size();
1873        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
1874            final ActivityStack stack = mStacks.get(stackNdx);
1875            stack.finishTopRunningActivityLocked(app);
1876        }
1877    }
1878
1879    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
1880        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1881            if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
1882                if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
1883                        mStacks.get(stackNdx));
1884                return;
1885            }
1886        }
1887    }
1888
1889    ActivityStack getStack(int stackId) {
1890        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1891            final ActivityStack stack = mStacks.get(stackNdx);
1892            if (stack.getStackId() == stackId) {
1893                return stack;
1894            }
1895        }
1896        return null;
1897    }
1898
1899    ArrayList<ActivityStack> getStacks() {
1900        return new ArrayList<ActivityStack>(mStacks);
1901    }
1902
1903    int createStack() {
1904        while (true) {
1905            if (++mLastStackId <= HOME_STACK_ID) {
1906                mLastStackId = HOME_STACK_ID + 1;
1907            }
1908            if (getStack(mLastStackId) == null) {
1909                break;
1910            }
1911        }
1912        mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
1913        return mLastStackId;
1914    }
1915
1916    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
1917        final TaskRecord task = anyTaskForIdLocked(taskId);
1918        if (task == null) {
1919            return;
1920        }
1921        final ActivityStack stack = getStack(stackId);
1922        if (stack == null) {
1923            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
1924            return;
1925        }
1926        removeTask(task);
1927        stack.addTask(task, toTop);
1928        mWindowManager.addTask(taskId, stackId, toTop);
1929        resumeTopActivitiesLocked();
1930    }
1931
1932    ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
1933        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1934            final ActivityRecord ar = mStacks.get(stackNdx).findTaskLocked(intent, info);
1935            if (ar != null) {
1936                return ar;
1937            }
1938        }
1939        return null;
1940    }
1941
1942    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
1943        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1944            final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
1945            if (ar != null) {
1946                return ar;
1947            }
1948        }
1949        return null;
1950    }
1951
1952    void goingToSleepLocked() {
1953        scheduleSleepTimeout();
1954        if (!mGoingToSleep.isHeld()) {
1955            mGoingToSleep.acquire();
1956            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1957                final ActivityStack stack = mStacks.get(stackNdx);
1958                if (stack.mResumedActivity != null) {
1959                    stack.stopIfSleepingLocked();
1960                }
1961            }
1962        }
1963    }
1964
1965    boolean shutdownLocked(int timeout) {
1966        boolean timedout = false;
1967        goingToSleepLocked();
1968        checkReadyForSleepLocked();
1969
1970        final long endTime = System.currentTimeMillis() + timeout;
1971        while (true) {
1972            boolean cantShutdown = false;
1973            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
1974                cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
1975            }
1976            if (cantShutdown) {
1977                long timeRemaining = endTime - System.currentTimeMillis();
1978                if (timeRemaining > 0) {
1979                    try {
1980                        mService.wait(timeRemaining);
1981                    } catch (InterruptedException e) {
1982                    }
1983                } else {
1984                    Slog.w(TAG, "Activity manager shutdown timed out");
1985                    timedout = true;
1986                    break;
1987                }
1988            } else {
1989                break;
1990            }
1991        }
1992
1993        // Force checkReadyForSleep to complete.
1994        mSleepTimeout = true;
1995        checkReadyForSleepLocked();
1996
1997        return timedout;
1998    }
1999
2000    void comeOutOfSleepIfNeededLocked() {
2001        removeSleepTimeouts();
2002        if (mGoingToSleep.isHeld()) {
2003            mGoingToSleep.release();
2004        }
2005        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2006            final ActivityStack stack = mStacks.get(stackNdx);
2007            stack.awakeFromSleepingLocked();
2008            if (isFrontStack(stack)) {
2009                resumeTopActivitiesLocked();
2010            }
2011        }
2012        mGoingToSleepActivities.clear();
2013    }
2014
2015    void activitySleptLocked(ActivityRecord r) {
2016        mGoingToSleepActivities.remove(r);
2017        checkReadyForSleepLocked();
2018    }
2019
2020    void checkReadyForSleepLocked() {
2021        if (!mService.isSleepingOrShuttingDown()) {
2022            // Do not care.
2023            return;
2024        }
2025
2026        if (!mSleepTimeout) {
2027            boolean dontSleep = false;
2028            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2029                dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
2030            }
2031
2032            if (mStoppingActivities.size() > 0) {
2033                // Still need to tell some activities to stop; can't sleep yet.
2034                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
2035                        + mStoppingActivities.size() + " activities");
2036                scheduleIdleLocked();
2037                dontSleep = true;
2038            }
2039
2040            if (mGoingToSleepActivities.size() > 0) {
2041                // Still need to tell some activities to sleep; can't sleep yet.
2042                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
2043                        + mGoingToSleepActivities.size() + " activities");
2044                dontSleep = true;
2045            }
2046
2047            if (dontSleep) {
2048                return;
2049            }
2050        }
2051
2052        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2053            mStacks.get(stackNdx).goToSleep();
2054        }
2055
2056        removeSleepTimeouts();
2057
2058        if (mGoingToSleep.isHeld()) {
2059            mGoingToSleep.release();
2060        }
2061        if (mService.mShuttingDown) {
2062            mService.notifyAll();
2063        }
2064    }
2065
2066    boolean reportResumedActivityLocked(ActivityRecord r) {
2067        final ActivityStack stack = r.task.stack;
2068        if (isFrontStack(stack)) {
2069            mService.updateUsageStats(r, true);
2070        }
2071        if (allResumedActivitiesComplete()) {
2072            ensureActivitiesVisibleLocked(null, 0);
2073            mWindowManager.executeAppTransition();
2074            return true;
2075        }
2076        return false;
2077    }
2078
2079    void handleAppCrashLocked(ProcessRecord app) {
2080        final int numStacks = mStacks.size();
2081        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2082            final ActivityStack stack = mStacks.get(stackNdx);
2083            stack.handleAppCrashLocked(app);
2084        }
2085    }
2086
2087    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
2088        // First the front stacks. In case any are not fullscreen and are in front of home.
2089        boolean showHomeBehindStack = false;
2090        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2091            final ActivityStack stack = mStacks.get(stackNdx);
2092            if (isFrontStack(stack)) {
2093                showHomeBehindStack =
2094                        stack.ensureActivitiesVisibleLocked(starting, configChanges);
2095            }
2096        }
2097        // Now do back stacks.
2098        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2099            final ActivityStack stack = mStacks.get(stackNdx);
2100            if (!isFrontStack(stack)) {
2101                stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
2102            }
2103        }
2104    }
2105
2106    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
2107        final int numStacks = mStacks.size();
2108        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2109            final ActivityStack stack = mStacks.get(stackNdx);
2110            stack.scheduleDestroyActivities(app, false, reason);
2111        }
2112    }
2113
2114    boolean switchUserLocked(int userId, UserStartedState uss) {
2115        mUserStates.put(mCurrentUser, new UserState());
2116        mCurrentUser = userId;
2117        UserState userState = mUserStates.get(userId);
2118        if (userState != null) {
2119            userState.restore();
2120            mUserStates.delete(userId);
2121        } else {
2122            mFocusedStack = null;
2123            if (DEBUG_STACK) Slog.d(TAG, "switchUserLocked: mStackState=" +
2124                    stackStateToString(STACK_STATE_HOME_IN_FRONT));
2125            mStackState = STACK_STATE_HOME_IN_FRONT;
2126        }
2127
2128        mStartingUsers.add(uss);
2129        boolean haveActivities = mHomeStack.switchUserLocked(userId);
2130
2131        resumeTopActivitiesLocked();
2132
2133        return haveActivities;
2134    }
2135
2136    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
2137        int N = mStoppingActivities.size();
2138        if (N <= 0) return null;
2139
2140        ArrayList<ActivityRecord> stops = null;
2141
2142        final boolean nowVisible = allResumedActivitiesVisible();
2143        for (int i=0; i<N; i++) {
2144            ActivityRecord s = mStoppingActivities.get(i);
2145            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
2146                    + nowVisible + " waitingVisible=" + s.waitingVisible
2147                    + " finishing=" + s.finishing);
2148            if (s.waitingVisible && nowVisible) {
2149                mWaitingVisibleActivities.remove(s);
2150                s.waitingVisible = false;
2151                if (s.finishing) {
2152                    // If this activity is finishing, it is sitting on top of
2153                    // everyone else but we now know it is no longer needed...
2154                    // so get rid of it.  Otherwise, we need to go through the
2155                    // normal flow and hide it once we determine that it is
2156                    // hidden by the activities in front of it.
2157                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
2158                    mWindowManager.setAppVisibility(s.appToken, false);
2159                }
2160            }
2161            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
2162                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
2163                if (stops == null) {
2164                    stops = new ArrayList<ActivityRecord>();
2165                }
2166                stops.add(s);
2167                mStoppingActivities.remove(i);
2168                N--;
2169                i--;
2170            }
2171        }
2172
2173        return stops;
2174    }
2175
2176    void validateTopActivitiesLocked() {
2177        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
2178            final ActivityStack stack = mStacks.get(stackNdx);
2179            final ActivityRecord r = stack.topRunningActivityLocked(null);
2180            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
2181            if (isFrontStack(stack)) {
2182                if (r == null) {
2183                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
2184                } else {
2185                    final ActivityRecord pausing = stack.mPausingActivity;
2186                    if (pausing != null && pausing == r) {
2187                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
2188                            " state=" + state);
2189                    }
2190                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
2191                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
2192                                " state=" + state);
2193                    }
2194                }
2195            } else {
2196                final ActivityRecord resumed = stack.mResumedActivity;
2197                if (resumed != null && resumed == r) {
2198                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
2199                        " state=" + state);
2200                }
2201                if (r != null && (state == ActivityState.INITIALIZING
2202                        || state == ActivityState.RESUMED)) {
2203                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
2204                            " state=" + state);
2205                }
2206            }
2207        }
2208    }
2209
2210    private static String stackStateToString(int stackState) {
2211        switch (stackState) {
2212            case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
2213            case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
2214            case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
2215            case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
2216            default: return "Unknown stackState=" + stackState;
2217        }
2218    }
2219
2220    public void dump(PrintWriter pw, String prefix) {
2221        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
2222                pw.println(mDismissKeyguardOnNextActivity);
2223        pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
2224        pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
2225        pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
2226    }
2227
2228    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2229        return getFocusedStack().getDumpActivitiesLocked(name);
2230    }
2231
2232    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
2233            boolean needSep, String prefix) {
2234        if (activity != null) {
2235            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
2236                if (needSep) {
2237                    pw.println();
2238                }
2239                pw.print(prefix);
2240                pw.println(activity);
2241                return true;
2242            }
2243        }
2244        return false;
2245    }
2246
2247    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2248            boolean dumpClient, String dumpPackage) {
2249        boolean printed = false;
2250        boolean needSep = false;
2251        final int numStacks = mStacks.size();
2252        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
2253            final ActivityStack stack = mStacks.get(stackNdx);
2254            StringBuilder stackHeader = new StringBuilder(128);
2255            stackHeader.append("  Stack #");
2256            stackHeader.append(mStacks.indexOf(stack));
2257            stackHeader.append(":");
2258            printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
2259                    stackHeader.toString());
2260            printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false, !dumpAll,
2261                    false, dumpPackage, true, "    Running activities (most recent first):", null);
2262
2263            needSep = printed;
2264            boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
2265                    "    mPausingActivity: ");
2266            if (pr) {
2267                printed = true;
2268                needSep = false;
2269            }
2270            pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
2271                    "    mResumedActivity: ");
2272            if (pr) {
2273                printed = true;
2274                needSep = false;
2275            }
2276            if (dumpAll) {
2277                pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
2278                        "    mLastPausedActivity: ");
2279                if (pr) {
2280                    printed = true;
2281                }
2282            }
2283            needSep = printed;
2284        }
2285
2286        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
2287                false, dumpPackage, true, "  Activities waiting to finish:", null);
2288        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
2289                false, dumpPackage, true, "  Activities waiting to stop:", null);
2290        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
2291                false, dumpPackage, true, "  Activities waiting for another to become visible:",
2292                null);
2293        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2294                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2295        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
2296                false, dumpPackage, true, "  Activities waiting to sleep:", null);
2297
2298        return printed;
2299    }
2300
2301    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
2302            String prefix, String label, boolean complete, boolean brief, boolean client,
2303            String dumpPackage, boolean needNL, String header1, String header2) {
2304        TaskRecord lastTask = null;
2305        String innerPrefix = null;
2306        String[] args = null;
2307        boolean printed = false;
2308        for (int i=list.size()-1; i>=0; i--) {
2309            final ActivityRecord r = list.get(i);
2310            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
2311                continue;
2312            }
2313            if (innerPrefix == null) {
2314                innerPrefix = prefix + "      ";
2315                args = new String[0];
2316            }
2317            printed = true;
2318            final boolean full = !brief && (complete || !r.isInHistory());
2319            if (needNL) {
2320                pw.println("");
2321                needNL = false;
2322            }
2323            if (header1 != null) {
2324                pw.println(header1);
2325                header1 = null;
2326            }
2327            if (header2 != null) {
2328                pw.println(header2);
2329                header2 = null;
2330            }
2331            if (lastTask != r.task) {
2332                lastTask = r.task;
2333                pw.print(prefix);
2334                pw.print(full ? "* " : "  ");
2335                pw.println(lastTask);
2336                if (full) {
2337                    lastTask.dump(pw, prefix + "  ");
2338                } else if (complete) {
2339                    // Complete + brief == give a summary.  Isn't that obvious?!?
2340                    if (lastTask.intent != null) {
2341                        pw.print(prefix); pw.print("  ");
2342                                pw.println(lastTask.intent.toInsecureStringWithClip());
2343                    }
2344                }
2345            }
2346            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
2347            pw.print(" #"); pw.print(i); pw.print(": ");
2348            pw.println(r);
2349            if (full) {
2350                r.dump(pw, innerPrefix);
2351            } else if (complete) {
2352                // Complete + brief == give a summary.  Isn't that obvious?!?
2353                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
2354                if (r.app != null) {
2355                    pw.print(innerPrefix); pw.println(r.app);
2356                }
2357            }
2358            if (client && r.app != null && r.app.thread != null) {
2359                // flush anything that is already in the PrintWriter since the thread is going
2360                // to write to the file descriptor directly
2361                pw.flush();
2362                try {
2363                    TransferPipe tp = new TransferPipe();
2364                    try {
2365                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
2366                                r.appToken, innerPrefix, args);
2367                        // Short timeout, since blocking here can
2368                        // deadlock with the application.
2369                        tp.go(fd, 2000);
2370                    } finally {
2371                        tp.kill();
2372                    }
2373                } catch (IOException e) {
2374                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
2375                } catch (RemoteException e) {
2376                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
2377                }
2378                needNL = true;
2379            }
2380        }
2381        return printed;
2382    }
2383
2384    void scheduleIdleTimeoutLocked(ActivityRecord next) {
2385        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
2386        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
2387        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2388    }
2389
2390    final void scheduleIdleLocked() {
2391        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
2392    }
2393
2394    void removeTimeoutsForActivityLocked(ActivityRecord r) {
2395        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
2396        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
2397    }
2398
2399    final void scheduleResumeTopActivities() {
2400        mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2401    }
2402
2403    void removeSleepTimeouts() {
2404        mSleepTimeout = false;
2405        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
2406    }
2407
2408    final void scheduleSleepTimeout() {
2409        removeSleepTimeouts();
2410        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
2411    }
2412
2413    private final class ActivityStackSupervisorHandler extends Handler {
2414
2415        public ActivityStackSupervisorHandler(Looper looper) {
2416            super(looper);
2417        }
2418
2419        void activityIdleInternal(ActivityRecord r) {
2420            synchronized (mService) {
2421                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
2422            }
2423        }
2424
2425        @Override
2426        public void handleMessage(Message msg) {
2427            switch (msg.what) {
2428                case IDLE_TIMEOUT_MSG: {
2429                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" +
2430                            Debug.getCallers(4));
2431                    if (mService.mDidDexOpt) {
2432                        mService.mDidDexOpt = false;
2433                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2434                        nmsg.obj = msg.obj;
2435                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
2436                        return;
2437                    }
2438                    // We don't at this point know if the activity is fullscreen,
2439                    // so we need to be conservative and assume it isn't.
2440                    activityIdleInternal((ActivityRecord)msg.obj);
2441                } break;
2442                case IDLE_NOW_MSG: {
2443                    activityIdleInternal((ActivityRecord)msg.obj);
2444                } break;
2445                case RESUME_TOP_ACTIVITY_MSG: {
2446                    synchronized (mService) {
2447                        resumeTopActivitiesLocked();
2448                    }
2449                } break;
2450                case SLEEP_TIMEOUT_MSG: {
2451                    synchronized (mService) {
2452                        if (mService.isSleepingOrShuttingDown()) {
2453                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
2454                            mSleepTimeout = true;
2455                            checkReadyForSleepLocked();
2456                        }
2457                    }
2458                } break;
2459            }
2460        }
2461    }
2462
2463    private final class UserState {
2464        final ActivityStack mSavedFocusedStack;
2465        final int mSavedStackState;
2466
2467        public UserState() {
2468            ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2469            mSavedFocusedStack = supervisor.mFocusedStack;
2470            mSavedStackState = supervisor.mStackState;
2471        }
2472
2473        void restore() {
2474            ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
2475            supervisor.mFocusedStack = mSavedFocusedStack;
2476            if (DEBUG_STACK) Slog.d(TAG, "UserState.restore: mStackState old=" +
2477                    stackStateToString(mSavedStackState));
2478            supervisor.mStackState = mSavedStackState;
2479        }
2480    }
2481}
2482