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