Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright (C) 2006 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.app.ActivityManager.LOCK_TASK_MODE_NONE;
     20 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
     21 import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
     22 import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
     23 import static android.app.ActivityOptions.ANIM_CUSTOM;
     24 import static android.app.ActivityOptions.ANIM_REMOTE_ANIMATION;
     25 import static android.app.ActivityOptions.ANIM_SCALE_UP;
     26 import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
     27 import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
     28 import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
     29 import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP;
     30 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
     31 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
     32 import static android.app.AppOpsManager.MODE_ALLOWED;
     33 import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
     34 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
     35 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
     36 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
     37 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
     38 import static android.app.WindowConfiguration.activityTypeToString;
     39 import static android.content.Intent.ACTION_MAIN;
     40 import static android.content.Intent.CATEGORY_HOME;
     41 import static android.content.Intent.CATEGORY_LAUNCHER;
     42 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
     43 import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
     44 import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
     45 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
     46 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
     47 import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
     48 import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
     49 import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
     50 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
     51 import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
     52 import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
     53 import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
     54 import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
     55 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
     56 import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
     57 import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
     58 import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
     59 import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
     60 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
     61 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
     62 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
     63 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
     64 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
     65 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
     66 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
     67 import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
     68 import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
     69 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
     70 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
     71 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
     72 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
     73 import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
     74 import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
     75 import static android.content.res.Configuration.EMPTY;
     76 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
     77 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
     78 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
     79 import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
     80 import static android.os.Build.VERSION_CODES.HONEYCOMB;
     81 import static android.os.Build.VERSION_CODES.O;
     82 import static android.os.Process.SYSTEM_UID;
     83 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
     84 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
     85 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
     86 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
     87 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
     88 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
     89 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
     90 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SAVED_STATE;
     91 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
     92 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
     93 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
     94 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
     95 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
     96 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
     97 import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
     98 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
     99 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
    100 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
    101 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
    102 import static com.android.server.am.ActivityStack.LAUNCH_TICK;
    103 import static com.android.server.am.ActivityStack.LAUNCH_TICK_MSG;
    104 import static com.android.server.am.ActivityStack.PAUSE_TIMEOUT_MSG;
    105 import static com.android.server.am.ActivityStack.STOP_TIMEOUT_MSG;
    106 import static com.android.server.am.EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME;
    107 import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
    108 import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
    109 import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
    110 import static com.android.server.am.TaskPersister.DEBUG;
    111 import static com.android.server.am.TaskPersister.IMAGE_EXTENSION;
    112 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
    113 import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
    114 import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
    115 import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
    116 import static com.android.server.am.ActivityRecordProto.PROC_ID;
    117 import static com.android.server.am.ActivityRecordProto.STATE;
    118 import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
    119 import static com.android.server.am.ActivityRecordProto.VISIBLE;
    120 import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
    121 import static com.android.server.wm.IdentifierProto.HASH_CODE;
    122 import static com.android.server.wm.IdentifierProto.TITLE;
    123 import static com.android.server.wm.IdentifierProto.USER_ID;
    124 
    125 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
    126 import static org.xmlpull.v1.XmlPullParser.END_TAG;
    127 import static org.xmlpull.v1.XmlPullParser.START_TAG;
    128 
    129 import android.annotation.NonNull;
    130 import android.app.ActivityManager.TaskDescription;
    131 import android.app.ActivityOptions;
    132 import android.app.PendingIntent;
    133 import android.app.PictureInPictureParams;
    134 import android.app.ResultInfo;
    135 import android.app.servertransaction.ActivityLifecycleItem;
    136 import android.app.servertransaction.ActivityRelaunchItem;
    137 import android.app.servertransaction.ClientTransaction;
    138 import android.app.servertransaction.ClientTransactionItem;
    139 import android.app.servertransaction.MoveToDisplayItem;
    140 import android.app.servertransaction.MultiWindowModeChangeItem;
    141 import android.app.servertransaction.NewIntentItem;
    142 import android.app.servertransaction.PauseActivityItem;
    143 import android.app.servertransaction.PipModeChangeItem;
    144 import android.app.servertransaction.ResumeActivityItem;
    145 import android.app.servertransaction.WindowVisibilityItem;
    146 import android.app.servertransaction.ActivityConfigurationChangeItem;
    147 import android.content.ComponentName;
    148 import android.content.Intent;
    149 import android.content.pm.ActivityInfo;
    150 import android.content.pm.ApplicationInfo;
    151 import android.content.res.CompatibilityInfo;
    152 import android.content.res.Configuration;
    153 import android.graphics.Bitmap;
    154 import android.graphics.GraphicBuffer;
    155 import android.graphics.Rect;
    156 import android.os.Binder;
    157 import android.os.Build;
    158 import android.os.Bundle;
    159 import android.os.Debug;
    160 import android.os.IBinder;
    161 import android.os.Message;
    162 import android.os.PersistableBundle;
    163 import android.os.Process;
    164 import android.os.RemoteException;
    165 import android.os.SystemClock;
    166 import android.os.Trace;
    167 import android.os.UserHandle;
    168 import android.os.storage.StorageManager;
    169 import android.service.voice.IVoiceInteractionSession;
    170 import android.util.EventLog;
    171 import android.util.Log;
    172 import android.util.MergedConfiguration;
    173 import android.util.Slog;
    174 import android.util.TimeUtils;
    175 import android.util.proto.ProtoOutputStream;
    176 import android.view.AppTransitionAnimationSpec;
    177 import android.view.IAppTransitionAnimationSpecsFuture;
    178 import android.view.IApplicationToken;
    179 import android.view.RemoteAnimationDefinition;
    180 import android.view.WindowManager.LayoutParams;
    181 
    182 import com.android.internal.R;
    183 import com.android.internal.app.ResolverActivity;
    184 import com.android.internal.content.ReferrerIntent;
    185 import com.android.internal.util.XmlUtils;
    186 import com.android.server.AttributeCache;
    187 import com.android.server.AttributeCache.Entry;
    188 import com.android.server.am.ActivityStack.ActivityState;
    189 import com.android.server.wm.AppWindowContainerController;
    190 import com.android.server.wm.AppWindowContainerListener;
    191 import com.android.server.wm.ConfigurationContainer;
    192 import com.android.server.wm.TaskWindowContainerController;
    193 
    194 import org.xmlpull.v1.XmlPullParser;
    195 import org.xmlpull.v1.XmlPullParserException;
    196 import org.xmlpull.v1.XmlSerializer;
    197 
    198 import java.io.File;
    199 import java.io.IOException;
    200 import java.io.PrintWriter;
    201 import java.lang.ref.WeakReference;
    202 import java.util.ArrayList;
    203 import java.util.Arrays;
    204 import java.util.HashSet;
    205 import java.util.List;
    206 import java.util.Objects;
    207 
    208 /**
    209  * An entry in the history stack, representing an activity.
    210  */
    211 final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener {
    212     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_AM;
    213     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
    214     private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
    215     private static final String TAG_STATES = TAG + POSTFIX_STATES;
    216     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
    217     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
    218     // TODO(b/67864419): Remove once recents component is overridden
    219     private static final String LEGACY_RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
    220 
    221     private static final boolean SHOW_ACTIVITY_START_TIME = true;
    222 
    223     private static final String ATTR_ID = "id";
    224     private static final String TAG_INTENT = "intent";
    225     private static final String ATTR_USERID = "user_id";
    226     private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
    227     private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
    228     private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
    229     private static final String ATTR_RESOLVEDTYPE = "resolved_type";
    230     private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
    231     static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
    232 
    233     final ActivityManagerService service; // owner
    234     final IApplicationToken.Stub appToken; // window manager token
    235     AppWindowContainerController mWindowContainerController;
    236     final ActivityInfo info; // all about me
    237     // TODO: This is duplicated state already contained in info.applicationInfo - remove
    238     ApplicationInfo appInfo; // information about activity's app
    239     final int launchedFromPid; // always the pid who started the activity.
    240     final int launchedFromUid; // always the uid who started the activity.
    241     final String launchedFromPackage; // always the package who started the activity.
    242     final int userId;          // Which user is this running for?
    243     final Intent intent;    // the original intent that generated us
    244     final ComponentName realActivity;  // the intent component, or target of an alias.
    245     final String shortComponentName; // the short component name of the intent
    246     final String resolvedType; // as per original caller;
    247     final String packageName; // the package implementing intent's component
    248     final String processName; // process where this component wants to run
    249     final String taskAffinity; // as per ActivityInfo.taskAffinity
    250     final boolean stateNotNeeded; // As per ActivityInfo.flags
    251     boolean fullscreen; // The activity is opaque and fills the entire space of this task.
    252     // TODO: See if it possible to combine this with the fullscreen field.
    253     final boolean hasWallpaper; // Has a wallpaper window as a background.
    254     final boolean noDisplay;  // activity is not displayed?
    255     private final boolean componentSpecified;  // did caller specify an explicit component?
    256     final boolean rootVoiceInteraction;  // was this the root activity of a voice interaction?
    257 
    258     private CharSequence nonLocalizedLabel;  // the label information from the package mgr.
    259     private int labelRes;           // the label information from the package mgr.
    260     private int icon;               // resource identifier of activity's icon.
    261     private int logo;               // resource identifier of activity's logo.
    262     private int theme;              // resource identifier of activity's theme.
    263     private int realTheme;          // actual theme resource we will use, never 0.
    264     private int windowFlags;        // custom window flags for preview window.
    265     private TaskRecord task;        // the task this is in.
    266     private long createTime = System.currentTimeMillis();
    267     long displayStartTime;  // when we started launching this activity
    268     long fullyDrawnStartTime; // when we started launching this activity
    269     private long startTime;         // last time this activity was started
    270     long lastVisibleTime;   // last time this activity became visible
    271     long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
    272     long pauseTime;         // last time we started pausing the activity
    273     long launchTickTime;    // base time for launch tick messages
    274     // Last configuration reported to the activity in the client process.
    275     private MergedConfiguration mLastReportedConfiguration;
    276     private int mLastReportedDisplayId;
    277     private boolean mLastReportedMultiWindowMode;
    278     private boolean mLastReportedPictureInPictureMode;
    279     CompatibilityInfo compat;// last used compatibility mode
    280     ActivityRecord resultTo; // who started this entry, so will get our reply
    281     final String resultWho; // additional identifier for use by resultTo.
    282     final int requestCode;  // code given by requester (resultTo)
    283     ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
    284     HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
    285     ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
    286     ActivityOptions pendingOptions; // most recently given options
    287     ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
    288     AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
    289     HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
    290     UriPermissionOwner uriPermissions; // current special URI access perms.
    291     ProcessRecord app;      // if non-null, hosting application
    292     private ActivityState mState;    // current state we are in
    293     Bundle  icicle;         // last saved activity state
    294     PersistableBundle persistentState; // last persistently saved activity state
    295     // TODO: See if this is still needed.
    296     boolean frontOfTask;    // is this the root activity of its task?
    297     boolean launchFailed;   // set if a launched failed, to abort on 2nd try
    298     boolean haveState;      // have we gotten the last activity state?
    299     boolean stopped;        // is activity pause finished?
    300     boolean delayedResume;  // not yet resumed because of stopped app switches?
    301     boolean finishing;      // activity in pending finish list?
    302     boolean deferRelaunchUntilPaused;   // relaunch of activity is being deferred until pause is
    303                                         // completed
    304     boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
    305     int configChangeFlags;  // which config values have changed
    306     private boolean keysPaused;     // has key dispatching been paused for it?
    307     int launchMode;         // the launch mode activity attribute.
    308     int lockTaskLaunchMode; // the lockTaskMode manifest attribute, subject to override
    309     boolean visible;        // does this activity's window need to be shown?
    310     boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
    311                                      // might hide this activity?
    312     private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
    313                                         // process that it is hidden.
    314     boolean sleeping;       // have we told the activity to sleep?
    315     boolean nowVisible;     // is this activity's window visible?
    316     boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
    317     boolean idle;           // has the activity gone idle?
    318     boolean hasBeenLaunched;// has this activity ever been launched?
    319     boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
    320     boolean immersive;      // immersive mode (don't interrupt if possible)
    321     boolean forceNewConfig; // force re-create with new config next time
    322     boolean supportsEnterPipOnTaskSwitch;  // This flag is set by the system to indicate that the
    323         // activity can enter picture in picture while pausing (only when switching to another task)
    324     PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
    325         // The PiP params used when deferring the entering of picture-in-picture.
    326     int launchCount;        // count of launches since last state
    327     long lastLaunchTime;    // time of last launch of this activity
    328     ComponentName requestedVrComponent; // the requested component for handling VR mode.
    329 
    330     String stringName;      // for caching of toString().
    331 
    332     private boolean inHistory;  // are we in the history stack?
    333     final ActivityStackSupervisor mStackSupervisor;
    334 
    335     static final int STARTING_WINDOW_NOT_SHOWN = 0;
    336     static final int STARTING_WINDOW_SHOWN = 1;
    337     static final int STARTING_WINDOW_REMOVED = 2;
    338     int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
    339     boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
    340 
    341     TaskDescription taskDescription; // the recents information for this activity
    342     boolean mLaunchTaskBehind; // this activity is actively being launched with
    343         // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
    344 
    345     // These configurations are collected from application's resources based on size-sensitive
    346     // qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
    347     // and drawable-sw400dp will be added to both as 400.
    348     private int[] mVerticalSizeConfigurations;
    349     private int[] mHorizontalSizeConfigurations;
    350     private int[] mSmallestSizeConfigurations;
    351 
    352     boolean pendingVoiceInteractionStart;   // Waiting for activity-invoked voice session
    353     IVoiceInteractionSession voiceSession;  // Voice interaction session for this activity
    354 
    355     // A hint to override the window specified rotation animation, or -1
    356     // to use the window specified value. We use this so that
    357     // we can select the right animation in the cases of starting
    358     // windows, where the app hasn't had time to set a value
    359     // on the window.
    360     int mRotationAnimationHint = -1;
    361 
    362     private boolean mShowWhenLocked;
    363     private boolean mTurnScreenOn;
    364 
    365     /**
    366      * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
    367      */
    368     private final Configuration mTmpConfig = new Configuration();
    369     private final Rect mTmpBounds = new Rect();
    370 
    371     private static String startingWindowStateToString(int state) {
    372         switch (state) {
    373             case STARTING_WINDOW_NOT_SHOWN:
    374                 return "STARTING_WINDOW_NOT_SHOWN";
    375             case STARTING_WINDOW_SHOWN:
    376                 return "STARTING_WINDOW_SHOWN";
    377             case STARTING_WINDOW_REMOVED:
    378                 return "STARTING_WINDOW_REMOVED";
    379             default:
    380                 return "unknown state=" + state;
    381         }
    382     }
    383 
    384     void dump(PrintWriter pw, String prefix) {
    385         final long now = SystemClock.uptimeMillis();
    386         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
    387                 pw.print(" processName="); pw.println(processName);
    388         pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
    389                 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
    390                 pw.print(" userId="); pw.println(userId);
    391         pw.print(prefix); pw.print("app="); pw.println(app);
    392         pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
    393         pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
    394                 pw.print(" task="); pw.println(task);
    395         pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
    396         pw.print(prefix); pw.print("realActivity=");
    397                 pw.println(realActivity.flattenToShortString());
    398         if (appInfo != null) {
    399             pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
    400             if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
    401                 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
    402             }
    403             pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
    404             if (appInfo.splitSourceDirs != null) {
    405                 pw.print(prefix); pw.print("splitDir=");
    406                         pw.println(Arrays.toString(appInfo.splitSourceDirs));
    407             }
    408         }
    409         pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
    410                 pw.print(" componentSpecified="); pw.print(componentSpecified);
    411                 pw.print(" mActivityType="); pw.println(
    412                         activityTypeToString(getActivityType()));
    413         if (rootVoiceInteraction) {
    414             pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
    415         }
    416         pw.print(prefix); pw.print("compat="); pw.print(compat);
    417                 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
    418                 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
    419                 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
    420         pw.println(prefix + "mLastReportedConfigurations:");
    421         mLastReportedConfiguration.dump(pw, prefix + " ");
    422 
    423         pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
    424         if (!getOverrideConfiguration().equals(EMPTY)) {
    425             pw.println(prefix + "OverrideConfiguration=" + getOverrideConfiguration());
    426         }
    427         if (!matchParentBounds()) {
    428             pw.println(prefix + "bounds=" + getBounds());
    429         }
    430         if (resultTo != null || resultWho != null) {
    431             pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
    432                     pw.print(" resultWho="); pw.print(resultWho);
    433                     pw.print(" resultCode="); pw.println(requestCode);
    434         }
    435         if (taskDescription != null) {
    436             final String iconFilename = taskDescription.getIconFilename();
    437             if (iconFilename != null || taskDescription.getLabel() != null ||
    438                     taskDescription.getPrimaryColor() != 0) {
    439                 pw.print(prefix); pw.print("taskDescription:");
    440                         pw.print(" label=\""); pw.print(taskDescription.getLabel());
    441                                 pw.print("\"");
    442                         pw.print(" icon="); pw.print(taskDescription.getInMemoryIcon() != null
    443                                 ? taskDescription.getInMemoryIcon().getByteCount() + " bytes"
    444                                 : "null");
    445                         pw.print(" iconResource="); pw.print(taskDescription.getIconResource());
    446                         pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
    447                         pw.print(" primaryColor=");
    448                         pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
    449                         pw.print(prefix + " backgroundColor=");
    450                         pw.println(Integer.toHexString(taskDescription.getBackgroundColor()));
    451                         pw.print(prefix + " statusBarColor=");
    452                         pw.println(Integer.toHexString(taskDescription.getStatusBarColor()));
    453                         pw.print(prefix + " navigationBarColor=");
    454                         pw.println(Integer.toHexString(taskDescription.getNavigationBarColor()));
    455             }
    456         }
    457         if (results != null) {
    458             pw.print(prefix); pw.print("results="); pw.println(results);
    459         }
    460         if (pendingResults != null && pendingResults.size() > 0) {
    461             pw.print(prefix); pw.println("Pending Results:");
    462             for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
    463                 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
    464                 pw.print(prefix); pw.print("  - ");
    465                 if (pir == null) {
    466                     pw.println("null");
    467                 } else {
    468                     pw.println(pir);
    469                     pir.dump(pw, prefix + "    ");
    470                 }
    471             }
    472         }
    473         if (newIntents != null && newIntents.size() > 0) {
    474             pw.print(prefix); pw.println("Pending New Intents:");
    475             for (int i=0; i<newIntents.size(); i++) {
    476                 Intent intent = newIntents.get(i);
    477                 pw.print(prefix); pw.print("  - ");
    478                 if (intent == null) {
    479                     pw.println("null");
    480                 } else {
    481                     pw.println(intent.toShortString(false, true, false, true));
    482                 }
    483             }
    484         }
    485         if (pendingOptions != null) {
    486             pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
    487         }
    488         if (appTimeTracker != null) {
    489             appTimeTracker.dumpWithHeader(pw, prefix, false);
    490         }
    491         if (uriPermissions != null) {
    492             uriPermissions.dump(pw, prefix);
    493         }
    494         pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
    495                 pw.print(" launchCount="); pw.print(launchCount);
    496                 pw.print(" lastLaunchTime=");
    497                 if (lastLaunchTime == 0) pw.print("0");
    498                 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
    499                 pw.println();
    500         pw.print(prefix); pw.print("haveState="); pw.print(haveState);
    501                 pw.print(" icicle="); pw.println(icicle);
    502         pw.print(prefix); pw.print("state="); pw.print(mState);
    503                 pw.print(" stopped="); pw.print(stopped);
    504                 pw.print(" delayedResume="); pw.print(delayedResume);
    505                 pw.print(" finishing="); pw.println(finishing);
    506         pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
    507                 pw.print(" inHistory="); pw.print(inHistory);
    508                 pw.print(" visible="); pw.print(visible);
    509                 pw.print(" sleeping="); pw.print(sleeping);
    510                 pw.print(" idle="); pw.print(idle);
    511                 pw.print(" mStartingWindowState=");
    512                 pw.println(startingWindowStateToString(mStartingWindowState));
    513         pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
    514                 pw.print(" noDisplay="); pw.print(noDisplay);
    515                 pw.print(" immersive="); pw.print(immersive);
    516                 pw.print(" launchMode="); pw.println(launchMode);
    517         pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
    518                 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
    519         pw.print(prefix); pw.print("mActivityType=");
    520                 pw.println(activityTypeToString(getActivityType()));
    521         if (requestedVrComponent != null) {
    522             pw.print(prefix);
    523             pw.print("requestedVrComponent=");
    524             pw.println(requestedVrComponent);
    525         }
    526         if (displayStartTime != 0 || startTime != 0) {
    527             pw.print(prefix); pw.print("displayStartTime=");
    528                     if (displayStartTime == 0) pw.print("0");
    529                     else TimeUtils.formatDuration(displayStartTime, now, pw);
    530                     pw.print(" startTime=");
    531                     if (startTime == 0) pw.print("0");
    532                     else TimeUtils.formatDuration(startTime, now, pw);
    533                     pw.println();
    534         }
    535         final boolean waitingVisible =
    536                 mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this);
    537         if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
    538             pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
    539                     pw.print(" nowVisible="); pw.print(nowVisible);
    540                     pw.print(" lastVisibleTime=");
    541                     if (lastVisibleTime == 0) pw.print("0");
    542                     else TimeUtils.formatDuration(lastVisibleTime, now, pw);
    543                     pw.println();
    544         }
    545         if (mDeferHidingClient) {
    546             pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
    547         }
    548         if (deferRelaunchUntilPaused || configChangeFlags != 0) {
    549             pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
    550                     pw.print(" configChangeFlags=");
    551                     pw.println(Integer.toHexString(configChangeFlags));
    552         }
    553         if (connections != null) {
    554             pw.print(prefix); pw.print("connections="); pw.println(connections);
    555         }
    556         if (info != null) {
    557             pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
    558             pw.println(prefix + "mLastReportedMultiWindowMode=" + mLastReportedMultiWindowMode
    559                     + " mLastReportedPictureInPictureMode=" + mLastReportedPictureInPictureMode);
    560             if (info.supportsPictureInPicture()) {
    561                 pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
    562                 pw.println(prefix + "supportsEnterPipOnTaskSwitch: "
    563                         + supportsEnterPipOnTaskSwitch);
    564             }
    565             if (info.maxAspectRatio != 0) {
    566                 pw.println(prefix + "maxAspectRatio=" + info.maxAspectRatio);
    567             }
    568         }
    569     }
    570 
    571     void updateApplicationInfo(ApplicationInfo aInfo) {
    572         appInfo = aInfo;
    573         info.applicationInfo = aInfo;
    574     }
    575 
    576     private boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
    577         return crossesSizeThreshold(mHorizontalSizeConfigurations, firstDp, secondDp);
    578     }
    579 
    580     private boolean crossesVerticalSizeThreshold(int firstDp, int secondDp) {
    581         return crossesSizeThreshold(mVerticalSizeConfigurations, firstDp, secondDp);
    582     }
    583 
    584     private boolean crossesSmallestSizeThreshold(int firstDp, int secondDp) {
    585         return crossesSizeThreshold(mSmallestSizeConfigurations, firstDp, secondDp);
    586     }
    587 
    588     /**
    589      * The purpose of this method is to decide whether the activity needs to be relaunched upon
    590      * changing its size. In most cases the activities don't need to be relaunched, if the resize
    591      * is small, all the activity content has to do is relayout itself within new bounds. There are
    592      * cases however, where the activity's content would be completely changed in the new size and
    593      * the full relaunch is required.
    594      *
    595      * The activity will report to us vertical and horizontal thresholds after which a relaunch is
    596      * required. These thresholds are collected from the application resource qualifiers. For
    597      * example, if application has layout-w600dp resource directory, then it needs a relaunch when
    598      * we resize from width of 650dp to 550dp, as it crosses the 600dp threshold. However, if
    599      * it resizes width from 620dp to 700dp, it won't be relaunched as it stays on the same side
    600      * of the threshold.
    601      */
    602     private static boolean crossesSizeThreshold(int[] thresholds, int firstDp,
    603             int secondDp) {
    604         if (thresholds == null) {
    605             return false;
    606         }
    607         for (int i = thresholds.length - 1; i >= 0; i--) {
    608             final int threshold = thresholds[i];
    609             if ((firstDp < threshold && secondDp >= threshold)
    610                     || (firstDp >= threshold && secondDp < threshold)) {
    611                 return true;
    612             }
    613         }
    614         return false;
    615     }
    616 
    617     void setSizeConfigurations(int[] horizontalSizeConfiguration,
    618             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
    619         mHorizontalSizeConfigurations = horizontalSizeConfiguration;
    620         mVerticalSizeConfigurations = verticalSizeConfigurations;
    621         mSmallestSizeConfigurations = smallestSizeConfigurations;
    622     }
    623 
    624     private void scheduleActivityMovedToDisplay(int displayId, Configuration config) {
    625         if (app == null || app.thread == null) {
    626             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG,
    627                     "Can't report activity moved to display - client not running, activityRecord="
    628                             + this + ", displayId=" + displayId);
    629             return;
    630         }
    631         try {
    632             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
    633                     "Reporting activity moved to display" + ", activityRecord=" + this
    634                             + ", displayId=" + displayId + ", config=" + config);
    635 
    636             service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
    637                     MoveToDisplayItem.obtain(displayId, config));
    638         } catch (RemoteException e) {
    639             // If process died, whatever.
    640         }
    641     }
    642 
    643     private void scheduleConfigurationChanged(Configuration config) {
    644         if (app == null || app.thread == null) {
    645             if (DEBUG_CONFIGURATION) Slog.w(TAG,
    646                     "Can't report activity configuration update - client not running"
    647                             + ", activityRecord=" + this);
    648             return;
    649         }
    650         try {
    651             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: "
    652                     + config);
    653 
    654             service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
    655                     ActivityConfigurationChangeItem.obtain(config));
    656         } catch (RemoteException e) {
    657             // If process died, whatever.
    658         }
    659     }
    660 
    661     void updateMultiWindowMode() {
    662         if (task == null || task.getStack() == null || app == null || app.thread == null) {
    663             return;
    664         }
    665 
    666         if (task.getStack().deferScheduleMultiWindowModeChanged()) {
    667             // Don't do anything if we are currently deferring multi-window mode change.
    668             return;
    669         }
    670 
    671         // An activity is considered to be in multi-window mode if its task isn't fullscreen.
    672         final boolean inMultiWindowMode = inMultiWindowMode();
    673         if (inMultiWindowMode != mLastReportedMultiWindowMode) {
    674             mLastReportedMultiWindowMode = inMultiWindowMode;
    675             scheduleMultiWindowModeChanged(getConfiguration());
    676         }
    677     }
    678 
    679     private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
    680         try {
    681             service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
    682                     MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode,
    683                             overrideConfig));
    684         } catch (Exception e) {
    685             // If process died, I don't care.
    686         }
    687     }
    688 
    689     void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) {
    690         if (task == null || task.getStack() == null || app == null || app.thread == null) {
    691             return;
    692         }
    693 
    694         final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
    695         if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
    696             // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
    697             // update that here in order
    698             mLastReportedPictureInPictureMode = inPictureInPictureMode;
    699             mLastReportedMultiWindowMode = inMultiWindowMode();
    700             final Configuration newConfig = task.computeNewOverrideConfigurationForBounds(
    701                     targetStackBounds, null);
    702             schedulePictureInPictureModeChanged(newConfig);
    703             scheduleMultiWindowModeChanged(newConfig);
    704         }
    705     }
    706 
    707     private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
    708         try {
    709             service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
    710                     PipModeChangeItem.obtain(mLastReportedPictureInPictureMode,
    711                             overrideConfig));
    712         } catch (Exception e) {
    713             // If process died, no one cares.
    714         }
    715     }
    716 
    717     @Override
    718     protected int getChildCount() {
    719         // {@link ActivityRecord} is a leaf node and has no children.
    720         return 0;
    721     }
    722 
    723     @Override
    724     protected ConfigurationContainer getChildAt(int index) {
    725         return null;
    726     }
    727 
    728     @Override
    729     protected ConfigurationContainer getParent() {
    730         return getTask();
    731     }
    732 
    733     TaskRecord getTask() {
    734         return task;
    735     }
    736 
    737     /**
    738      * Sets reference to the {@link TaskRecord} the {@link ActivityRecord} will treat as its parent.
    739      * Note that this does not actually add the {@link ActivityRecord} as a {@link TaskRecord}
    740      * children. However, this method will clean up references to this {@link ActivityRecord} in
    741      * {@link ActivityStack}.
    742      * @param task The new parent {@link TaskRecord}.
    743      */
    744     void setTask(TaskRecord task) {
    745         setTask(task /* task */, false /* reparenting */);
    746     }
    747 
    748     /**
    749      * This method should only be called by {@link TaskRecord#removeActivity(ActivityRecord)}.
    750      * @param task          The new parent task.
    751      * @param reparenting   Whether we're in the middle of reparenting.
    752      */
    753     void setTask(TaskRecord task, boolean reparenting) {
    754         // Do nothing if the {@link TaskRecord} is the same as the current {@link getTask}.
    755         if (task != null && task == getTask()) {
    756             return;
    757         }
    758 
    759         final ActivityStack oldStack = getStack();
    760         final ActivityStack newStack = task != null ? task.getStack() : null;
    761 
    762         // Inform old stack (if present) of activity removal and new stack (if set) of activity
    763         // addition.
    764         if (oldStack != newStack) {
    765             if (!reparenting && oldStack != null) {
    766                 oldStack.onActivityRemovedFromStack(this);
    767             }
    768 
    769             if (newStack != null) {
    770                 newStack.onActivityAddedToStack(this);
    771             }
    772         }
    773 
    774         this.task = task;
    775 
    776         if (!reparenting) {
    777             onParentChanged();
    778         }
    779     }
    780 
    781     /**
    782      * See {@link AppWindowContainerController#setWillCloseOrEnterPip(boolean)}
    783      */
    784     void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
    785         getWindowContainerController().setWillCloseOrEnterPip(willCloseOrEnterPip);
    786     }
    787 
    788     static class Token extends IApplicationToken.Stub {
    789         private final WeakReference<ActivityRecord> weakActivity;
    790         private final String name;
    791 
    792         Token(ActivityRecord activity, Intent intent) {
    793             weakActivity = new WeakReference<>(activity);
    794             name = intent.getComponent().flattenToShortString();
    795         }
    796 
    797         private static ActivityRecord tokenToActivityRecordLocked(Token token) {
    798             if (token == null) {
    799                 return null;
    800             }
    801             ActivityRecord r = token.weakActivity.get();
    802             if (r == null || r.getStack() == null) {
    803                 return null;
    804             }
    805             return r;
    806         }
    807 
    808         @Override
    809         public String toString() {
    810             StringBuilder sb = new StringBuilder(128);
    811             sb.append("Token{");
    812             sb.append(Integer.toHexString(System.identityHashCode(this)));
    813             sb.append(' ');
    814             sb.append(weakActivity.get());
    815             sb.append('}');
    816             return sb.toString();
    817         }
    818 
    819         @Override
    820         public String getName() {
    821             return name;
    822         }
    823     }
    824 
    825     static ActivityRecord forTokenLocked(IBinder token) {
    826         try {
    827             return Token.tokenToActivityRecordLocked((Token)token);
    828         } catch (ClassCastException e) {
    829             Slog.w(TAG, "Bad activity token: " + token, e);
    830             return null;
    831         }
    832     }
    833 
    834     boolean isResolverActivity() {
    835         return ResolverActivity.class.getName().equals(realActivity.getClassName());
    836     }
    837 
    838     boolean isResolverOrChildActivity() {
    839         if (!"android".equals(packageName)) {
    840             return false;
    841         }
    842         try {
    843             return ResolverActivity.class.isAssignableFrom(
    844                     Object.class.getClassLoader().loadClass(realActivity.getClassName()));
    845         } catch (ClassNotFoundException e) {
    846             return false;
    847         }
    848     }
    849 
    850     ActivityRecord(ActivityManagerService _service, ProcessRecord _caller, int _launchedFromPid,
    851             int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
    852             ActivityInfo aInfo, Configuration _configuration,
    853             ActivityRecord _resultTo, String _resultWho, int _reqCode,
    854             boolean _componentSpecified, boolean _rootVoiceInteraction,
    855             ActivityStackSupervisor supervisor, ActivityOptions options,
    856             ActivityRecord sourceRecord) {
    857         service = _service;
    858         appToken = new Token(this, _intent);
    859         info = aInfo;
    860         launchedFromPid = _launchedFromPid;
    861         launchedFromUid = _launchedFromUid;
    862         launchedFromPackage = _launchedFromPackage;
    863         userId = UserHandle.getUserId(aInfo.applicationInfo.uid);
    864         intent = _intent;
    865         shortComponentName = _intent.getComponent().flattenToShortString();
    866         resolvedType = _resolvedType;
    867         componentSpecified = _componentSpecified;
    868         rootVoiceInteraction = _rootVoiceInteraction;
    869         mLastReportedConfiguration = new MergedConfiguration(_configuration);
    870         resultTo = _resultTo;
    871         resultWho = _resultWho;
    872         requestCode = _reqCode;
    873         setState(INITIALIZING, "ActivityRecord ctor");
    874         frontOfTask = false;
    875         launchFailed = false;
    876         stopped = false;
    877         delayedResume = false;
    878         finishing = false;
    879         deferRelaunchUntilPaused = false;
    880         keysPaused = false;
    881         inHistory = false;
    882         visible = false;
    883         nowVisible = false;
    884         idle = false;
    885         hasBeenLaunched = false;
    886         mStackSupervisor = supervisor;
    887 
    888         // This starts out true, since the initial state of an activity is that we have everything,
    889         // and we shouldn't never consider it lacking in state to be removed if it dies.
    890         haveState = true;
    891 
    892         // If the class name in the intent doesn't match that of the target, this is
    893         // probably an alias. We have to create a new ComponentName object to keep track
    894         // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
    895         if (aInfo.targetActivity == null
    896                 || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
    897                 && (aInfo.launchMode == LAUNCH_MULTIPLE
    898                 || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
    899             realActivity = _intent.getComponent();
    900         } else {
    901             realActivity = new ComponentName(aInfo.packageName, aInfo.targetActivity);
    902         }
    903         taskAffinity = aInfo.taskAffinity;
    904         stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
    905         appInfo = aInfo.applicationInfo;
    906         nonLocalizedLabel = aInfo.nonLocalizedLabel;
    907         labelRes = aInfo.labelRes;
    908         if (nonLocalizedLabel == null && labelRes == 0) {
    909             ApplicationInfo app = aInfo.applicationInfo;
    910             nonLocalizedLabel = app.nonLocalizedLabel;
    911             labelRes = app.labelRes;
    912         }
    913         icon = aInfo.getIconResource();
    914         logo = aInfo.getLogoResource();
    915         theme = aInfo.getThemeResource();
    916         realTheme = theme;
    917         if (realTheme == 0) {
    918             realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
    919                     ? android.R.style.Theme : android.R.style.Theme_Holo;
    920         }
    921         if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
    922             windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
    923         }
    924         if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
    925                 && (aInfo.applicationInfo.uid == SYSTEM_UID
    926                     || aInfo.applicationInfo.uid == _caller.info.uid)) {
    927             processName = _caller.processName;
    928         } else {
    929             processName = aInfo.processName;
    930         }
    931 
    932         if ((aInfo.flags & FLAG_EXCLUDE_FROM_RECENTS) != 0) {
    933             intent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    934         }
    935 
    936         packageName = aInfo.applicationInfo.packageName;
    937         launchMode = aInfo.launchMode;
    938 
    939         Entry ent = AttributeCache.instance().get(packageName,
    940                 realTheme, com.android.internal.R.styleable.Window, userId);
    941 
    942         if (ent != null) {
    943             fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
    944             hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
    945             noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
    946         } else {
    947             hasWallpaper = false;
    948             noDisplay = false;
    949         }
    950 
    951         setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
    952 
    953         immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
    954 
    955         requestedVrComponent = (aInfo.requestedVrComponent == null) ?
    956                 null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
    957 
    958         mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
    959         mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
    960 
    961         mRotationAnimationHint = aInfo.rotationAnimation;
    962         lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
    963         if (appInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
    964                 || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
    965             lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
    966         }
    967 
    968         if (options != null) {
    969             pendingOptions = options;
    970             mLaunchTaskBehind = options.getLaunchTaskBehind();
    971 
    972             final int rotationAnimation = pendingOptions.getRotationAnimationHint();
    973             // Only override manifest supplied option if set.
    974             if (rotationAnimation >= 0) {
    975                 mRotationAnimationHint = rotationAnimation;
    976             }
    977             final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
    978             if (usageReport != null) {
    979                 appTimeTracker = new AppTimeTracker(usageReport);
    980             }
    981             final boolean useLockTask = pendingOptions.getLockTaskMode();
    982             if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
    983                 lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
    984             }
    985         }
    986     }
    987 
    988     void setProcess(ProcessRecord proc) {
    989         app = proc;
    990         final ActivityRecord root = task != null ? task.getRootActivity() : null;
    991         if (root == this) {
    992             task.setRootProcess(proc);
    993         }
    994     }
    995 
    996     AppWindowContainerController getWindowContainerController() {
    997         return mWindowContainerController;
    998     }
    999 
   1000     void createWindowContainer() {
   1001         if (mWindowContainerController != null) {
   1002             throw new IllegalArgumentException("Window container=" + mWindowContainerController
   1003                     + " already created for r=" + this);
   1004         }
   1005 
   1006         inHistory = true;
   1007 
   1008         final TaskWindowContainerController taskController = task.getWindowContainerController();
   1009 
   1010         // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
   1011         task.updateOverrideConfigurationFromLaunchBounds();
   1012         // Make sure override configuration is up-to-date before using to create window controller.
   1013         updateOverrideConfiguration();
   1014 
   1015         mWindowContainerController = new AppWindowContainerController(taskController, appToken,
   1016                 this, Integer.MAX_VALUE /* add on top */, info.screenOrientation, fullscreen,
   1017                 (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
   1018                 task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
   1019                 appInfo.targetSdkVersion, mRotationAnimationHint,
   1020                 ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
   1021 
   1022         task.addActivityToTop(this);
   1023 
   1024         // When an activity is started directly into a split-screen fullscreen stack, we need to
   1025         // update the initial multi-window modes so that the callbacks are scheduled correctly when
   1026         // the user leaves that mode.
   1027         mLastReportedMultiWindowMode = inMultiWindowMode();
   1028         mLastReportedPictureInPictureMode = inPinnedWindowingMode();
   1029     }
   1030 
   1031     void removeWindowContainer() {
   1032         // Do not try to remove a window container if we have already removed it.
   1033         if (mWindowContainerController == null) {
   1034             return;
   1035         }
   1036 
   1037         // Resume key dispatching if it is currently paused before we remove the container.
   1038         resumeKeyDispatchingLocked();
   1039 
   1040         mWindowContainerController.removeContainer(getDisplayId());
   1041         mWindowContainerController = null;
   1042     }
   1043 
   1044     /**
   1045      * Reparents this activity into {@param newTask} at the provided {@param position}.  The caller
   1046      * should ensure that the {@param newTask} is not already the parent of this activity.
   1047      */
   1048     void reparent(TaskRecord newTask, int position, String reason) {
   1049         final TaskRecord prevTask = task;
   1050         if (prevTask == newTask) {
   1051             throw new IllegalArgumentException(reason + ": task=" + newTask
   1052                     + " is already the parent of r=" + this);
   1053         }
   1054 
   1055         // TODO: Ensure that we do not directly reparent activities across stacks, as that may leave
   1056         //       the stacks in strange states. For now, we should use Task.reparent() to ensure that
   1057         //       the stack is left in an OK state.
   1058         if (prevTask != null && newTask != null && prevTask.getStack() != newTask.getStack()) {
   1059             throw new IllegalArgumentException(reason + ": task=" + newTask
   1060                     + " is in a different stack (" + newTask.getStackId() + ") than the parent of"
   1061                     + " r=" + this + " (" + prevTask.getStackId() + ")");
   1062         }
   1063 
   1064         // Must reparent first in window manager
   1065         mWindowContainerController.reparent(newTask.getWindowContainerController(), position);
   1066 
   1067         // Reparenting prevents informing the parent stack of activity removal in the case that
   1068         // the new stack has the same parent. we must manually signal here if this is not the case.
   1069         final ActivityStack prevStack = prevTask.getStack();
   1070 
   1071         if (prevStack != newTask.getStack()) {
   1072             prevStack.onActivityRemovedFromStack(this);
   1073         }
   1074         // Remove the activity from the old task and add it to the new task.
   1075         prevTask.removeActivity(this, true /* reparenting */);
   1076 
   1077         newTask.addActivityAtIndex(position, this);
   1078     }
   1079 
   1080     private boolean isHomeIntent(Intent intent) {
   1081         return ACTION_MAIN.equals(intent.getAction())
   1082                 && intent.hasCategory(CATEGORY_HOME)
   1083                 && intent.getCategories().size() == 1
   1084                 && intent.getData() == null
   1085                 && intent.getType() == null;
   1086     }
   1087 
   1088     static boolean isMainIntent(Intent intent) {
   1089         return ACTION_MAIN.equals(intent.getAction())
   1090                 && intent.hasCategory(CATEGORY_LAUNCHER)
   1091                 && intent.getCategories().size() == 1
   1092                 && intent.getData() == null
   1093                 && intent.getType() == null;
   1094     }
   1095 
   1096     private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
   1097         if (uid == Process.myUid() || uid == 0) {
   1098             // System process can launch home activity.
   1099             return true;
   1100         }
   1101         // Allow the recents component to launch the home activity.
   1102         final RecentTasks recentTasks = mStackSupervisor.mService.getRecentTasks();
   1103         if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
   1104             return true;
   1105         }
   1106         // Resolver activity can launch home activity.
   1107         return sourceRecord != null && sourceRecord.isResolverActivity();
   1108     }
   1109 
   1110     /**
   1111      * @return whether the given package name can launch an assist activity.
   1112      */
   1113     private boolean canLaunchAssistActivity(String packageName) {
   1114         final ComponentName assistComponent = service.mActiveVoiceInteractionServiceComponent;
   1115         if (assistComponent != null) {
   1116             return assistComponent.getPackageName().equals(packageName);
   1117         }
   1118         return false;
   1119     }
   1120 
   1121     private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent,
   1122             ActivityOptions options, ActivityRecord sourceRecord) {
   1123         int activityType = ACTIVITY_TYPE_UNDEFINED;
   1124         if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
   1125                 && isHomeIntent(intent) && !isResolverActivity()) {
   1126             // This sure looks like a home activity!
   1127             activityType = ACTIVITY_TYPE_HOME;
   1128 
   1129             if (info.resizeMode == RESIZE_MODE_FORCE_RESIZEABLE
   1130                     || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
   1131                 // We only allow home activities to be resizeable if they explicitly requested it.
   1132                 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
   1133             }
   1134         } else if (realActivity.getClassName().contains(LEGACY_RECENTS_PACKAGE_NAME) ||
   1135                 service.getRecentTasks().isRecentsComponent(realActivity, appInfo.uid)) {
   1136             activityType = ACTIVITY_TYPE_RECENTS;
   1137         } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT
   1138                 && canLaunchAssistActivity(launchedFromPackage)) {
   1139             activityType = ACTIVITY_TYPE_ASSISTANT;
   1140         }
   1141         setActivityType(activityType);
   1142     }
   1143 
   1144     void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
   1145         if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
   1146             task.setTaskToAffiliateWith(taskToAffiliateWith);
   1147         }
   1148     }
   1149 
   1150     /**
   1151      * @return Stack value from current task, null if there is no task.
   1152      */
   1153     <T extends ActivityStack> T getStack() {
   1154         return task != null ? (T) task.getStack() : null;
   1155     }
   1156 
   1157     int getStackId() {
   1158         return getStack() != null ? getStack().mStackId : INVALID_STACK_ID;
   1159     }
   1160 
   1161     ActivityDisplay getDisplay() {
   1162         final ActivityStack stack = getStack();
   1163         return stack != null ? stack.getDisplay() : null;
   1164     }
   1165 
   1166     boolean changeWindowTranslucency(boolean toOpaque) {
   1167         if (fullscreen == toOpaque) {
   1168             return false;
   1169         }
   1170 
   1171         // Keep track of the number of fullscreen activities in this task.
   1172         task.numFullscreen += toOpaque ? +1 : -1;
   1173 
   1174         fullscreen = toOpaque;
   1175         return true;
   1176     }
   1177 
   1178     void takeFromHistory() {
   1179         if (inHistory) {
   1180             inHistory = false;
   1181             if (task != null && !finishing) {
   1182                 task = null;
   1183             }
   1184             clearOptionsLocked();
   1185         }
   1186     }
   1187 
   1188     boolean isInHistory() {
   1189         return inHistory;
   1190     }
   1191 
   1192     boolean isInStackLocked() {
   1193         final ActivityStack stack = getStack();
   1194         return stack != null && stack.isInStackLocked(this) != null;
   1195     }
   1196 
   1197     boolean isPersistable() {
   1198         return (info.persistableMode == PERSIST_ROOT_ONLY ||
   1199                 info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
   1200                 (intent == null || (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
   1201     }
   1202 
   1203     boolean isFocusable() {
   1204         return mStackSupervisor.isFocusable(this, isAlwaysFocusable());
   1205     }
   1206 
   1207     boolean isResizeable() {
   1208         return ActivityInfo.isResizeableMode(info.resizeMode) || info.supportsPictureInPicture();
   1209     }
   1210 
   1211     /**
   1212      * @return whether this activity is non-resizeable or forced to be resizeable
   1213      */
   1214     boolean isNonResizableOrForcedResizable() {
   1215         return info.resizeMode != RESIZE_MODE_RESIZEABLE
   1216                 && info.resizeMode != RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
   1217     }
   1218 
   1219     /**
   1220      * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
   1221      */
   1222     boolean supportsPictureInPicture() {
   1223         return service.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
   1224                 && info.supportsPictureInPicture();
   1225     }
   1226 
   1227     /**
   1228      * @return whether this activity supports split-screen multi-window and can be put in the docked
   1229      *         stack.
   1230      */
   1231     @Override
   1232     public boolean supportsSplitScreenWindowingMode() {
   1233         // An activity can not be docked even if it is considered resizeable because it only
   1234         // supports picture-in-picture mode but has a non-resizeable resizeMode
   1235         return super.supportsSplitScreenWindowingMode()
   1236                 && service.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
   1237     }
   1238 
   1239     /**
   1240      * @return whether this activity supports freeform multi-window and can be put in the freeform
   1241      *         stack.
   1242      */
   1243     boolean supportsFreeform() {
   1244         return service.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
   1245     }
   1246 
   1247     /**
   1248      * @return whether this activity supports non-PiP multi-window.
   1249      */
   1250     private boolean supportsResizeableMultiWindow() {
   1251         return service.mSupportsMultiWindow && !isActivityTypeHome()
   1252                 && (ActivityInfo.isResizeableMode(info.resizeMode)
   1253                         || service.mForceResizableActivities);
   1254     }
   1255 
   1256     /**
   1257      * Check whether this activity can be launched on the specified display.
   1258      * @param displayId Target display id.
   1259      * @return {@code true} if either it is the default display or this activity is resizeable and
   1260      *         can be put a secondary screen.
   1261      */
   1262     boolean canBeLaunchedOnDisplay(int displayId) {
   1263         final TaskRecord task = getTask();
   1264 
   1265         // The resizeability of an Activity's parent task takes precendence over the ActivityInfo.
   1266         // This allows for a non resizable activity to be launched into a resizeable task.
   1267         final boolean resizeable =
   1268                 task != null ? task.isResizeable() : supportsResizeableMultiWindow();
   1269 
   1270         return service.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
   1271                 resizeable, launchedFromPid, launchedFromUid, info);
   1272     }
   1273 
   1274     /**
   1275      * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
   1276      *         the activity has requested to enter PiP when it would otherwise be stopped.
   1277      *
   1278      * @return whether this activity is currently allowed to enter PIP.
   1279      */
   1280     boolean checkEnterPictureInPictureState(String caller, boolean beforeStopping) {
   1281         if (!supportsPictureInPicture()) {
   1282             return false;
   1283         }
   1284 
   1285         // Check app-ops and see if PiP is supported for this package
   1286         if (!checkEnterPictureInPictureAppOpsState()) {
   1287             return false;
   1288         }
   1289 
   1290         // Check to see if we are in VR mode, and disallow PiP if so
   1291         if (service.shouldDisableNonVrUiLocked()) {
   1292             return false;
   1293         }
   1294 
   1295         boolean isKeyguardLocked = service.isKeyguardLocked();
   1296         boolean isCurrentAppLocked = service.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
   1297         final ActivityDisplay display = getDisplay();
   1298         boolean hasPinnedStack = display != null && display.hasPinnedStack();
   1299         // Don't return early if !isNotLocked, since we want to throw an exception if the activity
   1300         // is in an incorrect state
   1301         boolean isNotLockedOrOnKeyguard = !isKeyguardLocked && !isCurrentAppLocked;
   1302 
   1303         // We don't allow auto-PiP when something else is already pipped.
   1304         if (beforeStopping && hasPinnedStack) {
   1305             return false;
   1306         }
   1307 
   1308         switch (mState) {
   1309             case RESUMED:
   1310                 // When visible, allow entering PiP if the app is not locked.  If it is over the
   1311                 // keyguard, then we will prompt to unlock in the caller before entering PiP.
   1312                 return !isCurrentAppLocked &&
   1313                         (supportsEnterPipOnTaskSwitch || !beforeStopping);
   1314             case PAUSING:
   1315             case PAUSED:
   1316                 // When pausing, then only allow enter PiP as in the resume state, and in addition,
   1317                 // require that there is not an existing PiP activity and that the current system
   1318                 // state supports entering PiP
   1319                 return isNotLockedOrOnKeyguard && !hasPinnedStack
   1320                         && supportsEnterPipOnTaskSwitch;
   1321             case STOPPING:
   1322                 // When stopping in a valid state, then only allow enter PiP as in the pause state.
   1323                 // Otherwise, fall through to throw an exception if the caller is trying to enter
   1324                 // PiP in an invalid stopping state.
   1325                 if (supportsEnterPipOnTaskSwitch) {
   1326                     return isNotLockedOrOnKeyguard && !hasPinnedStack;
   1327                 }
   1328             default:
   1329                 return false;
   1330         }
   1331     }
   1332 
   1333     /**
   1334      * @return Whether AppOps allows this package to enter picture-in-picture.
   1335      */
   1336     private boolean checkEnterPictureInPictureAppOpsState() {
   1337         try {
   1338             return service.getAppOpsService().checkOperation(OP_PICTURE_IN_PICTURE,
   1339                     appInfo.uid, packageName) == MODE_ALLOWED;
   1340         } catch (RemoteException e) {
   1341             // Local call
   1342         }
   1343         return false;
   1344     }
   1345 
   1346     boolean isAlwaysFocusable() {
   1347         return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
   1348     }
   1349 
   1350 
   1351     /**
   1352      * @return true if the activity contains windows that have
   1353      *         {@link LayoutParams#FLAG_DISMISS_KEYGUARD} set
   1354      */
   1355     boolean hasDismissKeyguardWindows() {
   1356         return service.mWindowManager.containsDismissKeyguardWindow(appToken);
   1357     }
   1358 
   1359     void makeFinishingLocked() {
   1360         if (finishing) {
   1361             return;
   1362         }
   1363         finishing = true;
   1364         if (stopped) {
   1365             clearOptionsLocked();
   1366         }
   1367 
   1368         if (service != null) {
   1369             service.mTaskChangeNotificationController.notifyTaskStackChanged();
   1370         }
   1371     }
   1372 
   1373     UriPermissionOwner getUriPermissionsLocked() {
   1374         if (uriPermissions == null) {
   1375             uriPermissions = new UriPermissionOwner(service, this);
   1376         }
   1377         return uriPermissions;
   1378     }
   1379 
   1380     void addResultLocked(ActivityRecord from, String resultWho,
   1381             int requestCode, int resultCode,
   1382             Intent resultData) {
   1383         ActivityResult r = new ActivityResult(from, resultWho,
   1384                 requestCode, resultCode, resultData);
   1385         if (results == null) {
   1386             results = new ArrayList<ResultInfo>();
   1387         }
   1388         results.add(r);
   1389     }
   1390 
   1391     void removeResultsLocked(ActivityRecord from, String resultWho,
   1392             int requestCode) {
   1393         if (results != null) {
   1394             for (int i=results.size()-1; i>=0; i--) {
   1395                 ActivityResult r = (ActivityResult)results.get(i);
   1396                 if (r.mFrom != from) continue;
   1397                 if (r.mResultWho == null) {
   1398                     if (resultWho != null) continue;
   1399                 } else {
   1400                     if (!r.mResultWho.equals(resultWho)) continue;
   1401                 }
   1402                 if (r.mRequestCode != requestCode) continue;
   1403 
   1404                 results.remove(i);
   1405             }
   1406         }
   1407     }
   1408 
   1409     private void addNewIntentLocked(ReferrerIntent intent) {
   1410         if (newIntents == null) {
   1411             newIntents = new ArrayList<>();
   1412         }
   1413         newIntents.add(intent);
   1414     }
   1415 
   1416     final boolean isSleeping() {
   1417         final ActivityStack stack = getStack();
   1418         return stack != null ? stack.shouldSleepActivities() : service.isSleepingLocked();
   1419     }
   1420 
   1421     /**
   1422      * Deliver a new Intent to an existing activity, so that its onNewIntent()
   1423      * method will be called at the proper time.
   1424      */
   1425     final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
   1426         // The activity now gets access to the data associated with this Intent.
   1427         service.grantUriPermissionFromIntentLocked(callingUid, packageName,
   1428                 intent, getUriPermissionsLocked(), userId);
   1429         final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
   1430         boolean unsent = true;
   1431         final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
   1432 
   1433         // We want to immediately deliver the intent to the activity if:
   1434         // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
   1435         //   the user to see the visual effects caused by the intent delivery now.
   1436         // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
   1437         if ((mState == RESUMED || mState == PAUSED
   1438                 || isTopActivityWhileSleeping) && app != null && app.thread != null) {
   1439             try {
   1440                 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
   1441                 ar.add(rintent);
   1442                 service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
   1443                         NewIntentItem.obtain(ar, mState == PAUSED));
   1444                 unsent = false;
   1445             } catch (RemoteException e) {
   1446                 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
   1447             } catch (NullPointerException e) {
   1448                 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
   1449             }
   1450         }
   1451         if (unsent) {
   1452             addNewIntentLocked(rintent);
   1453         }
   1454     }
   1455 
   1456     void updateOptionsLocked(ActivityOptions options) {
   1457         if (options != null) {
   1458             if (pendingOptions != null) {
   1459                 pendingOptions.abort();
   1460             }
   1461             pendingOptions = options;
   1462         }
   1463     }
   1464 
   1465     void applyOptionsLocked() {
   1466         if (pendingOptions != null
   1467                 && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
   1468             final int animationType = pendingOptions.getAnimationType();
   1469             switch (animationType) {
   1470                 case ANIM_CUSTOM:
   1471                     service.mWindowManager.overridePendingAppTransition(
   1472                             pendingOptions.getPackageName(),
   1473                             pendingOptions.getCustomEnterResId(),
   1474                             pendingOptions.getCustomExitResId(),
   1475                             pendingOptions.getOnAnimationStartListener());
   1476                     break;
   1477                 case ANIM_CLIP_REVEAL:
   1478                     service.mWindowManager.overridePendingAppTransitionClipReveal(
   1479                             pendingOptions.getStartX(), pendingOptions.getStartY(),
   1480                             pendingOptions.getWidth(), pendingOptions.getHeight());
   1481                     if (intent.getSourceBounds() == null) {
   1482                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
   1483                                 pendingOptions.getStartY(),
   1484                                 pendingOptions.getStartX()+pendingOptions.getWidth(),
   1485                                 pendingOptions.getStartY()+pendingOptions.getHeight()));
   1486                     }
   1487                     break;
   1488                 case ANIM_SCALE_UP:
   1489                     service.mWindowManager.overridePendingAppTransitionScaleUp(
   1490                             pendingOptions.getStartX(), pendingOptions.getStartY(),
   1491                             pendingOptions.getWidth(), pendingOptions.getHeight());
   1492                     if (intent.getSourceBounds() == null) {
   1493                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
   1494                                 pendingOptions.getStartY(),
   1495                                 pendingOptions.getStartX()+pendingOptions.getWidth(),
   1496                                 pendingOptions.getStartY()+pendingOptions.getHeight()));
   1497                     }
   1498                     break;
   1499                 case ANIM_THUMBNAIL_SCALE_UP:
   1500                 case ANIM_THUMBNAIL_SCALE_DOWN:
   1501                     final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
   1502                     final GraphicBuffer buffer = pendingOptions.getThumbnail();
   1503                     service.mWindowManager.overridePendingAppTransitionThumb(buffer,
   1504                             pendingOptions.getStartX(), pendingOptions.getStartY(),
   1505                             pendingOptions.getOnAnimationStartListener(),
   1506                             scaleUp);
   1507                     if (intent.getSourceBounds() == null && buffer != null) {
   1508                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
   1509                                 pendingOptions.getStartY(),
   1510                                 pendingOptions.getStartX() + buffer.getWidth(),
   1511                                 pendingOptions.getStartY() + buffer.getHeight()));
   1512                     }
   1513                     break;
   1514                 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
   1515                 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
   1516                     final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
   1517                     final IAppTransitionAnimationSpecsFuture specsFuture =
   1518                             pendingOptions.getSpecsFuture();
   1519                     if (specsFuture != null) {
   1520                         service.mWindowManager.overridePendingAppTransitionMultiThumbFuture(
   1521                                 specsFuture, pendingOptions.getOnAnimationStartListener(),
   1522                                 animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
   1523                     } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
   1524                             && specs != null) {
   1525                         service.mWindowManager.overridePendingAppTransitionMultiThumb(
   1526                                 specs, pendingOptions.getOnAnimationStartListener(),
   1527                                 pendingOptions.getAnimationFinishedListener(), false);
   1528                     } else {
   1529                         service.mWindowManager.overridePendingAppTransitionAspectScaledThumb(
   1530                                 pendingOptions.getThumbnail(),
   1531                                 pendingOptions.getStartX(), pendingOptions.getStartY(),
   1532                                 pendingOptions.getWidth(), pendingOptions.getHeight(),
   1533                                 pendingOptions.getOnAnimationStartListener(),
   1534                                 (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
   1535                         if (intent.getSourceBounds() == null) {
   1536                             intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
   1537                                     pendingOptions.getStartY(),
   1538                                     pendingOptions.getStartX() + pendingOptions.getWidth(),
   1539                                     pendingOptions.getStartY() + pendingOptions.getHeight()));
   1540                         }
   1541                     }
   1542                     break;
   1543                 case ANIM_OPEN_CROSS_PROFILE_APPS:
   1544                     service.mWindowManager.overridePendingAppTransitionStartCrossProfileApps();
   1545                     break;
   1546                 case ANIM_REMOTE_ANIMATION:
   1547                     service.mWindowManager.overridePendingAppTransitionRemote(
   1548                             pendingOptions.getRemoteAnimationAdapter());
   1549                     break;
   1550                 default:
   1551                     Slog.e(TAG, "applyOptionsLocked: Unknown animationType=" + animationType);
   1552                     break;
   1553             }
   1554 
   1555             if (task == null) {
   1556                 clearOptionsLocked(false /* withAbort */);
   1557             } else {
   1558                 // This will clear the options for all the ActivityRecords for this Task.
   1559                 task.clearAllPendingOptions();
   1560             }
   1561         }
   1562     }
   1563 
   1564     ActivityOptions getOptionsForTargetActivityLocked() {
   1565         return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
   1566     }
   1567 
   1568     void clearOptionsLocked() {
   1569         clearOptionsLocked(true /* withAbort */);
   1570     }
   1571 
   1572     void clearOptionsLocked(boolean withAbort) {
   1573         if (withAbort && pendingOptions != null) {
   1574             pendingOptions.abort();
   1575         }
   1576         pendingOptions = null;
   1577     }
   1578 
   1579     ActivityOptions takeOptionsLocked() {
   1580         ActivityOptions opts = pendingOptions;
   1581         pendingOptions = null;
   1582         return opts;
   1583     }
   1584 
   1585     void removeUriPermissionsLocked() {
   1586         if (uriPermissions != null) {
   1587             uriPermissions.removeUriPermissionsLocked();
   1588             uriPermissions = null;
   1589         }
   1590     }
   1591 
   1592     void pauseKeyDispatchingLocked() {
   1593         if (!keysPaused) {
   1594             keysPaused = true;
   1595 
   1596             if (mWindowContainerController != null) {
   1597                 mWindowContainerController.pauseKeyDispatching();
   1598             }
   1599         }
   1600     }
   1601 
   1602     void resumeKeyDispatchingLocked() {
   1603         if (keysPaused) {
   1604             keysPaused = false;
   1605 
   1606             if (mWindowContainerController != null) {
   1607                 mWindowContainerController.resumeKeyDispatching();
   1608             }
   1609         }
   1610     }
   1611 
   1612     private void updateTaskDescription(CharSequence description) {
   1613         task.lastDescription = description;
   1614     }
   1615 
   1616     void setDeferHidingClient(boolean deferHidingClient) {
   1617         if (mDeferHidingClient == deferHidingClient) {
   1618             return;
   1619         }
   1620         mDeferHidingClient = deferHidingClient;
   1621         if (!mDeferHidingClient && !visible) {
   1622             // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
   1623             // update the visibility.
   1624             setVisibility(false);
   1625         }
   1626     }
   1627 
   1628     void setVisibility(boolean visible) {
   1629         mWindowContainerController.setVisibility(visible, mDeferHidingClient);
   1630         mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
   1631     }
   1632 
   1633     // TODO: Look into merging with #setVisibility()
   1634     void setVisible(boolean newVisible) {
   1635         visible = newVisible;
   1636         mDeferHidingClient = !visible && mDeferHidingClient;
   1637         setVisibility(visible);
   1638         mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
   1639     }
   1640 
   1641     void setState(ActivityState state, String reason) {
   1642         if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
   1643                         + " to:" + state + " reason:" + reason);
   1644 
   1645         if (state == mState) {
   1646             // No need to do anything if state doesn't change.
   1647             if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state);
   1648             return;
   1649         }
   1650 
   1651         mState = state;
   1652 
   1653         final TaskRecord parent = getTask();
   1654 
   1655         if (parent != null) {
   1656             parent.onActivityStateChanged(this, state, reason);
   1657         }
   1658 
   1659         // The WindowManager interprets the app stopping signal as
   1660         // an indication that the Surface will eventually be destroyed.
   1661         // This however isn't necessarily true if we are going to sleep.
   1662         if (state == STOPPING && !isSleeping()) {
   1663             mWindowContainerController.notifyAppStopping();
   1664         }
   1665     }
   1666 
   1667     ActivityState getState() {
   1668         return mState;
   1669     }
   1670 
   1671     /**
   1672      * Returns {@code true} if the Activity is in the specified state.
   1673      */
   1674     boolean isState(ActivityState state) {
   1675         return state == mState;
   1676     }
   1677 
   1678     /**
   1679      * Returns {@code true} if the Activity is in one of the specified states.
   1680      */
   1681     boolean isState(ActivityState state1, ActivityState state2) {
   1682         return state1 == mState || state2 == mState;
   1683     }
   1684 
   1685     /**
   1686      * Returns {@code true} if the Activity is in one of the specified states.
   1687      */
   1688     boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
   1689         return state1 == mState || state2 == mState || state3 == mState;
   1690     }
   1691 
   1692     /**
   1693      * Returns {@code true} if the Activity is in one of the specified states.
   1694      */
   1695     boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
   1696             ActivityState state4) {
   1697         return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
   1698     }
   1699 
   1700     void notifyAppResumed(boolean wasStopped) {
   1701         mWindowContainerController.notifyAppResumed(wasStopped);
   1702     }
   1703 
   1704     void notifyUnknownVisibilityLaunched() {
   1705 
   1706         // No display activities never add a window, so there is no point in waiting them for
   1707         // relayout.
   1708         if (!noDisplay) {
   1709             mWindowContainerController.notifyUnknownVisibilityLaunched();
   1710         }
   1711     }
   1712 
   1713     /**
   1714      * @return true if the input activity should be made visible, ignoring any effect Keyguard
   1715      * might have on the visibility
   1716      *
   1717      * @see {@link ActivityStack#checkKeyguardVisibility}
   1718      */
   1719     boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
   1720         if (!okToShowLocked()) {
   1721             return false;
   1722         }
   1723 
   1724         return !behindFullscreenActivity || mLaunchTaskBehind;
   1725     }
   1726 
   1727     void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
   1728         // This activity is not currently visible, but is running. Tell it to become visible.
   1729         if (mState == RESUMED || this == starting) {
   1730             if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
   1731                     "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
   1732             return;
   1733         }
   1734 
   1735         // If this activity is paused, tell it to now show its window.
   1736         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
   1737                 "Making visible and scheduling visibility: " + this);
   1738         final ActivityStack stack = getStack();
   1739         try {
   1740             if (stack.mTranslucentActivityWaiting != null) {
   1741                 updateOptionsLocked(returningOptions);
   1742                 stack.mUndrawnActivitiesBelowTopTranslucent.add(this);
   1743             }
   1744             setVisible(true);
   1745             sleeping = false;
   1746             app.pendingUiClean = true;
   1747             if (reportToClient) {
   1748                 makeClientVisible();
   1749             } else {
   1750                 mClientVisibilityDeferred = true;
   1751             }
   1752             // The activity may be waiting for stop, but that is no longer appropriate for it.
   1753             mStackSupervisor.mStoppingActivities.remove(this);
   1754             mStackSupervisor.mGoingToSleepActivities.remove(this);
   1755         } catch (Exception e) {
   1756             // Just skip on any failure; we'll make it visible when it next restarts.
   1757             Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
   1758         }
   1759         handleAlreadyVisible();
   1760     }
   1761 
   1762     /** Send visibility change message to the client and pause if needed. */
   1763     void makeClientVisible() {
   1764         mClientVisibilityDeferred = false;
   1765         try {
   1766             service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
   1767                     WindowVisibilityItem.obtain(true /* showWindow */));
   1768             if (shouldPauseWhenBecomingVisible()) {
   1769                 // An activity must be in the {@link PAUSING} state for the system to validate
   1770                 // the move to {@link PAUSED}.
   1771                 setState(PAUSING, "makeVisibleIfNeeded");
   1772                 service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
   1773                         PauseActivityItem.obtain(finishing, false /* userLeaving */,
   1774                                 configChangeFlags, false /* dontReport */));
   1775             }
   1776         } catch (Exception e) {
   1777             Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
   1778         }
   1779     }
   1780 
   1781     /** Check if activity should be moved to PAUSED state when it becomes visible. */
   1782     private boolean shouldPauseWhenBecomingVisible() {
   1783         // If the activity is stopped or stopping, cycle to the paused state. We avoid doing
   1784         // this when there is an activity waiting to become translucent as the extra binder
   1785         // calls will lead to noticeable jank. A later call to
   1786         // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to the proper
   1787         // paused state. We also avoid doing this for the activity the stack supervisor
   1788         // considers the resumed activity, as normal means will bring the activity from STOPPED
   1789         // to RESUMED. Adding PAUSING in this scenario will lead to double lifecycles.
   1790         if (!isState(STOPPED, STOPPING) || getStack().mTranslucentActivityWaiting != null
   1791                 || mStackSupervisor.getResumedActivityLocked() == this) {
   1792             return false;
   1793         }
   1794 
   1795         // Check if position in task allows to become paused
   1796         final int positionInTask = task.mActivities.indexOf(this);
   1797         if (positionInTask == -1) {
   1798             throw new IllegalStateException("Activity not found in its task");
   1799         }
   1800         if (positionInTask == task.mActivities.size() - 1) {
   1801             // It's the topmost activity in the task - should become paused now
   1802             return true;
   1803         }
   1804         // Check if activity above is finishing now and this one becomes the topmost in task.
   1805         final ActivityRecord activityAbove = task.mActivities.get(positionInTask + 1);
   1806         if (activityAbove.finishing && results == null) {
   1807             // We will only allow pausing if activity above wasn't launched for result. Otherwise it
   1808             // will cause this activity to resume before getting result.
   1809             return true;
   1810         }
   1811         return false;
   1812     }
   1813 
   1814     boolean handleAlreadyVisible() {
   1815         stopFreezingScreenLocked(false);
   1816         try {
   1817             if (returningOptions != null) {
   1818                 app.thread.scheduleOnNewActivityOptions(appToken, returningOptions.toBundle());
   1819             }
   1820         } catch(RemoteException e) {
   1821         }
   1822         return mState == RESUMED;
   1823     }
   1824 
   1825     static void activityResumedLocked(IBinder token) {
   1826         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   1827         if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
   1828         if (r != null) {
   1829             r.icicle = null;
   1830             r.haveState = false;
   1831         }
   1832     }
   1833 
   1834     /**
   1835      * Once we know that we have asked an application to put an activity in the resumed state
   1836      * (either by launching it or explicitly telling it), this function updates the rest of our
   1837      * state to match that fact.
   1838      */
   1839     void completeResumeLocked() {
   1840         final boolean wasVisible = visible;
   1841         setVisible(true);
   1842         if (!wasVisible) {
   1843             // Visibility has changed, so take a note of it so we call the TaskStackChangedListener
   1844             mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
   1845         }
   1846         idle = false;
   1847         results = null;
   1848         newIntents = null;
   1849         stopped = false;
   1850 
   1851         if (isActivityTypeHome()) {
   1852             ProcessRecord app = task.mActivities.get(0).app;
   1853             if (app != null && app != service.mHomeProcess) {
   1854                 service.mHomeProcess = app;
   1855             }
   1856         }
   1857 
   1858         if (nowVisible) {
   1859             // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
   1860             mStackSupervisor.reportActivityVisibleLocked(this);
   1861         }
   1862 
   1863         // Schedule an idle timeout in case the app doesn't do it for us.
   1864         mStackSupervisor.scheduleIdleTimeoutLocked(this);
   1865 
   1866         mStackSupervisor.reportResumedActivityLocked(this);
   1867 
   1868         resumeKeyDispatchingLocked();
   1869         final ActivityStack stack = getStack();
   1870         mStackSupervisor.mNoAnimActivities.clear();
   1871 
   1872         // Mark the point when the activity is resuming
   1873         // TODO: To be more accurate, the mark should be before the onCreate,
   1874         //       not after the onResume. But for subsequent starts, onResume is fine.
   1875         if (app != null) {
   1876             cpuTimeAtResume = service.mProcessCpuTracker.getCpuTimeForPid(app.pid);
   1877         } else {
   1878             cpuTimeAtResume = 0; // Couldn't get the cpu time of process
   1879         }
   1880 
   1881         returningOptions = null;
   1882 
   1883         if (canTurnScreenOn()) {
   1884             mStackSupervisor.wakeUp("turnScreenOnFlag");
   1885         } else {
   1886             // If the screen is going to turn on because the caller explicitly requested it and
   1887             // the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
   1888             // pause and then resume again later, which will result in a double life-cycle event.
   1889             stack.checkReadyForSleep();
   1890         }
   1891     }
   1892 
   1893     final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
   1894             CharSequence description) {
   1895         final ActivityStack stack = getStack();
   1896         if (mState != STOPPING) {
   1897             Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
   1898             stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
   1899             return;
   1900         }
   1901         if (newPersistentState != null) {
   1902             persistentState = newPersistentState;
   1903             service.notifyTaskPersisterLocked(task, false);
   1904         }
   1905         if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
   1906 
   1907         if (newIcicle != null) {
   1908             // If icicle is null, this is happening due to a timeout, so we haven't really saved
   1909             // the state.
   1910             icicle = newIcicle;
   1911             haveState = true;
   1912             launchCount = 0;
   1913             updateTaskDescription(description);
   1914         }
   1915         if (!stopped) {
   1916             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
   1917             stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
   1918             stopped = true;
   1919             setState(STOPPED, "activityStoppedLocked");
   1920 
   1921             mWindowContainerController.notifyAppStopped();
   1922 
   1923             if (finishing) {
   1924                 clearOptionsLocked();
   1925             } else {
   1926                 if (deferRelaunchUntilPaused) {
   1927                     stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
   1928                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   1929                 } else {
   1930                     mStackSupervisor.updatePreviousProcessLocked(this);
   1931                 }
   1932             }
   1933         }
   1934     }
   1935 
   1936     void startLaunchTickingLocked() {
   1937         if (Build.IS_USER) {
   1938             return;
   1939         }
   1940         if (launchTickTime == 0) {
   1941             launchTickTime = SystemClock.uptimeMillis();
   1942             continueLaunchTickingLocked();
   1943         }
   1944     }
   1945 
   1946     boolean continueLaunchTickingLocked() {
   1947         if (launchTickTime == 0) {
   1948             return false;
   1949         }
   1950 
   1951         final ActivityStack stack = getStack();
   1952         if (stack == null) {
   1953             return false;
   1954         }
   1955 
   1956         Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
   1957         stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
   1958         stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
   1959         return true;
   1960     }
   1961 
   1962     void finishLaunchTickingLocked() {
   1963         launchTickTime = 0;
   1964         final ActivityStack stack = getStack();
   1965         if (stack != null) {
   1966             stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
   1967         }
   1968     }
   1969 
   1970     // IApplicationToken
   1971 
   1972     public boolean mayFreezeScreenLocked(ProcessRecord app) {
   1973         // Only freeze the screen if this activity is currently attached to
   1974         // an application, and that application is not blocked or unresponding.
   1975         // In any other case, we can't count on getting the screen unfrozen,
   1976         // so it is best to leave as-is.
   1977         return app != null && !app.crashing && !app.notResponding;
   1978     }
   1979 
   1980     public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
   1981         if (mayFreezeScreenLocked(app)) {
   1982             mWindowContainerController.startFreezingScreen(configChanges);
   1983         }
   1984     }
   1985 
   1986     public void stopFreezingScreenLocked(boolean force) {
   1987         if (force || frozenBeforeDestroy) {
   1988             frozenBeforeDestroy = false;
   1989             mWindowContainerController.stopFreezingScreen(force);
   1990         }
   1991     }
   1992 
   1993     public void reportFullyDrawnLocked(boolean restoredFromBundle) {
   1994         final long curTime = SystemClock.uptimeMillis();
   1995         if (displayStartTime != 0) {
   1996             reportLaunchTimeLocked(curTime);
   1997         }
   1998         final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
   1999                 getWindowingMode());
   2000         if (fullyDrawnStartTime != 0 && entry != null) {
   2001             final long thisTime = curTime - fullyDrawnStartTime;
   2002             final long totalTime = entry.mFullyDrawnStartTime != 0
   2003                     ? (curTime - entry.mFullyDrawnStartTime) : thisTime;
   2004             if (SHOW_ACTIVITY_START_TIME) {
   2005                 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
   2006                 EventLog.writeEvent(AM_ACTIVITY_FULLY_DRAWN_TIME,
   2007                         userId, System.identityHashCode(this), shortComponentName,
   2008                         thisTime, totalTime);
   2009                 StringBuilder sb = service.mStringBuilder;
   2010                 sb.setLength(0);
   2011                 sb.append("Fully drawn ");
   2012                 sb.append(shortComponentName);
   2013                 sb.append(": ");
   2014                 TimeUtils.formatDuration(thisTime, sb);
   2015                 if (thisTime != totalTime) {
   2016                     sb.append(" (total ");
   2017                     TimeUtils.formatDuration(totalTime, sb);
   2018                     sb.append(")");
   2019                 }
   2020                 Log.i(TAG, sb.toString());
   2021             }
   2022             if (totalTime > 0) {
   2023                 //service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
   2024             }
   2025             entry.mFullyDrawnStartTime = 0;
   2026         }
   2027         mStackSupervisor.getActivityMetricsLogger().logAppTransitionReportedDrawn(this,
   2028                 restoredFromBundle);
   2029         fullyDrawnStartTime = 0;
   2030     }
   2031 
   2032     private void reportLaunchTimeLocked(final long curTime) {
   2033         final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
   2034                 getWindowingMode());
   2035         if (entry == null) {
   2036             return;
   2037         }
   2038         final long thisTime = curTime - displayStartTime;
   2039         final long totalTime = entry.mLaunchStartTime != 0
   2040                 ? (curTime - entry.mLaunchStartTime) : thisTime;
   2041         if (SHOW_ACTIVITY_START_TIME) {
   2042             Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
   2043             EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
   2044                     userId, System.identityHashCode(this), shortComponentName,
   2045                     thisTime, totalTime);
   2046             StringBuilder sb = service.mStringBuilder;
   2047             sb.setLength(0);
   2048             sb.append("Displayed ");
   2049             sb.append(shortComponentName);
   2050             sb.append(": ");
   2051             TimeUtils.formatDuration(thisTime, sb);
   2052             if (thisTime != totalTime) {
   2053                 sb.append(" (total ");
   2054                 TimeUtils.formatDuration(totalTime, sb);
   2055                 sb.append(")");
   2056             }
   2057             Log.i(TAG, sb.toString());
   2058         }
   2059         mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
   2060         if (totalTime > 0) {
   2061             //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
   2062         }
   2063         displayStartTime = 0;
   2064         entry.mLaunchStartTime = 0;
   2065     }
   2066 
   2067     @Override
   2068     public void onStartingWindowDrawn(long timestamp) {
   2069         synchronized (service) {
   2070             mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
   2071                     getWindowingMode(), timestamp);
   2072         }
   2073     }
   2074 
   2075     @Override
   2076     public void onWindowsDrawn(long timestamp) {
   2077         synchronized (service) {
   2078             mStackSupervisor.getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(),
   2079                     timestamp);
   2080             if (displayStartTime != 0) {
   2081                 reportLaunchTimeLocked(timestamp);
   2082             }
   2083             mStackSupervisor.sendWaitingVisibleReportLocked(this);
   2084             startTime = 0;
   2085             finishLaunchTickingLocked();
   2086             if (task != null) {
   2087                 task.hasBeenVisible = true;
   2088             }
   2089         }
   2090     }
   2091 
   2092     @Override
   2093     public void onWindowsVisible() {
   2094         synchronized (service) {
   2095             mStackSupervisor.reportActivityVisibleLocked(this);
   2096             if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
   2097             if (!nowVisible) {
   2098                 nowVisible = true;
   2099                 lastVisibleTime = SystemClock.uptimeMillis();
   2100                 if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
   2101                     // If this activity was already idle or there is an activity that must be
   2102                     // stopped immediately after visible, then we now need to make sure we perform
   2103                     // the full stop of any activities that are waiting to do so. This is because
   2104                     // we won't do that while they are still waiting for this one to become visible.
   2105                     final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
   2106                     if (size > 0) {
   2107                         for (int i = 0; i < size; i++) {
   2108                             final ActivityRecord r =
   2109                                     mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i);
   2110                             if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
   2111                         }
   2112                         mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
   2113                         mStackSupervisor.scheduleIdleLocked();
   2114                     }
   2115                 } else {
   2116                     // Instead of doing the full stop routine here, let's just hide any activities
   2117                     // we now can, and let them stop when the normal idle happens.
   2118                     mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
   2119                             false /* remove */, true /* processPausingActivities */);
   2120                 }
   2121                 service.scheduleAppGcsLocked();
   2122             }
   2123         }
   2124     }
   2125 
   2126     @Override
   2127     public void onWindowsGone() {
   2128         synchronized (service) {
   2129             if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
   2130             nowVisible = false;
   2131         }
   2132     }
   2133 
   2134     @Override
   2135     public boolean keyDispatchingTimedOut(String reason, int windowPid) {
   2136         ActivityRecord anrActivity;
   2137         ProcessRecord anrApp;
   2138         boolean windowFromSameProcessAsActivity;
   2139         synchronized (service) {
   2140             anrActivity = getWaitingHistoryRecordLocked();
   2141             anrApp = app;
   2142             windowFromSameProcessAsActivity =
   2143                     app == null || app.pid == windowPid || windowPid == -1;
   2144         }
   2145         if (windowFromSameProcessAsActivity) {
   2146             return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
   2147         } else {
   2148             // In this case another process added windows using this activity token. So, we call the
   2149             // generic service input dispatch timed out method so that the right process is blamed.
   2150             return service.inputDispatchingTimedOut(windowPid, false /* aboveSystem */, reason) < 0;
   2151         }
   2152     }
   2153 
   2154     private ActivityRecord getWaitingHistoryRecordLocked() {
   2155         // First find the real culprit...  if this activity is waiting for
   2156         // another activity to start or has stopped, then the key dispatching
   2157         // timeout should not be caused by this.
   2158         if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) {
   2159             final ActivityStack stack = mStackSupervisor.getFocusedStack();
   2160             // Try to use the one which is closest to top.
   2161             ActivityRecord r = stack.getResumedActivity();
   2162             if (r == null) {
   2163                 r = stack.mPausingActivity;
   2164             }
   2165             if (r != null) {
   2166                 return r;
   2167             }
   2168         }
   2169         return this;
   2170     }
   2171 
   2172     /** Checks whether the activity should be shown for current user. */
   2173     public boolean okToShowLocked() {
   2174         // We cannot show activities when the device is locked and the application is not
   2175         // encryption aware.
   2176         if (!StorageManager.isUserKeyUnlocked(userId)
   2177                 && !info.applicationInfo.isEncryptionAware()) {
   2178             return false;
   2179         }
   2180 
   2181         return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
   2182                 || (mStackSupervisor.isCurrentProfileLocked(userId)
   2183                 && service.mUserController.isUserRunning(userId, 0 /* flags */));
   2184     }
   2185 
   2186     /**
   2187      * This method will return true if the activity is either visible, is becoming visible, is
   2188      * currently pausing, or is resumed.
   2189      */
   2190     public boolean isInterestingToUserLocked() {
   2191         return visible || nowVisible || mState == PAUSING || mState == RESUMED;
   2192     }
   2193 
   2194     void setSleeping(boolean _sleeping) {
   2195         setSleeping(_sleeping, false);
   2196     }
   2197 
   2198     void setSleeping(boolean _sleeping, boolean force) {
   2199         if (!force && sleeping == _sleeping) {
   2200             return;
   2201         }
   2202         if (app != null && app.thread != null) {
   2203             try {
   2204                 app.thread.scheduleSleeping(appToken, _sleeping);
   2205                 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
   2206                     mStackSupervisor.mGoingToSleepActivities.add(this);
   2207                 }
   2208                 sleeping = _sleeping;
   2209             } catch (RemoteException e) {
   2210                 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
   2211             }
   2212         }
   2213     }
   2214 
   2215     static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   2216         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   2217         if (r == null) {
   2218             return INVALID_TASK_ID;
   2219         }
   2220         final TaskRecord task = r.task;
   2221         final int activityNdx = task.mActivities.indexOf(r);
   2222         if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
   2223             return INVALID_TASK_ID;
   2224         }
   2225         return task.taskId;
   2226     }
   2227 
   2228     static ActivityRecord isInStackLocked(IBinder token) {
   2229         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   2230         return (r != null) ? r.getStack().isInStackLocked(r) : null;
   2231     }
   2232 
   2233     static ActivityStack getStackLocked(IBinder token) {
   2234         final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   2235         if (r != null) {
   2236             return r.getStack();
   2237         }
   2238         return null;
   2239     }
   2240 
   2241     /**
   2242      * @return display id to which this record is attached, -1 if not attached.
   2243      */
   2244     int getDisplayId() {
   2245         final ActivityStack stack = getStack();
   2246         if (stack == null) {
   2247             return -1;
   2248         }
   2249         return stack.mDisplayId;
   2250     }
   2251 
   2252     final boolean isDestroyable() {
   2253         if (finishing || app == null) {
   2254             // This would be redundant.
   2255             return false;
   2256         }
   2257         final ActivityStack stack = getStack();
   2258         if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
   2259                 || !haveState || !stopped) {
   2260             // We're not ready for this kind of thing.
   2261             return false;
   2262         }
   2263         if (visible) {
   2264             // The user would notice this!
   2265             return false;
   2266         }
   2267         return true;
   2268     }
   2269 
   2270     private static String createImageFilename(long createTime, int taskId) {
   2271         return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
   2272                 IMAGE_EXTENSION;
   2273     }
   2274 
   2275     void setTaskDescription(TaskDescription _taskDescription) {
   2276         Bitmap icon;
   2277         if (_taskDescription.getIconFilename() == null &&
   2278                 (icon = _taskDescription.getIcon()) != null) {
   2279             final String iconFilename = createImageFilename(createTime, task.taskId);
   2280             final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
   2281                     iconFilename);
   2282             final String iconFilePath = iconFile.getAbsolutePath();
   2283             service.getRecentTasks().saveImage(icon, iconFilePath);
   2284             _taskDescription.setIconFilename(iconFilePath);
   2285         }
   2286         taskDescription = _taskDescription;
   2287     }
   2288 
   2289     void setVoiceSessionLocked(IVoiceInteractionSession session) {
   2290         voiceSession = session;
   2291         pendingVoiceInteractionStart = false;
   2292     }
   2293 
   2294     void clearVoiceSessionLocked() {
   2295         voiceSession = null;
   2296         pendingVoiceInteractionStart = false;
   2297     }
   2298 
   2299     void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
   2300         showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
   2301     }
   2302 
   2303     void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
   2304             boolean fromRecents) {
   2305         if (mWindowContainerController == null) {
   2306             return;
   2307         }
   2308         if (mTaskOverlay) {
   2309             // We don't show starting window for overlay activities.
   2310             return;
   2311         }
   2312 
   2313         final CompatibilityInfo compatInfo =
   2314                 service.compatibilityInfoForPackageLocked(info.applicationInfo);
   2315         final boolean shown = mWindowContainerController.addStartingWindow(packageName, theme,
   2316                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
   2317                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
   2318                 allowTaskSnapshot(),
   2319                 mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
   2320                 fromRecents);
   2321         if (shown) {
   2322             mStartingWindowState = STARTING_WINDOW_SHOWN;
   2323         }
   2324     }
   2325 
   2326     void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
   2327         if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
   2328             if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
   2329             mStartingWindowState = STARTING_WINDOW_REMOVED;
   2330             mWindowContainerController.removeStartingWindow();
   2331         }
   2332     }
   2333 
   2334     int getRequestedOrientation() {
   2335         return mWindowContainerController.getOrientation();
   2336     }
   2337 
   2338     void setRequestedOrientation(int requestedOrientation) {
   2339         final int displayId = getDisplayId();
   2340         final Configuration displayConfig =
   2341                 mStackSupervisor.getDisplayOverrideConfiguration(displayId);
   2342 
   2343         final Configuration config = mWindowContainerController.setOrientation(requestedOrientation,
   2344                 displayId, displayConfig, mayFreezeScreenLocked(app));
   2345         if (config != null) {
   2346             frozenBeforeDestroy = true;
   2347             if (!service.updateDisplayOverrideConfigurationLocked(config, this,
   2348                     false /* deferResume */, displayId)) {
   2349                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   2350             }
   2351         }
   2352         service.mTaskChangeNotificationController.notifyActivityRequestedOrientationChanged(
   2353                 task.taskId, requestedOrientation);
   2354     }
   2355 
   2356     void setDisablePreviewScreenshots(boolean disable) {
   2357         mWindowContainerController.setDisablePreviewScreenshots(disable);
   2358     }
   2359 
   2360     /**
   2361      * Set the last reported global configuration to the client. Should be called whenever a new
   2362      * global configuration is sent to the client for this activity.
   2363      */
   2364     void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
   2365         mLastReportedConfiguration.setGlobalConfiguration(config);
   2366     }
   2367 
   2368     /**
   2369      * Set the last reported configuration to the client. Should be called whenever
   2370      * a new merged configuration is sent to the client for this activity.
   2371      */
   2372     void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
   2373         setLastReportedConfiguration(config.getGlobalConfiguration(),
   2374             config.getOverrideConfiguration());
   2375     }
   2376 
   2377     private void setLastReportedConfiguration(Configuration global, Configuration override) {
   2378         mLastReportedConfiguration.setConfiguration(global, override);
   2379     }
   2380 
   2381     // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
   2382     private void updateOverrideConfiguration() {
   2383         mTmpConfig.unset();
   2384         computeBounds(mTmpBounds);
   2385 
   2386         if (mTmpBounds.equals(getOverrideBounds())) {
   2387             return;
   2388         }
   2389 
   2390         setBounds(mTmpBounds);
   2391 
   2392         final Rect updatedBounds = getOverrideBounds();
   2393 
   2394         // Bounds changed...update configuration to match.
   2395         if (!matchParentBounds()) {
   2396             task.computeOverrideConfiguration(mTmpConfig, updatedBounds, null /* insetBounds */,
   2397                     false /* overrideWidth */, false /* overrideHeight */);
   2398         }
   2399 
   2400         onOverrideConfigurationChanged(mTmpConfig);
   2401     }
   2402 
   2403     /** Returns true if the configuration is compatible with this activity. */
   2404     boolean isConfigurationCompatible(Configuration config) {
   2405         final int orientation = mWindowContainerController != null
   2406                 ? mWindowContainerController.getOrientation() : info.screenOrientation;
   2407         if (isFixedOrientationPortrait(orientation)
   2408                 && config.orientation != ORIENTATION_PORTRAIT) {
   2409             return false;
   2410         }
   2411         if (isFixedOrientationLandscape(orientation)
   2412                 && config.orientation != ORIENTATION_LANDSCAPE) {
   2413             return false;
   2414         }
   2415         return true;
   2416     }
   2417 
   2418     /**
   2419      * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
   2420      */
   2421     // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
   2422     private void computeBounds(Rect outBounds) {
   2423         outBounds.setEmpty();
   2424         final float maxAspectRatio = info.maxAspectRatio;
   2425         final ActivityStack stack = getStack();
   2426         if (task == null || stack == null || task.inMultiWindowMode() || maxAspectRatio == 0
   2427                 || isInVrUiMode(getConfiguration())) {
   2428             // We don't set override configuration if that activity task isn't fullscreen. I.e. the
   2429             // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
   2430             // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
   2431             // if we are in VR mode.
   2432             return;
   2433         }
   2434 
   2435         // We must base this on the parent configuration, because we set our override
   2436         // configuration's appBounds based on the result of this method. If we used our own
   2437         // configuration, it would be influenced by past invocations.
   2438         final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
   2439         final int containingAppWidth = appBounds.width();
   2440         final int containingAppHeight = appBounds.height();
   2441         int maxActivityWidth = containingAppWidth;
   2442         int maxActivityHeight = containingAppHeight;
   2443 
   2444         if (containingAppWidth < containingAppHeight) {
   2445             // Width is the shorter side, so we use that to figure-out what the max. height
   2446             // should be given the aspect ratio.
   2447             maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
   2448         } else {
   2449             // Height is the shorter side, so we use that to figure-out what the max. width
   2450             // should be given the aspect ratio.
   2451             maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
   2452         }
   2453 
   2454         if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) {
   2455             // The display matches or is less than the activity aspect ratio, so nothing else to do.
   2456             // Return the existing bounds. If this method is running for the first time,
   2457             // {@link #getOverrideBounds()} will be empty (representing no override). If the method has run
   2458             // before, then effect of {@link #getOverrideBounds()} will already have been applied to the
   2459             // value returned from {@link getConfiguration}. Refer to
   2460             // {@link TaskRecord#computeOverrideConfiguration}.
   2461             outBounds.set(getOverrideBounds());
   2462             return;
   2463         }
   2464 
   2465         // Compute configuration based on max supported width and height.
   2466         // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
   2467         // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
   2468         // bounds would end up too small.
   2469         outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top);
   2470 
   2471         if (service.mWindowManager.getNavBarPosition() == NAV_BAR_LEFT) {
   2472             // Position the activity frame on the opposite side of the nav bar.
   2473             outBounds.left = appBounds.right - maxActivityWidth;
   2474             outBounds.right = appBounds.right;
   2475         }
   2476     }
   2477 
   2478     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
   2479         return ensureActivityConfiguration(globalChanges, preserveWindow,
   2480                 false /* ignoreStopState */);
   2481     }
   2482 
   2483     /**
   2484      * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
   2485      * is updated with the correct configuration and all other bookkeeping is handled.
   2486      *
   2487      * @param globalChanges The changes to the global configuration.
   2488      * @param preserveWindow If the activity window should be preserved on screen if the activity
   2489      *                       is relaunched.
   2490      * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
   2491      *                        state. This is useful for the case where we know the activity will be
   2492      *                        visible soon and we want to ensure its configuration before we make it
   2493      *                        visible.
   2494      * @return True if the activity was relaunched and false if it wasn't relaunched because we
   2495      *         can't or the app handles the specific configuration that is changing.
   2496      */
   2497     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
   2498             boolean ignoreStopState) {
   2499         final ActivityStack stack = getStack();
   2500         if (stack.mConfigWillChange) {
   2501             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2502                     "Skipping config check (will change): " + this);
   2503             return true;
   2504         }
   2505 
   2506         // We don't worry about activities that are finishing.
   2507         if (finishing) {
   2508             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2509                     "Configuration doesn't matter in finishing " + this);
   2510             stopFreezingScreenLocked(false);
   2511             return true;
   2512         }
   2513 
   2514         if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
   2515             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2516                     "Skipping config check stopped or stopping: " + this);
   2517             return true;
   2518         }
   2519 
   2520         // TODO: We should add ActivityRecord.shouldBeVisible() that checks if the activity should
   2521         // be visible based on the stack, task, and lockscreen state and use that here instead. The
   2522         // method should be based on the logic in ActivityStack.ensureActivitiesVisibleLocked().
   2523         // Skip updating configuration for activity is a stack that shouldn't be visible.
   2524         if (!stack.shouldBeVisible(null /* starting */)) {
   2525             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2526                     "Skipping config check invisible stack: " + this);
   2527             return true;
   2528         }
   2529 
   2530         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2531                 "Ensuring correct configuration: " + this);
   2532 
   2533         final int newDisplayId = getDisplayId();
   2534         final boolean displayChanged = mLastReportedDisplayId != newDisplayId;
   2535         if (displayChanged) {
   2536             mLastReportedDisplayId = newDisplayId;
   2537         }
   2538         // TODO(b/36505427): Is there a better place to do this?
   2539         updateOverrideConfiguration();
   2540 
   2541         // Short circuit: if the two full configurations are equal (the common case), then there is
   2542         // nothing to do.  We test the full configuration instead of the global and merged override
   2543         // configurations because there are cases (like moving a task to the pinned stack) where
   2544         // the combine configurations are equal, but would otherwise differ in the override config
   2545         mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
   2546         if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
   2547             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2548                     "Configuration & display unchanged in " + this);
   2549             return true;
   2550         }
   2551 
   2552         // Okay we now are going to make this activity have the new config.
   2553         // But then we need to figure out how it needs to deal with that.
   2554 
   2555         // Find changes between last reported merged configuration and the current one. This is used
   2556         // to decide whether to relaunch an activity or just report a configuration change.
   2557         final int changes = getConfigurationChanges(mTmpConfig);
   2558 
   2559         // Update last reported values.
   2560         final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
   2561 
   2562         setLastReportedConfiguration(service.getGlobalConfiguration(), newMergedOverrideConfig);
   2563 
   2564         if (mState == INITIALIZING) {
   2565             // No need to relaunch or schedule new config for activity that hasn't been launched
   2566             // yet. We do, however, return after applying the config to activity record, so that
   2567             // it will use it for launch transaction.
   2568             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2569                     "Skipping config check for initializing activity: " + this);
   2570             return true;
   2571         }
   2572 
   2573         if (changes == 0 && !forceNewConfig) {
   2574             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2575                     "Configuration no differences in " + this);
   2576             // There are no significant differences, so we won't relaunch but should still deliver
   2577             // the new configuration to the client process.
   2578             if (displayChanged) {
   2579                 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
   2580             } else {
   2581                 scheduleConfigurationChanged(newMergedOverrideConfig);
   2582             }
   2583             return true;
   2584         }
   2585 
   2586         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2587                 "Configuration changes for " + this + ", allChanges="
   2588                         + Configuration.configurationDiffToString(changes));
   2589 
   2590         // If the activity isn't currently running, just leave the new configuration and it will
   2591         // pick that up next time it starts.
   2592         if (app == null || app.thread == null) {
   2593             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2594                     "Configuration doesn't matter not running " + this);
   2595             stopFreezingScreenLocked(false);
   2596             forceNewConfig = false;
   2597             return true;
   2598         }
   2599 
   2600         // Figure out how to handle the changes between the configurations.
   2601         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2602                 "Checking to restart " + info.name + ": changed=0x"
   2603                         + Integer.toHexString(changes) + ", handles=0x"
   2604                         + Integer.toHexString(info.getRealConfigChanged())
   2605                         + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
   2606 
   2607         if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
   2608             // Aha, the activity isn't handling the change, so DIE DIE DIE.
   2609             configChangeFlags |= changes;
   2610             startFreezingScreenLocked(app, globalChanges);
   2611             forceNewConfig = false;
   2612             preserveWindow &= isResizeOnlyChange(changes);
   2613             if (app == null || app.thread == null) {
   2614                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2615                         "Config is destroying non-running " + this);
   2616                 stack.destroyActivityLocked(this, true, "config");
   2617             } else if (mState == PAUSING) {
   2618                 // A little annoying: we are waiting for this activity to finish pausing. Let's not
   2619                 // do anything now, but just flag that it needs to be restarted when done pausing.
   2620                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2621                         "Config is skipping already pausing " + this);
   2622                 deferRelaunchUntilPaused = true;
   2623                 preserveWindowOnDeferredRelaunch = preserveWindow;
   2624                 return true;
   2625             } else if (mState == RESUMED) {
   2626                 // Try to optimize this case: the configuration is changing and we need to restart
   2627                 // the top, resumed activity. Instead of doing the normal handshaking, just say
   2628                 // "restart!".
   2629                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2630                         "Config is relaunching resumed " + this);
   2631 
   2632                 if (DEBUG_STATES && !visible) {
   2633                     Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
   2634                             + " called by " + Debug.getCallers(4));
   2635                 }
   2636 
   2637                 relaunchActivityLocked(true /* andResume */, preserveWindow);
   2638             } else {
   2639                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   2640                         "Config is relaunching non-resumed " + this);
   2641                 relaunchActivityLocked(false /* andResume */, preserveWindow);
   2642             }
   2643 
   2644             // All done...  tell the caller we weren't able to keep this activity around.
   2645             return false;
   2646         }
   2647 
   2648         // Default case: the activity can handle this new configuration, so hand it over.
   2649         // NOTE: We only forward the override configuration as the system level configuration
   2650         // changes is always sent to all processes when they happen so it can just use whatever
   2651         // system level configuration it last got.
   2652         if (displayChanged) {
   2653             scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
   2654         } else {
   2655             scheduleConfigurationChanged(newMergedOverrideConfig);
   2656         }
   2657         stopFreezingScreenLocked(false);
   2658 
   2659         return true;
   2660     }
   2661 
   2662     /**
   2663      * When assessing a configuration change, decide if the changes flags and the new configurations
   2664      * should cause the Activity to relaunch.
   2665      *
   2666      * @param changes the changes due to the given configuration.
   2667      * @param changesConfig the configuration that was used to calculate the given changes via a
   2668      *        call to getConfigurationChanges.
   2669      */
   2670     private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
   2671         int configChanged = info.getRealConfigChanged();
   2672         boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
   2673 
   2674         // Override for apps targeting pre-O sdks
   2675         // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
   2676         // to the config change.
   2677         // For O and later, apps will be required to add configChanges="uimode" to their manifest.
   2678         if (appInfo.targetSdkVersion < O
   2679                 && requestedVrComponent != null
   2680                 && onlyVrUiModeChanged) {
   2681             configChanged |= CONFIG_UI_MODE;
   2682         }
   2683 
   2684         return (changes&(~configChanged)) != 0;
   2685     }
   2686 
   2687     /**
   2688      * Returns true if the configuration change is solely due to the UI mode switching into or out
   2689      * of UI_MODE_TYPE_VR_HEADSET.
   2690      */
   2691     private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
   2692         final Configuration currentConfig = getConfiguration();
   2693         return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
   2694             != isInVrUiMode(lastReportedConfig));
   2695     }
   2696 
   2697     private int getConfigurationChanges(Configuration lastReportedConfig) {
   2698         // Determine what has changed.  May be nothing, if this is a config that has come back from
   2699         // the app after going idle.  In that case we just want to leave the official config object
   2700         // now in the activity and do nothing else.
   2701         final Configuration currentConfig = getConfiguration();
   2702         int changes = lastReportedConfig.diff(currentConfig);
   2703         // We don't want to use size changes if they don't cross boundaries that are important to
   2704         // the app.
   2705         if ((changes & CONFIG_SCREEN_SIZE) != 0) {
   2706             final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp,
   2707                     currentConfig.screenWidthDp)
   2708                     || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp,
   2709                     currentConfig.screenHeightDp);
   2710             if (!crosses) {
   2711                 changes &= ~CONFIG_SCREEN_SIZE;
   2712             }
   2713         }
   2714         if ((changes & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
   2715             final int oldSmallest = lastReportedConfig.smallestScreenWidthDp;
   2716             final int newSmallest = currentConfig.smallestScreenWidthDp;
   2717             if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
   2718                 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
   2719             }
   2720         }
   2721         // We don't want window configuration to cause relaunches.
   2722         if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) {
   2723             changes &= ~CONFIG_WINDOW_CONFIGURATION;
   2724         }
   2725 
   2726         return changes;
   2727     }
   2728 
   2729     private static boolean isResizeOnlyChange(int change) {
   2730         return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
   2731                 | CONFIG_SCREEN_LAYOUT)) == 0;
   2732     }
   2733 
   2734     void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
   2735         if (service.mSuppressResizeConfigChanges && preserveWindow) {
   2736             configChangeFlags = 0;
   2737             return;
   2738         }
   2739 
   2740         List<ResultInfo> pendingResults = null;
   2741         List<ReferrerIntent> pendingNewIntents = null;
   2742         if (andResume) {
   2743             pendingResults = results;
   2744             pendingNewIntents = newIntents;
   2745         }
   2746         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
   2747                 "Relaunching: " + this + " with results=" + pendingResults
   2748                         + " newIntents=" + pendingNewIntents + " andResume=" + andResume
   2749                         + " preserveWindow=" + preserveWindow);
   2750         EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
   2751                         : AM_RELAUNCH_ACTIVITY, userId, System.identityHashCode(this),
   2752                 task.taskId, shortComponentName);
   2753 
   2754         startFreezingScreenLocked(app, 0);
   2755 
   2756         try {
   2757             if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
   2758                     "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
   2759                             + " callers=" + Debug.getCallers(6));
   2760             forceNewConfig = false;
   2761             mStackSupervisor.activityRelaunchingLocked(this);
   2762             final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
   2763                     pendingNewIntents, configChangeFlags,
   2764                     new MergedConfiguration(service.getGlobalConfiguration(),
   2765                             getMergedOverrideConfiguration()),
   2766                     preserveWindow);
   2767             final ActivityLifecycleItem lifecycleItem;
   2768             if (andResume) {
   2769                 lifecycleItem = ResumeActivityItem.obtain(service.isNextTransitionForward());
   2770             } else {
   2771                 lifecycleItem = PauseActivityItem.obtain();
   2772             }
   2773             final ClientTransaction transaction = ClientTransaction.obtain(app.thread, appToken);
   2774             transaction.addCallback(callbackItem);
   2775             transaction.setLifecycleStateRequest(lifecycleItem);
   2776             service.getLifecycleManager().scheduleTransaction(transaction);
   2777             // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
   2778             // request resume if this activity is currently resumed, which implies we aren't
   2779             // sleeping.
   2780         } catch (RemoteException e) {
   2781             if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e);
   2782         }
   2783 
   2784         if (andResume) {
   2785             if (DEBUG_STATES) {
   2786                 Slog.d(TAG_STATES, "Resumed after relaunch " + this);
   2787             }
   2788             results = null;
   2789             newIntents = null;
   2790             service.getAppWarningsLocked().onResumeActivity(this);
   2791             service.showAskCompatModeDialogLocked(this);
   2792         } else {
   2793             service.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
   2794             setState(PAUSED, "relaunchActivityLocked");
   2795         }
   2796 
   2797         configChangeFlags = 0;
   2798         deferRelaunchUntilPaused = false;
   2799         preserveWindowOnDeferredRelaunch = false;
   2800     }
   2801 
   2802     private boolean isProcessRunning() {
   2803         ProcessRecord proc = app;
   2804         if (proc == null) {
   2805             proc = service.mProcessNames.get(processName, info.applicationInfo.uid);
   2806         }
   2807         return proc != null && proc.thread != null;
   2808     }
   2809 
   2810     /**
   2811      * @return Whether a task snapshot starting window may be shown.
   2812      */
   2813     private boolean allowTaskSnapshot() {
   2814         if (newIntents == null) {
   2815             return true;
   2816         }
   2817 
   2818         // Restrict task snapshot starting window to launcher start, or there is no intent at all
   2819         // (eg. task being brought to front). If the intent is something else, likely the app is
   2820         // going to show some specific page or view, instead of what's left last time.
   2821         for (int i = newIntents.size() - 1; i >= 0; i--) {
   2822             final Intent intent = newIntents.get(i);
   2823             if (intent != null && !ActivityRecord.isMainIntent(intent)) {
   2824                 return false;
   2825             }
   2826         }
   2827         return true;
   2828     }
   2829 
   2830     /**
   2831      * Returns {@code true} if the associated activity has the no history flag set on it.
   2832      * {@code false} otherwise.
   2833      */
   2834     boolean isNoHistory() {
   2835         return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
   2836                 || (info.flags & FLAG_NO_HISTORY) != 0;
   2837     }
   2838 
   2839     void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
   2840         out.attribute(null, ATTR_ID, String.valueOf(createTime));
   2841         out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
   2842         if (launchedFromPackage != null) {
   2843             out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
   2844         }
   2845         if (resolvedType != null) {
   2846             out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
   2847         }
   2848         out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
   2849         out.attribute(null, ATTR_USERID, String.valueOf(userId));
   2850 
   2851         if (taskDescription != null) {
   2852             taskDescription.saveToXml(out);
   2853         }
   2854 
   2855         out.startTag(null, TAG_INTENT);
   2856         intent.saveToXml(out);
   2857         out.endTag(null, TAG_INTENT);
   2858 
   2859         if (isPersistable() && persistentState != null) {
   2860             out.startTag(null, TAG_PERSISTABLEBUNDLE);
   2861             persistentState.saveToXml(out);
   2862             out.endTag(null, TAG_PERSISTABLEBUNDLE);
   2863         }
   2864     }
   2865 
   2866     static ActivityRecord restoreFromXml(XmlPullParser in,
   2867             ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
   2868         Intent intent = null;
   2869         PersistableBundle persistentState = null;
   2870         int launchedFromUid = 0;
   2871         String launchedFromPackage = null;
   2872         String resolvedType = null;
   2873         boolean componentSpecified = false;
   2874         int userId = 0;
   2875         long createTime = -1;
   2876         final int outerDepth = in.getDepth();
   2877         TaskDescription taskDescription = new TaskDescription();
   2878 
   2879         for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
   2880             final String attrName = in.getAttributeName(attrNdx);
   2881             final String attrValue = in.getAttributeValue(attrNdx);
   2882             if (DEBUG) Slog.d(TaskPersister.TAG,
   2883                         "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
   2884             if (ATTR_ID.equals(attrName)) {
   2885                 createTime = Long.parseLong(attrValue);
   2886             } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
   2887                 launchedFromUid = Integer.parseInt(attrValue);
   2888             } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
   2889                 launchedFromPackage = attrValue;
   2890             } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
   2891                 resolvedType = attrValue;
   2892             } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
   2893                 componentSpecified = Boolean.parseBoolean(attrValue);
   2894             } else if (ATTR_USERID.equals(attrName)) {
   2895                 userId = Integer.parseInt(attrValue);
   2896             } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
   2897                 taskDescription.restoreFromXml(attrName, attrValue);
   2898             } else {
   2899                 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
   2900             }
   2901         }
   2902 
   2903         int event;
   2904         while (((event = in.next()) != END_DOCUMENT) &&
   2905                 (event != END_TAG || in.getDepth() >= outerDepth)) {
   2906             if (event == START_TAG) {
   2907                 final String name = in.getName();
   2908                 if (DEBUG)
   2909                         Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
   2910                 if (TAG_INTENT.equals(name)) {
   2911                     intent = Intent.restoreFromXml(in);
   2912                     if (DEBUG)
   2913                             Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
   2914                 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
   2915                     persistentState = PersistableBundle.restoreFromXml(in);
   2916                     if (DEBUG) Slog.d(TaskPersister.TAG,
   2917                             "ActivityRecord: persistentState=" + persistentState);
   2918                 } else {
   2919                     Slog.w(TAG, "restoreActivity: unexpected name=" + name);
   2920                     XmlUtils.skipCurrentTag(in);
   2921                 }
   2922             }
   2923         }
   2924 
   2925         if (intent == null) {
   2926             throw new XmlPullParserException("restoreActivity error intent=" + intent);
   2927         }
   2928 
   2929         final ActivityManagerService service = stackSupervisor.mService;
   2930         final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
   2931                 userId, Binder.getCallingUid());
   2932         if (aInfo == null) {
   2933             throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
   2934                     " resolvedType=" + resolvedType);
   2935         }
   2936         final ActivityRecord r = new ActivityRecord(service, null /* caller */,
   2937                 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
   2938                 aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
   2939                 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
   2940                 stackSupervisor, null /* options */, null /* sourceRecord */);
   2941 
   2942         r.persistentState = persistentState;
   2943         r.taskDescription = taskDescription;
   2944         r.createTime = createTime;
   2945 
   2946         return r;
   2947     }
   2948 
   2949     private static boolean isInVrUiMode(Configuration config) {
   2950         return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
   2951     }
   2952 
   2953     int getUid() {
   2954         return info.applicationInfo.uid;
   2955     }
   2956 
   2957     void setShowWhenLocked(boolean showWhenLocked) {
   2958         mShowWhenLocked = showWhenLocked;
   2959         mStackSupervisor.ensureActivitiesVisibleLocked(null, 0 /* configChanges */,
   2960                 false /* preserveWindows */);
   2961     }
   2962 
   2963     /**
   2964      * @return true if the activity windowing mode is not
   2965      *         {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and activity contains
   2966      *         windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the activity
   2967      *         has set {@link #mShowWhenLocked}.
   2968      *         Multi-windowing mode will be exited if true is returned.
   2969      */
   2970     boolean canShowWhenLocked() {
   2971         return !inPinnedWindowingMode() && (mShowWhenLocked
   2972                 || service.mWindowManager.containsShowWhenLockedWindow(appToken));
   2973     }
   2974 
   2975     void setTurnScreenOn(boolean turnScreenOn) {
   2976         mTurnScreenOn = turnScreenOn;
   2977     }
   2978 
   2979     /**
   2980      * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
   2981      * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
   2982      * depending on Keyguard state
   2983      *
   2984      * @return true if the screen can be turned on, false otherwise.
   2985      */
   2986     boolean canTurnScreenOn() {
   2987         final ActivityStack stack = getStack();
   2988         return mTurnScreenOn && stack != null &&
   2989                 stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
   2990     }
   2991 
   2992     boolean getTurnScreenOnFlag() {
   2993         return mTurnScreenOn;
   2994     }
   2995 
   2996     boolean isTopRunningActivity() {
   2997         return mStackSupervisor.topRunningActivityLocked() == this;
   2998     }
   2999 
   3000     void registerRemoteAnimations(RemoteAnimationDefinition definition) {
   3001         mWindowContainerController.registerRemoteAnimations(definition);
   3002     }
   3003 
   3004     @Override
   3005     public String toString() {
   3006         if (stringName != null) {
   3007             return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
   3008                     (finishing ? " f}" : "}");
   3009         }
   3010         StringBuilder sb = new StringBuilder(128);
   3011         sb.append("ActivityRecord{");
   3012         sb.append(Integer.toHexString(System.identityHashCode(this)));
   3013         sb.append(" u");
   3014         sb.append(userId);
   3015         sb.append(' ');
   3016         sb.append(intent.getComponent().flattenToShortString());
   3017         stringName = sb.toString();
   3018         return toString();
   3019     }
   3020 
   3021     void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
   3022         final long token = proto.start(fieldId);
   3023         proto.write(HASH_CODE, System.identityHashCode(this));
   3024         proto.write(USER_ID, userId);
   3025         proto.write(TITLE, intent.getComponent().flattenToShortString());
   3026         proto.end(token);
   3027     }
   3028 
   3029     public void writeToProto(ProtoOutputStream proto, long fieldId) {
   3030         final long token = proto.start(fieldId);
   3031         super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
   3032         writeIdentifierToProto(proto, IDENTIFIER);
   3033         proto.write(STATE, mState.toString());
   3034         proto.write(VISIBLE, visible);
   3035         proto.write(FRONT_OF_TASK, frontOfTask);
   3036         if (app != null) {
   3037             proto.write(PROC_ID, app.pid);
   3038         }
   3039         proto.write(TRANSLUCENT, !fullscreen);
   3040         proto.end(token);
   3041     }
   3042 }
   3043