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 com.android.server.am.ActivityManagerDebugConfig.*;
     20 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
     21 
     22 import android.app.ActivityManager.TaskDescription;
     23 import android.app.PendingIntent;
     24 import android.os.PersistableBundle;
     25 import android.os.Trace;
     26 
     27 import com.android.internal.app.ResolverActivity;
     28 import com.android.internal.content.ReferrerIntent;
     29 import com.android.internal.util.XmlUtils;
     30 import com.android.server.AttributeCache;
     31 import com.android.server.am.ActivityStack.ActivityState;
     32 import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
     33 
     34 import android.app.ActivityOptions;
     35 import android.app.ResultInfo;
     36 import android.content.ComponentName;
     37 import android.content.Intent;
     38 import android.content.pm.ActivityInfo;
     39 import android.content.pm.ApplicationInfo;
     40 import android.content.res.CompatibilityInfo;
     41 import android.content.res.Configuration;
     42 import android.graphics.Bitmap;
     43 import android.graphics.Rect;
     44 import android.os.Build;
     45 import android.os.Bundle;
     46 import android.os.IBinder;
     47 import android.os.Message;
     48 import android.os.Process;
     49 import android.os.RemoteException;
     50 import android.os.SystemClock;
     51 import android.os.UserHandle;
     52 import android.util.EventLog;
     53 import android.util.Log;
     54 import android.util.Slog;
     55 import android.util.TimeUtils;
     56 import android.view.IApplicationToken;
     57 import android.view.WindowManager;
     58 
     59 import org.xmlpull.v1.XmlPullParser;
     60 import org.xmlpull.v1.XmlPullParserException;
     61 import org.xmlpull.v1.XmlSerializer;
     62 
     63 import java.io.IOException;
     64 import java.io.PrintWriter;
     65 import java.lang.ref.WeakReference;
     66 import java.util.ArrayList;
     67 import java.util.HashSet;
     68 import java.util.Objects;
     69 
     70 /**
     71  * An entry in the history stack, representing an activity.
     72  */
     73 final class ActivityRecord {
     74     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_AM;
     75     private static final String TAG_STATES = TAG + POSTFIX_STATES;
     76     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
     77     private static final String TAG_THUMBNAILS = TAG + POSTFIX_THUMBNAILS;
     78 
     79     private static final boolean SHOW_ACTIVITY_START_TIME = true;
     80     final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
     81 
     82     private static final String ATTR_ID = "id";
     83     private static final String TAG_INTENT = "intent";
     84     private static final String ATTR_USERID = "user_id";
     85     private static final String TAG_PERSISTABLEBUNDLE = "persistable_bundle";
     86     private static final String ATTR_LAUNCHEDFROMUID = "launched_from_uid";
     87     private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
     88     private static final String ATTR_RESOLVEDTYPE = "resolved_type";
     89     private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
     90     static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
     91 
     92     final ActivityManagerService service; // owner
     93     final IApplicationToken.Stub appToken; // window manager token
     94     final ActivityInfo info; // all about me
     95     final ApplicationInfo appInfo; // information about activity's app
     96     final int launchedFromUid; // always the uid who started the activity.
     97     final String launchedFromPackage; // always the package who started the activity.
     98     final int userId;          // Which user is this running for?
     99     final Intent intent;    // the original intent that generated us
    100     final ComponentName realActivity;  // the intent component, or target of an alias.
    101     final String shortComponentName; // the short component name of the intent
    102     final String resolvedType; // as per original caller;
    103     final String packageName; // the package implementing intent's component
    104     final String processName; // process where this component wants to run
    105     final String taskAffinity; // as per ActivityInfo.taskAffinity
    106     final boolean stateNotNeeded; // As per ActivityInfo.flags
    107     boolean fullscreen; // covers the full screen?
    108     final boolean noDisplay;  // activity is not displayed?
    109     final boolean componentSpecified;  // did caller specifiy an explicit component?
    110     final boolean rootVoiceInteraction;  // was this the root activity of a voice interaction?
    111 
    112     static final int APPLICATION_ACTIVITY_TYPE = 0;
    113     static final int HOME_ACTIVITY_TYPE = 1;
    114     static final int RECENTS_ACTIVITY_TYPE = 2;
    115     int mActivityType;
    116 
    117     CharSequence nonLocalizedLabel;  // the label information from the package mgr.
    118     int labelRes;           // the label information from the package mgr.
    119     int icon;               // resource identifier of activity's icon.
    120     int logo;               // resource identifier of activity's logo.
    121     int theme;              // resource identifier of activity's theme.
    122     int realTheme;          // actual theme resource we will use, never 0.
    123     int windowFlags;        // custom window flags for preview window.
    124     TaskRecord task;        // the task this is in.
    125     long createTime = System.currentTimeMillis();
    126     long displayStartTime;  // when we started launching this activity
    127     long fullyDrawnStartTime; // when we started launching this activity
    128     long startTime;         // last time this activity was started
    129     long lastVisibleTime;   // last time this activity became visible
    130     long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
    131     long pauseTime;         // last time we started pausing the activity
    132     long launchTickTime;    // base time for launch tick messages
    133     Configuration configuration; // configuration activity was last running in
    134     // Overridden configuration by the activity stack
    135     // WARNING: Reference points to {@link ActivityStack#mOverrideConfig}, so its internal state
    136     // should never be altered directly.
    137     Configuration stackConfigOverride;
    138     CompatibilityInfo compat;// last used compatibility mode
    139     ActivityRecord resultTo; // who started this entry, so will get our reply
    140     final String resultWho; // additional identifier for use by resultTo.
    141     final int requestCode;  // code given by requester (resultTo)
    142     ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
    143     HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
    144     ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
    145     ActivityOptions pendingOptions; // most recently given options
    146     ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
    147     AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
    148     HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
    149     UriPermissionOwner uriPermissions; // current special URI access perms.
    150     ProcessRecord app;      // if non-null, hosting application
    151     ActivityState state;    // current state we are in
    152     Bundle  icicle;         // last saved activity state
    153     PersistableBundle persistentState; // last persistently saved activity state
    154     boolean frontOfTask;    // is this the root activity of its task?
    155     boolean launchFailed;   // set if a launched failed, to abort on 2nd try
    156     boolean haveState;      // have we gotten the last activity state?
    157     boolean stopped;        // is activity pause finished?
    158     boolean delayedResume;  // not yet resumed because of stopped app switches?
    159     boolean finishing;      // activity in pending finish list?
    160     boolean configDestroy;  // need to destroy due to config change?
    161     int configChangeFlags;  // which config values have changed
    162     boolean keysPaused;     // has key dispatching been paused for it?
    163     int launchMode;         // the launch mode activity attribute.
    164     boolean visible;        // does this activity's window need to be shown?
    165     boolean sleeping;       // have we told the activity to sleep?
    166     boolean nowVisible;     // is this activity's window visible?
    167     boolean idle;           // has the activity gone idle?
    168     boolean hasBeenLaunched;// has this activity ever been launched?
    169     boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
    170     boolean immersive;      // immersive mode (don't interrupt if possible)
    171     boolean forceNewConfig; // force re-create with new config next time
    172     int launchCount;        // count of launches since last state
    173     long lastLaunchTime;    // time of last lauch of this activity
    174     ArrayList<ActivityContainer> mChildContainers = new ArrayList<ActivityContainer>();
    175 
    176     String stringName;      // for caching of toString().
    177 
    178     private boolean inHistory;  // are we in the history stack?
    179     final ActivityStackSupervisor mStackSupervisor;
    180     boolean mStartingWindowShown = false;
    181     ActivityContainer mInitialActivityContainer;
    182 
    183     TaskDescription taskDescription; // the recents information for this activity
    184     boolean mLaunchTaskBehind; // this activity is actively being launched with
    185         // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
    186 
    187     void dump(PrintWriter pw, String prefix) {
    188         final long now = SystemClock.uptimeMillis();
    189         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
    190                 pw.print(" processName="); pw.println(processName);
    191         pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
    192                 pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
    193                 pw.print(" userId="); pw.println(userId);
    194         pw.print(prefix); pw.print("app="); pw.println(app);
    195         pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
    196         pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
    197                 pw.print(" task="); pw.println(task);
    198         pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
    199         pw.print(prefix); pw.print("realActivity=");
    200                 pw.println(realActivity.flattenToShortString());
    201         if (appInfo != null) {
    202             pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
    203             if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
    204                 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
    205             }
    206             pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
    207         }
    208         pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
    209                 pw.print(" componentSpecified="); pw.print(componentSpecified);
    210                 pw.print(" mActivityType="); pw.println(mActivityType);
    211         if (rootVoiceInteraction) {
    212             pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
    213         }
    214         pw.print(prefix); pw.print("compat="); pw.print(compat);
    215                 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
    216                 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
    217                 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
    218         pw.print(prefix); pw.print("config="); pw.println(configuration);
    219         pw.print(prefix); pw.print("stackConfigOverride="); pw.println(stackConfigOverride);
    220         if (resultTo != null || resultWho != null) {
    221             pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
    222                     pw.print(" resultWho="); pw.print(resultWho);
    223                     pw.print(" resultCode="); pw.println(requestCode);
    224         }
    225         if (taskDescription != null) {
    226             final String iconFilename = taskDescription.getIconFilename();
    227             if (iconFilename != null || taskDescription.getLabel() != null ||
    228                     taskDescription.getPrimaryColor() != 0) {
    229                 pw.print(prefix); pw.print("taskDescription:");
    230                         pw.print(" iconFilename="); pw.print(taskDescription.getIconFilename());
    231                         pw.print(" label=\""); pw.print(taskDescription.getLabel());
    232                                 pw.print("\"");
    233                         pw.print(" color=");
    234                         pw.println(Integer.toHexString(taskDescription.getPrimaryColor()));
    235             }
    236             if (iconFilename == null && taskDescription.getIcon() != null) {
    237                 pw.print(prefix); pw.println("taskDescription contains Bitmap");
    238             }
    239         }
    240         if (results != null) {
    241             pw.print(prefix); pw.print("results="); pw.println(results);
    242         }
    243         if (pendingResults != null && pendingResults.size() > 0) {
    244             pw.print(prefix); pw.println("Pending Results:");
    245             for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
    246                 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
    247                 pw.print(prefix); pw.print("  - ");
    248                 if (pir == null) {
    249                     pw.println("null");
    250                 } else {
    251                     pw.println(pir);
    252                     pir.dump(pw, prefix + "    ");
    253                 }
    254             }
    255         }
    256         if (newIntents != null && newIntents.size() > 0) {
    257             pw.print(prefix); pw.println("Pending New Intents:");
    258             for (int i=0; i<newIntents.size(); i++) {
    259                 Intent intent = newIntents.get(i);
    260                 pw.print(prefix); pw.print("  - ");
    261                 if (intent == null) {
    262                     pw.println("null");
    263                 } else {
    264                     pw.println(intent.toShortString(false, true, false, true));
    265                 }
    266             }
    267         }
    268         if (pendingOptions != null) {
    269             pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
    270         }
    271         if (appTimeTracker != null) {
    272             appTimeTracker.dumpWithHeader(pw, prefix, false);
    273         }
    274         if (uriPermissions != null) {
    275             uriPermissions.dump(pw, prefix);
    276         }
    277         pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
    278                 pw.print(" launchCount="); pw.print(launchCount);
    279                 pw.print(" lastLaunchTime=");
    280                 if (lastLaunchTime == 0) pw.print("0");
    281                 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
    282                 pw.println();
    283         pw.print(prefix); pw.print("haveState="); pw.print(haveState);
    284                 pw.print(" icicle="); pw.println(icicle);
    285         pw.print(prefix); pw.print("state="); pw.print(state);
    286                 pw.print(" stopped="); pw.print(stopped);
    287                 pw.print(" delayedResume="); pw.print(delayedResume);
    288                 pw.print(" finishing="); pw.println(finishing);
    289         pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
    290                 pw.print(" inHistory="); pw.print(inHistory);
    291                 pw.print(" visible="); pw.print(visible);
    292                 pw.print(" sleeping="); pw.print(sleeping);
    293                 pw.print(" idle="); pw.println(idle);
    294         pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
    295                 pw.print(" noDisplay="); pw.print(noDisplay);
    296                 pw.print(" immersive="); pw.print(immersive);
    297                 pw.print(" launchMode="); pw.println(launchMode);
    298         pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
    299                 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
    300         pw.print(prefix); pw.print("mActivityType=");
    301                 pw.println(activityTypeToString(mActivityType));
    302         if (displayStartTime != 0 || startTime != 0) {
    303             pw.print(prefix); pw.print("displayStartTime=");
    304                     if (displayStartTime == 0) pw.print("0");
    305                     else TimeUtils.formatDuration(displayStartTime, now, pw);
    306                     pw.print(" startTime=");
    307                     if (startTime == 0) pw.print("0");
    308                     else TimeUtils.formatDuration(startTime, now, pw);
    309                     pw.println();
    310         }
    311         final boolean waitingVisible = mStackSupervisor.mWaitingVisibleActivities.contains(this);
    312         if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
    313             pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
    314                     pw.print(" nowVisible="); pw.print(nowVisible);
    315                     pw.print(" lastVisibleTime=");
    316                     if (lastVisibleTime == 0) pw.print("0");
    317                     else TimeUtils.formatDuration(lastVisibleTime, now, pw);
    318                     pw.println();
    319         }
    320         if (configDestroy || configChangeFlags != 0) {
    321             pw.print(prefix); pw.print("configDestroy="); pw.print(configDestroy);
    322                     pw.print(" configChangeFlags=");
    323                     pw.println(Integer.toHexString(configChangeFlags));
    324         }
    325         if (connections != null) {
    326             pw.print(prefix); pw.print("connections="); pw.println(connections);
    327         }
    328     }
    329 
    330     static class Token extends IApplicationToken.Stub {
    331         private final WeakReference<ActivityRecord> weakActivity;
    332         private final ActivityManagerService mService;
    333 
    334         Token(ActivityRecord activity, ActivityManagerService service) {
    335             weakActivity = new WeakReference<>(activity);
    336             mService = service;
    337         }
    338 
    339         @Override
    340         public void windowsDrawn() {
    341             synchronized (mService) {
    342                 ActivityRecord r = tokenToActivityRecordLocked(this);
    343                 if (r != null) {
    344                     r.windowsDrawnLocked();
    345                 }
    346             }
    347         }
    348 
    349         @Override
    350         public void windowsVisible() {
    351             synchronized (mService) {
    352                 ActivityRecord r = tokenToActivityRecordLocked(this);
    353                 if (r != null) {
    354                     r.windowsVisibleLocked();
    355                 }
    356             }
    357         }
    358 
    359         @Override
    360         public void windowsGone() {
    361             synchronized (mService) {
    362                 ActivityRecord r = tokenToActivityRecordLocked(this);
    363                 if (r != null) {
    364                     if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + r);
    365                     r.nowVisible = false;
    366                     return;
    367                 }
    368             }
    369         }
    370 
    371         @Override
    372         public boolean keyDispatchingTimedOut(String reason) {
    373             ActivityRecord r;
    374             ActivityRecord anrActivity;
    375             ProcessRecord anrApp;
    376             synchronized (mService) {
    377                 r = tokenToActivityRecordLocked(this);
    378                 if (r == null) {
    379                     return false;
    380                 }
    381                 anrActivity = r.getWaitingHistoryRecordLocked();
    382                 anrApp = r != null ? r.app : null;
    383             }
    384             return mService.inputDispatchingTimedOut(anrApp, anrActivity, r, false, reason);
    385         }
    386 
    387         @Override
    388         public long getKeyDispatchingTimeout() {
    389             synchronized (mService) {
    390                 ActivityRecord r = tokenToActivityRecordLocked(this);
    391                 if (r == null) {
    392                     return 0;
    393                 }
    394                 r = r.getWaitingHistoryRecordLocked();
    395                 return ActivityManagerService.getInputDispatchingTimeoutLocked(r);
    396             }
    397         }
    398 
    399         private static final ActivityRecord tokenToActivityRecordLocked(Token token) {
    400             if (token == null) {
    401                 return null;
    402             }
    403             ActivityRecord r = token.weakActivity.get();
    404             if (r == null || r.task == null || r.task.stack == null) {
    405                 return null;
    406             }
    407             return r;
    408         }
    409 
    410         @Override
    411         public String toString() {
    412             StringBuilder sb = new StringBuilder(128);
    413             sb.append("Token{");
    414             sb.append(Integer.toHexString(System.identityHashCode(this)));
    415             sb.append(' ');
    416             sb.append(weakActivity.get());
    417             sb.append('}');
    418             return sb.toString();
    419         }
    420     }
    421 
    422     static ActivityRecord forTokenLocked(IBinder token) {
    423         try {
    424             return Token.tokenToActivityRecordLocked((Token)token);
    425         } catch (ClassCastException e) {
    426             Slog.w(TAG, "Bad activity token: " + token, e);
    427             return null;
    428         }
    429     }
    430 
    431     boolean isNotResolverActivity() {
    432         return !ResolverActivity.class.getName().equals(realActivity.getClassName());
    433     }
    434 
    435     ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,
    436             int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
    437             ActivityInfo aInfo, Configuration _configuration,
    438             ActivityRecord _resultTo, String _resultWho, int _reqCode,
    439             boolean _componentSpecified, boolean _rootVoiceInteraction,
    440             ActivityStackSupervisor supervisor,
    441             ActivityContainer container, Bundle options) {
    442         service = _service;
    443         appToken = new Token(this, service);
    444         info = aInfo;
    445         launchedFromUid = _launchedFromUid;
    446         launchedFromPackage = _launchedFromPackage;
    447         userId = UserHandle.getUserId(aInfo.applicationInfo.uid);
    448         intent = _intent;
    449         shortComponentName = _intent.getComponent().flattenToShortString();
    450         resolvedType = _resolvedType;
    451         componentSpecified = _componentSpecified;
    452         rootVoiceInteraction = _rootVoiceInteraction;
    453         configuration = _configuration;
    454         stackConfigOverride = (container != null)
    455                 ? container.mStack.mOverrideConfig : Configuration.EMPTY;
    456         resultTo = _resultTo;
    457         resultWho = _resultWho;
    458         requestCode = _reqCode;
    459         state = ActivityState.INITIALIZING;
    460         frontOfTask = false;
    461         launchFailed = false;
    462         stopped = false;
    463         delayedResume = false;
    464         finishing = false;
    465         configDestroy = false;
    466         keysPaused = false;
    467         inHistory = false;
    468         visible = true;
    469         nowVisible = false;
    470         idle = false;
    471         hasBeenLaunched = false;
    472         mStackSupervisor = supervisor;
    473         mInitialActivityContainer = container;
    474         if (options != null) {
    475             pendingOptions = new ActivityOptions(options);
    476             mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind();
    477             PendingIntent usageReport = pendingOptions.getUsageTimeReport();
    478             if (usageReport != null) {
    479                 appTimeTracker = new AppTimeTracker(usageReport);
    480             }
    481         }
    482 
    483         // This starts out true, since the initial state of an activity
    484         // is that we have everything, and we shouldn't never consider it
    485         // lacking in state to be removed if it dies.
    486         haveState = true;
    487 
    488         if (aInfo != null) {
    489             if (aInfo.targetActivity == null
    490                     || aInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE
    491                     || aInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
    492                 realActivity = _intent.getComponent();
    493             } else {
    494                 realActivity = new ComponentName(aInfo.packageName,
    495                         aInfo.targetActivity);
    496             }
    497             taskAffinity = aInfo.taskAffinity;
    498             stateNotNeeded = (aInfo.flags&
    499                     ActivityInfo.FLAG_STATE_NOT_NEEDED) != 0;
    500             appInfo = aInfo.applicationInfo;
    501             nonLocalizedLabel = aInfo.nonLocalizedLabel;
    502             labelRes = aInfo.labelRes;
    503             if (nonLocalizedLabel == null && labelRes == 0) {
    504                 ApplicationInfo app = aInfo.applicationInfo;
    505                 nonLocalizedLabel = app.nonLocalizedLabel;
    506                 labelRes = app.labelRes;
    507             }
    508             icon = aInfo.getIconResource();
    509             logo = aInfo.getLogoResource();
    510             theme = aInfo.getThemeResource();
    511             realTheme = theme;
    512             if (realTheme == 0) {
    513                 realTheme = aInfo.applicationInfo.targetSdkVersion
    514                         < Build.VERSION_CODES.HONEYCOMB
    515                         ? android.R.style.Theme
    516                         : android.R.style.Theme_Holo;
    517             }
    518             if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
    519                 windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
    520             }
    521             if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
    522                     && _caller != null
    523                     && (aInfo.applicationInfo.uid == Process.SYSTEM_UID
    524                             || aInfo.applicationInfo.uid == _caller.info.uid)) {
    525                 processName = _caller.processName;
    526             } else {
    527                 processName = aInfo.processName;
    528             }
    529 
    530             if (intent != null && (aInfo.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0) {
    531                 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    532             }
    533 
    534             packageName = aInfo.applicationInfo.packageName;
    535             launchMode = aInfo.launchMode;
    536 
    537             AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
    538                     realTheme, com.android.internal.R.styleable.Window, userId);
    539             final boolean translucent = ent != null && (ent.array.getBoolean(
    540                     com.android.internal.R.styleable.Window_windowIsTranslucent, false)
    541                     || (!ent.array.hasValue(
    542                             com.android.internal.R.styleable.Window_windowIsTranslucent)
    543                             && ent.array.getBoolean(
    544                                     com.android.internal.R.styleable.Window_windowSwipeToDismiss,
    545                                             false)));
    546             fullscreen = ent != null && !ent.array.getBoolean(
    547                     com.android.internal.R.styleable.Window_windowIsFloating, false)
    548                     && !translucent;
    549             noDisplay = ent != null && ent.array.getBoolean(
    550                     com.android.internal.R.styleable.Window_windowNoDisplay, false);
    551 
    552             if ((!_componentSpecified || _launchedFromUid == Process.myUid()
    553                     || _launchedFromUid == 0) &&
    554                     Intent.ACTION_MAIN.equals(_intent.getAction()) &&
    555                     _intent.hasCategory(Intent.CATEGORY_HOME) &&
    556                     _intent.getCategories().size() == 1 &&
    557                     _intent.getData() == null &&
    558                     _intent.getType() == null &&
    559                     (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
    560                     isNotResolverActivity()) {
    561                 // This sure looks like a home activity!
    562                 mActivityType = HOME_ACTIVITY_TYPE;
    563             } else if (realActivity.getClassName().contains(RECENTS_PACKAGE_NAME)) {
    564                 mActivityType = RECENTS_ACTIVITY_TYPE;
    565             } else {
    566                 mActivityType = APPLICATION_ACTIVITY_TYPE;
    567             }
    568 
    569             immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;
    570         } else {
    571             realActivity = null;
    572             taskAffinity = null;
    573             stateNotNeeded = false;
    574             appInfo = null;
    575             processName = null;
    576             packageName = null;
    577             fullscreen = true;
    578             noDisplay = false;
    579             mActivityType = APPLICATION_ACTIVITY_TYPE;
    580             immersive = false;
    581         }
    582     }
    583 
    584     void setTask(TaskRecord newTask, TaskRecord taskToAffiliateWith) {
    585         if (task != null && task.removeActivity(this) && task != newTask && task.stack != null) {
    586             task.stack.removeTask(task, "setTask");
    587         }
    588         task = newTask;
    589         setTaskToAffiliateWith(taskToAffiliateWith);
    590     }
    591 
    592     void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
    593         if (taskToAffiliateWith != null &&
    594                 launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE &&
    595                 launchMode != ActivityInfo.LAUNCH_SINGLE_TASK) {
    596             task.setTaskToAffiliateWith(taskToAffiliateWith);
    597         }
    598     }
    599 
    600     boolean changeWindowTranslucency(boolean toOpaque) {
    601         if (fullscreen == toOpaque) {
    602             return false;
    603         }
    604 
    605         // Keep track of the number of fullscreen activities in this task.
    606         task.numFullscreen += toOpaque ? +1 : -1;
    607 
    608         fullscreen = toOpaque;
    609         return true;
    610     }
    611 
    612     void putInHistory() {
    613         if (!inHistory) {
    614             inHistory = true;
    615         }
    616     }
    617 
    618     void takeFromHistory() {
    619         if (inHistory) {
    620             inHistory = false;
    621             if (task != null && !finishing) {
    622                 task = null;
    623             }
    624             clearOptionsLocked();
    625         }
    626     }
    627 
    628     boolean isInHistory() {
    629         return inHistory;
    630     }
    631 
    632     boolean isInStackLocked() {
    633         return task != null && task.stack != null && task.stack.isInStackLocked(this) != null;
    634     }
    635 
    636     boolean isHomeActivity() {
    637         return mActivityType == HOME_ACTIVITY_TYPE;
    638     }
    639 
    640     boolean isRecentsActivity() {
    641         return mActivityType == RECENTS_ACTIVITY_TYPE;
    642     }
    643 
    644     boolean isApplicationActivity() {
    645         return mActivityType == APPLICATION_ACTIVITY_TYPE;
    646     }
    647 
    648     boolean isPersistable() {
    649         return (info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY ||
    650                 info.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS) &&
    651                 (intent == null ||
    652                         (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
    653     }
    654 
    655     void makeFinishingLocked() {
    656         if (!finishing) {
    657             if (task != null && task.stack != null
    658                     && this == task.stack.getVisibleBehindActivity()) {
    659                 // A finishing activity should not remain as visible in the background
    660                 mStackSupervisor.requestVisibleBehindLocked(this, false);
    661             }
    662             finishing = true;
    663             if (stopped) {
    664                 clearOptionsLocked();
    665             }
    666         }
    667     }
    668 
    669     UriPermissionOwner getUriPermissionsLocked() {
    670         if (uriPermissions == null) {
    671             uriPermissions = new UriPermissionOwner(service, this);
    672         }
    673         return uriPermissions;
    674     }
    675 
    676     void addResultLocked(ActivityRecord from, String resultWho,
    677             int requestCode, int resultCode,
    678             Intent resultData) {
    679         ActivityResult r = new ActivityResult(from, resultWho,
    680                 requestCode, resultCode, resultData);
    681         if (results == null) {
    682             results = new ArrayList<ResultInfo>();
    683         }
    684         results.add(r);
    685     }
    686 
    687     void removeResultsLocked(ActivityRecord from, String resultWho,
    688             int requestCode) {
    689         if (results != null) {
    690             for (int i=results.size()-1; i>=0; i--) {
    691                 ActivityResult r = (ActivityResult)results.get(i);
    692                 if (r.mFrom != from) continue;
    693                 if (r.mResultWho == null) {
    694                     if (resultWho != null) continue;
    695                 } else {
    696                     if (!r.mResultWho.equals(resultWho)) continue;
    697                 }
    698                 if (r.mRequestCode != requestCode) continue;
    699 
    700                 results.remove(i);
    701             }
    702         }
    703     }
    704 
    705     void addNewIntentLocked(ReferrerIntent intent) {
    706         if (newIntents == null) {
    707             newIntents = new ArrayList<>();
    708         }
    709         newIntents.add(intent);
    710     }
    711 
    712     /**
    713      * Deliver a new Intent to an existing activity, so that its onNewIntent()
    714      * method will be called at the proper time.
    715      */
    716     final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
    717         // The activity now gets access to the data associated with this Intent.
    718         service.grantUriPermissionFromIntentLocked(callingUid, packageName,
    719                 intent, getUriPermissionsLocked(), userId);
    720         // We want to immediately deliver the intent to the activity if
    721         // it is currently the top resumed activity...  however, if the
    722         // device is sleeping, then all activities are stopped, so in that
    723         // case we will deliver it if this is the current top activity on its
    724         // stack.
    725         final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
    726         boolean unsent = true;
    727         if ((state == ActivityState.RESUMED
    728                 || (service.isSleeping() && task.stack != null
    729                     && task.stack.topRunningActivityLocked(null) == this))
    730                 && app != null && app.thread != null) {
    731             try {
    732                 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
    733                 ar.add(rintent);
    734                 app.thread.scheduleNewIntent(ar, appToken);
    735                 unsent = false;
    736             } catch (RemoteException e) {
    737                 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
    738             } catch (NullPointerException e) {
    739                 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
    740             }
    741         }
    742         if (unsent) {
    743             addNewIntentLocked(rintent);
    744         }
    745     }
    746 
    747     void updateOptionsLocked(Bundle options) {
    748         if (options != null) {
    749             if (pendingOptions != null) {
    750                 pendingOptions.abort();
    751             }
    752             pendingOptions = new ActivityOptions(options);
    753         }
    754     }
    755 
    756     void updateOptionsLocked(ActivityOptions options) {
    757         if (options != null) {
    758             if (pendingOptions != null) {
    759                 pendingOptions.abort();
    760             }
    761             pendingOptions = options;
    762         }
    763     }
    764 
    765     void applyOptionsLocked() {
    766         if (pendingOptions != null
    767                 && pendingOptions.getAnimationType() != ActivityOptions.ANIM_SCENE_TRANSITION) {
    768             final int animationType = pendingOptions.getAnimationType();
    769             switch (animationType) {
    770                 case ActivityOptions.ANIM_CUSTOM:
    771                     service.mWindowManager.overridePendingAppTransition(
    772                             pendingOptions.getPackageName(),
    773                             pendingOptions.getCustomEnterResId(),
    774                             pendingOptions.getCustomExitResId(),
    775                             pendingOptions.getOnAnimationStartListener());
    776                     break;
    777                 case ActivityOptions.ANIM_CLIP_REVEAL:
    778                     service.mWindowManager.overridePendingAppTransitionClipReveal(
    779                             pendingOptions.getStartX(), pendingOptions.getStartY(),
    780                             pendingOptions.getWidth(), pendingOptions.getHeight());
    781                     if (intent.getSourceBounds() == null) {
    782                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
    783                                 pendingOptions.getStartY(),
    784                                 pendingOptions.getStartX()+pendingOptions.getWidth(),
    785                                 pendingOptions.getStartY()+pendingOptions.getHeight()));
    786                     }
    787                     break;
    788                 case ActivityOptions.ANIM_SCALE_UP:
    789                     service.mWindowManager.overridePendingAppTransitionScaleUp(
    790                             pendingOptions.getStartX(), pendingOptions.getStartY(),
    791                             pendingOptions.getWidth(), pendingOptions.getHeight());
    792                     if (intent.getSourceBounds() == null) {
    793                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
    794                                 pendingOptions.getStartY(),
    795                                 pendingOptions.getStartX()+pendingOptions.getWidth(),
    796                                 pendingOptions.getStartY()+pendingOptions.getHeight()));
    797                     }
    798                     break;
    799                 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
    800                 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
    801                     boolean scaleUp = (animationType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
    802                     service.mWindowManager.overridePendingAppTransitionThumb(
    803                             pendingOptions.getThumbnail(),
    804                             pendingOptions.getStartX(), pendingOptions.getStartY(),
    805                             pendingOptions.getOnAnimationStartListener(),
    806                             scaleUp);
    807                     if (intent.getSourceBounds() == null) {
    808                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
    809                                 pendingOptions.getStartY(),
    810                                 pendingOptions.getStartX()
    811                                         + pendingOptions.getThumbnail().getWidth(),
    812                                 pendingOptions.getStartY()
    813                                         + pendingOptions.getThumbnail().getHeight()));
    814                     }
    815                     break;
    816                 case ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP:
    817                 case ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
    818                     service.mWindowManager.overridePendingAppTransitionAspectScaledThumb(
    819                             pendingOptions.getThumbnail(),
    820                             pendingOptions.getStartX(), pendingOptions.getStartY(),
    821                             pendingOptions.getWidth(), pendingOptions.getHeight(),
    822                             pendingOptions.getOnAnimationStartListener(),
    823                             (animationType == ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP));
    824                     if (intent.getSourceBounds() == null) {
    825                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
    826                                 pendingOptions.getStartY(),
    827                                 pendingOptions.getStartX() + pendingOptions.getWidth(),
    828                                 pendingOptions.getStartY() + pendingOptions.getHeight()));
    829                     }
    830                     break;
    831                 default:
    832                     Slog.e(TAG, "applyOptionsLocked: Unknown animationType=" + animationType);
    833                     break;
    834             }
    835             pendingOptions = null;
    836         }
    837     }
    838 
    839     ActivityOptions getOptionsForTargetActivityLocked() {
    840         return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
    841     }
    842 
    843     void clearOptionsLocked() {
    844         if (pendingOptions != null) {
    845             pendingOptions.abort();
    846             pendingOptions = null;
    847         }
    848     }
    849 
    850     ActivityOptions takeOptionsLocked() {
    851         ActivityOptions opts = pendingOptions;
    852         pendingOptions = null;
    853         return opts;
    854     }
    855 
    856     void removeUriPermissionsLocked() {
    857         if (uriPermissions != null) {
    858             uriPermissions.removeUriPermissionsLocked();
    859             uriPermissions = null;
    860         }
    861     }
    862 
    863     void pauseKeyDispatchingLocked() {
    864         if (!keysPaused) {
    865             keysPaused = true;
    866             service.mWindowManager.pauseKeyDispatching(appToken);
    867         }
    868     }
    869 
    870     void resumeKeyDispatchingLocked() {
    871         if (keysPaused) {
    872             keysPaused = false;
    873             service.mWindowManager.resumeKeyDispatching(appToken);
    874         }
    875     }
    876 
    877     void updateThumbnailLocked(Bitmap newThumbnail, CharSequence description) {
    878         if (newThumbnail != null) {
    879             if (DEBUG_THUMBNAILS) Slog.i(TAG_THUMBNAILS,
    880                     "Setting thumbnail of " + this + " to " + newThumbnail);
    881             boolean thumbnailUpdated = task.setLastThumbnail(newThumbnail);
    882             if (thumbnailUpdated && isPersistable()) {
    883                 mStackSupervisor.mService.notifyTaskPersisterLocked(task, false);
    884             }
    885         }
    886         task.lastDescription = description;
    887     }
    888 
    889     void startLaunchTickingLocked() {
    890         if (ActivityManagerService.IS_USER_BUILD) {
    891             return;
    892         }
    893         if (launchTickTime == 0) {
    894             launchTickTime = SystemClock.uptimeMillis();
    895             continueLaunchTickingLocked();
    896         }
    897     }
    898 
    899     boolean continueLaunchTickingLocked() {
    900         if (launchTickTime == 0) {
    901             return false;
    902         }
    903 
    904         final ActivityStack stack = task.stack;
    905         if (stack == null) {
    906             return false;
    907         }
    908 
    909         Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG, this);
    910         stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
    911         stack.mHandler.sendMessageDelayed(msg, ActivityStack.LAUNCH_TICK);
    912         return true;
    913     }
    914 
    915     void finishLaunchTickingLocked() {
    916         launchTickTime = 0;
    917         final ActivityStack stack = task.stack;
    918         if (stack != null) {
    919             stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
    920         }
    921     }
    922 
    923     // IApplicationToken
    924 
    925     public boolean mayFreezeScreenLocked(ProcessRecord app) {
    926         // Only freeze the screen if this activity is currently attached to
    927         // an application, and that application is not blocked or unresponding.
    928         // In any other case, we can't count on getting the screen unfrozen,
    929         // so it is best to leave as-is.
    930         return app != null && !app.crashing && !app.notResponding;
    931     }
    932 
    933     public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
    934         if (mayFreezeScreenLocked(app)) {
    935             service.mWindowManager.startAppFreezingScreen(appToken, configChanges);
    936         }
    937     }
    938 
    939     public void stopFreezingScreenLocked(boolean force) {
    940         if (force || frozenBeforeDestroy) {
    941             frozenBeforeDestroy = false;
    942             service.mWindowManager.stopAppFreezingScreen(appToken, force);
    943         }
    944     }
    945 
    946     public void reportFullyDrawnLocked() {
    947         final long curTime = SystemClock.uptimeMillis();
    948         if (displayStartTime != 0) {
    949             reportLaunchTimeLocked(curTime);
    950         }
    951         final ActivityStack stack = task.stack;
    952         if (fullyDrawnStartTime != 0 && stack != null) {
    953             final long thisTime = curTime - fullyDrawnStartTime;
    954             final long totalTime = stack.mFullyDrawnStartTime != 0
    955                     ? (curTime - stack.mFullyDrawnStartTime) : thisTime;
    956             if (SHOW_ACTIVITY_START_TIME) {
    957                 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
    958                 EventLog.writeEvent(EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME,
    959                         userId, System.identityHashCode(this), shortComponentName,
    960                         thisTime, totalTime);
    961                 StringBuilder sb = service.mStringBuilder;
    962                 sb.setLength(0);
    963                 sb.append("Fully drawn ");
    964                 sb.append(shortComponentName);
    965                 sb.append(": ");
    966                 TimeUtils.formatDuration(thisTime, sb);
    967                 if (thisTime != totalTime) {
    968                     sb.append(" (total ");
    969                     TimeUtils.formatDuration(totalTime, sb);
    970                     sb.append(")");
    971                 }
    972                 Log.i(TAG, sb.toString());
    973             }
    974             if (totalTime > 0) {
    975                 //service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
    976             }
    977             stack.mFullyDrawnStartTime = 0;
    978         }
    979         fullyDrawnStartTime = 0;
    980     }
    981 
    982     private void reportLaunchTimeLocked(final long curTime) {
    983         final ActivityStack stack = task.stack;
    984         if (stack == null) {
    985             return;
    986         }
    987         final long thisTime = curTime - displayStartTime;
    988         final long totalTime = stack.mLaunchStartTime != 0
    989                 ? (curTime - stack.mLaunchStartTime) : thisTime;
    990         if (SHOW_ACTIVITY_START_TIME) {
    991             Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
    992             EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
    993                     userId, System.identityHashCode(this), shortComponentName,
    994                     thisTime, totalTime);
    995             StringBuilder sb = service.mStringBuilder;
    996             sb.setLength(0);
    997             sb.append("Displayed ");
    998             sb.append(shortComponentName);
    999             sb.append(": ");
   1000             TimeUtils.formatDuration(thisTime, sb);
   1001             if (thisTime != totalTime) {
   1002                 sb.append(" (total ");
   1003                 TimeUtils.formatDuration(totalTime, sb);
   1004                 sb.append(")");
   1005             }
   1006             Log.i(TAG, sb.toString());
   1007         }
   1008         mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
   1009         if (totalTime > 0) {
   1010             //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
   1011         }
   1012         displayStartTime = 0;
   1013         stack.mLaunchStartTime = 0;
   1014     }
   1015 
   1016     void windowsDrawnLocked() {
   1017         if (displayStartTime != 0) {
   1018             reportLaunchTimeLocked(SystemClock.uptimeMillis());
   1019         }
   1020         mStackSupervisor.sendWaitingVisibleReportLocked(this);
   1021         startTime = 0;
   1022         finishLaunchTickingLocked();
   1023         if (task != null) {
   1024             task.hasBeenVisible = true;
   1025         }
   1026     }
   1027 
   1028     void windowsVisibleLocked() {
   1029         mStackSupervisor.reportActivityVisibleLocked(this);
   1030         if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
   1031         if (!nowVisible) {
   1032             nowVisible = true;
   1033             lastVisibleTime = SystemClock.uptimeMillis();
   1034             if (!idle) {
   1035                 // Instead of doing the full stop routine here, let's just hide any activities
   1036                 // we now can, and let them stop when the normal idle happens.
   1037                 mStackSupervisor.processStoppingActivitiesLocked(false);
   1038             } else {
   1039                 // If this activity was already idle, then we now need to make sure we perform
   1040                 // the full stop of any activities that are waiting to do so. This is because
   1041                 // we won't do that while they are still waiting for this one to become visible.
   1042                 final int size = mStackSupervisor.mWaitingVisibleActivities.size();
   1043                 if (size > 0) {
   1044                     for (int i = 0; i < size; i++) {
   1045                         ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);
   1046                         if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
   1047                     }
   1048                     mStackSupervisor.mWaitingVisibleActivities.clear();
   1049                     mStackSupervisor.scheduleIdleLocked();
   1050                 }
   1051             }
   1052             service.scheduleAppGcsLocked();
   1053         }
   1054     }
   1055 
   1056     ActivityRecord getWaitingHistoryRecordLocked() {
   1057         // First find the real culprit...  if this activity is waiting for
   1058         // another activity to start or has stopped, then the key dispatching
   1059         // timeout should not be caused by this.
   1060         if (mStackSupervisor.mWaitingVisibleActivities.contains(this) || stopped) {
   1061             final ActivityStack stack = mStackSupervisor.getFocusedStack();
   1062             // Try to use the one which is closest to top.
   1063             ActivityRecord r = stack.mResumedActivity;
   1064             if (r == null) {
   1065                 r = stack.mPausingActivity;
   1066             }
   1067             if (r != null) {
   1068                 return r;
   1069             }
   1070         }
   1071         return this;
   1072     }
   1073 
   1074     /**
   1075      * This method will return true if the activity is either visible, is becoming visible, is
   1076      * currently pausing, or is resumed.
   1077      */
   1078     public boolean isInterestingToUserLocked() {
   1079         return visible || nowVisible || state == ActivityState.PAUSING ||
   1080                 state == ActivityState.RESUMED;
   1081     }
   1082 
   1083     public void setSleeping(boolean _sleeping) {
   1084         if (sleeping == _sleeping) {
   1085             return;
   1086         }
   1087         if (app != null && app.thread != null) {
   1088             try {
   1089                 app.thread.scheduleSleeping(appToken, _sleeping);
   1090                 if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
   1091                     mStackSupervisor.mGoingToSleepActivities.add(this);
   1092                 }
   1093                 sleeping = _sleeping;
   1094             } catch (RemoteException e) {
   1095                 Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
   1096             }
   1097         }
   1098     }
   1099 
   1100     static void activityResumedLocked(IBinder token) {
   1101         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   1102         if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
   1103         r.icicle = null;
   1104         r.haveState = false;
   1105     }
   1106 
   1107     static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   1108         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   1109         if (r == null) {
   1110             return INVALID_TASK_ID;
   1111         }
   1112         final TaskRecord task = r.task;
   1113         final int activityNdx = task.mActivities.indexOf(r);
   1114         if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
   1115             return INVALID_TASK_ID;
   1116         }
   1117         return task.taskId;
   1118     }
   1119 
   1120     static ActivityRecord isInStackLocked(IBinder token) {
   1121         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   1122         return (r != null) ? r.task.stack.isInStackLocked(r) : null;
   1123     }
   1124 
   1125     static ActivityStack getStackLocked(IBinder token) {
   1126         final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   1127         if (r != null) {
   1128             return r.task.stack;
   1129         }
   1130         return null;
   1131     }
   1132 
   1133     final boolean isDestroyable() {
   1134         if (finishing || app == null || state == ActivityState.DESTROYING
   1135                 || state == ActivityState.DESTROYED) {
   1136             // This would be redundant.
   1137             return false;
   1138         }
   1139         if (task == null || task.stack == null || this == task.stack.mResumedActivity
   1140                 || this == task.stack.mPausingActivity || !haveState || !stopped) {
   1141             // We're not ready for this kind of thing.
   1142             return false;
   1143         }
   1144         if (visible) {
   1145             // The user would notice this!
   1146             return false;
   1147         }
   1148         return true;
   1149     }
   1150 
   1151     private static String createImageFilename(long createTime, int taskId) {
   1152         return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
   1153                 TaskPersister.IMAGE_EXTENSION;
   1154     }
   1155 
   1156     void setTaskDescription(TaskDescription _taskDescription) {
   1157         Bitmap icon;
   1158         if (_taskDescription.getIconFilename() == null &&
   1159                 (icon = _taskDescription.getIcon()) != null) {
   1160             final String iconFilename = createImageFilename(createTime, task.taskId);
   1161             mStackSupervisor.mService.mTaskPersister.saveImage(icon, iconFilename);
   1162             _taskDescription.setIconFilename(iconFilename);
   1163         }
   1164         taskDescription = _taskDescription;
   1165     }
   1166 
   1167     void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
   1168         out.attribute(null, ATTR_ID, String.valueOf(createTime));
   1169         out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
   1170         if (launchedFromPackage != null) {
   1171             out.attribute(null, ATTR_LAUNCHEDFROMPACKAGE, launchedFromPackage);
   1172         }
   1173         if (resolvedType != null) {
   1174             out.attribute(null, ATTR_RESOLVEDTYPE, resolvedType);
   1175         }
   1176         out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
   1177         out.attribute(null, ATTR_USERID, String.valueOf(userId));
   1178 
   1179         if (taskDescription != null) {
   1180             taskDescription.saveToXml(out);
   1181         }
   1182 
   1183         out.startTag(null, TAG_INTENT);
   1184         intent.saveToXml(out);
   1185         out.endTag(null, TAG_INTENT);
   1186 
   1187         if (isPersistable() && persistentState != null) {
   1188             out.startTag(null, TAG_PERSISTABLEBUNDLE);
   1189             persistentState.saveToXml(out);
   1190             out.endTag(null, TAG_PERSISTABLEBUNDLE);
   1191         }
   1192     }
   1193 
   1194     static ActivityRecord restoreFromXml(XmlPullParser in,
   1195             ActivityStackSupervisor stackSupervisor) throws IOException, XmlPullParserException {
   1196         Intent intent = null;
   1197         PersistableBundle persistentState = null;
   1198         int launchedFromUid = 0;
   1199         String launchedFromPackage = null;
   1200         String resolvedType = null;
   1201         boolean componentSpecified = false;
   1202         int userId = 0;
   1203         long createTime = -1;
   1204         final int outerDepth = in.getDepth();
   1205         TaskDescription taskDescription = new TaskDescription();
   1206 
   1207         for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
   1208             final String attrName = in.getAttributeName(attrNdx);
   1209             final String attrValue = in.getAttributeValue(attrNdx);
   1210             if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
   1211                         "ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
   1212             if (ATTR_ID.equals(attrName)) {
   1213                 createTime = Long.valueOf(attrValue);
   1214             } else if (ATTR_LAUNCHEDFROMUID.equals(attrName)) {
   1215                 launchedFromUid = Integer.valueOf(attrValue);
   1216             } else if (ATTR_LAUNCHEDFROMPACKAGE.equals(attrName)) {
   1217                 launchedFromPackage = attrValue;
   1218             } else if (ATTR_RESOLVEDTYPE.equals(attrName)) {
   1219                 resolvedType = attrValue;
   1220             } else if (ATTR_COMPONENTSPECIFIED.equals(attrName)) {
   1221                 componentSpecified = Boolean.valueOf(attrValue);
   1222             } else if (ATTR_USERID.equals(attrName)) {
   1223                 userId = Integer.valueOf(attrValue);
   1224             } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
   1225                 taskDescription.restoreFromXml(attrName, attrValue);
   1226             } else {
   1227                 Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
   1228             }
   1229         }
   1230 
   1231         int event;
   1232         while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
   1233                 (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
   1234             if (event == XmlPullParser.START_TAG) {
   1235                 final String name = in.getName();
   1236                 if (TaskPersister.DEBUG)
   1237                         Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
   1238                 if (TAG_INTENT.equals(name)) {
   1239                     intent = Intent.restoreFromXml(in);
   1240                     if (TaskPersister.DEBUG)
   1241                             Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
   1242                 } else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
   1243                     persistentState = PersistableBundle.restoreFromXml(in);
   1244                     if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
   1245                             "ActivityRecord: persistentState=" + persistentState);
   1246                 } else {
   1247                     Slog.w(TAG, "restoreActivity: unexpected name=" + name);
   1248                     XmlUtils.skipCurrentTag(in);
   1249                 }
   1250             }
   1251         }
   1252 
   1253         if (intent == null) {
   1254             throw new XmlPullParserException("restoreActivity error intent=" + intent);
   1255         }
   1256 
   1257         final ActivityManagerService service = stackSupervisor.mService;
   1258         final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
   1259                 userId);
   1260         if (aInfo == null) {
   1261             throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
   1262                     " resolvedType=" + resolvedType);
   1263         }
   1264         final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid,
   1265                 launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(),
   1266                 null, null, 0, componentSpecified, false, stackSupervisor, null, null);
   1267 
   1268         r.persistentState = persistentState;
   1269         r.taskDescription = taskDescription;
   1270         r.createTime = createTime;
   1271 
   1272         return r;
   1273     }
   1274 
   1275     private static String activityTypeToString(int type) {
   1276         switch (type) {
   1277             case APPLICATION_ACTIVITY_TYPE: return "APPLICATION_ACTIVITY_TYPE";
   1278             case HOME_ACTIVITY_TYPE: return "HOME_ACTIVITY_TYPE";
   1279             case RECENTS_ACTIVITY_TYPE: return "RECENTS_ACTIVITY_TYPE";
   1280             default: return Integer.toString(type);
   1281         }
   1282     }
   1283 
   1284     @Override
   1285     public String toString() {
   1286         if (stringName != null) {
   1287             return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
   1288                     (finishing ? " f}" : "}");
   1289         }
   1290         StringBuilder sb = new StringBuilder(128);
   1291         sb.append("ActivityRecord{");
   1292         sb.append(Integer.toHexString(System.identityHashCode(this)));
   1293         sb.append(" u");
   1294         sb.append(userId);
   1295         sb.append(' ');
   1296         sb.append(intent.getComponent().flattenToShortString());
   1297         stringName = sb.toString();
   1298         return toString();
   1299     }
   1300 }
   1301