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