Home | History | Annotate | Download | only in am
      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 
     17 package com.android.server.am;
     18 
     19 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
     20 
     21 import static com.android.server.am.ActivityManagerDebugConfig.*;
     22 
     23 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
     24 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
     25 
     26 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
     27 
     28 import android.util.ArraySet;
     29 import com.android.internal.app.IVoiceInteractor;
     30 import com.android.internal.content.ReferrerIntent;
     31 import com.android.internal.os.BatteryStatsImpl;
     32 import com.android.server.Watchdog;
     33 import com.android.server.am.ActivityManagerService.ItemMatcher;
     34 import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
     35 import com.android.server.wm.AppTransition;
     36 import com.android.server.wm.TaskGroup;
     37 import com.android.server.wm.WindowManagerService;
     38 
     39 import android.app.Activity;
     40 import android.app.ActivityManager;
     41 import android.app.ActivityOptions;
     42 import android.app.AppGlobals;
     43 import android.app.IActivityController;
     44 import android.app.ResultInfo;
     45 import android.app.ActivityManager.RunningTaskInfo;
     46 import android.content.ComponentName;
     47 import android.content.Intent;
     48 import android.content.pm.ActivityInfo;
     49 import android.content.pm.PackageManager;
     50 import android.content.res.Configuration;
     51 import android.graphics.Bitmap;
     52 import android.net.Uri;
     53 import android.os.Binder;
     54 import android.os.Bundle;
     55 import android.os.Debug;
     56 import android.os.Handler;
     57 import android.os.IBinder;
     58 import android.os.Looper;
     59 import android.os.Message;
     60 import android.os.PersistableBundle;
     61 import android.os.RemoteException;
     62 import android.os.SystemClock;
     63 import android.os.Trace;
     64 import android.os.UserHandle;
     65 import android.service.voice.IVoiceInteractionSession;
     66 import android.util.EventLog;
     67 import android.util.Slog;
     68 import android.view.Display;
     69 
     70 import java.io.FileDescriptor;
     71 import java.io.PrintWriter;
     72 import java.lang.ref.WeakReference;
     73 import java.util.ArrayList;
     74 import java.util.Iterator;
     75 import java.util.List;
     76 import java.util.Objects;
     77 import java.util.Set;
     78 
     79 /**
     80  * State and management of a single stack of activities.
     81  */
     82 final 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