1/*
2 * Copyright (C) 2010 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.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
20
21import static com.android.server.am.ActivityManagerDebugConfig.*;
22
23import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
24import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
25
26import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
27
28import android.util.ArraySet;
29import com.android.internal.app.IVoiceInteractor;
30import com.android.internal.content.ReferrerIntent;
31import com.android.internal.os.BatteryStatsImpl;
32import com.android.server.Watchdog;
33import com.android.server.am.ActivityManagerService.ItemMatcher;
34import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
35import com.android.server.wm.AppTransition;
36import com.android.server.wm.TaskGroup;
37import com.android.server.wm.WindowManagerService;
38
39import android.app.Activity;
40import android.app.ActivityManager;
41import android.app.ActivityOptions;
42import android.app.AppGlobals;
43import android.app.IActivityController;
44import android.app.ResultInfo;
45import android.app.ActivityManager.RunningTaskInfo;
46import android.content.ComponentName;
47import android.content.Intent;
48import android.content.pm.ActivityInfo;
49import android.content.pm.PackageManager;
50import android.content.res.Configuration;
51import android.graphics.Bitmap;
52import android.net.Uri;
53import android.os.Binder;
54import android.os.Bundle;
55import android.os.Debug;
56import android.os.Handler;
57import android.os.IBinder;
58import android.os.Looper;
59import android.os.Message;
60import android.os.PersistableBundle;
61import android.os.RemoteException;
62import android.os.SystemClock;
63import android.os.Trace;
64import android.os.UserHandle;
65import android.service.voice.IVoiceInteractionSession;
66import android.util.EventLog;
67import android.util.Slog;
68import android.view.Display;
69
70import java.io.FileDescriptor;
71import java.io.PrintWriter;
72import java.lang.ref.WeakReference;
73import java.util.ArrayList;
74import java.util.Iterator;
75import java.util.List;
76import java.util.Objects;
77import java.util.Set;
78
79/**
80 * State and management of a single stack of activities.
81 */
82final class ActivityStack {
83
84    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM;
85    private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
86    private static final String TAG_APP = TAG + POSTFIX_APP;
87    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
88    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
89    private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
90    private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
91    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
92    private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
93    private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
94    private static final String TAG_SCREENSHOTS = TAG + POSTFIX_SCREENSHOTS;
95    private static final String TAG_STACK = TAG + POSTFIX_STACK;
96    private static final String TAG_STATES = TAG + POSTFIX_STATES;
97    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
98    private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
99    private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
100    private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
101    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
102
103    private static final boolean VALIDATE_TOKENS = false;
104
105    // Ticks during which we check progress while waiting for an app to launch.
106    static final int LAUNCH_TICK = 500;
107
108    // How long we wait until giving up on the last activity to pause.  This
109    // is short because it directly impacts the responsiveness of starting the
110    // next activity.
111    static final int PAUSE_TIMEOUT = 500;
112
113    // How long we wait for the activity to tell us it has stopped before
114    // giving up.  This is a good amount of time because we really need this
115    // from the application in order to get its saved state.
116    static final int STOP_TIMEOUT = 10*1000;
117
118    // How long we wait until giving up on an activity telling us it has
119    // finished destroying itself.
120    static final int DESTROY_TIMEOUT = 10*1000;
121
122    // How long until we reset a task when the user returns to it.  Currently
123    // disabled.
124    static final long ACTIVITY_INACTIVE_RESET_TIME = 0;
125
126    // How long between activity launches that we consider safe to not warn
127    // the user about an unexpected activity being launched on top.
128    static final long START_WARN_TIME = 5*1000;
129
130    // Set to false to disable the preview that is shown while a new activity
131    // is being started.
132    static final boolean SHOW_APP_STARTING_PREVIEW = true;
133
134    // How long to wait for all background Activities to redraw following a call to
135    // convertToTranslucent().
136    static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
137
138    enum ActivityState {
139        INITIALIZING,
140        RESUMED,
141        PAUSING,
142        PAUSED,
143        STOPPING,
144        STOPPED,
145        FINISHING,
146        DESTROYING,
147        DESTROYED
148    }
149
150    final ActivityManagerService mService;
151    final WindowManagerService mWindowManager;
152    private final RecentTasks mRecentTasks;
153
154    /**
155     * The back history of all previous (and possibly still
156     * running) activities.  It contains #TaskRecord objects.
157     */
158    private ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
159
160    /**
161     * Used for validating app tokens with window manager.
162     */
163    final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<>();
164
165    /**
166     * List of running activities, sorted by recent usage.
167     * The first entry in the list is the least recently used.
168     * It contains HistoryRecord objects.
169     */
170    final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
171
172    /**
173     * Animations that for the current transition have requested not to
174     * be considered for the transition animation.
175     */
176    final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>();
177
178    /**
179     * When we are in the process of pausing an activity, before starting the
180     * next one, this variable holds the activity that is currently being paused.
181     */
182    ActivityRecord mPausingActivity = null;
183
184    /**
185     * This is the last activity that we put into the paused state.  This is
186     * used to determine if we need to do an activity transition while sleeping,
187     * when we normally hold the top activity paused.
188     */
189    ActivityRecord mLastPausedActivity = null;
190
191    /**
192     * Activities that specify No History must be removed once the user navigates away from them.
193     * If the device goes to sleep with such an activity in the paused state then we save it here
194     * and finish it later if another activity replaces it on wakeup.
195     */
196    ActivityRecord mLastNoHistoryActivity = null;
197
198    /**
199     * Current activity that is resumed, or null if there is none.
200     */
201    ActivityRecord mResumedActivity = null;
202
203    /**
204     * This is the last activity that has been started.  It is only used to
205     * identify when multiple activities are started at once so that the user
206     * can be warned they may not be in the activity they think they are.
207     */
208    ActivityRecord mLastStartedActivity = null;
209
210    // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
211    // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
212    // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
213    // Activity in mTranslucentActivityWaiting is notified via
214    // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
215    // background activity being drawn then the same call will be made with a true value.
216    ActivityRecord mTranslucentActivityWaiting = null;
217    private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
218            new ArrayList<ActivityRecord>();
219
220    /**
221     * Set when we know we are going to be calling updateConfiguration()
222     * soon, so want to skip intermediate config checks.
223     */
224    boolean mConfigWillChange;
225
226    // Whether or not this stack covers the entire screen; by default stacks are full screen
227    boolean mFullscreen = true;
228
229    long mLaunchStartTime = 0;
230    long mFullyDrawnStartTime = 0;
231
232    int mCurrentUser;
233
234    final int mStackId;
235    final ActivityContainer mActivityContainer;
236    /** The other stacks, in order, on the attached display. Updated at attach/detach time. */
237    ArrayList<ActivityStack> mStacks;
238    /** The attached Display's unique identifier, or -1 if detached */
239    int mDisplayId;
240
241    /** Run all ActivityStacks through this */
242    final ActivityStackSupervisor mStackSupervisor;
243
244    Configuration mOverrideConfig;
245    /** True if the stack was forced to full screen because {@link TaskRecord#mResizeable} is false
246     * and the stack was previously resized. */
247    private boolean mForcedFullscreen = false;
248
249    static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
250    static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
251    static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
252    static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
253    static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
254    static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
255    static final int RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG =
256            ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7;
257
258    static class ScheduleDestroyArgs {
259        final ProcessRecord mOwner;
260        final String mReason;
261        ScheduleDestroyArgs(ProcessRecord owner, String reason) {
262            mOwner = owner;
263            mReason = reason;
264        }
265    }
266
267    final Handler mHandler;
268
269    final class ActivityStackHandler extends Handler {
270
271        ActivityStackHandler(Looper looper) {
272            super(looper);
273        }
274
275        @Override
276        public void handleMessage(Message msg) {
277            switch (msg.what) {
278                case PAUSE_TIMEOUT_MSG: {
279                    ActivityRecord r = (ActivityRecord)msg.obj;
280                    // We don't at this point know if the activity is fullscreen,
281                    // so we need to be conservative and assume it isn't.
282                    Slog.w(TAG, "Activity pause timeout for " + r);
283                    synchronized (mService) {
284                        if (r.app != null) {
285                            mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
286                        }
287                        activityPausedLocked(r.appToken, true);
288                    }
289                } break;
290                case LAUNCH_TICK_MSG: {
291                    ActivityRecord r = (ActivityRecord)msg.obj;
292                    synchronized (mService) {
293                        if (r.continueLaunchTickingLocked()) {
294                            mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
295                        }
296                    }
297                } break;
298                case DESTROY_TIMEOUT_MSG: {
299                    ActivityRecord r = (ActivityRecord)msg.obj;
300                    // We don't at this point know if the activity is fullscreen,
301                    // so we need to be conservative and assume it isn't.
302                    Slog.w(TAG, "Activity destroy timeout for " + r);
303                    synchronized (mService) {
304                        activityDestroyedLocked(r != null ? r.appToken : null, "destroyTimeout");
305                    }
306                } break;
307                case STOP_TIMEOUT_MSG: {
308                    ActivityRecord r = (ActivityRecord)msg.obj;
309                    // We don't at this point know if the activity is fullscreen,
310                    // so we need to be conservative and assume it isn't.
311                    Slog.w(TAG, "Activity stop timeout for " + r);
312                    synchronized (mService) {
313                        if (r.isInHistory()) {
314                            activityStoppedLocked(r, null, null, null);
315                        }
316                    }
317                } break;
318                case DESTROY_ACTIVITIES_MSG: {
319                    ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj;
320                    synchronized (mService) {
321                        destroyActivitiesLocked(args.mOwner, args.mReason);
322                    }
323                } break;
324                case TRANSLUCENT_TIMEOUT_MSG: {
325                    synchronized (mService) {
326                        notifyActivityDrawnLocked(null);
327                    }
328                } break;
329                case RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG: {
330                    synchronized (mService) {
331                        final ActivityRecord r = getVisibleBehindActivity();
332                        Slog.e(TAG, "Timeout waiting for cancelVisibleBehind player=" + r);
333                        if (r != null) {
334                            mService.killAppAtUsersRequest(r.app, null);
335                        }
336                    }
337                } break;
338            }
339        }
340    }
341
342    int numActivities() {
343        int count = 0;
344        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
345            count += mTaskHistory.get(taskNdx).mActivities.size();
346        }
347        return count;
348    }
349
350    int numTasks() {
351        return mTaskHistory.size();
352    }
353
354    ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer,
355            RecentTasks recentTasks) {
356        mActivityContainer = activityContainer;
357        mStackSupervisor = activityContainer.getOuter();
358        mService = mStackSupervisor.mService;
359        mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
360        mWindowManager = mService.mWindowManager;
361        mStackId = activityContainer.mStackId;
362        mCurrentUser = mService.mCurrentUserId;
363        mRecentTasks = recentTasks;
364        mOverrideConfig = Configuration.EMPTY;
365    }
366
367    boolean okToShowLocked(ActivityRecord r) {
368        return mStackSupervisor.isCurrentProfileLocked(r.userId)
369                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0;
370    }
371
372    final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
373        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
374            ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked(notTop);
375            if (r != null) {
376                return r;
377            }
378        }
379        return null;
380    }
381
382    final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
383        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
384            final TaskRecord task = mTaskHistory.get(taskNdx);
385            final ArrayList<ActivityRecord> activities = task.mActivities;
386            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
387                ActivityRecord r = activities.get(activityNdx);
388                if (!r.finishing && !r.delayedResume && r != notTop && okToShowLocked(r)) {
389                    return r;
390                }
391            }
392        }
393        return null;
394    }
395
396    /**
397     * This is a simplified version of topRunningActivityLocked that provides a number of
398     * optional skip-over modes.  It is intended for use with the ActivityController hook only.
399     *
400     * @param token If non-null, any history records matching this token will be skipped.
401     * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
402     *
403     * @return Returns the HistoryRecord of the next activity on the stack.
404     */
405    final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
406        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
407            TaskRecord task = mTaskHistory.get(taskNdx);
408            if (task.taskId == taskId) {
409                continue;
410            }
411            ArrayList<ActivityRecord> activities = task.mActivities;
412            for (int i = activities.size() - 1; i >= 0; --i) {
413                final ActivityRecord r = activities.get(i);
414                // Note: the taskId check depends on real taskId fields being non-zero
415                if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) {
416                    return r;
417                }
418            }
419        }
420        return null;
421    }
422
423    final ActivityRecord topActivity() {
424        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
425            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
426            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
427                final ActivityRecord r = activities.get(activityNdx);
428                if (!r.finishing) {
429                    return r;
430                }
431            }
432        }
433        return null;
434    }
435
436    final TaskRecord topTask() {
437        final int size = mTaskHistory.size();
438        if (size > 0) {
439            return mTaskHistory.get(size - 1);
440        }
441        return null;
442    }
443
444    TaskRecord taskForIdLocked(int id) {
445        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
446            final TaskRecord task = mTaskHistory.get(taskNdx);
447            if (task.taskId == id) {
448                return task;
449            }
450        }
451        return null;
452    }
453
454    ActivityRecord isInStackLocked(IBinder token) {
455        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
456        return isInStackLocked(r);
457    }
458
459    ActivityRecord isInStackLocked(ActivityRecord r) {
460        if (r == null) {
461            return null;
462        }
463        final TaskRecord task = r.task;
464        if (task != null && task.stack != null
465                && task.mActivities.contains(r) && mTaskHistory.contains(task)) {
466            if (task.stack != this) Slog.w(TAG,
467                    "Illegal state! task does not point to stack it is in.");
468            return r;
469        }
470        return null;
471    }
472
473    final boolean updateLRUListLocked(ActivityRecord r) {
474        final boolean hadit = mLRUActivities.remove(r);
475        mLRUActivities.add(r);
476        return hadit;
477    }
478
479    final boolean isHomeStack() {
480        return mStackId == HOME_STACK_ID;
481    }
482
483    final boolean isOnHomeDisplay() {
484        return isAttached() &&
485                mActivityContainer.mActivityDisplay.mDisplayId == Display.DEFAULT_DISPLAY;
486    }
487
488    final void moveToFront(String reason) {
489        if (isAttached()) {
490            final boolean homeStack = isHomeStack()
491                    || (mActivityContainer.mParentActivity != null
492                        && mActivityContainer.mParentActivity.isHomeActivity());
493            ActivityStack lastFocusStack = null;
494            if (!homeStack) {
495                // Need to move this stack to the front before calling
496                // {@link ActivityStackSupervisor#moveHomeStack} below.
497                lastFocusStack = mStacks.get(mStacks.size() - 1);
498                mStacks.remove(this);
499                mStacks.add(this);
500            }
501            // TODO(multi-display): Focus stack currently adjusted in call to move home stack.
502            // Needs to also work if focus is moving to the non-home display.
503            if (isOnHomeDisplay()) {
504                mStackSupervisor.moveHomeStack(homeStack, reason, lastFocusStack);
505            }
506            final TaskRecord task = topTask();
507            if (task != null) {
508                mWindowManager.moveTaskToTop(task.taskId);
509            }
510        }
511    }
512
513    final boolean isAttached() {
514        return mStacks != null;
515    }
516
517    /**
518     * Returns the top activity in any existing task matching the given
519     * Intent.  Returns null if no such task is found.
520     */
521    ActivityRecord findTaskLocked(ActivityRecord target) {
522        Intent intent = target.intent;
523        ActivityInfo info = target.info;
524        ComponentName cls = intent.getComponent();
525        if (info.targetActivity != null) {
526            cls = new ComponentName(info.packageName, info.targetActivity);
527        }
528        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
529        boolean isDocument = intent != null & intent.isDocument();
530        // If documentData is non-null then it must match the existing task data.
531        Uri documentData = isDocument ? intent.getData() : null;
532
533        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + this);
534        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
535            final TaskRecord task = mTaskHistory.get(taskNdx);
536            if (task.voiceSession != null) {
537                // We never match voice sessions; those always run independently.
538                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
539                continue;
540            }
541            if (task.userId != userId) {
542                // Looking for a different task.
543                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
544                continue;
545            }
546            final ActivityRecord r = task.getTopActivity();
547            if (r == null || r.finishing || r.userId != userId ||
548                    r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
549                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
550                continue;
551            }
552
553            final Intent taskIntent = task.intent;
554            final Intent affinityIntent = task.affinityIntent;
555            final boolean taskIsDocument;
556            final Uri taskDocumentData;
557            if (taskIntent != null && taskIntent.isDocument()) {
558                taskIsDocument = true;
559                taskDocumentData = taskIntent.getData();
560            } else if (affinityIntent != null && affinityIntent.isDocument()) {
561                taskIsDocument = true;
562                taskDocumentData = affinityIntent.getData();
563            } else {
564                taskIsDocument = false;
565                taskDocumentData = null;
566            }
567
568            if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
569                    + taskIntent.getComponent().flattenToShortString()
570                    + "/aff=" + r.task.rootAffinity + " to new cls="
571                    + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
572            if (!isDocument && !taskIsDocument && task.rootAffinity != null) {
573                if (task.rootAffinity.equals(target.taskAffinity)) {
574                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity!");
575                    return r;
576                }
577            } else if (taskIntent != null && taskIntent.getComponent() != null &&
578                    taskIntent.getComponent().compareTo(cls) == 0 &&
579                    Objects.equals(documentData, taskDocumentData)) {
580                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
581                //dump();
582                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
583                        "For Intent " + intent + " bringing to top: " + r.intent);
584                return r;
585            } else if (affinityIntent != null && affinityIntent.getComponent() != null &&
586                    affinityIntent.getComponent().compareTo(cls) == 0 &&
587                    Objects.equals(documentData, taskDocumentData)) {
588                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
589                //dump();
590                if (DEBUG_TASKS) Slog.d(TAG_TASKS,
591                        "For Intent " + intent + " bringing to top: " + r.intent);
592                return r;
593            } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task);
594        }
595
596        return null;
597    }
598
599    /**
600     * Returns the first activity (starting from the top of the stack) that
601     * is the same as the given activity.  Returns null if no such activity
602     * is found.
603     */
604    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
605        ComponentName cls = intent.getComponent();
606        if (info.targetActivity != null) {
607            cls = new ComponentName(info.packageName, info.targetActivity);
608        }
609        final int userId = UserHandle.getUserId(info.applicationInfo.uid);
610
611        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
612            final TaskRecord task = mTaskHistory.get(taskNdx);
613            final boolean notCurrentUserTask =
614                    !mStackSupervisor.isCurrentProfileLocked(task.userId);
615            final ArrayList<ActivityRecord> activities = task.mActivities;
616
617            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
618                ActivityRecord r = activities.get(activityNdx);
619                if (notCurrentUserTask && (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
620                    continue;
621                }
622                if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
623                    return r;
624                }
625            }
626        }
627
628        return null;
629    }
630
631    /*
632     * Move the activities around in the stack to bring a user to the foreground.
633     */
634    final void switchUserLocked(int userId) {
635        if (mCurrentUser == userId) {
636            return;
637        }
638        mCurrentUser = userId;
639
640        // Move userId's tasks to the top.
641        int index = mTaskHistory.size();
642        for (int i = 0; i < index; ) {
643            final TaskRecord task = mTaskHistory.get(i);
644
645            // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is
646            // okay to show the activity when locked.
647            if (mStackSupervisor.isCurrentProfileLocked(task.userId)
648                    || task.topRunningActivityLocked(null) != null) {
649                if (DEBUG_TASKS) Slog.d(TAG_TASKS, "switchUserLocked: stack=" + getStackId() +
650                        " moving " + task + " to top");
651                mTaskHistory.remove(i);
652                mTaskHistory.add(task);
653                --index;
654                // Use same value for i.
655            } else {
656                ++i;
657            }
658        }
659        if (VALIDATE_TOKENS) {
660            validateAppTokensLocked();
661        }
662    }
663
664    void minimalResumeActivityLocked(ActivityRecord r) {
665        r.state = ActivityState.RESUMED;
666        if (DEBUG_STATES) Slog.v(TAG_STATES,
667                "Moving to RESUMED: " + r + " (starting new instance)");
668        r.stopped = false;
669        mResumedActivity = r;
670        r.task.touchActiveTime();
671        mRecentTasks.addLocked(r.task);
672        completeResumeLocked(r);
673        mStackSupervisor.checkReadyForSleepLocked();
674        setLaunchTime(r);
675        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
676                "Launch completed; removing icicle of " + r.icicle);
677    }
678
679    private void startLaunchTraces(String packageName) {
680        if (mFullyDrawnStartTime != 0)  {
681            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
682        }
683        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
684        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
685    }
686
687    private void stopFullyDrawnTraceIfNeeded() {
688        if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
689            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
690            mFullyDrawnStartTime = 0;
691        }
692    }
693
694    void setLaunchTime(ActivityRecord r) {
695        if (r.displayStartTime == 0) {
696            r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
697            if (mLaunchStartTime == 0) {
698                startLaunchTraces(r.packageName);
699                mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
700            }
701        } else if (mLaunchStartTime == 0) {
702            startLaunchTraces(r.packageName);
703            mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
704        }
705    }
706
707    void clearLaunchTime(ActivityRecord r) {
708        // Make sure that there is no activity waiting for this to launch.
709        if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
710            r.displayStartTime = r.fullyDrawnStartTime = 0;
711        } else {
712            mStackSupervisor.removeTimeoutsForActivityLocked(r);
713            mStackSupervisor.scheduleIdleTimeoutLocked(r);
714        }
715    }
716
717    void awakeFromSleepingLocked() {
718        // Ensure activities are no longer sleeping.
719        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
720            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
721            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
722                activities.get(activityNdx).setSleeping(false);
723            }
724        }
725        if (mPausingActivity != null) {
726            Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
727            activityPausedLocked(mPausingActivity.appToken, true);
728        }
729    }
730
731    /**
732     * @return true if something must be done before going to sleep.
733     */
734    boolean checkReadyForSleepLocked() {
735        if (mResumedActivity != null) {
736            // Still have something resumed; can't sleep until it is paused.
737            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
738            if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
739                    "Sleep => pause with userLeaving=false");
740            startPausingLocked(false, true, false, false);
741            return true;
742        }
743        if (mPausingActivity != null) {
744            // Still waiting for something to pause; can't sleep yet.
745            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
746            return true;
747        }
748
749        if (hasVisibleBehindActivity()) {
750            // Stop visible behind activity before going to sleep.
751            final ActivityRecord r = mActivityContainer.mActivityDisplay.mVisibleBehindActivity;
752            mStackSupervisor.mStoppingActivities.add(r);
753            if (DEBUG_STATES) Slog.v(TAG_STATES,
754                    "Sleep still waiting to stop visible behind " + r);
755            return true;
756        }
757
758        return false;
759    }
760
761    void goToSleep() {
762        ensureActivitiesVisibleLocked(null, 0);
763
764        // Make sure any stopped but visible activities are now sleeping.
765        // This ensures that the activity's onStop() is called.
766        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
767            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
768            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
769                final ActivityRecord r = activities.get(activityNdx);
770                if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) {
771                    r.setSleeping(true);
772                }
773            }
774        }
775    }
776
777    public final Bitmap screenshotActivities(ActivityRecord who) {
778        if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "screenshotActivities: " + who);
779        if (who.noDisplay) {
780            if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tNo display");
781            return null;
782        }
783
784        if (isHomeStack()) {
785            // This is an optimization -- since we never show Home or Recents within Recents itself,
786            // we can just go ahead and skip taking the screenshot if this is the home stack.
787            if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tHome stack");
788            return null;
789        }
790
791        int w = mService.mThumbnailWidth;
792        int h = mService.mThumbnailHeight;
793        if (w > 0) {
794            if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tTaking screenshot");
795            return mWindowManager.screenshotApplications(who.appToken, Display.DEFAULT_DISPLAY,
796                    w, h);
797        }
798        Slog.e(TAG, "Invalid thumbnail dimensions: " + w + "x" + h);
799        return null;
800    }
801
802    /**
803     * Start pausing the currently resumed activity.  It is an error to call this if there
804     * is already an activity being paused or there is no resumed activity.
805     *
806     * @param userLeaving True if this should result in an onUserLeaving to the current activity.
807     * @param uiSleeping True if this is happening with the user interface going to sleep (the
808     * screen turning off).
809     * @param resuming True if this is being called as part of resuming the top activity, so
810     * we shouldn't try to instigate a resume here.
811     * @param dontWait True if the caller does not want to wait for the pause to complete.  If
812     * set to true, we will immediately complete the pause here before returning.
813     * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
814     * it to tell us when it is done.
815     */
816    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
817            boolean dontWait) {
818        if (mPausingActivity != null) {
819            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
820                    + " state=" + mPausingActivity.state);
821            if (!mService.isSleeping()) {
822                // Avoid recursion among check for sleep and complete pause during sleeping.
823                // Because activity will be paused immediately after resume, just let pause
824                // be completed by the order of activity paused from clients.
825                completePauseLocked(false);
826            }
827        }
828        ActivityRecord prev = mResumedActivity;
829        if (prev == null) {
830            if (!resuming) {
831                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
832                mStackSupervisor.resumeTopActivitiesLocked();
833            }
834            return false;
835        }
836
837        if (mActivityContainer.mParentActivity == null) {
838            // Top level stack, not a child. Look for child stacks.
839            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
840        }
841
842        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
843        else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
844        mResumedActivity = null;
845        mPausingActivity = prev;
846        mLastPausedActivity = prev;
847        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
848                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
849        prev.state = ActivityState.PAUSING;
850        prev.task.touchActiveTime();
851        clearLaunchTime(prev);
852        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
853        if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
854            prev.updateThumbnailLocked(screenshotActivities(prev), null);
855        }
856        stopFullyDrawnTraceIfNeeded();
857
858        mService.updateCpuStats();
859
860        if (prev.app != null && prev.app.thread != null) {
861            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
862            try {
863                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
864                        prev.userId, System.identityHashCode(prev),
865                        prev.shortComponentName);
866                mService.updateUsageStats(prev, false);
867                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
868                        userLeaving, prev.configChangeFlags, dontWait);
869            } catch (Exception e) {
870                // Ignore exception, if process died other code will cleanup.
871                Slog.w(TAG, "Exception thrown during pause", e);
872                mPausingActivity = null;
873                mLastPausedActivity = null;
874                mLastNoHistoryActivity = null;
875            }
876        } else {
877            mPausingActivity = null;
878            mLastPausedActivity = null;
879            mLastNoHistoryActivity = null;
880        }
881
882        // If we are not going to sleep, we want to ensure the device is
883        // awake until the next activity is started.
884        if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
885            mStackSupervisor.acquireLaunchWakelock();
886        }
887
888        if (mPausingActivity != null) {
889            // Have the window manager pause its key dispatching until the new
890            // activity has started.  If we're pausing the activity just because
891            // the screen is being turned off and the UI is sleeping, don't interrupt
892            // key dispatch; the same activity will pick it up again on wakeup.
893            if (!uiSleeping) {
894                prev.pauseKeyDispatchingLocked();
895            } else if (DEBUG_PAUSE) {
896                 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
897            }
898
899            if (dontWait) {
900                // If the caller said they don't want to wait for the pause, then complete
901                // the pause now.
902                completePauseLocked(false);
903                return false;
904
905            } else {
906                // Schedule a pause timeout in case the app doesn't respond.
907                // We don't give it much time because this directly impacts the
908                // responsiveness seen by the user.
909                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
910                msg.obj = prev;
911                prev.pauseTime = SystemClock.uptimeMillis();
912                mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
913                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
914                return true;
915            }
916
917        } else {
918            // This activity failed to schedule the
919            // pause, so just treat it as being paused now.
920            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
921            if (!resuming) {
922                mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
923            }
924            return false;
925        }
926    }
927
928    final void activityPausedLocked(IBinder token, boolean timeout) {
929        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
930            "Activity paused: token=" + token + ", timeout=" + timeout);
931
932        final ActivityRecord r = isInStackLocked(token);
933        if (r != null) {
934            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
935            if (mPausingActivity == r) {
936                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
937                        + (timeout ? " (due to timeout)" : " (pause complete)"));
938                completePauseLocked(true);
939            } else {
940                EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
941                        r.userId, System.identityHashCode(r), r.shortComponentName,
942                        mPausingActivity != null
943                            ? mPausingActivity.shortComponentName : "(none)");
944                if (r.finishing && r.state == ActivityState.PAUSING) {
945                    if (DEBUG_PAUSE) Slog.v(TAG,
946                            "Executing finish of failed to pause activity: " + r);
947                    finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
948                }
949            }
950        }
951    }
952
953    final void activityStoppedLocked(ActivityRecord r, Bundle icicle,
954            PersistableBundle persistentState, CharSequence description) {
955        if (r.state != ActivityState.STOPPING) {
956            Slog.i(TAG, "Activity reported stop, but no longer stopping: " + r);
957            mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
958            return;
959        }
960        if (persistentState != null) {
961            r.persistentState = persistentState;
962            mService.notifyTaskPersisterLocked(r.task, false);
963        }
964        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + r + ": " + icicle);
965        if (icicle != null) {
966            // If icicle is null, this is happening due to a timeout, so we
967            // haven't really saved the state.
968            r.icicle = icicle;
969            r.haveState = true;
970            r.launchCount = 0;
971            r.updateThumbnailLocked(null, description);
972        }
973        if (!r.stopped) {
974            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + r + " (stop complete)");
975            mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
976            r.stopped = true;
977            r.state = ActivityState.STOPPED;
978            if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == r) {
979                mStackSupervisor.requestVisibleBehindLocked(r, false);
980            }
981            if (r.finishing) {
982                r.clearOptionsLocked();
983            } else {
984                if (r.configDestroy) {
985                    destroyActivityLocked(r, true, "stop-config");
986                    mStackSupervisor.resumeTopActivitiesLocked();
987                } else {
988                    mStackSupervisor.updatePreviousProcessLocked(r);
989                }
990            }
991        }
992    }
993
994    private void completePauseLocked(boolean resumeNext) {
995        ActivityRecord prev = mPausingActivity;
996        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
997
998        if (prev != null) {
999            prev.state = ActivityState.PAUSED;
1000            if (prev.finishing) {
1001                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
1002                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
1003            } else if (prev.app != null) {
1004                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending stop: " + prev);
1005                if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
1006                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
1007                            "Complete pause, no longer waiting: " + prev);
1008                }
1009                if (prev.configDestroy) {
1010                    // The previous is being paused because the configuration
1011                    // is changing, which means it is actually stopping...
1012                    // To juggle the fact that we are also starting a new
1013                    // instance right now, we need to first completely stop
1014                    // the current instance before starting the new one.
1015                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev);
1016                    destroyActivityLocked(prev, true, "pause-config");
1017                } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
1018                    // If we were visible then resumeTopActivities will release resources before
1019                    // stopping.
1020                    mStackSupervisor.mStoppingActivities.add(prev);
1021                    if (mStackSupervisor.mStoppingActivities.size() > 3 ||
1022                            prev.frontOfTask && mTaskHistory.size() <= 1) {
1023                        // If we already have a few activities waiting to stop,
1024                        // then give up on things going idle and start clearing
1025                        // them out. Or if r is the last of activity of the last task the stack
1026                        // will be empty and must be cleared immediately.
1027                        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "To many pending stops, forcing idle");
1028                        mStackSupervisor.scheduleIdleLocked();
1029                    } else {
1030                        mStackSupervisor.checkReadyForSleepLocked();
1031                    }
1032                }
1033            } else {
1034                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
1035                prev = null;
1036            }
1037            // It is possible the activity was freezing the screen before it was paused.
1038            // In that case go ahead and remove the freeze this activity has on the screen
1039            // since it is no longer visible.
1040            prev.stopFreezingScreenLocked(true /*force*/);
1041            mPausingActivity = null;
1042        }
1043
1044        if (resumeNext) {
1045            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
1046            if (!mService.isSleepingOrShuttingDown()) {
1047                mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
1048            } else {
1049                mStackSupervisor.checkReadyForSleepLocked();
1050                ActivityRecord top = topStack.topRunningActivityLocked(null);
1051                if (top == null || (prev != null && top != prev)) {
1052                    // If there are no more activities available to run,
1053                    // do resume anyway to start something.  Also if the top
1054                    // activity on the stack is not the just paused activity,
1055                    // we need to go ahead and resume it to ensure we complete
1056                    // an in-flight app switch.
1057                    mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
1058                }
1059            }
1060        }
1061
1062        if (prev != null) {
1063            prev.resumeKeyDispatchingLocked();
1064
1065            if (prev.app != null && prev.cpuTimeAtResume > 0
1066                    && mService.mBatteryStatsService.isOnBattery()) {
1067                long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
1068                        - prev.cpuTimeAtResume;
1069                if (diff > 0) {
1070                    BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
1071                    synchronized (bsi) {
1072                        BatteryStatsImpl.Uid.Proc ps =
1073                                bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
1074                                        prev.info.packageName);
1075                        if (ps != null) {
1076                            ps.addForegroundTimeLocked(diff);
1077                        }
1078                    }
1079                }
1080            }
1081            prev.cpuTimeAtResume = 0; // reset it
1082        }
1083
1084        // Notfiy when the task stack has changed
1085        mService.notifyTaskStackChangedLocked();
1086    }
1087
1088    /**
1089     * Once we know that we have asked an application to put an activity in
1090     * the resumed state (either by launching it or explicitly telling it),
1091     * this function updates the rest of our state to match that fact.
1092     */
1093    private void completeResumeLocked(ActivityRecord next) {
1094        next.idle = false;
1095        next.results = null;
1096        next.newIntents = null;
1097
1098        if (next.isHomeActivity() && next.isNotResolverActivity()) {
1099            ProcessRecord app = next.task.mActivities.get(0).app;
1100            if (app != null && app != mService.mHomeProcess) {
1101                mService.mHomeProcess = app;
1102            }
1103        }
1104
1105        if (next.nowVisible) {
1106            // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
1107            mStackSupervisor.notifyActivityDrawnForKeyguard();
1108        }
1109
1110        // schedule an idle timeout in case the app doesn't do it for us.
1111        mStackSupervisor.scheduleIdleTimeoutLocked(next);
1112
1113        mStackSupervisor.reportResumedActivityLocked(next);
1114
1115        next.resumeKeyDispatchingLocked();
1116        mNoAnimActivities.clear();
1117
1118        // Mark the point when the activity is resuming
1119        // TODO: To be more accurate, the mark should be before the onCreate,
1120        //       not after the onResume. But for subsequent starts, onResume is fine.
1121        if (next.app != null) {
1122            next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid);
1123        } else {
1124            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
1125        }
1126
1127        next.returningOptions = null;
1128
1129        if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == next) {
1130            // When resuming an activity, require it to call requestVisibleBehind() again.
1131            mActivityContainer.mActivityDisplay.setVisibleBehindActivity(null);
1132        }
1133    }
1134
1135    private void setVisible(ActivityRecord r, boolean visible) {
1136        r.visible = visible;
1137        mWindowManager.setAppVisibility(r.appToken, visible);
1138        final ArrayList<ActivityContainer> containers = r.mChildContainers;
1139        for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
1140            ActivityContainer container = containers.get(containerNdx);
1141            container.setVisible(visible);
1142        }
1143    }
1144
1145    // Find the first visible activity above the passed activity and if it is translucent return it
1146    // otherwise return null;
1147    ActivityRecord findNextTranslucentActivity(ActivityRecord r) {
1148        TaskRecord task = r.task;
1149        if (task == null) {
1150            return null;
1151        }
1152
1153        ActivityStack stack = task.stack;
1154        if (stack == null) {
1155            return null;
1156        }
1157
1158        int stackNdx = mStacks.indexOf(stack);
1159
1160        ArrayList<TaskRecord> tasks = stack.mTaskHistory;
1161        int taskNdx = tasks.indexOf(task);
1162
1163        ArrayList<ActivityRecord> activities = task.mActivities;
1164        int activityNdx = activities.indexOf(r) + 1;
1165
1166        final int numStacks = mStacks.size();
1167        while (stackNdx < numStacks) {
1168            ActivityStack historyStack = mStacks.get(stackNdx);
1169            tasks = historyStack.mTaskHistory;
1170            final int numTasks = tasks.size();
1171            while (taskNdx < numTasks) {
1172                activities = tasks.get(taskNdx).mActivities;
1173                final int numActivities = activities.size();
1174                while (activityNdx < numActivities) {
1175                    final ActivityRecord activity = activities.get(activityNdx);
1176                    if (!activity.finishing) {
1177                        return historyStack.mFullscreen && activity.fullscreen ? null : activity;
1178                    }
1179                    ++activityNdx;
1180                }
1181                activityNdx = 0;
1182                ++taskNdx;
1183            }
1184            taskNdx = 0;
1185            ++stackNdx;
1186        }
1187
1188        return null;
1189    }
1190
1191    private ActivityStack getNextVisibleStackLocked() {
1192        ArrayList<ActivityStack> stacks = mStacks;
1193        final ActivityRecord parent = mActivityContainer.mParentActivity;
1194        if (parent != null) {
1195            stacks = parent.task.stack.mStacks;
1196        }
1197        if (stacks != null) {
1198            for (int i = stacks.size() - 1; i >= 0; --i) {
1199                ActivityStack stack = stacks.get(i);
1200                if (stack != this && stack.isStackVisibleLocked()) {
1201                    return stack;
1202                }
1203            }
1204        }
1205        return null;
1206    }
1207
1208    // Checks if any of the stacks above this one has a fullscreen activity behind it.
1209    // If so, this stack is hidden, otherwise it is visible.
1210    private boolean isStackVisibleLocked() {
1211        if (!isAttached()) {
1212            return false;
1213        }
1214
1215        if (mStackSupervisor.isFrontStack(this)) {
1216            return true;
1217        }
1218
1219        /**
1220         * Start at the task above this one and go up, looking for a visible
1221         * fullscreen activity, or a translucent activity that requested the
1222         * wallpaper to be shown behind it.
1223         */
1224        for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
1225            ActivityStack stack = mStacks.get(i);
1226            // stack above isn't full screen, so, we assume we're still visible. at some point
1227            // we should look at the stack bounds to see if we're occluded even if the stack
1228            // isn't fullscreen
1229            if (!stack.mFullscreen) {
1230                continue;
1231            }
1232            final ArrayList<TaskRecord> tasks = stack.getAllTasks();
1233            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1234                final TaskRecord task = tasks.get(taskNdx);
1235                final ArrayList<ActivityRecord> activities = task.mActivities;
1236                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1237                    final ActivityRecord r = activities.get(activityNdx);
1238
1239                    // Conditions for an activity to obscure the stack we're
1240                    // examining:
1241                    // 1. Not Finishing AND Visible AND:
1242                    // 2. Either:
1243                    // - Full Screen Activity OR
1244                    // - On top of Home and our stack is NOT home
1245                    if (!r.finishing && r.visible && (r.fullscreen ||
1246                            (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()))) {
1247                        return false;
1248                    }
1249                }
1250            }
1251        }
1252
1253        return true;
1254    }
1255
1256    /**
1257     * Make sure that all activities that need to be visible (that is, they
1258     * currently can be seen by the user) actually are.
1259     */
1260    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
1261        ActivityRecord top = topRunningActivityLocked(null);
1262        if (top == null) {
1263            return;
1264        }
1265        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1266                "ensureActivitiesVisible behind " + top
1267                + " configChanges=0x" + Integer.toHexString(configChanges));
1268
1269        if (mTranslucentActivityWaiting != top) {
1270            mUndrawnActivitiesBelowTopTranslucent.clear();
1271            if (mTranslucentActivityWaiting != null) {
1272                // Call the callback with a timeout indication.
1273                notifyActivityDrawnLocked(null);
1274                mTranslucentActivityWaiting = null;
1275            }
1276            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1277        }
1278
1279        // If the top activity is not fullscreen, then we need to
1280        // make sure any activities under it are now visible.
1281        boolean aboveTop = true;
1282        boolean behindFullscreen = !isStackVisibleLocked();
1283        boolean noStackActivityResumed = (isInStackLocked(starting) == null);
1284
1285        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1286            final TaskRecord task = mTaskHistory.get(taskNdx);
1287            final ArrayList<ActivityRecord> activities = task.mActivities;
1288            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1289                final ActivityRecord r = activities.get(activityNdx);
1290                if (r.finishing) {
1291                    continue;
1292                }
1293                if (aboveTop && r != top) {
1294                    continue;
1295                }
1296                aboveTop = false;
1297                // mLaunchingBehind: Activities launching behind are at the back of the task stack
1298                // but must be drawn initially for the animation as though they were visible.
1299                if (!behindFullscreen || r.mLaunchTaskBehind) {
1300                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1301                            "Make visible? " + r + " finishing=" + r.finishing
1302                            + " state=" + r.state);
1303
1304                    // First: if this is not the current activity being started, make
1305                    // sure it matches the current configuration.
1306                    if (r != starting) {
1307                        ensureActivityConfigurationLocked(r, 0);
1308                    }
1309
1310                    if (r.app == null || r.app.thread == null) {
1311                        // This activity needs to be visible, but isn't even running...
1312                        // get it started and resume if no other stack in this stack is resumed.
1313                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1314                                "Start and freeze screen for " + r);
1315                        if (r != starting) {
1316                            r.startFreezingScreenLocked(r.app, configChanges);
1317                        }
1318                        if (!r.visible || r.mLaunchTaskBehind) {
1319                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1320                                    "Starting and making visible: " + r);
1321                            setVisible(r, true);
1322                        }
1323                        if (r != starting) {
1324                            mStackSupervisor.startSpecificActivityLocked(
1325                                    r, noStackActivityResumed, false);
1326                            if (activityNdx >= activities.size()) {
1327                                // Record may be removed if its process needs to restart.
1328                                activityNdx = activities.size() - 1;
1329                            } else {
1330                                noStackActivityResumed = false;
1331                            }
1332                        }
1333
1334                    } else if (r.visible) {
1335                        // If this activity is already visible, then there is nothing
1336                        // else to do here.
1337                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1338                                "Skipping: already visible at " + r);
1339                        r.stopFreezingScreenLocked(false);
1340                        try {
1341                            if (r.returningOptions != null) {
1342                                r.app.thread.scheduleOnNewActivityOptions(r.appToken,
1343                                        r.returningOptions);
1344                            }
1345                        } catch(RemoteException e) {
1346                        }
1347                        if (r.state == ActivityState.RESUMED) {
1348                            noStackActivityResumed = false;
1349                        }
1350                    } else {
1351                        // This activity is not currently visible, but is running.
1352                        // Tell it to become visible.
1353                        r.visible = true;
1354                        if (r.state != ActivityState.RESUMED && r != starting) {
1355                            // If this activity is paused, tell it
1356                            // to now show its window.
1357                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1358                                    "Making visible and scheduling visibility: " + r);
1359                            try {
1360                                if (mTranslucentActivityWaiting != null) {
1361                                    r.updateOptionsLocked(r.returningOptions);
1362                                    mUndrawnActivitiesBelowTopTranslucent.add(r);
1363                                }
1364                                setVisible(r, true);
1365                                r.sleeping = false;
1366                                r.app.pendingUiClean = true;
1367                                r.app.thread.scheduleWindowVisibility(r.appToken, true);
1368                                r.stopFreezingScreenLocked(false);
1369                            } catch (Exception e) {
1370                                // Just skip on any failure; we'll make it
1371                                // visible when it next restarts.
1372                                Slog.w(TAG, "Exception thrown making visibile: "
1373                                        + r.intent.getComponent(), e);
1374                            }
1375                        }
1376                    }
1377
1378                    // Aggregate current change flags.
1379                    configChanges |= r.configChangeFlags;
1380
1381                    if (r.fullscreen) {
1382                        // At this point, nothing else needs to be shown
1383                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r);
1384                        behindFullscreen = true;
1385                    } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
1386                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r);
1387                        behindFullscreen = true;
1388                    }
1389                } else {
1390                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1391                        "Make invisible? " + r + " finishing=" + r.finishing
1392                        + " state=" + r.state + " behindFullscreen=" + behindFullscreen);
1393                    // Now for any activities that aren't visible to the user, make
1394                    // sure they no longer are keeping the screen frozen.
1395                    if (r.visible) {
1396                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r);
1397                        try {
1398                            setVisible(r, false);
1399                            switch (r.state) {
1400                                case STOPPING:
1401                                case STOPPED:
1402                                    if (r.app != null && r.app.thread != null) {
1403                                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
1404                                                "Scheduling invisibility: " + r);
1405                                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
1406                                    }
1407                                    break;
1408
1409                                case INITIALIZING:
1410                                case RESUMED:
1411                                case PAUSING:
1412                                case PAUSED:
1413                                    // This case created for transitioning activities from
1414                                    // translucent to opaque {@link Activity#convertToOpaque}.
1415                                    if (getVisibleBehindActivity() == r) {
1416                                        releaseBackgroundResources(r);
1417                                    } else {
1418                                        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
1419                                            mStackSupervisor.mStoppingActivities.add(r);
1420                                        }
1421                                        mStackSupervisor.scheduleIdleLocked();
1422                                    }
1423                                    break;
1424
1425                                default:
1426                                    break;
1427                            }
1428                        } catch (Exception e) {
1429                            // Just skip on any failure; we'll make it
1430                            // visible when it next restarts.
1431                            Slog.w(TAG, "Exception thrown making hidden: "
1432                                    + r.intent.getComponent(), e);
1433                        }
1434                    } else {
1435                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
1436                    }
1437                }
1438            }
1439        }
1440
1441        if (mTranslucentActivityWaiting != null &&
1442                mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
1443            // Nothing is getting drawn or everything was already visible, don't wait for timeout.
1444            notifyActivityDrawnLocked(null);
1445        }
1446    }
1447
1448    void convertActivityToTranslucent(ActivityRecord r) {
1449        mTranslucentActivityWaiting = r;
1450        mUndrawnActivitiesBelowTopTranslucent.clear();
1451        mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
1452    }
1453
1454    void clearOtherAppTimeTrackers(AppTimeTracker except) {
1455        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1456            final TaskRecord task = mTaskHistory.get(taskNdx);
1457            final ArrayList<ActivityRecord> activities = task.mActivities;
1458            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1459                final ActivityRecord r = activities.get(activityNdx);
1460                if ( r.appTimeTracker != except) {
1461                    r.appTimeTracker = null;
1462                }
1463            }
1464        }
1465    }
1466
1467    /**
1468     * Called as activities below the top translucent activity are redrawn. When the last one is
1469     * redrawn notify the top activity by calling
1470     * {@link Activity#onTranslucentConversionComplete}.
1471     *
1472     * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
1473     * occurred and the activity will be notified immediately.
1474     */
1475    void notifyActivityDrawnLocked(ActivityRecord r) {
1476        mActivityContainer.setDrawn();
1477        if ((r == null)
1478                || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
1479                        mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
1480            // The last undrawn activity below the top has just been drawn. If there is an
1481            // opaque activity at the top, notify it that it can become translucent safely now.
1482            final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
1483            mTranslucentActivityWaiting = null;
1484            mUndrawnActivitiesBelowTopTranslucent.clear();
1485            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1486
1487            if (waitingActivity != null) {
1488                mWindowManager.setWindowOpaque(waitingActivity.appToken, false);
1489                if (waitingActivity.app != null && waitingActivity.app.thread != null) {
1490                    try {
1491                        waitingActivity.app.thread.scheduleTranslucentConversionComplete(
1492                                waitingActivity.appToken, r != null);
1493                    } catch (RemoteException e) {
1494                    }
1495                }
1496            }
1497        }
1498    }
1499
1500    /** If any activities below the top running one are in the INITIALIZING state and they have a
1501     * starting window displayed then remove that starting window. It is possible that the activity
1502     * in this state will never resumed in which case that starting window will be orphaned. */
1503    void cancelInitializingActivities() {
1504        final ActivityRecord topActivity = topRunningActivityLocked(null);
1505        boolean aboveTop = true;
1506        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
1507            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
1508            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1509                final ActivityRecord r = activities.get(activityNdx);
1510                if (aboveTop) {
1511                    if (r == topActivity) {
1512                        aboveTop = false;
1513                    }
1514                    continue;
1515                }
1516
1517                if (r.state == ActivityState.INITIALIZING && r.mStartingWindowShown) {
1518                    if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY,
1519                            "Found orphaned starting window " + r);
1520                    r.mStartingWindowShown = false;
1521                    mWindowManager.removeAppStartingWindow(r.appToken);
1522                }
1523            }
1524        }
1525    }
1526
1527    /**
1528     * Ensure that the top activity in the stack is resumed.
1529     *
1530     * @param prev The previously resumed activity, for when in the process
1531     * of pausing; can be null to call from elsewhere.
1532     *
1533     * @return Returns true if something is being resumed, or false if
1534     * nothing happened.
1535     */
1536    final boolean resumeTopActivityLocked(ActivityRecord prev) {
1537        return resumeTopActivityLocked(prev, null);
1538    }
1539
1540    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
1541        if (mStackSupervisor.inResumeTopActivity) {
1542            // Don't even start recursing.
1543            return false;
1544        }
1545
1546        boolean result = false;
1547        try {
1548            // Protect against recursion.
1549            mStackSupervisor.inResumeTopActivity = true;
1550            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
1551                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
1552                mService.updateSleepIfNeededLocked();
1553            }
1554            result = resumeTopActivityInnerLocked(prev, options);
1555        } finally {
1556            mStackSupervisor.inResumeTopActivity = false;
1557        }
1558        return result;
1559    }
1560
1561    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
1562        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
1563
1564        if (!mService.mBooting && !mService.mBooted) {
1565            // Not ready yet!
1566            return false;
1567        }
1568
1569        ActivityRecord parent = mActivityContainer.mParentActivity;
1570        if ((parent != null && parent.state != ActivityState.RESUMED) ||
1571                !mActivityContainer.isAttachedLocked()) {
1572            // Do not resume this stack if its parent is not resumed.
1573            // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
1574            return false;
1575        }
1576
1577        cancelInitializingActivities();
1578
1579        // Find the first activity that is not finishing.
1580        final ActivityRecord next = topRunningActivityLocked(null);
1581
1582        // Remember how we'll process this pause/resume situation, and ensure
1583        // that the state is reset however we wind up proceeding.
1584        final boolean userLeaving = mStackSupervisor.mUserLeaving;
1585        mStackSupervisor.mUserLeaving = false;
1586
1587        final TaskRecord prevTask = prev != null ? prev.task : null;
1588        if (next == null) {
1589            // There are no more activities!
1590            final String reason = "noMoreActivities";
1591            if (!mFullscreen) {
1592                // Try to move focus to the next visible stack with a running activity if this
1593                // stack is not covering the entire screen.
1594                final ActivityStack stack = getNextVisibleStackLocked();
1595                if (adjustFocusToNextVisibleStackLocked(stack, reason)) {
1596                    return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
1597                }
1598            }
1599            // Let's just start up the Launcher...
1600            ActivityOptions.abort(options);
1601            if (DEBUG_STATES) Slog.d(TAG_STATES,
1602                    "resumeTopActivityLocked: No more activities go home");
1603            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1604            // Only resume home if on home display
1605            final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
1606                    HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
1607            return isOnHomeDisplay() &&
1608                    mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
1609        }
1610
1611        next.delayedResume = false;
1612
1613        // If the top activity is the resumed one, nothing to do.
1614        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
1615                    mStackSupervisor.allResumedActivitiesComplete()) {
1616            // Make sure we have executed any pending transitions, since there
1617            // should be nothing left to do at this point.
1618            mWindowManager.executeAppTransition();
1619            mNoAnimActivities.clear();
1620            ActivityOptions.abort(options);
1621            if (DEBUG_STATES) Slog.d(TAG_STATES,
1622                    "resumeTopActivityLocked: Top activity resumed " + next);
1623            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1624            return false;
1625        }
1626
1627        final TaskRecord nextTask = next.task;
1628        if (prevTask != null && prevTask.stack == this &&
1629                prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
1630            if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
1631            if (prevTask == nextTask) {
1632                prevTask.setFrontOfTask();
1633            } else if (prevTask != topTask()) {
1634                // This task is going away but it was supposed to return to the home stack.
1635                // Now the task above it has to return to the home task instead.
1636                final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
1637                mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
1638            } else if (!isOnHomeDisplay()) {
1639                return false;
1640            } else if (!isHomeStack()){
1641                if (DEBUG_STATES) Slog.d(TAG_STATES,
1642                        "resumeTopActivityLocked: Launching home next");
1643                final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
1644                        HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
1645                return isOnHomeDisplay() &&
1646                        mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
1647            }
1648        }
1649
1650        // If we are sleeping, and there is no resumed activity, and the top
1651        // activity is paused, well that is the state we want.
1652        if (mService.isSleepingOrShuttingDown()
1653                && mLastPausedActivity == next
1654                && mStackSupervisor.allPausedActivitiesComplete()) {
1655            // Make sure we have executed any pending transitions, since there
1656            // should be nothing left to do at this point.
1657            mWindowManager.executeAppTransition();
1658            mNoAnimActivities.clear();
1659            ActivityOptions.abort(options);
1660            if (DEBUG_STATES) Slog.d(TAG_STATES,
1661                    "resumeTopActivityLocked: Going to sleep and all paused");
1662            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1663            return false;
1664        }
1665
1666        // Make sure that the user who owns this activity is started.  If not,
1667        // we will just leave it as is because someone should be bringing
1668        // another user's activities to the top of the stack.
1669        if (mService.mStartedUsers.get(next.userId) == null) {
1670            Slog.w(TAG, "Skipping resume of top activity " + next
1671                    + ": user " + next.userId + " is stopped");
1672            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1673            return false;
1674        }
1675
1676        // The activity may be waiting for stop, but that is no longer
1677        // appropriate for it.
1678        mStackSupervisor.mStoppingActivities.remove(next);
1679        mStackSupervisor.mGoingToSleepActivities.remove(next);
1680        next.sleeping = false;
1681        mStackSupervisor.mWaitingVisibleActivities.remove(next);
1682
1683        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
1684
1685        // If we are currently pausing an activity, then don't do anything
1686        // until that is done.
1687        if (!mStackSupervisor.allPausedActivitiesComplete()) {
1688            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
1689                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
1690            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1691            return false;
1692        }
1693
1694        // Okay we are now going to start a switch, to 'next'.  We may first
1695        // have to pause the current activity, but this is an important point
1696        // where we have decided to go to 'next' so keep track of that.
1697        // XXX "App Redirected" dialog is getting too many false positives
1698        // at this point, so turn off for now.
1699        if (false) {
1700            if (mLastStartedActivity != null && !mLastStartedActivity.finishing) {
1701                long now = SystemClock.uptimeMillis();
1702                final boolean inTime = mLastStartedActivity.startTime != 0
1703                        && (mLastStartedActivity.startTime + START_WARN_TIME) >= now;
1704                final int lastUid = mLastStartedActivity.info.applicationInfo.uid;
1705                final int nextUid = next.info.applicationInfo.uid;
1706                if (inTime && lastUid != nextUid
1707                        && lastUid != next.launchedFromUid
1708                        && mService.checkPermission(
1709                                android.Manifest.permission.STOP_APP_SWITCHES,
1710                                -1, next.launchedFromUid)
1711                        != PackageManager.PERMISSION_GRANTED) {
1712                    mService.showLaunchWarningLocked(mLastStartedActivity, next);
1713                } else {
1714                    next.startTime = now;
1715                    mLastStartedActivity = next;
1716                }
1717            } else {
1718                next.startTime = SystemClock.uptimeMillis();
1719                mLastStartedActivity = next;
1720            }
1721        }
1722
1723        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
1724
1725        // We need to start pausing the current activity so the top one
1726        // can be resumed...
1727        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
1728        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
1729        if (mResumedActivity != null) {
1730            if (DEBUG_STATES) Slog.d(TAG_STATES,
1731                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
1732            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
1733        }
1734        if (pausing) {
1735            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
1736                    "resumeTopActivityLocked: Skip resume: need to start pausing");
1737            // At this point we want to put the upcoming activity's process
1738            // at the top of the LRU list, since we know we will be needing it
1739            // very soon and it would be a waste to let it get killed if it
1740            // happens to be sitting towards the end.
1741            if (next.app != null && next.app.thread != null) {
1742                mService.updateLruProcessLocked(next.app, true, null);
1743            }
1744            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1745            return true;
1746        }
1747
1748        // If the most recent activity was noHistory but was only stopped rather
1749        // than stopped+finished because the device went to sleep, we need to make
1750        // sure to finish it as we're making a new activity topmost.
1751        if (mService.isSleeping() && mLastNoHistoryActivity != null &&
1752                !mLastNoHistoryActivity.finishing) {
1753            if (DEBUG_STATES) Slog.d(TAG_STATES,
1754                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
1755            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
1756                    null, "resume-no-history", false);
1757            mLastNoHistoryActivity = null;
1758        }
1759
1760        if (prev != null && prev != next) {
1761            if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
1762                    && next != null && !next.nowVisible) {
1763                mStackSupervisor.mWaitingVisibleActivities.add(prev);
1764                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1765                        "Resuming top, waiting visible to hide: " + prev);
1766            } else {
1767                // The next activity is already visible, so hide the previous
1768                // activity's windows right now so we can show the new one ASAP.
1769                // We only do this if the previous is finishing, which should mean
1770                // it is on top of the one being resumed so hiding it quickly
1771                // is good.  Otherwise, we want to do the normal route of allowing
1772                // the resumed activity to be shown so we can decide if the
1773                // previous should actually be hidden depending on whether the
1774                // new one is found to be full-screen or not.
1775                if (prev.finishing) {
1776                    mWindowManager.setAppVisibility(prev.appToken, false);
1777                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1778                            "Not waiting for visible to hide: " + prev + ", waitingVisible="
1779                            + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
1780                            + ", nowVisible=" + next.nowVisible);
1781                } else {
1782                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1783                            "Previous already visible but still waiting to hide: " + prev
1784                            + ", waitingVisible="
1785                            + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
1786                            + ", nowVisible=" + next.nowVisible);
1787                }
1788            }
1789        }
1790
1791        // Launching this app's activity, make sure the app is no longer
1792        // considered stopped.
1793        try {
1794            AppGlobals.getPackageManager().setPackageStoppedState(
1795                    next.packageName, false, next.userId); /* TODO: Verify if correct userid */
1796        } catch (RemoteException e1) {
1797        } catch (IllegalArgumentException e) {
1798            Slog.w(TAG, "Failed trying to unstop package "
1799                    + next.packageName + ": " + e);
1800        }
1801
1802        // We are starting up the next activity, so tell the window manager
1803        // that the previous one will be hidden soon.  This way it can know
1804        // to ignore it when computing the desired screen orientation.
1805        boolean anim = true;
1806        if (prev != null) {
1807            if (prev.finishing) {
1808                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
1809                        "Prepare close transition: prev=" + prev);
1810                if (mNoAnimActivities.contains(prev)) {
1811                    anim = false;
1812                    mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
1813                } else {
1814                    mWindowManager.prepareAppTransition(prev.task == next.task
1815                            ? AppTransition.TRANSIT_ACTIVITY_CLOSE
1816                            : AppTransition.TRANSIT_TASK_CLOSE, false);
1817                }
1818                mWindowManager.setAppWillBeHidden(prev.appToken);
1819                mWindowManager.setAppVisibility(prev.appToken, false);
1820            } else {
1821                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
1822                        "Prepare open transition: prev=" + prev);
1823                if (mNoAnimActivities.contains(next)) {
1824                    anim = false;
1825                    mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
1826                } else {
1827                    mWindowManager.prepareAppTransition(prev.task == next.task
1828                            ? AppTransition.TRANSIT_ACTIVITY_OPEN
1829                            : next.mLaunchTaskBehind
1830                                    ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
1831                                    : AppTransition.TRANSIT_TASK_OPEN, false);
1832                }
1833            }
1834            if (false) {
1835                mWindowManager.setAppWillBeHidden(prev.appToken);
1836                mWindowManager.setAppVisibility(prev.appToken, false);
1837            }
1838        } else {
1839            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
1840            if (mNoAnimActivities.contains(next)) {
1841                anim = false;
1842                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
1843            } else {
1844                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
1845            }
1846        }
1847
1848        Bundle resumeAnimOptions = null;
1849        if (anim) {
1850            ActivityOptions opts = next.getOptionsForTargetActivityLocked();
1851            if (opts != null) {
1852                resumeAnimOptions = opts.toBundle();
1853            }
1854            next.applyOptionsLocked();
1855        } else {
1856            next.clearOptionsLocked();
1857        }
1858
1859        ActivityStack lastStack = mStackSupervisor.getLastStack();
1860        if (next.app != null && next.app.thread != null) {
1861            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);
1862
1863            // This activity is now becoming visible.
1864            mWindowManager.setAppVisibility(next.appToken, true);
1865
1866            // schedule launch ticks to collect information about slow apps.
1867            next.startLaunchTickingLocked();
1868
1869            ActivityRecord lastResumedActivity =
1870                    lastStack == null ? null :lastStack.mResumedActivity;
1871            ActivityState lastState = next.state;
1872
1873            mService.updateCpuStats();
1874
1875            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
1876            next.state = ActivityState.RESUMED;
1877            mResumedActivity = next;
1878            next.task.touchActiveTime();
1879            mRecentTasks.addLocked(next.task);
1880            mService.updateLruProcessLocked(next.app, true, null);
1881            updateLRUListLocked(next);
1882            mService.updateOomAdjLocked();
1883
1884            // Have the window manager re-evaluate the orientation of
1885            // the screen based on the new activity order.
1886            boolean notUpdated = true;
1887            if (mStackSupervisor.isFrontStack(this)) {
1888                Configuration config = mWindowManager.updateOrientationFromAppTokens(
1889                        mService.mConfiguration,
1890                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
1891                if (config != null) {
1892                    next.frozenBeforeDestroy = true;
1893                }
1894                notUpdated = !mService.updateConfigurationLocked(config, next, false, false);
1895            }
1896
1897            if (notUpdated) {
1898                // The configuration update wasn't able to keep the existing
1899                // instance of the activity, and instead started a new one.
1900                // We should be all done, but let's just make sure our activity
1901                // is still at the top and schedule another run if something
1902                // weird happened.
1903                ActivityRecord nextNext = topRunningActivityLocked(null);
1904                if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
1905                        "Activity config changed during resume: " + next
1906                        + ", new next: " + nextNext);
1907                if (nextNext != next) {
1908                    // Do over!
1909                    mStackSupervisor.scheduleResumeTopActivities();
1910                }
1911                if (mStackSupervisor.reportResumedActivityLocked(next)) {
1912                    mNoAnimActivities.clear();
1913                    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1914                    return true;
1915                }
1916                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1917                return false;
1918            }
1919
1920            try {
1921                // Deliver all pending results.
1922                ArrayList<ResultInfo> a = next.results;
1923                if (a != null) {
1924                    final int N = a.size();
1925                    if (!next.finishing && N > 0) {
1926                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
1927                                "Delivering results to " + next + ": " + a);
1928                        next.app.thread.scheduleSendResult(next.appToken, a);
1929                    }
1930                }
1931
1932                if (next.newIntents != null) {
1933                    next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
1934                }
1935
1936                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
1937                        System.identityHashCode(next), next.task.taskId, next.shortComponentName);
1938
1939                next.sleeping = false;
1940                mService.showAskCompatModeDialogLocked(next);
1941                next.app.pendingUiClean = true;
1942                next.app.forceProcessStateUpTo(mService.mTopProcessState);
1943                next.clearOptionsLocked();
1944                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
1945                        mService.isNextTransitionForward(), resumeAnimOptions);
1946
1947                mStackSupervisor.checkReadyForSleepLocked();
1948
1949                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next);
1950            } catch (Exception e) {
1951                // Whoops, need to restart this activity!
1952                if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
1953                        + lastState + ": " + next);
1954                next.state = lastState;
1955                if (lastStack != null) {
1956                    lastStack.mResumedActivity = lastResumedActivity;
1957                }
1958                Slog.i(TAG, "Restarting because process died: " + next);
1959                if (!next.hasBeenLaunched) {
1960                    next.hasBeenLaunched = true;
1961                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
1962                        mStackSupervisor.isFrontStack(lastStack)) {
1963                    mWindowManager.setAppStartingWindow(
1964                            next.appToken, next.packageName, next.theme,
1965                            mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
1966                            next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
1967                            next.windowFlags, null, true);
1968                }
1969                mStackSupervisor.startSpecificActivityLocked(next, true, false);
1970                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1971                return true;
1972            }
1973
1974            // From this point on, if something goes wrong there is no way
1975            // to recover the activity.
1976            try {
1977                next.visible = true;
1978                completeResumeLocked(next);
1979            } catch (Exception e) {
1980                // If any exception gets thrown, toss away this
1981                // activity and try the next one.
1982                Slog.w(TAG, "Exception thrown during resume of " + next, e);
1983                requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
1984                        "resume-exception", true);
1985                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
1986                return true;
1987            }
1988            next.stopped = false;
1989
1990        } else {
1991            // Whoops, need to restart this activity!
1992            if (!next.hasBeenLaunched) {
1993                next.hasBeenLaunched = true;
1994            } else {
1995                if (SHOW_APP_STARTING_PREVIEW) {
1996                    mWindowManager.setAppStartingWindow(
1997                            next.appToken, next.packageName, next.theme,
1998                            mService.compatibilityInfoForPackageLocked(
1999                                    next.info.applicationInfo),
2000                            next.nonLocalizedLabel,
2001                            next.labelRes, next.icon, next.logo, next.windowFlags,
2002                            null, true);
2003                }
2004                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
2005            }
2006            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
2007            mStackSupervisor.startSpecificActivityLocked(next, true, true);
2008        }
2009
2010        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2011        return true;
2012    }
2013
2014    private TaskRecord getNextTask(TaskRecord targetTask) {
2015        final int index = mTaskHistory.indexOf(targetTask);
2016        if (index >= 0) {
2017            final int numTasks = mTaskHistory.size();
2018            for (int i = index + 1; i < numTasks; ++i) {
2019                TaskRecord task = mTaskHistory.get(i);
2020                if (task.userId == targetTask.userId) {
2021                    return task;
2022                }
2023            }
2024        }
2025        return null;
2026    }
2027
2028    private void insertTaskAtTop(TaskRecord task, ActivityRecord newActivity) {
2029        // If the moving task is over home stack, transfer its return type to next task
2030        if (task.isOverHomeStack()) {
2031            final TaskRecord nextTask = getNextTask(task);
2032            if (nextTask != null) {
2033                nextTask.setTaskToReturnTo(task.getTaskToReturnTo());
2034            }
2035        }
2036
2037        // If this is being moved to the top by another activity or being launched from the home
2038        // activity, set mTaskToReturnTo accordingly.
2039        if (isOnHomeDisplay()) {
2040            ActivityStack lastStack = mStackSupervisor.getLastStack();
2041            final boolean fromHome = lastStack.isHomeStack();
2042            if (!isHomeStack() && (fromHome || topTask() != task)) {
2043                task.setTaskToReturnTo(fromHome
2044                        ? lastStack.topTask() == null
2045                                ? HOME_ACTIVITY_TYPE
2046                                : lastStack.topTask().taskType
2047                        : APPLICATION_ACTIVITY_TYPE);
2048            }
2049        } else {
2050            task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
2051        }
2052
2053        mTaskHistory.remove(task);
2054        // Now put task at top.
2055        int taskNdx = mTaskHistory.size();
2056        final boolean notShownWhenLocked =
2057                (newActivity != null && (newActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0)
2058                || (newActivity == null && task.topRunningActivityLocked(null) == null);
2059        if (!mStackSupervisor.isCurrentProfileLocked(task.userId) && notShownWhenLocked) {
2060            // Put non-current user tasks below current user tasks.
2061            while (--taskNdx >= 0) {
2062                final TaskRecord tmpTask = mTaskHistory.get(taskNdx);
2063                if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId)
2064                        || tmpTask.topRunningActivityLocked(null) == null) {
2065                    break;
2066                }
2067            }
2068            ++taskNdx;
2069        }
2070        mTaskHistory.add(taskNdx, task);
2071        updateTaskMovement(task, true);
2072    }
2073
2074    final void startActivityLocked(ActivityRecord r, boolean newTask,
2075            boolean doResume, boolean keepCurTransition, Bundle options) {
2076        TaskRecord rTask = r.task;
2077        final int taskId = rTask.taskId;
2078        // mLaunchTaskBehind tasks get placed at the back of the task stack.
2079        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
2080            // Last activity in task had been removed or ActivityManagerService is reusing task.
2081            // Insert or replace.
2082            // Might not even be in.
2083            insertTaskAtTop(rTask, r);
2084            mWindowManager.moveTaskToTop(taskId);
2085        }
2086        TaskRecord task = null;
2087        if (!newTask) {
2088            // If starting in an existing task, find where that is...
2089            boolean startIt = true;
2090            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2091                task = mTaskHistory.get(taskNdx);
2092                if (task.getTopActivity() == null) {
2093                    // All activities in task are finishing.
2094                    continue;
2095                }
2096                if (task == r.task) {
2097                    // Here it is!  Now, if this is not yet visible to the
2098                    // user, then just add it without starting; it will
2099                    // get started when the user navigates back to it.
2100                    if (!startIt) {
2101                        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
2102                                + task, new RuntimeException("here").fillInStackTrace());
2103                        task.addActivityToTop(r);
2104                        r.putInHistory();
2105                        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
2106                                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
2107                                (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
2108                                r.userId, r.info.configChanges, task.voiceSession != null,
2109                                r.mLaunchTaskBehind);
2110                        if (VALIDATE_TOKENS) {
2111                            validateAppTokensLocked();
2112                        }
2113                        ActivityOptions.abort(options);
2114                        return;
2115                    }
2116                    break;
2117                } else if (task.numFullscreen > 0) {
2118                    startIt = false;
2119                }
2120            }
2121        }
2122
2123        // Place a new activity at top of stack, so it is next to interact
2124        // with the user.
2125
2126        // If we are not placing the new activity frontmost, we do not want
2127        // to deliver the onUserLeaving callback to the actual frontmost
2128        // activity
2129        if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
2130            mStackSupervisor.mUserLeaving = false;
2131            if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2132                    "startActivity() behind front, mUserLeaving=false");
2133        }
2134
2135        task = r.task;
2136
2137        // Slot the activity into the history stack and proceed
2138        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
2139                new RuntimeException("here").fillInStackTrace());
2140        task.addActivityToTop(r);
2141        task.setFrontOfTask();
2142
2143        r.putInHistory();
2144        if (!isHomeStack() || numActivities() > 0) {
2145            // We want to show the starting preview window if we are
2146            // switching to a new task, or the next activity's process is
2147            // not currently running.
2148            boolean showStartingIcon = newTask;
2149            ProcessRecord proc = r.app;
2150            if (proc == null) {
2151                proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2152            }
2153            if (proc == null || proc.thread == null) {
2154                showStartingIcon = true;
2155            }
2156            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2157                    "Prepare open transition: starting " + r);
2158            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2159                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
2160                mNoAnimActivities.add(r);
2161            } else {
2162                mWindowManager.prepareAppTransition(newTask
2163                        ? r.mLaunchTaskBehind
2164                                ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
2165                                : AppTransition.TRANSIT_TASK_OPEN
2166                        : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
2167                mNoAnimActivities.remove(r);
2168            }
2169            mWindowManager.addAppToken(task.mActivities.indexOf(r),
2170                    r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
2171                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
2172                    r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
2173            boolean doShow = true;
2174            if (newTask) {
2175                // Even though this activity is starting fresh, we still need
2176                // to reset it to make sure we apply affinities to move any
2177                // existing activities from other tasks in to it.
2178                // If the caller has requested that the target task be
2179                // reset, then do so.
2180                if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2181                    resetTaskIfNeededLocked(r, r);
2182                    doShow = topRunningNonDelayedActivityLocked(null) == r;
2183                }
2184            } else if (options != null && new ActivityOptions(options).getAnimationType()
2185                    == ActivityOptions.ANIM_SCENE_TRANSITION) {
2186                doShow = false;
2187            }
2188            if (r.mLaunchTaskBehind) {
2189                // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
2190                // tell WindowManager that r is visible even though it is at the back of the stack.
2191                mWindowManager.setAppVisibility(r.appToken, true);
2192                ensureActivitiesVisibleLocked(null, 0);
2193            } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
2194                // Figure out if we are transitioning from another activity that is
2195                // "has the same starting icon" as the next one.  This allows the
2196                // window manager to keep the previous window it had previously
2197                // created, if it still had one.
2198                ActivityRecord prev = mResumedActivity;
2199                if (prev != null) {
2200                    // We don't want to reuse the previous starting preview if:
2201                    // (1) The current activity is in a different task.
2202                    if (prev.task != r.task) {
2203                        prev = null;
2204                    }
2205                    // (2) The current activity is already displayed.
2206                    else if (prev.nowVisible) {
2207                        prev = null;
2208                    }
2209                }
2210                mWindowManager.setAppStartingWindow(
2211                        r.appToken, r.packageName, r.theme,
2212                        mService.compatibilityInfoForPackageLocked(
2213                                r.info.applicationInfo), r.nonLocalizedLabel,
2214                        r.labelRes, r.icon, r.logo, r.windowFlags,
2215                        prev != null ? prev.appToken : null, showStartingIcon);
2216                r.mStartingWindowShown = true;
2217            }
2218        } else {
2219            // If this is the first activity, don't do any fancy animations,
2220            // because there is nothing for it to animate on top of.
2221            mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
2222                    r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
2223                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
2224                    r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
2225            ActivityOptions.abort(options);
2226            options = null;
2227        }
2228        if (VALIDATE_TOKENS) {
2229            validateAppTokensLocked();
2230        }
2231
2232        if (doResume) {
2233            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
2234        }
2235    }
2236
2237    final void validateAppTokensLocked() {
2238        mValidateAppTokens.clear();
2239        mValidateAppTokens.ensureCapacity(numActivities());
2240        final int numTasks = mTaskHistory.size();
2241        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
2242            TaskRecord task = mTaskHistory.get(taskNdx);
2243            final ArrayList<ActivityRecord> activities = task.mActivities;
2244            if (activities.isEmpty()) {
2245                continue;
2246            }
2247            TaskGroup group = new TaskGroup();
2248            group.taskId = task.taskId;
2249            mValidateAppTokens.add(group);
2250            final int numActivities = activities.size();
2251            for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
2252                final ActivityRecord r = activities.get(activityNdx);
2253                group.tokens.add(r.appToken);
2254            }
2255        }
2256        mWindowManager.validateAppTokens(mStackId, mValidateAppTokens);
2257    }
2258
2259    /**
2260     * Perform a reset of the given task, if needed as part of launching it.
2261     * Returns the new HistoryRecord at the top of the task.
2262     */
2263    /**
2264     * Helper method for #resetTaskIfNeededLocked.
2265     * We are inside of the task being reset...  we'll either finish this activity, push it out
2266     * for another task, or leave it as-is.
2267     * @param task The task containing the Activity (taskTop) that might be reset.
2268     * @param forceReset
2269     * @return An ActivityOptions that needs to be processed.
2270     */
2271    final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
2272        ActivityOptions topOptions = null;
2273
2274        int replyChainEnd = -1;
2275        boolean canMoveOptions = true;
2276
2277        // We only do this for activities that are not the root of the task (since if we finish
2278        // the root, we may no longer have the task!).
2279        final ArrayList<ActivityRecord> activities = task.mActivities;
2280        final int numActivities = activities.size();
2281        final int rootActivityNdx = task.findEffectiveRootIndex();
2282        for (int i = numActivities - 1; i > rootActivityNdx; --i ) {
2283            ActivityRecord target = activities.get(i);
2284            if (target.frontOfTask)
2285                break;
2286
2287            final int flags = target.info.flags;
2288            final boolean finishOnTaskLaunch =
2289                    (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
2290            final boolean allowTaskReparenting =
2291                    (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
2292            final boolean clearWhenTaskReset =
2293                    (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
2294
2295            if (!finishOnTaskLaunch
2296                    && !clearWhenTaskReset
2297                    && target.resultTo != null) {
2298                // If this activity is sending a reply to a previous
2299                // activity, we can't do anything with it now until
2300                // we reach the start of the reply chain.
2301                // XXX note that we are assuming the result is always
2302                // to the previous activity, which is almost always
2303                // the case but we really shouldn't count on.
2304                if (replyChainEnd < 0) {
2305                    replyChainEnd = i;
2306                }
2307            } else if (!finishOnTaskLaunch
2308                    && !clearWhenTaskReset
2309                    && allowTaskReparenting
2310                    && target.taskAffinity != null
2311                    && !target.taskAffinity.equals(task.affinity)) {
2312                // If this activity has an affinity for another
2313                // task, then we need to move it out of here.  We will
2314                // move it as far out of the way as possible, to the
2315                // bottom of the activity stack.  This also keeps it
2316                // correctly ordered with any activities we previously
2317                // moved.
2318                final TaskRecord targetTask;
2319                final ActivityRecord bottom =
2320                        !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
2321                                mTaskHistory.get(0).mActivities.get(0) : null;
2322                if (bottom != null && target.taskAffinity != null
2323                        && target.taskAffinity.equals(bottom.task.affinity)) {
2324                    // If the activity currently at the bottom has the
2325                    // same task affinity as the one we are moving,
2326                    // then merge it into the same task.
2327                    targetTask = bottom.task;
2328                    if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
2329                            + " out to bottom task " + bottom.task);
2330                } else {
2331                    targetTask = createTaskRecord(mStackSupervisor.getNextTaskId(), target.info,
2332                            null, null, null, false);
2333                    targetTask.affinityIntent = target.intent;
2334                    if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
2335                            + " out to new task " + target.task);
2336                }
2337
2338                final int targetTaskId = targetTask.taskId;
2339                mWindowManager.setAppTask(target.appToken, targetTaskId);
2340
2341                boolean noOptions = canMoveOptions;
2342                final int start = replyChainEnd < 0 ? i : replyChainEnd;
2343                for (int srcPos = start; srcPos >= i; --srcPos) {
2344                    final ActivityRecord p = activities.get(srcPos);
2345                    if (p.finishing) {
2346                        continue;
2347                    }
2348
2349                    canMoveOptions = false;
2350                    if (noOptions && topOptions == null) {
2351                        topOptions = p.takeOptionsLocked();
2352                        if (topOptions != null) {
2353                            noOptions = false;
2354                        }
2355                    }
2356                    if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
2357                            "Removing activity " + p + " from task=" + task + " adding to task="
2358                            + targetTask + " Callers=" + Debug.getCallers(4));
2359                    if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2360                            "Pushing next activity " + p + " out to target's task " + target.task);
2361                    p.setTask(targetTask, null);
2362                    targetTask.addActivityAtBottom(p);
2363
2364                    mWindowManager.setAppTask(p.appToken, targetTaskId);
2365                }
2366
2367                mWindowManager.moveTaskToBottom(targetTaskId);
2368                if (VALIDATE_TOKENS) {
2369                    validateAppTokensLocked();
2370                }
2371
2372                replyChainEnd = -1;
2373            } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) {
2374                // If the activity should just be removed -- either
2375                // because it asks for it, or the task should be
2376                // cleared -- then finish it and anything that is
2377                // part of its reply chain.
2378                int end;
2379                if (clearWhenTaskReset) {
2380                    // In this case, we want to finish this activity
2381                    // and everything above it, so be sneaky and pretend
2382                    // like these are all in the reply chain.
2383                    end = activities.size() - 1;
2384                } else if (replyChainEnd < 0) {
2385                    end = i;
2386                } else {
2387                    end = replyChainEnd;
2388                }
2389                boolean noOptions = canMoveOptions;
2390                for (int srcPos = i; srcPos <= end; srcPos++) {
2391                    ActivityRecord p = activities.get(srcPos);
2392                    if (p.finishing) {
2393                        continue;
2394                    }
2395                    canMoveOptions = false;
2396                    if (noOptions && topOptions == null) {
2397                        topOptions = p.takeOptionsLocked();
2398                        if (topOptions != null) {
2399                            noOptions = false;
2400                        }
2401                    }
2402                    if (DEBUG_TASKS) Slog.w(TAG_TASKS,
2403                            "resetTaskIntendedTask: calling finishActivity on " + p);
2404                    if (finishActivityLocked(
2405                            p, Activity.RESULT_CANCELED, null, "reset-task", false)) {
2406                        end--;
2407                        srcPos--;
2408                    }
2409                }
2410                replyChainEnd = -1;
2411            } else {
2412                // If we were in the middle of a chain, well the
2413                // activity that started it all doesn't want anything
2414                // special, so leave it all as-is.
2415                replyChainEnd = -1;
2416            }
2417        }
2418
2419        return topOptions;
2420    }
2421
2422    /**
2423     * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given
2424     * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop.
2425     * @param affinityTask The task we are looking for an affinity to.
2426     * @param task Task that resetTaskIfNeededLocked.taskTop belongs to.
2427     * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked.
2428     * @param forceReset Flag passed in to resetTaskIfNeededLocked.
2429     */
2430    private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task,
2431            boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) {
2432        int replyChainEnd = -1;
2433        final int taskId = task.taskId;
2434        final String taskAffinity = task.affinity;
2435
2436        final ArrayList<ActivityRecord> activities = affinityTask.mActivities;
2437        final int numActivities = activities.size();
2438        final int rootActivityNdx = affinityTask.findEffectiveRootIndex();
2439
2440        // Do not operate on or below the effective root Activity.
2441        for (int i = numActivities - 1; i > rootActivityNdx; --i) {
2442            ActivityRecord target = activities.get(i);
2443            if (target.frontOfTask)
2444                break;
2445
2446            final int flags = target.info.flags;
2447            boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
2448            boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
2449
2450            if (target.resultTo != null) {
2451                // If this activity is sending a reply to a previous
2452                // activity, we can't do anything with it now until
2453                // we reach the start of the reply chain.
2454                // XXX note that we are assuming the result is always
2455                // to the previous activity, which is almost always
2456                // the case but we really shouldn't count on.
2457                if (replyChainEnd < 0) {
2458                    replyChainEnd = i;
2459                }
2460            } else if (topTaskIsHigher
2461                    && allowTaskReparenting
2462                    && taskAffinity != null
2463                    && taskAffinity.equals(target.taskAffinity)) {
2464                // This activity has an affinity for our task. Either remove it if we are
2465                // clearing or move it over to our task.  Note that
2466                // we currently punt on the case where we are resetting a
2467                // task that is not at the top but who has activities above
2468                // with an affinity to it...  this is really not a normal
2469                // case, and we will need to later pull that task to the front
2470                // and usually at that point we will do the reset and pick
2471                // up those remaining activities.  (This only happens if
2472                // someone starts an activity in a new task from an activity
2473                // in a task that is not currently on top.)
2474                if (forceReset || finishOnTaskLaunch) {
2475                    final int start = replyChainEnd >= 0 ? replyChainEnd : i;
2476                    if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2477                            "Finishing task at index " + start + " to " + i);
2478                    for (int srcPos = start; srcPos >= i; --srcPos) {
2479                        final ActivityRecord p = activities.get(srcPos);
2480                        if (p.finishing) {
2481                            continue;
2482                        }
2483                        finishActivityLocked(
2484                                p, Activity.RESULT_CANCELED, null, "move-affinity", false);
2485                    }
2486                } else {
2487                    if (taskInsertionPoint < 0) {
2488                        taskInsertionPoint = task.mActivities.size();
2489
2490                    }
2491
2492                    final int start = replyChainEnd >= 0 ? replyChainEnd : i;
2493                    if (DEBUG_TASKS) Slog.v(TAG_TASKS,
2494                            "Reparenting from task=" + affinityTask + ":" + start + "-" + i
2495                            + " to task=" + task + ":" + taskInsertionPoint);
2496                    for (int srcPos = start; srcPos >= i; --srcPos) {
2497                        final ActivityRecord p = activities.get(srcPos);
2498                        p.setTask(task, null);
2499                        task.addActivityAtIndex(taskInsertionPoint, p);
2500
2501                        if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
2502                                "Removing and adding activity " + p + " to stack at " + task
2503                                + " callers=" + Debug.getCallers(3));
2504                        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Pulling activity " + p
2505                                + " from " + srcPos + " in to resetting task " + task);
2506                        mWindowManager.setAppTask(p.appToken, taskId);
2507                    }
2508                    mWindowManager.moveTaskToTop(taskId);
2509                    if (VALIDATE_TOKENS) {
2510                        validateAppTokensLocked();
2511                    }
2512
2513                    // Now we've moved it in to place...  but what if this is
2514                    // a singleTop activity and we have put it on top of another
2515                    // instance of the same activity?  Then we drop the instance
2516                    // below so it remains singleTop.
2517                    if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
2518                        ArrayList<ActivityRecord> taskActivities = task.mActivities;
2519                        int targetNdx = taskActivities.indexOf(target);
2520                        if (targetNdx > 0) {
2521                            ActivityRecord p = taskActivities.get(targetNdx - 1);
2522                            if (p.intent.getComponent().equals(target.intent.getComponent())) {
2523                                finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
2524                                        false);
2525                            }
2526                        }
2527                    }
2528                }
2529
2530                replyChainEnd = -1;
2531            }
2532        }
2533        return taskInsertionPoint;
2534    }
2535
2536    final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
2537            ActivityRecord newActivity) {
2538        boolean forceReset =
2539                (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
2540        if (ACTIVITY_INACTIVE_RESET_TIME > 0
2541                && taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
2542            if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
2543                forceReset = true;
2544            }
2545        }
2546
2547        final TaskRecord task = taskTop.task;
2548
2549        /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
2550         * for remaining tasks. Used for later tasks to reparent to task. */
2551        boolean taskFound = false;
2552
2553        /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */
2554        ActivityOptions topOptions = null;
2555
2556        // Preserve the location for reparenting in the new task.
2557        int reparentInsertionPoint = -1;
2558
2559        for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
2560            final TaskRecord targetTask = mTaskHistory.get(i);
2561
2562            if (targetTask == task) {
2563                topOptions = resetTargetTaskIfNeededLocked(task, forceReset);
2564                taskFound = true;
2565            } else {
2566                reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task,
2567                        taskFound, forceReset, reparentInsertionPoint);
2568            }
2569        }
2570
2571        int taskNdx = mTaskHistory.indexOf(task);
2572        if (taskNdx >= 0) {
2573            do {
2574                taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
2575            } while (taskTop == null && taskNdx >= 0);
2576        }
2577
2578        if (topOptions != null) {
2579            // If we got some ActivityOptions from an activity on top that
2580            // was removed from the task, propagate them to the new real top.
2581            if (taskTop != null) {
2582                taskTop.updateOptionsLocked(topOptions);
2583            } else {
2584                topOptions.abort();
2585            }
2586        }
2587
2588        return taskTop;
2589    }
2590
2591    void sendActivityResultLocked(int callingUid, ActivityRecord r,
2592            String resultWho, int requestCode, int resultCode, Intent data) {
2593
2594        if (callingUid > 0) {
2595            mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2596                    data, r.getUriPermissionsLocked(), r.userId);
2597        }
2598
2599        if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
2600                + " : who=" + resultWho + " req=" + requestCode
2601                + " res=" + resultCode + " data=" + data);
2602        if (mResumedActivity == r && r.app != null && r.app.thread != null) {
2603            try {
2604                ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2605                list.add(new ResultInfo(resultWho, requestCode,
2606                        resultCode, data));
2607                r.app.thread.scheduleSendResult(r.appToken, list);
2608                return;
2609            } catch (Exception e) {
2610                Slog.w(TAG, "Exception thrown sending result to " + r, e);
2611            }
2612        }
2613
2614        r.addResultLocked(null, resultWho, requestCode, resultCode, data);
2615    }
2616
2617    private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {
2618        if (mStackSupervisor.isFrontStack(this) && mService.mFocusedActivity == r) {
2619            ActivityRecord next = topRunningActivityLocked(null);
2620            final String myReason = reason + " adjustFocus";
2621            if (next != r) {
2622                final TaskRecord task = r.task;
2623                if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
2624                    // For non-fullscreen stack, we want to move the focus to the next visible
2625                    // stack to prevent the home screen from moving to the top and obscuring
2626                    // other visible stacks.
2627                    if (!mFullscreen
2628                            && adjustFocusToNextVisibleStackLocked(null, myReason)) {
2629                        return;
2630                    }
2631                    // Move the home stack to the top if this stack is fullscreen or there is no
2632                    // other visible stack.
2633                    if (mStackSupervisor.moveHomeStackTaskToTop(
2634                            task.getTaskToReturnTo(), myReason)) {
2635                        // Activity focus was already adjusted. Nothing else to do...
2636                        return;
2637                    }
2638                }
2639            }
2640
2641            final ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
2642            if (top != null) {
2643                mService.setFocusedActivityLocked(top, myReason);
2644            }
2645        }
2646    }
2647
2648    private boolean adjustFocusToNextVisibleStackLocked(ActivityStack inStack, String reason) {
2649        final ActivityStack stack = (inStack != null) ? inStack : getNextVisibleStackLocked();
2650        final String myReason = reason + " adjustFocusToNextVisibleStack";
2651        if (stack == null) {
2652            return false;
2653        }
2654        final ActivityRecord top = stack.topRunningActivityLocked(null);
2655        if (top == null) {
2656            return false;
2657        }
2658        mService.setFocusedActivityLocked(top, myReason);
2659        return true;
2660    }
2661
2662    final void stopActivityLocked(ActivityRecord r) {
2663        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
2664        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
2665                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
2666            if (!r.finishing) {
2667                if (!mService.isSleeping()) {
2668                    if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
2669                    if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
2670                            "stop-no-history", false)) {
2671                        // Activity was finished, no need to continue trying to schedule stop.
2672                        adjustFocusedActivityLocked(r, "stopActivityFinished");
2673                        r.resumeKeyDispatchingLocked();
2674                        return;
2675                    }
2676                } else {
2677                    if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
2678                            + " on stop because we're just sleeping");
2679                }
2680            }
2681        }
2682
2683        if (r.app != null && r.app.thread != null) {
2684            adjustFocusedActivityLocked(r, "stopActivity");
2685            r.resumeKeyDispatchingLocked();
2686            try {
2687                r.stopped = false;
2688                if (DEBUG_STATES) Slog.v(TAG_STATES,
2689                        "Moving to STOPPING: " + r + " (stop requested)");
2690                r.state = ActivityState.STOPPING;
2691                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
2692                        "Stopping visible=" + r.visible + " for " + r);
2693                if (!r.visible) {
2694                    mWindowManager.setAppVisibility(r.appToken, false);
2695                }
2696                r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
2697                if (mService.isSleepingOrShuttingDown()) {
2698                    r.setSleeping(true);
2699                }
2700                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
2701                mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
2702            } catch (Exception e) {
2703                // Maybe just ignore exceptions here...  if the process
2704                // has crashed, our death notification will clean things
2705                // up.
2706                Slog.w(TAG, "Exception thrown during pause", e);
2707                // Just in case, assume it to be stopped.
2708                r.stopped = true;
2709                if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
2710                r.state = ActivityState.STOPPED;
2711                if (r.configDestroy) {
2712                    destroyActivityLocked(r, true, "stop-except");
2713                }
2714            }
2715        }
2716    }
2717
2718    /**
2719     * @return Returns true if the activity is being finished, false if for
2720     * some reason it is being left as-is.
2721     */
2722    final boolean requestFinishActivityLocked(IBinder token, int resultCode,
2723            Intent resultData, String reason, boolean oomAdj) {
2724        ActivityRecord r = isInStackLocked(token);
2725        if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
2726                "Finishing activity token=" + token + " r="
2727                + ", result=" + resultCode + ", data=" + resultData
2728                + ", reason=" + reason);
2729        if (r == null) {
2730            return false;
2731        }
2732
2733        finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
2734        return true;
2735    }
2736
2737    final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
2738        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2739            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2740            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2741                ActivityRecord r = activities.get(activityNdx);
2742                if (r.resultTo == self && r.requestCode == requestCode) {
2743                    if ((r.resultWho == null && resultWho == null) ||
2744                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
2745                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
2746                                false);
2747                    }
2748                }
2749            }
2750        }
2751        mService.updateOomAdjLocked();
2752    }
2753
2754    final void finishTopRunningActivityLocked(ProcessRecord app, String reason) {
2755        ActivityRecord r = topRunningActivityLocked(null);
2756        if (r != null && r.app == app) {
2757            // If the top running activity is from this crashing
2758            // process, then terminate it to avoid getting in a loop.
2759            Slog.w(TAG, "  Force finishing activity "
2760                    + r.intent.getComponent().flattenToShortString());
2761            int taskNdx = mTaskHistory.indexOf(r.task);
2762            int activityNdx = r.task.mActivities.indexOf(r);
2763            finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
2764            // Also terminate any activities below it that aren't yet
2765            // stopped, to avoid a situation where one will get
2766            // re-start our crashing activity once it gets resumed again.
2767            --activityNdx;
2768            if (activityNdx < 0) {
2769                do {
2770                    --taskNdx;
2771                    if (taskNdx < 0) {
2772                        break;
2773                    }
2774                    activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
2775                } while (activityNdx < 0);
2776            }
2777            if (activityNdx >= 0) {
2778                r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
2779                if (r.state == ActivityState.RESUMED
2780                        || r.state == ActivityState.PAUSING
2781                        || r.state == ActivityState.PAUSED) {
2782                    if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
2783                        Slog.w(TAG, "  Force finishing activity "
2784                                + r.intent.getComponent().flattenToShortString());
2785                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
2786                    }
2787                }
2788            }
2789        }
2790    }
2791
2792    final void finishVoiceTask(IVoiceInteractionSession session) {
2793        IBinder sessionBinder = session.asBinder();
2794        boolean didOne = false;
2795        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2796            TaskRecord tr = mTaskHistory.get(taskNdx);
2797            if (tr.voiceSession != null && tr.voiceSession.asBinder() == sessionBinder) {
2798                for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
2799                    ActivityRecord r = tr.mActivities.get(activityNdx);
2800                    if (!r.finishing) {
2801                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice",
2802                                false);
2803                        didOne = true;
2804                    }
2805                }
2806            }
2807        }
2808        if (didOne) {
2809            mService.updateOomAdjLocked();
2810        }
2811    }
2812
2813    final boolean finishActivityAffinityLocked(ActivityRecord r) {
2814        ArrayList<ActivityRecord> activities = r.task.mActivities;
2815        for (int index = activities.indexOf(r); index >= 0; --index) {
2816            ActivityRecord cur = activities.get(index);
2817            if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) {
2818                break;
2819            }
2820            finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
2821        }
2822        return true;
2823    }
2824
2825    final void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
2826        // send the result
2827        ActivityRecord resultTo = r.resultTo;
2828        if (resultTo != null) {
2829            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
2830                    + " who=" + r.resultWho + " req=" + r.requestCode
2831                    + " res=" + resultCode + " data=" + resultData);
2832            if (resultTo.userId != r.userId) {
2833                if (resultData != null) {
2834                    resultData.prepareToLeaveUser(r.userId);
2835                }
2836            }
2837            if (r.info.applicationInfo.uid > 0) {
2838                mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
2839                        resultTo.packageName, resultData,
2840                        resultTo.getUriPermissionsLocked(), resultTo.userId);
2841            }
2842            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
2843                                     resultData);
2844            r.resultTo = null;
2845        }
2846        else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
2847
2848        // Make sure this HistoryRecord is not holding on to other resources,
2849        // because clients have remote IPC references to this object so we
2850        // can't assume that will go away and want to avoid circular IPC refs.
2851        r.results = null;
2852        r.pendingResults = null;
2853        r.newIntents = null;
2854        r.icicle = null;
2855    }
2856
2857    /**
2858     * @return Returns true if this activity has been removed from the history
2859     * list, or false if it is still in the list and will be removed later.
2860     */
2861    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
2862            String reason, boolean oomAdj) {
2863        if (r.finishing) {
2864            Slog.w(TAG, "Duplicate finish request for " + r);
2865            return false;
2866        }
2867
2868        r.makeFinishingLocked();
2869        final TaskRecord task = r.task;
2870        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2871                r.userId, System.identityHashCode(r),
2872                task.taskId, r.shortComponentName, reason);
2873        final ArrayList<ActivityRecord> activities = task.mActivities;
2874        final int index = activities.indexOf(r);
2875        if (index < (activities.size() - 1)) {
2876            task.setFrontOfTask();
2877            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
2878                // If the caller asked that this activity (and all above it)
2879                // be cleared when the task is reset, don't lose that information,
2880                // but propagate it up to the next activity.
2881                ActivityRecord next = activities.get(index+1);
2882                next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
2883            }
2884        }
2885
2886        r.pauseKeyDispatchingLocked();
2887
2888        adjustFocusedActivityLocked(r, "finishActivity");
2889
2890        finishActivityResultsLocked(r, resultCode, resultData);
2891
2892        if (mResumedActivity == r) {
2893            boolean endTask = index <= 0;
2894            if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2895                    "Prepare close transition: finishing " + r);
2896            mWindowManager.prepareAppTransition(endTask
2897                    ? AppTransition.TRANSIT_TASK_CLOSE
2898                    : AppTransition.TRANSIT_ACTIVITY_CLOSE, false);
2899
2900            // Tell window manager to prepare for this one to be removed.
2901            mWindowManager.setAppVisibility(r.appToken, false);
2902
2903            if (mPausingActivity == null) {
2904                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
2905                if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2906                        "finish() => pause with userLeaving=false");
2907                startPausingLocked(false, false, false, false);
2908            }
2909
2910            if (endTask) {
2911                mStackSupervisor.removeLockedTaskLocked(task);
2912            }
2913        } else if (r.state != ActivityState.PAUSING) {
2914            // If the activity is PAUSING, we will complete the finish once
2915            // it is done pausing; else we can just directly finish it here.
2916            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
2917            return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
2918        } else {
2919            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
2920        }
2921
2922        return false;
2923    }
2924
2925    static final int FINISH_IMMEDIATELY = 0;
2926    static final int FINISH_AFTER_PAUSE = 1;
2927    static final int FINISH_AFTER_VISIBLE = 2;
2928
2929    final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
2930        // First things first: if this activity is currently visible,
2931        // and the resumed activity is not yet visible, then hold off on
2932        // finishing until the resumed one becomes visible.
2933        if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
2934            if (!mStackSupervisor.mStoppingActivities.contains(r)) {
2935                mStackSupervisor.mStoppingActivities.add(r);
2936                if (mStackSupervisor.mStoppingActivities.size() > 3
2937                        || r.frontOfTask && mTaskHistory.size() <= 1) {
2938                    // If we already have a few activities waiting to stop,
2939                    // then give up on things going idle and start clearing
2940                    // them out. Or if r is the last of activity of the last task the stack
2941                    // will be empty and must be cleared immediately.
2942                    mStackSupervisor.scheduleIdleLocked();
2943                } else {
2944                    mStackSupervisor.checkReadyForSleepLocked();
2945                }
2946            }
2947            if (DEBUG_STATES) Slog.v(TAG_STATES,
2948                    "Moving to STOPPING: "+ r + " (finish requested)");
2949            r.state = ActivityState.STOPPING;
2950            if (oomAdj) {
2951                mService.updateOomAdjLocked();
2952            }
2953            return r;
2954        }
2955
2956        // make sure the record is cleaned out of other places.
2957        mStackSupervisor.mStoppingActivities.remove(r);
2958        mStackSupervisor.mGoingToSleepActivities.remove(r);
2959        mStackSupervisor.mWaitingVisibleActivities.remove(r);
2960        if (mResumedActivity == r) {
2961            mResumedActivity = null;
2962        }
2963        final ActivityState prevState = r.state;
2964        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
2965        r.state = ActivityState.FINISHING;
2966
2967        if (mode == FINISH_IMMEDIATELY
2968                || (mode == FINISH_AFTER_PAUSE && prevState == ActivityState.PAUSED)
2969                || prevState == ActivityState.STOPPED
2970                || prevState == ActivityState.INITIALIZING) {
2971            // If this activity is already stopped, we can just finish
2972            // it right now.
2973            r.makeFinishingLocked();
2974            boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
2975            if (activityRemoved) {
2976                mStackSupervisor.resumeTopActivitiesLocked();
2977            }
2978            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
2979                    "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
2980                    " destroy returned removed=" + activityRemoved);
2981            return activityRemoved ? null : r;
2982        }
2983
2984        // Need to go through the full pause cycle to get this
2985        // activity into the stopped state and then finish it.
2986        if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
2987        mStackSupervisor.mFinishingActivities.add(r);
2988        r.resumeKeyDispatchingLocked();
2989        mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
2990        return r;
2991    }
2992
2993    void finishAllActivitiesLocked(boolean immediately) {
2994        boolean noActivitiesInStack = true;
2995        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
2996            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
2997            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
2998                final ActivityRecord r = activities.get(activityNdx);
2999                noActivitiesInStack = false;
3000                if (r.finishing && !immediately) {
3001                    continue;
3002                }
3003                Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r + " immediately");
3004                finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
3005            }
3006        }
3007        if (noActivitiesInStack) {
3008            mActivityContainer.onTaskListEmptyLocked();
3009        }
3010    }
3011
3012    final boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) {
3013        // Basic case: for simple app-centric recents, we need to recreate
3014        // the task if the affinity has changed.
3015        if (srec == null || srec.task.affinity == null ||
3016                !srec.task.affinity.equals(destAffinity)) {
3017            return true;
3018        }
3019        // Document-centric case: an app may be split in to multiple documents;
3020        // they need to re-create their task if this current activity is the root
3021        // of a document, unless simply finishing it will return them to the the
3022        // correct app behind.
3023        if (srec.frontOfTask && srec.task != null && srec.task.getBaseIntent() != null
3024                && srec.task.getBaseIntent().isDocument()) {
3025            // Okay, this activity is at the root of its task.  What to do, what to do...
3026            if (srec.task.getTaskToReturnTo() != ActivityRecord.APPLICATION_ACTIVITY_TYPE) {
3027                // Finishing won't return to an application, so we need to recreate.
3028                return true;
3029            }
3030            // We now need to get the task below it to determine what to do.
3031            int taskIdx = mTaskHistory.indexOf(srec.task);
3032            if (taskIdx <= 0) {
3033                Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec);
3034                return false;
3035            }
3036            if (taskIdx == 0) {
3037                // At the bottom of the stack, nothing to go back to.
3038                return true;
3039            }
3040            TaskRecord prevTask = mTaskHistory.get(taskIdx);
3041            if (!srec.task.affinity.equals(prevTask.affinity)) {
3042                // These are different apps, so need to recreate.
3043                return true;
3044            }
3045        }
3046        return false;
3047    }
3048
3049    final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
3050            Intent resultData) {
3051        final TaskRecord task = srec.task;
3052        final ArrayList<ActivityRecord> activities = task.mActivities;
3053        final int start = activities.indexOf(srec);
3054        if (!mTaskHistory.contains(task) || (start < 0)) {
3055            return false;
3056        }
3057        int finishTo = start - 1;
3058        ActivityRecord parent = finishTo < 0 ? null : activities.get(finishTo);
3059        boolean foundParentInTask = false;
3060        final ComponentName dest = destIntent.getComponent();
3061        if (start > 0 && dest != null) {
3062            for (int i = finishTo; i >= 0; i--) {
3063                ActivityRecord r = activities.get(i);
3064                if (r.info.packageName.equals(dest.getPackageName()) &&
3065                        r.info.name.equals(dest.getClassName())) {
3066                    finishTo = i;
3067                    parent = r;
3068                    foundParentInTask = true;
3069                    break;
3070                }
3071            }
3072        }
3073
3074        IActivityController controller = mService.mController;
3075        if (controller != null) {
3076            ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
3077            if (next != null) {
3078                // ask watcher if this is allowed
3079                boolean resumeOK = true;
3080                try {
3081                    resumeOK = controller.activityResuming(next.packageName);
3082                } catch (RemoteException e) {
3083                    mService.mController = null;
3084                    Watchdog.getInstance().setActivityController(null);
3085                }
3086
3087                if (!resumeOK) {
3088                    return false;
3089                }
3090            }
3091        }
3092        final long origId = Binder.clearCallingIdentity();
3093        for (int i = start; i > finishTo; i--) {
3094            ActivityRecord r = activities.get(i);
3095            requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
3096            // Only return the supplied result for the first activity finished
3097            resultCode = Activity.RESULT_CANCELED;
3098            resultData = null;
3099        }
3100
3101        if (parent != null && foundParentInTask) {
3102            final int parentLaunchMode = parent.info.launchMode;
3103            final int destIntentFlags = destIntent.getFlags();
3104            if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
3105                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
3106                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
3107                    (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3108                parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
3109                        srec.packageName);
3110            } else {
3111                try {
3112                    ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
3113                            destIntent.getComponent(), 0, srec.userId);
3114                    int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent,
3115                            null, aInfo, null, null, parent.appToken, null,
3116                            0, -1, parent.launchedFromUid, parent.launchedFromPackage,
3117                            -1, parent.launchedFromUid, 0, null, false, true, null, null, null);
3118                    foundParentInTask = res == ActivityManager.START_SUCCESS;
3119                } catch (RemoteException e) {
3120                    foundParentInTask = false;
3121                }
3122                requestFinishActivityLocked(parent.appToken, resultCode,
3123                        resultData, "navigate-top", true);
3124            }
3125        }
3126        Binder.restoreCallingIdentity(origId);
3127        return foundParentInTask;
3128    }
3129    /**
3130     * Perform the common clean-up of an activity record.  This is called both
3131     * as part of destroyActivityLocked() (when destroying the client-side
3132     * representation) and cleaning things up as a result of its hosting
3133     * processing going away, in which case there is no remaining client-side
3134     * state to destroy so only the cleanup here is needed.
3135     *
3136     * Note: Call before #removeActivityFromHistoryLocked.
3137     */
3138    final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices,
3139            boolean setState) {
3140        if (mResumedActivity == r) {
3141            mResumedActivity = null;
3142        }
3143        if (mPausingActivity == r) {
3144            mPausingActivity = null;
3145        }
3146        mService.clearFocusedActivity(r);
3147
3148        r.configDestroy = false;
3149        r.frozenBeforeDestroy = false;
3150
3151        if (setState) {
3152            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
3153            r.state = ActivityState.DESTROYED;
3154            if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
3155            r.app = null;
3156        }
3157
3158        // Make sure this record is no longer in the pending finishes list.
3159        // This could happen, for example, if we are trimming activities
3160        // down to the max limit while they are still waiting to finish.
3161        mStackSupervisor.mFinishingActivities.remove(r);
3162        mStackSupervisor.mWaitingVisibleActivities.remove(r);
3163
3164        // Remove any pending results.
3165        if (r.finishing && r.pendingResults != null) {
3166            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
3167                PendingIntentRecord rec = apr.get();
3168                if (rec != null) {
3169                    mService.cancelIntentSenderLocked(rec, false);
3170                }
3171            }
3172            r.pendingResults = null;
3173        }
3174
3175        if (cleanServices) {
3176            cleanUpActivityServicesLocked(r);
3177        }
3178
3179        // Get rid of any pending idle timeouts.
3180        removeTimeoutsForActivityLocked(r);
3181        if (getVisibleBehindActivity() == r) {
3182            mStackSupervisor.requestVisibleBehindLocked(r, false);
3183        }
3184    }
3185
3186    private void removeTimeoutsForActivityLocked(ActivityRecord r) {
3187        mStackSupervisor.removeTimeoutsForActivityLocked(r);
3188        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
3189        mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
3190        mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
3191        r.finishLaunchTickingLocked();
3192    }
3193
3194    private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
3195        mStackSupervisor.removeChildActivityContainers(r);
3196        finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
3197        r.makeFinishingLocked();
3198        if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
3199                "Removing activity " + r + " from stack callers=" + Debug.getCallers(5));
3200
3201        r.takeFromHistory();
3202        removeTimeoutsForActivityLocked(r);
3203        if (DEBUG_STATES) Slog.v(TAG_STATES,
3204                "Moving to DESTROYED: " + r + " (removed from history)");
3205        r.state = ActivityState.DESTROYED;
3206        if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
3207        r.app = null;
3208        mWindowManager.removeAppToken(r.appToken);
3209        if (VALIDATE_TOKENS) {
3210            validateAppTokensLocked();
3211        }
3212        final TaskRecord task = r.task;
3213        if (task != null && task.removeActivity(r)) {
3214            if (DEBUG_STACK) Slog.i(TAG_STACK,
3215                    "removeActivityFromHistoryLocked: last activity removed from " + this);
3216            if (mStackSupervisor.isFrontStack(this) && task == topTask() &&
3217                    task.isOverHomeStack()) {
3218                mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason);
3219            }
3220            removeTask(task, reason);
3221        }
3222        cleanUpActivityServicesLocked(r);
3223        r.removeUriPermissionsLocked();
3224    }
3225
3226    /**
3227     * Perform clean-up of service connections in an activity record.
3228     */
3229    final void cleanUpActivityServicesLocked(ActivityRecord r) {
3230        // Throw away any services that have been bound by this activity.
3231        if (r.connections != null) {
3232            Iterator<ConnectionRecord> it = r.connections.iterator();
3233            while (it.hasNext()) {
3234                ConnectionRecord c = it.next();
3235                mService.mServices.removeConnectionLocked(c, null, r);
3236            }
3237            r.connections = null;
3238        }
3239    }
3240
3241    final void scheduleDestroyActivities(ProcessRecord owner, String reason) {
3242        Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG);
3243        msg.obj = new ScheduleDestroyArgs(owner, reason);
3244        mHandler.sendMessage(msg);
3245    }
3246
3247    final void destroyActivitiesLocked(ProcessRecord owner, String reason) {
3248        boolean lastIsOpaque = false;
3249        boolean activityRemoved = false;
3250        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3251            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3252            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3253                final ActivityRecord r = activities.get(activityNdx);
3254                if (r.finishing) {
3255                    continue;
3256                }
3257                if (r.fullscreen) {
3258                    lastIsOpaque = true;
3259                }
3260                if (owner != null && r.app != owner) {
3261                    continue;
3262                }
3263                if (!lastIsOpaque) {
3264                    continue;
3265                }
3266                if (r.isDestroyable()) {
3267                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.state
3268                            + " resumed=" + mResumedActivity
3269                            + " pausing=" + mPausingActivity + " for reason " + reason);
3270                    if (destroyActivityLocked(r, true, reason)) {
3271                        activityRemoved = true;
3272                    }
3273                }
3274            }
3275        }
3276        if (activityRemoved) {
3277            mStackSupervisor.resumeTopActivitiesLocked();
3278        }
3279    }
3280
3281    final boolean safelyDestroyActivityLocked(ActivityRecord r, String reason) {
3282        if (r.isDestroyable()) {
3283            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3284                    "Destroying " + r + " in state " + r.state + " resumed=" + mResumedActivity
3285                    + " pausing=" + mPausingActivity + " for reason " + reason);
3286            return destroyActivityLocked(r, true, reason);
3287        }
3288        return false;
3289    }
3290
3291    final int releaseSomeActivitiesLocked(ProcessRecord app, ArraySet<TaskRecord> tasks,
3292            String reason) {
3293        // Iterate over tasks starting at the back (oldest) first.
3294        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app);
3295        int maxTasks = tasks.size() / 4;
3296        if (maxTasks < 1) {
3297            maxTasks = 1;
3298        }
3299        int numReleased = 0;
3300        for (int taskNdx = 0; taskNdx < mTaskHistory.size() && maxTasks > 0; taskNdx++) {
3301            final TaskRecord task = mTaskHistory.get(taskNdx);
3302            if (!tasks.contains(task)) {
3303                continue;
3304            }
3305            if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Looking for activities to release in " + task);
3306            int curNum = 0;
3307            final ArrayList<ActivityRecord> activities = task.mActivities;
3308            for (int actNdx = 0; actNdx < activities.size(); actNdx++) {
3309                final ActivityRecord activity = activities.get(actNdx);
3310                if (activity.app == app && activity.isDestroyable()) {
3311                    if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + activity
3312                            + " in state " + activity.state + " resumed=" + mResumedActivity
3313                            + " pausing=" + mPausingActivity + " for reason " + reason);
3314                    destroyActivityLocked(activity, true, reason);
3315                    if (activities.get(actNdx) != activity) {
3316                        // Was removed from list, back up so we don't miss the next one.
3317                        actNdx--;
3318                    }
3319                    curNum++;
3320                }
3321            }
3322            if (curNum > 0) {
3323                numReleased += curNum;
3324                maxTasks--;
3325                if (mTaskHistory.get(taskNdx) != task) {
3326                    // The entire task got removed, back up so we don't miss the next one.
3327                    taskNdx--;
3328                }
3329            }
3330        }
3331        if (DEBUG_RELEASE) Slog.d(TAG_RELEASE,
3332                "Done releasing: did " + numReleased + " activities");
3333        return numReleased;
3334    }
3335
3336    /**
3337     * Destroy the current CLIENT SIDE instance of an activity.  This may be
3338     * called both when actually finishing an activity, or when performing
3339     * a configuration switch where we destroy the current client-side object
3340     * but then create a new client-side object for this same HistoryRecord.
3341     */
3342    final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
3343        if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(TAG_SWITCH,
3344                "Removing activity from " + reason + ": token=" + r
3345                + ", app=" + (r.app != null ? r.app.processName : "(null)"));
3346        EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
3347                r.userId, System.identityHashCode(r),
3348                r.task.taskId, r.shortComponentName, reason);
3349
3350        boolean removedFromHistory = false;
3351
3352        cleanUpActivityLocked(r, false, false);
3353
3354        final boolean hadApp = r.app != null;
3355
3356        if (hadApp) {
3357            if (removeFromApp) {
3358                r.app.activities.remove(r);
3359                if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
3360                    mService.mHeavyWeightProcess = null;
3361                    mService.mHandler.sendEmptyMessage(
3362                            ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
3363                }
3364                if (r.app.activities.isEmpty()) {
3365                    // Update any services we are bound to that might care about whether
3366                    // their client may have activities.
3367                    mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
3368                    // No longer have activities, so update LRU list and oom adj.
3369                    mService.updateLruProcessLocked(r.app, false, null);
3370                    mService.updateOomAdjLocked();
3371                }
3372            }
3373
3374            boolean skipDestroy = false;
3375
3376            try {
3377                if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
3378                r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
3379                        r.configChangeFlags);
3380            } catch (Exception e) {
3381                // We can just ignore exceptions here...  if the process
3382                // has crashed, our death notification will clean things
3383                // up.
3384                //Slog.w(TAG, "Exception thrown during finish", e);
3385                if (r.finishing) {
3386                    removeActivityFromHistoryLocked(r, reason + " exceptionInScheduleDestroy");
3387                    removedFromHistory = true;
3388                    skipDestroy = true;
3389                }
3390            }
3391
3392            r.nowVisible = false;
3393
3394            // If the activity is finishing, we need to wait on removing it
3395            // from the list to give it a chance to do its cleanup.  During
3396            // that time it may make calls back with its token so we need to
3397            // be able to find it on the list and so we don't want to remove
3398            // it from the list yet.  Otherwise, we can just immediately put
3399            // it in the destroyed state since we are not removing it from the
3400            // list.
3401            if (r.finishing && !skipDestroy) {
3402                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r
3403                        + " (destroy requested)");
3404                r.state = ActivityState.DESTROYING;
3405                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
3406                mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
3407            } else {
3408                if (DEBUG_STATES) Slog.v(TAG_STATES,
3409                        "Moving to DESTROYED: " + r + " (destroy skipped)");
3410                r.state = ActivityState.DESTROYED;
3411                if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
3412                r.app = null;
3413            }
3414        } else {
3415            // remove this record from the history.
3416            if (r.finishing) {
3417                removeActivityFromHistoryLocked(r, reason + " hadNoApp");
3418                removedFromHistory = true;
3419            } else {
3420                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
3421                r.state = ActivityState.DESTROYED;
3422                if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
3423                r.app = null;
3424            }
3425        }
3426
3427        r.configChangeFlags = 0;
3428
3429        if (!mLRUActivities.remove(r) && hadApp) {
3430            Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
3431        }
3432
3433        return removedFromHistory;
3434    }
3435
3436    final void activityDestroyedLocked(IBinder token, String reason) {
3437        final long origId = Binder.clearCallingIdentity();
3438        try {
3439            ActivityRecord r = ActivityRecord.forTokenLocked(token);
3440            if (r != null) {
3441                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
3442            }
3443            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + r);
3444
3445            if (isInStackLocked(r) != null) {
3446                if (r.state == ActivityState.DESTROYING) {
3447                    cleanUpActivityLocked(r, true, false);
3448                    removeActivityFromHistoryLocked(r, reason);
3449                }
3450            }
3451            mStackSupervisor.resumeTopActivitiesLocked();
3452        } finally {
3453            Binder.restoreCallingIdentity(origId);
3454        }
3455    }
3456
3457    void releaseBackgroundResources(ActivityRecord r) {
3458        if (hasVisibleBehindActivity() &&
3459                !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
3460            if (r == topRunningActivityLocked(null)) {
3461                // Don't release the top activity if it has requested to run behind the next
3462                // activity.
3463                return;
3464            }
3465            if (DEBUG_STATES) Slog.d(TAG_STATES, "releaseBackgroundResources activtyDisplay=" +
3466                    mActivityContainer.mActivityDisplay + " visibleBehind=" + r + " app=" + r.app +
3467                    " thread=" + r.app.thread);
3468            if (r != null && r.app != null && r.app.thread != null) {
3469                try {
3470                    r.app.thread.scheduleCancelVisibleBehind(r.appToken);
3471                } catch (RemoteException e) {
3472                }
3473                mHandler.sendEmptyMessageDelayed(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG, 500);
3474            } else {
3475                Slog.e(TAG, "releaseBackgroundResources: activity " + r + " no longer running");
3476                backgroundResourcesReleased();
3477            }
3478        }
3479    }
3480
3481    final void backgroundResourcesReleased() {
3482        mHandler.removeMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG);
3483        final ActivityRecord r = getVisibleBehindActivity();
3484        if (r != null) {
3485            mStackSupervisor.mStoppingActivities.add(r);
3486            setVisibleBehindActivity(null);
3487            mStackSupervisor.scheduleIdleTimeoutLocked(null);
3488        }
3489        mStackSupervisor.resumeTopActivitiesLocked();
3490    }
3491
3492    boolean hasVisibleBehindActivity() {
3493        return isAttached() && mActivityContainer.mActivityDisplay.hasVisibleBehindActivity();
3494    }
3495
3496    void setVisibleBehindActivity(ActivityRecord r) {
3497        if (isAttached()) {
3498            mActivityContainer.mActivityDisplay.setVisibleBehindActivity(r);
3499        }
3500    }
3501
3502    ActivityRecord getVisibleBehindActivity() {
3503        return isAttached() ? mActivityContainer.mActivityDisplay.mVisibleBehindActivity : null;
3504    }
3505
3506    private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
3507            ProcessRecord app, String listName) {
3508        int i = list.size();
3509        if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
3510            "Removing app " + app + " from list " + listName + " with " + i + " entries");
3511        while (i > 0) {
3512            i--;
3513            ActivityRecord r = list.get(i);
3514            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r);
3515            if (r.app == app) {
3516                if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!");
3517                list.remove(i);
3518                removeTimeoutsForActivityLocked(r);
3519            }
3520        }
3521    }
3522
3523    boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
3524        removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
3525        removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
3526                "mStoppingActivities");
3527        removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
3528                "mGoingToSleepActivities");
3529        removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
3530                "mWaitingVisibleActivities");
3531        removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
3532                "mFinishingActivities");
3533
3534        boolean hasVisibleActivities = false;
3535
3536        // Clean out the history list.
3537        int i = numActivities();
3538        if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
3539                "Removing app " + app + " from history with " + i + " entries");
3540        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
3541            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
3542            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
3543                final ActivityRecord r = activities.get(activityNdx);
3544                --i;
3545                if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
3546                        "Record #" + i + " " + r + ": app=" + r.app);
3547                if (r.app == app) {
3548                    if (r.visible) {
3549                        hasVisibleActivities = true;
3550                    }
3551                    final boolean remove;
3552                    if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
3553                        // Don't currently have state for the activity, or
3554                        // it is finishing -- always remove it.
3555                        remove = true;
3556                    } else if (r.launchCount > 2 &&
3557                            r.lastLaunchTime > (SystemClock.uptimeMillis()-60000)) {
3558                        // We have launched this activity too many times since it was
3559                        // able to run, so give up and remove it.
3560                        remove = true;
3561                    } else {
3562                        // The process may be gone, but the activity lives on!
3563                        remove = false;
3564                    }
3565                    if (remove) {
3566                        if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
3567                                "Removing activity " + r + " from stack at " + i
3568                                + ": haveState=" + r.haveState
3569                                + " stateNotNeeded=" + r.stateNotNeeded
3570                                + " finishing=" + r.finishing
3571                                + " state=" + r.state + " callers=" + Debug.getCallers(5));
3572                        if (!r.finishing) {
3573                            Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
3574                            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3575                                    r.userId, System.identityHashCode(r),
3576                                    r.task.taskId, r.shortComponentName,
3577                                    "proc died without state saved");
3578                            if (r.state == ActivityState.RESUMED) {
3579                                mService.updateUsageStats(r, false);
3580                            }
3581                        }
3582                    } else {
3583                        // We have the current state for this activity, so
3584                        // it can be restarted later when needed.
3585                        if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
3586                        if (DEBUG_APP) Slog.v(TAG_APP,
3587                                "Clearing app during removeHistory for activity " + r);
3588                        r.app = null;
3589                        r.nowVisible = false;
3590                        if (!r.haveState) {
3591                            if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
3592                                    "App died, clearing saved state of " + r);
3593                            r.icicle = null;
3594                        }
3595                    }
3596                    cleanUpActivityLocked(r, true, true);
3597                    if (remove) {
3598                        removeActivityFromHistoryLocked(r, "appDied");
3599                    }
3600                }
3601            }
3602        }
3603
3604        return hasVisibleActivities;
3605    }
3606
3607    final void updateTransitLocked(int transit, Bundle options) {
3608        if (options != null) {
3609            ActivityRecord r = topRunningActivityLocked(null);
3610            if (r != null && r.state != ActivityState.RESUMED) {
3611                r.updateOptionsLocked(options);
3612            } else {
3613                ActivityOptions.abort(options);
3614            }
3615        }
3616        mWindowManager.prepareAppTransition(transit, false);
3617    }
3618
3619    void updateTaskMovement(TaskRecord task, boolean toFront) {
3620        if (task.isPersistable) {
3621            task.mLastTimeMoved = System.currentTimeMillis();
3622            // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
3623            // recently will be most negative, tasks sent to the bottom before that will be less
3624            // negative. Similarly for recent tasks moved to the top which will be most positive.
3625            if (!toFront) {
3626                task.mLastTimeMoved *= -1;
3627            }
3628        }
3629    }
3630
3631    void moveHomeStackTaskToTop(int homeStackTaskType) {
3632        final int top = mTaskHistory.size() - 1;
3633        for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
3634            final TaskRecord task = mTaskHistory.get(taskNdx);
3635            if (task.taskType == homeStackTaskType) {
3636                if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
3637                        "moveHomeStackTaskToTop: moving " + task);
3638                mTaskHistory.remove(taskNdx);
3639                mTaskHistory.add(top, task);
3640                updateTaskMovement(task, true);
3641                return;
3642            }
3643        }
3644    }
3645
3646    final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, Bundle options,
3647            AppTimeTracker timeTracker, String reason) {
3648        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
3649
3650        final int numTasks = mTaskHistory.size();
3651        final int index = mTaskHistory.indexOf(tr);
3652        if (numTasks == 0 || index < 0)  {
3653            // nothing to do!
3654            if (noAnimation) {
3655                ActivityOptions.abort(options);
3656            } else {
3657                updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
3658            }
3659            return;
3660        }
3661
3662        if (timeTracker != null) {
3663            // The caller wants a time tracker associated with this task.
3664            for (int i = tr.mActivities.size() - 1; i >= 0; i--) {
3665                tr.mActivities.get(i).appTimeTracker = timeTracker;
3666            }
3667        }
3668
3669        // Shift all activities with this task up to the top
3670        // of the stack, keeping them in the same internal order.
3671        insertTaskAtTop(tr, null);
3672
3673        // Set focus to the top running activity of this stack.
3674        ActivityRecord r = topRunningActivityLocked(null);
3675        mService.setFocusedActivityLocked(r, reason);
3676
3677        if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
3678        if (noAnimation) {
3679            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
3680            if (r != null) {
3681                mNoAnimActivities.add(r);
3682            }
3683            ActivityOptions.abort(options);
3684        } else {
3685            updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
3686        }
3687
3688        mStackSupervisor.resumeTopActivitiesLocked();
3689        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
3690
3691        if (VALIDATE_TOKENS) {
3692            validateAppTokensLocked();
3693        }
3694    }
3695
3696    /**
3697     * Worker method for rearranging history stack. Implements the function of moving all
3698     * activities for a specific task (gathering them if disjoint) into a single group at the
3699     * bottom of the stack.
3700     *
3701     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
3702     * to premeptively cancel the move.
3703     *
3704     * @param taskId The taskId to collect and move to the bottom.
3705     * @return Returns true if the move completed, false if not.
3706     */
3707    final boolean moveTaskToBackLocked(int taskId) {
3708        final TaskRecord tr = taskForIdLocked(taskId);
3709        if (tr == null) {
3710            Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
3711            return false;
3712        }
3713
3714        Slog.i(TAG, "moveTaskToBack: " + tr);
3715        mStackSupervisor.removeLockedTaskLocked(tr);
3716
3717        // If we have a watcher, preflight the move before committing to it.  First check
3718        // for *other* available tasks, but if none are available, then try again allowing the
3719        // current task to be selected.
3720        if (mStackSupervisor.isFrontStack(this) && mService.mController != null) {
3721            ActivityRecord next = topRunningActivityLocked(null, taskId);
3722            if (next == null) {
3723                next = topRunningActivityLocked(null, 0);
3724            }
3725            if (next != null) {
3726                // ask watcher if this is allowed
3727                boolean moveOK = true;
3728                try {
3729                    moveOK = mService.mController.activityResuming(next.packageName);
3730                } catch (RemoteException e) {
3731                    mService.mController = null;
3732                    Watchdog.getInstance().setActivityController(null);
3733                }
3734                if (!moveOK) {
3735                    return false;
3736                }
3737            }
3738        }
3739
3740        if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
3741
3742        boolean prevIsHome = false;
3743
3744        // If true, we should resume the home activity next if the task we are moving to the
3745        // back is over the home stack. We force to false if the task we are moving to back
3746        // is the home task and we don't want it resumed after moving to the back.
3747        final boolean canGoHome = !tr.isHomeTask() && tr.isOverHomeStack();
3748        if (canGoHome) {
3749            final TaskRecord nextTask = getNextTask(tr);
3750            if (nextTask != null) {
3751                nextTask.setTaskToReturnTo(tr.getTaskToReturnTo());
3752            } else {
3753                prevIsHome = true;
3754            }
3755        }
3756        mTaskHistory.remove(tr);
3757        mTaskHistory.add(0, tr);
3758        updateTaskMovement(tr, false);
3759
3760        // There is an assumption that moving a task to the back moves it behind the home activity.
3761        // We make sure here that some activity in the stack will launch home.
3762        int numTasks = mTaskHistory.size();
3763        for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
3764            final TaskRecord task = mTaskHistory.get(taskNdx);
3765            if (task.isOverHomeStack()) {
3766                break;
3767            }
3768            if (taskNdx == 1) {
3769                // Set the last task before tr to go to home.
3770                task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
3771            }
3772        }
3773
3774        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_TO_BACK, false);
3775        mWindowManager.moveTaskToBottom(taskId);
3776
3777        if (VALIDATE_TOKENS) {
3778            validateAppTokensLocked();
3779        }
3780
3781        final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null;
3782        if (prevIsHome || (task == tr && canGoHome) || (numTasks <= 1 && isOnHomeDisplay())) {
3783            if (!mService.mBooting && !mService.mBooted) {
3784                // Not ready yet!
3785                return false;
3786            }
3787            final int taskToReturnTo = tr.getTaskToReturnTo();
3788            tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
3789            return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null, "moveTaskToBack");
3790        }
3791
3792        mStackSupervisor.resumeTopActivitiesLocked();
3793        return true;
3794    }
3795
3796    static final void logStartActivity(int tag, ActivityRecord r,
3797            TaskRecord task) {
3798        final Uri data = r.intent.getData();
3799        final String strData = data != null ? data.toSafeString() : null;
3800
3801        EventLog.writeEvent(tag,
3802                r.userId, System.identityHashCode(r), task.taskId,
3803                r.shortComponentName, r.intent.getAction(),
3804                r.intent.getType(), strData, r.intent.getFlags());
3805    }
3806
3807    /**
3808     * Make sure the given activity matches the current configuration.  Returns
3809     * false if the activity had to be destroyed.  Returns true if the
3810     * configuration is the same, or the activity will remain running as-is
3811     * for whatever reason.  Ensures the HistoryRecord is updated with the
3812     * correct configuration and all other bookkeeping is handled.
3813     */
3814    final boolean ensureActivityConfigurationLocked(ActivityRecord r,
3815            int globalChanges) {
3816        if (mConfigWillChange) {
3817            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3818                    "Skipping config check (will change): " + r);
3819            return true;
3820        }
3821
3822        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3823                "Ensuring correct configuration: " + r);
3824
3825        // Make sure the current stack override configuration is supported by the top task
3826        // before continuing.
3827        final TaskRecord topTask = topTask();
3828        if (topTask != null && ((topTask.mResizeable && mForcedFullscreen)
3829                    || (!topTask.mResizeable && !mFullscreen))) {
3830            final boolean prevFullscreen = mFullscreen;
3831            final Configuration newOverrideConfig =
3832                    mWindowManager.forceStackToFullscreen(mStackId, !topTask.mResizeable);
3833            updateOverrideConfiguration(newOverrideConfig);
3834            mForcedFullscreen = !prevFullscreen && mFullscreen;
3835            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3836                    "Updated stack config to support task=" + topTask
3837                            + " resizeable=" + topTask.mResizeable
3838                            + " mForcedFullscreen=" + mForcedFullscreen
3839                            + " prevFullscreen=" + prevFullscreen
3840                            + " mFullscreen=" + mFullscreen);
3841        }
3842
3843        // Short circuit: if the two configurations are the exact same
3844        // object (the common case), then there is nothing to do.
3845        Configuration newConfig = mService.mConfiguration;
3846        if (r.configuration == newConfig
3847                && r.stackConfigOverride == mOverrideConfig
3848                && !r.forceNewConfig) {
3849            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3850                    "Configuration unchanged in " + r);
3851            return true;
3852        }
3853
3854        // We don't worry about activities that are finishing.
3855        if (r.finishing) {
3856            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3857                    "Configuration doesn't matter in finishing " + r);
3858            r.stopFreezingScreenLocked(false);
3859            return true;
3860        }
3861
3862        // Okay we now are going to make this activity have the new config.
3863        // But then we need to figure out how it needs to deal with that.
3864        final Configuration oldConfig = r.configuration;
3865        final Configuration oldStackOverride = r.stackConfigOverride;
3866        r.configuration = newConfig;
3867        r.stackConfigOverride = mOverrideConfig;
3868
3869        // Determine what has changed.  May be nothing, if this is a config
3870        // that has come back from the app after going idle.  In that case
3871        // we just want to leave the official config object now in the
3872        // activity and do nothing else.
3873        int stackChanges = oldStackOverride.diff(mOverrideConfig);
3874        if (stackChanges == 0) {
3875            // {@link Configuration#diff} doesn't catch changes from unset values.
3876            // Check for changes we care about.
3877            if (oldStackOverride.orientation != mOverrideConfig.orientation) {
3878                stackChanges |= ActivityInfo.CONFIG_ORIENTATION;
3879            }
3880            if (oldStackOverride.screenHeightDp != mOverrideConfig.screenHeightDp
3881                    || oldStackOverride.screenWidthDp != mOverrideConfig.screenWidthDp) {
3882                stackChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
3883            }
3884            if (oldStackOverride.smallestScreenWidthDp != mOverrideConfig.smallestScreenWidthDp) {
3885                stackChanges |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
3886            }
3887        }
3888        final int changes = oldConfig.diff(newConfig) | stackChanges;
3889        if (changes == 0 && !r.forceNewConfig) {
3890            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3891                    "Configuration no differences in " + r);
3892            return true;
3893        }
3894
3895        // If the activity isn't currently running, just leave the new
3896        // configuration and it will pick that up next time it starts.
3897        if (r.app == null || r.app.thread == null) {
3898            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3899                    "Configuration doesn't matter not running " + r);
3900            r.stopFreezingScreenLocked(false);
3901            r.forceNewConfig = false;
3902            return true;
3903        }
3904
3905        // Figure out how to handle the changes between the configurations.
3906        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3907                "Checking to restart " + r.info.name + ": changed=0x"
3908                + Integer.toHexString(changes) + ", handles=0x"
3909                + Integer.toHexString(r.info.getRealConfigChanged()) + ", newConfig=" + newConfig);
3910
3911        if ((changes&(~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) {
3912            // Aha, the activity isn't handling the change, so DIE DIE DIE.
3913            r.configChangeFlags |= changes;
3914            r.startFreezingScreenLocked(r.app, globalChanges);
3915            r.forceNewConfig = false;
3916            if (r.app == null || r.app.thread == null) {
3917                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3918                        "Config is destroying non-running " + r);
3919                destroyActivityLocked(r, true, "config");
3920            } else if (r.state == ActivityState.PAUSING) {
3921                // A little annoying: we are waiting for this activity to
3922                // finish pausing.  Let's not do anything now, but just
3923                // flag that it needs to be restarted when done pausing.
3924                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3925                        "Config is skipping already pausing " + r);
3926                r.configDestroy = true;
3927                return true;
3928            } else if (r.state == ActivityState.RESUMED) {
3929                // Try to optimize this case: the configuration is changing
3930                // and we need to restart the top, resumed activity.
3931                // Instead of doing the normal handshaking, just say
3932                // "restart!".
3933                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3934                        "Config is relaunching resumed " + r);
3935                relaunchActivityLocked(r, r.configChangeFlags, true);
3936                r.configChangeFlags = 0;
3937            } else {
3938                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
3939                        "Config is relaunching non-resumed " + r);
3940                relaunchActivityLocked(r, r.configChangeFlags, false);
3941                r.configChangeFlags = 0;
3942            }
3943
3944            // All done...  tell the caller we weren't able to keep this
3945            // activity around.
3946            return false;
3947        }
3948
3949        // Default case: the activity can handle this new configuration, so hand it over.
3950        // NOTE: We only forward the stack override configuration as the system level configuration
3951        // changes is always sent to all processes when they happen so it can just use whatever
3952        // system level configuration it last got.
3953        if (r.app != null && r.app.thread != null) {
3954            try {
3955                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending new config to " + r);
3956                r.app.thread.scheduleActivityConfigurationChanged(
3957                        r.appToken, new Configuration(mOverrideConfig));
3958            } catch (RemoteException e) {
3959                // If process died, whatever.
3960            }
3961        }
3962        r.stopFreezingScreenLocked(false);
3963
3964        return true;
3965    }
3966
3967    private boolean relaunchActivityLocked(ActivityRecord r, int changes, boolean andResume) {
3968        List<ResultInfo> results = null;
3969        List<ReferrerIntent> newIntents = null;
3970        if (andResume) {
3971            results = r.results;
3972            newIntents = r.newIntents;
3973        }
3974        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
3975                "Relaunching: " + r + " with results=" + results + " newIntents=" + newIntents
3976                + " andResume=" + andResume);
3977        EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
3978                : EventLogTags.AM_RELAUNCH_ACTIVITY, r.userId, System.identityHashCode(r),
3979                r.task.taskId, r.shortComponentName);
3980
3981        r.startFreezingScreenLocked(r.app, 0);
3982
3983        mStackSupervisor.removeChildActivityContainers(r);
3984
3985        try {
3986            if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
3987                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r);
3988            r.forceNewConfig = false;
3989            r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
3990                    !andResume, new Configuration(mService.mConfiguration),
3991                    new Configuration(mOverrideConfig));
3992            // Note: don't need to call pauseIfSleepingLocked() here, because
3993            // the caller will only pass in 'andResume' if this activity is
3994            // currently resumed, which implies we aren't sleeping.
3995        } catch (RemoteException e) {
3996            if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
3997        }
3998
3999        if (andResume) {
4000            r.results = null;
4001            r.newIntents = null;
4002            r.state = ActivityState.RESUMED;
4003        } else {
4004            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4005            r.state = ActivityState.PAUSED;
4006        }
4007
4008        return true;
4009    }
4010
4011    boolean willActivityBeVisibleLocked(IBinder token) {
4012        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4013            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4014            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4015                final ActivityRecord r = activities.get(activityNdx);
4016                if (r.appToken == token) {
4017                    return true;
4018                }
4019                if (r.fullscreen && !r.finishing) {
4020                    return false;
4021                }
4022            }
4023        }
4024        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
4025        if (r == null) {
4026            return false;
4027        }
4028        if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false,"
4029                + " would have returned true for r=" + r);
4030        return !r.finishing;
4031    }
4032
4033    void closeSystemDialogsLocked() {
4034        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4035            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4036            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4037                final ActivityRecord r = activities.get(activityNdx);
4038                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
4039                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
4040                }
4041            }
4042        }
4043    }
4044
4045    boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
4046            boolean doit, boolean evenPersistent, int userId) {
4047        boolean didSomething = false;
4048        TaskRecord lastTask = null;
4049        ComponentName homeActivity = null;
4050        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4051            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4052            int numActivities = activities.size();
4053            for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
4054                ActivityRecord r = activities.get(activityNdx);
4055                final boolean sameComponent =
4056                        (r.packageName.equals(packageName) && (filterByClasses == null
4057                                || filterByClasses.contains(r.realActivity.getClassName())))
4058                        || (packageName == null && r.userId == userId);
4059                if ((userId == UserHandle.USER_ALL || r.userId == userId)
4060                        && (sameComponent || r.task == lastTask)
4061                        && (r.app == null || evenPersistent || !r.app.persistent)) {
4062                    if (!doit) {
4063                        if (r.finishing) {
4064                            // If this activity is just finishing, then it is not
4065                            // interesting as far as something to stop.
4066                            continue;
4067                        }
4068                        return true;
4069                    }
4070                    if (r.isHomeActivity()) {
4071                        if (homeActivity != null && homeActivity.equals(r.realActivity)) {
4072                            Slog.i(TAG, "Skip force-stop again " + r);
4073                            continue;
4074                        } else {
4075                            homeActivity = r.realActivity;
4076                        }
4077                    }
4078                    didSomething = true;
4079                    Slog.i(TAG, "  Force finishing activity " + r);
4080                    if (sameComponent) {
4081                        if (r.app != null) {
4082                            r.app.removed = true;
4083                        }
4084                        r.app = null;
4085                    }
4086                    lastTask = r.task;
4087                    if (finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
4088                            true)) {
4089                        // r has been deleted from mActivities, accommodate.
4090                        --numActivities;
4091                        --activityNdx;
4092                    }
4093                }
4094            }
4095        }
4096        return didSomething;
4097    }
4098
4099    void getTasksLocked(List<RunningTaskInfo> list, int callingUid, boolean allowed) {
4100        boolean focusedStack = mStackSupervisor.getFocusedStack() == this;
4101        boolean topTask = true;
4102        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4103            final TaskRecord task = mTaskHistory.get(taskNdx);
4104            if (task.getTopActivity() == null) {
4105                continue;
4106            }
4107            ActivityRecord r = null;
4108            ActivityRecord top = null;
4109            ActivityRecord tmp;
4110            int numActivities = 0;
4111            int numRunning = 0;
4112            final ArrayList<ActivityRecord> activities = task.mActivities;
4113            if (!allowed && !task.isHomeTask() && task.effectiveUid != callingUid) {
4114                continue;
4115            }
4116            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4117                tmp = activities.get(activityNdx);
4118                if (tmp.finishing) {
4119                    continue;
4120                }
4121                r = tmp;
4122
4123                // Initialize state for next task if needed.
4124                if (top == null || (top.state == ActivityState.INITIALIZING)) {
4125                    top = r;
4126                    numActivities = numRunning = 0;
4127                }
4128
4129                // Add 'r' into the current task.
4130                numActivities++;
4131                if (r.app != null && r.app.thread != null) {
4132                    numRunning++;
4133                }
4134
4135                if (DEBUG_ALL) Slog.v(
4136                    TAG, r.intent.getComponent().flattenToShortString()
4137                    + ": task=" + r.task);
4138            }
4139
4140            RunningTaskInfo ci = new RunningTaskInfo();
4141            ci.id = task.taskId;
4142            ci.baseActivity = r.intent.getComponent();
4143            ci.topActivity = top.intent.getComponent();
4144            ci.lastActiveTime = task.lastActiveTime;
4145            if (focusedStack && topTask) {
4146                // Give the latest time to ensure foreground task can be sorted
4147                // at the first, because lastActiveTime of creating task is 0.
4148                ci.lastActiveTime = System.currentTimeMillis();
4149                topTask = false;
4150            }
4151
4152            if (top.task != null) {
4153                ci.description = top.task.lastDescription;
4154            }
4155            ci.numActivities = numActivities;
4156            ci.numRunning = numRunning;
4157            list.add(ci);
4158        }
4159    }
4160
4161    public void unhandledBackLocked() {
4162        final int top = mTaskHistory.size() - 1;
4163        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Performing unhandledBack(): top activity at " + top);
4164        if (top >= 0) {
4165            final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
4166            int activityTop = activities.size() - 1;
4167            if (activityTop > 0) {
4168                finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
4169                        "unhandled-back", true);
4170            }
4171        }
4172    }
4173
4174    /**
4175     * Reset local parameters because an app's activity died.
4176     * @param app The app of the activity that died.
4177     * @return result from removeHistoryRecordsForAppLocked.
4178     */
4179    boolean handleAppDiedLocked(ProcessRecord app) {
4180        if (mPausingActivity != null && mPausingActivity.app == app) {
4181            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
4182                    "App died while pausing: " + mPausingActivity);
4183            mPausingActivity = null;
4184        }
4185        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4186            mLastPausedActivity = null;
4187            mLastNoHistoryActivity = null;
4188        }
4189
4190        return removeHistoryRecordsForAppLocked(app);
4191    }
4192
4193    void handleAppCrashLocked(ProcessRecord app) {
4194        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4195            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4196            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4197                final ActivityRecord r = activities.get(activityNdx);
4198                if (r.app == app) {
4199                    Slog.w(TAG, "  Force finishing activity "
4200                            + r.intent.getComponent().flattenToShortString());
4201                    // Force the destroy to skip right to removal.
4202                    r.app = null;
4203                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
4204                }
4205            }
4206        }
4207    }
4208
4209    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
4210            boolean dumpClient, String dumpPackage, boolean needSep, String header) {
4211        boolean printed = false;
4212        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4213            final TaskRecord task = mTaskHistory.get(taskNdx);
4214            printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
4215                    mTaskHistory.get(taskNdx).mActivities, "    ", "Hist", true, !dumpAll,
4216                    dumpClient, dumpPackage, needSep, header,
4217                    "    Task id #" + task.taskId);
4218            if (printed) {
4219                header = null;
4220            }
4221        }
4222        return printed;
4223    }
4224
4225    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
4226        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
4227
4228        if ("all".equals(name)) {
4229            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4230                activities.addAll(mTaskHistory.get(taskNdx).mActivities);
4231            }
4232        } else if ("top".equals(name)) {
4233            final int top = mTaskHistory.size() - 1;
4234            if (top >= 0) {
4235                final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities;
4236                int listTop = list.size() - 1;
4237                if (listTop >= 0) {
4238                    activities.add(list.get(listTop));
4239                }
4240            }
4241        } else {
4242            ItemMatcher matcher = new ItemMatcher();
4243            matcher.build(name);
4244
4245            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4246                for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) {
4247                    if (matcher.match(r1, r1.intent.getComponent())) {
4248                        activities.add(r1);
4249                    }
4250                }
4251            }
4252        }
4253
4254        return activities;
4255    }
4256
4257    ActivityRecord restartPackage(String packageName) {
4258        ActivityRecord starting = topRunningActivityLocked(null);
4259
4260        // All activities that came from the package must be
4261        // restarted as if there was a config change.
4262        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4263            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
4264            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
4265                final ActivityRecord a = activities.get(activityNdx);
4266                if (a.info.packageName.equals(packageName)) {
4267                    a.forceNewConfig = true;
4268                    if (starting != null && a == starting && a.visible) {
4269                        a.startFreezingScreenLocked(starting.app,
4270                                ActivityInfo.CONFIG_SCREEN_LAYOUT);
4271                    }
4272                }
4273            }
4274        }
4275
4276        return starting;
4277    }
4278
4279    void removeTask(TaskRecord task, String reason) {
4280        removeTask(task, reason, true /* notMoving */);
4281    }
4282
4283    /**
4284     * Removes the input task from this stack.
4285     * @param task to remove.
4286     * @param reason for removal.
4287     * @param notMoving task to another stack. In the case we are moving we don't want to perform
4288     *                  some operations on the task like removing it from window manager or recents.
4289     */
4290    void removeTask(TaskRecord task, String reason, boolean notMoving) {
4291        if (notMoving) {
4292            mStackSupervisor.removeLockedTaskLocked(task);
4293            mWindowManager.removeTask(task.taskId);
4294        }
4295
4296        final ActivityRecord r = mResumedActivity;
4297        if (r != null && r.task == task) {
4298            mResumedActivity = null;
4299        }
4300
4301        final int taskNdx = mTaskHistory.indexOf(task);
4302        final int topTaskNdx = mTaskHistory.size() - 1;
4303        if (task.isOverHomeStack() && taskNdx < topTaskNdx) {
4304            final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1);
4305            if (!nextTask.isOverHomeStack()) {
4306                nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
4307            }
4308        }
4309        mTaskHistory.remove(task);
4310        updateTaskMovement(task, true);
4311
4312        if (notMoving && task.mActivities.isEmpty()) {
4313            final boolean isVoiceSession = task.voiceSession != null;
4314            if (isVoiceSession) {
4315                try {
4316                    task.voiceSession.taskFinished(task.intent, task.taskId);
4317                } catch (RemoteException e) {
4318                }
4319            }
4320            if (task.autoRemoveFromRecents() || isVoiceSession) {
4321                // Task creator asked to remove this when done, or this task was a voice
4322                // interaction, so it should not remain on the recent tasks list.
4323                mRecentTasks.remove(task);
4324                task.removedFromRecents();
4325            }
4326        }
4327
4328        if (mTaskHistory.isEmpty()) {
4329            if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
4330            final boolean notHomeStack = !isHomeStack();
4331            if (isOnHomeDisplay()) {
4332                String myReason = reason + " leftTaskHistoryEmpty";
4333                if (mFullscreen || !adjustFocusToNextVisibleStackLocked(null, myReason)) {
4334                    mStackSupervisor.moveHomeStack(notHomeStack, myReason);
4335                }
4336            }
4337            if (mStacks != null) {
4338                mStacks.remove(this);
4339                mStacks.add(0, this);
4340            }
4341            if (notHomeStack) {
4342                mActivityContainer.onTaskListEmptyLocked();
4343            }
4344        }
4345
4346        task.stack = null;
4347    }
4348
4349    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
4350            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
4351            boolean toTop) {
4352        TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
4353                voiceInteractor);
4354        addTask(task, toTop, false);
4355        return task;
4356    }
4357
4358    ArrayList<TaskRecord> getAllTasks() {
4359        return new ArrayList<>(mTaskHistory);
4360    }
4361
4362    void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
4363        task.stack = this;
4364        if (toTop) {
4365            insertTaskAtTop(task, null);
4366        } else {
4367            mTaskHistory.add(0, task);
4368            updateTaskMovement(task, false);
4369        }
4370        if (!moving && task.voiceSession != null) {
4371            try {
4372                task.voiceSession.taskStarted(task.intent, task.taskId);
4373            } catch (RemoteException e) {
4374            }
4375        }
4376    }
4377
4378    public int getStackId() {
4379        return mStackId;
4380    }
4381
4382    @Override
4383    public String toString() {
4384        return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
4385                + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
4386    }
4387
4388    boolean updateOverrideConfiguration(Configuration newConfig) {
4389        Configuration oldConfig = mOverrideConfig;
4390        mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
4391        // We override the configuration only when the stack's dimensions are different from
4392        // the display. In this manner, we know that if the override configuration is empty,
4393        // the stack is necessarily full screen.
4394        mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
4395        return !mOverrideConfig.equals(oldConfig);
4396    }
4397
4398    void onLockTaskPackagesUpdatedLocked() {
4399        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
4400            mTaskHistory.get(taskNdx).setLockTaskAuth();
4401        }
4402    }
4403}
4404