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 com.android.internal.app.ResolverActivity;
     20 import com.android.server.AttributeCache;
     21 import com.android.server.am.ActivityStack.ActivityState;
     22 
     23 import android.app.Activity;
     24 import android.app.ActivityOptions;
     25 import android.content.ComponentName;
     26 import android.content.Intent;
     27 import android.content.pm.ActivityInfo;
     28 import android.content.pm.ApplicationInfo;
     29 import android.content.res.CompatibilityInfo;
     30 import android.content.res.Configuration;
     31 import android.graphics.Bitmap;
     32 import android.graphics.Rect;
     33 import android.os.Build;
     34 import android.os.Bundle;
     35 import android.os.IBinder;
     36 import android.os.Message;
     37 import android.os.Process;
     38 import android.os.RemoteException;
     39 import android.os.SystemClock;
     40 import android.os.UserHandle;
     41 import android.util.EventLog;
     42 import android.util.Log;
     43 import android.util.Slog;
     44 import android.util.TimeUtils;
     45 import android.view.IApplicationToken;
     46 import android.view.WindowManager;
     47 
     48 import java.io.PrintWriter;
     49 import java.lang.ref.WeakReference;
     50 import java.util.ArrayList;
     51 import java.util.HashSet;
     52 
     53 /**
     54  * An entry in the history stack, representing an activity.
     55  */
     56 final class ActivityRecord {
     57     final ActivityManagerService service; // owner
     58     final ActivityStack stack; // owner
     59     final IApplicationToken.Stub appToken; // window manager token
     60     final ActivityInfo info; // all about me
     61     final int launchedFromUid; // always the uid who started the activity.
     62     final String launchedFromPackage; // always the package who started the activity.
     63     final int userId;          // Which user is this running for?
     64     final Intent intent;    // the original intent that generated us
     65     final ComponentName realActivity;  // the intent component, or target of an alias.
     66     final String shortComponentName; // the short component name of the intent
     67     final String resolvedType; // as per original caller;
     68     final String packageName; // the package implementing intent's component
     69     final String processName; // process where this component wants to run
     70     final String taskAffinity; // as per ActivityInfo.taskAffinity
     71     final boolean stateNotNeeded; // As per ActivityInfo.flags
     72     final boolean fullscreen; // covers the full screen?
     73     final boolean noDisplay;  // activity is not displayed?
     74     final boolean componentSpecified;  // did caller specifiy an explicit component?
     75     final boolean isHomeActivity; // do we consider this to be a home activity?
     76     final String baseDir;   // where activity source (resources etc) located
     77     final String resDir;   // where public activity source (public resources etc) located
     78     final String dataDir;   // where activity data should go
     79     CharSequence nonLocalizedLabel;  // the label information from the package mgr.
     80     int labelRes;           // the label information from the package mgr.
     81     int icon;               // resource identifier of activity's icon.
     82     int theme;              // resource identifier of activity's theme.
     83     int realTheme;          // actual theme resource we will use, never 0.
     84     int windowFlags;        // custom window flags for preview window.
     85     TaskRecord task;        // the task this is in.
     86     ThumbnailHolder thumbHolder; // where our thumbnails should go.
     87     long launchTime;        // when we starting launching this activity
     88     long startTime;         // last time this activity was started
     89     long lastVisibleTime;   // last time this activity became visible
     90     long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
     91     long pauseTime;         // last time we started pausing the activity
     92     long launchTickTime;    // base time for launch tick messages
     93     Configuration configuration; // configuration activity was last running in
     94     CompatibilityInfo compat;// last used compatibility mode
     95     ActivityRecord resultTo; // who started this entry, so will get our reply
     96     final String resultWho; // additional identifier for use by resultTo.
     97     final int requestCode;  // code given by requester (resultTo)
     98     ArrayList results;      // pending ActivityResult objs we have received
     99     HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
    100     ArrayList newIntents;   // any pending new intents for single-top mode
    101     ActivityOptions pendingOptions; // most recently given options
    102     HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
    103     UriPermissionOwner uriPermissions; // current special URI access perms.
    104     ProcessRecord app;      // if non-null, hosting application
    105     ActivityState state;    // current state we are in
    106     Bundle  icicle;         // last saved activity state
    107     boolean frontOfTask;    // is this the root activity of its task?
    108     boolean launchFailed;   // set if a launched failed, to abort on 2nd try
    109     boolean haveState;      // have we gotten the last activity state?
    110     boolean stopped;        // is activity pause finished?
    111     boolean delayedResume;  // not yet resumed because of stopped app switches?
    112     boolean finishing;      // activity in pending finish list?
    113     boolean configDestroy;  // need to destroy due to config change?
    114     int configChangeFlags;  // which config values have changed
    115     boolean keysPaused;     // has key dispatching been paused for it?
    116     int launchMode;         // the launch mode activity attribute.
    117     boolean visible;        // does this activity's window need to be shown?
    118     boolean sleeping;       // have we told the activity to sleep?
    119     boolean waitingVisible; // true if waiting for a new act to become vis
    120     boolean nowVisible;     // is this activity's window visible?
    121     boolean thumbnailNeeded;// has someone requested a thumbnail?
    122     boolean idle;           // has the activity gone idle?
    123     boolean hasBeenLaunched;// has this activity ever been launched?
    124     boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
    125     boolean immersive;      // immersive mode (don't interrupt if possible)
    126     boolean forceNewConfig; // force re-create with new config next time
    127     int launchCount;        // count of launches since last state
    128     long lastLaunchTime;    // time of last lauch of this activity
    129 
    130     String stringName;      // for caching of toString().
    131 
    132     private boolean inHistory;  // are we in the history stack?
    133 
    134     void dump(PrintWriter pw, String prefix) {
    135         final long now = SystemClock.uptimeMillis();
    136         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
    137                 pw.print(" processName="); pw.println(processName);
    138         pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
    139                 pw.print(" launchedFromPackage="); pw.println(launchedFromPackage);
    140                 pw.print(" userId="); pw.println(userId);
    141         pw.print(prefix); pw.print("app="); pw.println(app);
    142         pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
    143         pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
    144                 pw.print(" task="); pw.println(task);
    145         pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
    146         pw.print(prefix); pw.print("realActivity=");
    147                 pw.println(realActivity.flattenToShortString());
    148         pw.print(prefix); pw.print("baseDir="); pw.println(baseDir);
    149         if (!resDir.equals(baseDir)) {
    150             pw.print(prefix); pw.print("resDir="); pw.println(resDir);
    151         }
    152         pw.print(prefix); pw.print("dataDir="); pw.println(dataDir);
    153         pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
    154                 pw.print(" componentSpecified="); pw.print(componentSpecified);
    155                 pw.print(" isHomeActivity="); pw.println(isHomeActivity);
    156         pw.print(prefix); pw.print("compat="); pw.print(compat);
    157                 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
    158                 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
    159                 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
    160         pw.print(prefix); pw.print("config="); pw.println(configuration);
    161         if (resultTo != null || resultWho != null) {
    162             pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
    163                     pw.print(" resultWho="); pw.print(resultWho);
    164                     pw.print(" resultCode="); pw.println(requestCode);
    165         }
    166         if (results != null) {
    167             pw.print(prefix); pw.print("results="); pw.println(results);
    168         }
    169         if (pendingResults != null && pendingResults.size() > 0) {
    170             pw.print(prefix); pw.println("Pending Results:");
    171             for (WeakReference<PendingIntentRecord> wpir : pendingResults) {
    172                 PendingIntentRecord pir = wpir != null ? wpir.get() : null;
    173                 pw.print(prefix); pw.print("  - ");
    174                 if (pir == null) {
    175                     pw.println("null");
    176                 } else {
    177                     pw.println(pir);
    178                     pir.dump(pw, prefix + "    ");
    179                 }
    180             }
    181         }
    182         if (newIntents != null && newIntents.size() > 0) {
    183             pw.print(prefix); pw.println("Pending New Intents:");
    184             for (int i=0; i<newIntents.size(); i++) {
    185                 Intent intent = (Intent)newIntents.get(i);
    186                 pw.print(prefix); pw.print("  - ");
    187                 if (intent == null) {
    188                     pw.println("null");
    189                 } else {
    190                     pw.println(intent.toShortString(false, true, false, true));
    191                 }
    192             }
    193         }
    194         if (pendingOptions != null) {
    195             pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
    196         }
    197         if (uriPermissions != null) {
    198             if (uriPermissions.readUriPermissions != null) {
    199                 pw.print(prefix); pw.print("readUriPermissions=");
    200                         pw.println(uriPermissions.readUriPermissions);
    201             }
    202             if (uriPermissions.writeUriPermissions != null) {
    203                 pw.print(prefix); pw.print("writeUriPermissions=");
    204                         pw.println(uriPermissions.writeUriPermissions);
    205             }
    206         }
    207         pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
    208                 pw.print(" launchCount="); pw.print(launchCount);
    209                 pw.print(" lastLaunchTime=");
    210                 if (lastLaunchTime == 0) pw.print("0");
    211                 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
    212                 pw.println();
    213         pw.print(prefix); pw.print(" haveState="); pw.print(haveState);
    214                 pw.print(" icicle="); pw.println(icicle);
    215         pw.print(prefix); pw.print("state="); pw.print(state);
    216                 pw.print(" stopped="); pw.print(stopped);
    217                 pw.print(" delayedResume="); pw.print(delayedResume);
    218                 pw.print(" finishing="); pw.println(finishing);
    219         pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
    220                 pw.print(" inHistory="); pw.print(inHistory);
    221                 pw.print(" visible="); pw.print(visible);
    222                 pw.print(" sleeping="); pw.print(sleeping);
    223                 pw.print(" idle="); pw.println(idle);
    224         pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
    225                 pw.print(" noDisplay="); pw.print(noDisplay);
    226                 pw.print(" immersive="); pw.print(immersive);
    227                 pw.print(" launchMode="); pw.println(launchMode);
    228         pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
    229                 pw.print(" thumbnailNeeded="); pw.print(thumbnailNeeded);
    230                 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
    231         pw.print(prefix); pw.print("thumbHolder: ");
    232                 pw.print(Integer.toHexString(System.identityHashCode(thumbHolder)));
    233                 if (thumbHolder != null) {
    234                     pw.print(" bm="); pw.print(thumbHolder.lastThumbnail);
    235                     pw.print(" desc="); pw.print(thumbHolder.lastDescription);
    236                 }
    237                 pw.println();
    238         if (launchTime != 0 || startTime != 0) {
    239             pw.print(prefix); pw.print("launchTime=");
    240                     if (launchTime == 0) pw.print("0");
    241                     else TimeUtils.formatDuration(launchTime, now, pw);
    242                     pw.print(" startTime=");
    243                     if (startTime == 0) pw.print("0");
    244                     else TimeUtils.formatDuration(startTime, now, pw);
    245                     pw.println();
    246         }
    247         if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
    248             pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
    249                     pw.print(" nowVisible="); pw.print(nowVisible);
    250                     pw.print(" lastVisibleTime=");
    251                     if (lastVisibleTime == 0) pw.print("0");
    252                     else TimeUtils.formatDuration(lastVisibleTime, now, pw);
    253                     pw.println();
    254         }
    255         if (configDestroy || configChangeFlags != 0) {
    256             pw.print(prefix); pw.print("configDestroy="); pw.print(configDestroy);
    257                     pw.print(" configChangeFlags=");
    258                     pw.println(Integer.toHexString(configChangeFlags));
    259         }
    260         if (connections != null) {
    261             pw.print(prefix); pw.print("connections="); pw.println(connections);
    262         }
    263     }
    264 
    265     static class Token extends IApplicationToken.Stub {
    266         final WeakReference<ActivityRecord> weakActivity;
    267 
    268         Token(ActivityRecord activity) {
    269             weakActivity = new WeakReference<ActivityRecord>(activity);
    270         }
    271 
    272         @Override public void windowsDrawn() throws RemoteException {
    273             ActivityRecord activity = weakActivity.get();
    274             if (activity != null) {
    275                 activity.windowsDrawn();
    276             }
    277         }
    278 
    279         @Override public void windowsVisible() throws RemoteException {
    280             ActivityRecord activity = weakActivity.get();
    281             if (activity != null) {
    282                 activity.windowsVisible();
    283             }
    284         }
    285 
    286         @Override public void windowsGone() throws RemoteException {
    287             ActivityRecord activity = weakActivity.get();
    288             if (activity != null) {
    289                 activity.windowsGone();
    290             }
    291         }
    292 
    293         @Override public boolean keyDispatchingTimedOut() throws RemoteException {
    294             ActivityRecord activity = weakActivity.get();
    295             if (activity != null) {
    296                 return activity.keyDispatchingTimedOut();
    297             }
    298             return false;
    299         }
    300 
    301         @Override public long getKeyDispatchingTimeout() throws RemoteException {
    302             ActivityRecord activity = weakActivity.get();
    303             if (activity != null) {
    304                 return activity.getKeyDispatchingTimeout();
    305             }
    306             return 0;
    307         }
    308 
    309         public String toString() {
    310             StringBuilder sb = new StringBuilder(128);
    311             sb.append("Token{");
    312             sb.append(Integer.toHexString(System.identityHashCode(this)));
    313             sb.append(' ');
    314             sb.append(weakActivity.get());
    315             sb.append('}');
    316             return sb.toString();
    317         }
    318     }
    319 
    320     static ActivityRecord forToken(IBinder token) {
    321         try {
    322             return token != null ? ((Token)token).weakActivity.get() : null;
    323         } catch (ClassCastException e) {
    324             Slog.w(ActivityManagerService.TAG, "Bad activity token: " + token, e);
    325             return null;
    326         }
    327     }
    328 
    329     ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,
    330             int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
    331             ActivityInfo aInfo, Configuration _configuration,
    332             ActivityRecord _resultTo, String _resultWho, int _reqCode,
    333             boolean _componentSpecified) {
    334         service = _service;
    335         stack = _stack;
    336         appToken = new Token(this);
    337         info = aInfo;
    338         launchedFromUid = _launchedFromUid;
    339         launchedFromPackage = _launchedFromPackage;
    340         userId = UserHandle.getUserId(aInfo.applicationInfo.uid);
    341         intent = _intent;
    342         shortComponentName = _intent.getComponent().flattenToShortString();
    343         resolvedType = _resolvedType;
    344         componentSpecified = _componentSpecified;
    345         configuration = _configuration;
    346         resultTo = _resultTo;
    347         resultWho = _resultWho;
    348         requestCode = _reqCode;
    349         state = ActivityState.INITIALIZING;
    350         frontOfTask = false;
    351         launchFailed = false;
    352         stopped = false;
    353         delayedResume = false;
    354         finishing = false;
    355         configDestroy = false;
    356         keysPaused = false;
    357         inHistory = false;
    358         visible = true;
    359         waitingVisible = false;
    360         nowVisible = false;
    361         thumbnailNeeded = false;
    362         idle = false;
    363         hasBeenLaunched = false;
    364 
    365         // This starts out true, since the initial state of an activity
    366         // is that we have everything, and we shouldn't never consider it
    367         // lacking in state to be removed if it dies.
    368         haveState = true;
    369 
    370         if (aInfo != null) {
    371             if (aInfo.targetActivity == null
    372                     || aInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE
    373                     || aInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
    374                 realActivity = _intent.getComponent();
    375             } else {
    376                 realActivity = new ComponentName(aInfo.packageName,
    377                         aInfo.targetActivity);
    378             }
    379             taskAffinity = aInfo.taskAffinity;
    380             stateNotNeeded = (aInfo.flags&
    381                     ActivityInfo.FLAG_STATE_NOT_NEEDED) != 0;
    382             baseDir = aInfo.applicationInfo.sourceDir;
    383             resDir = aInfo.applicationInfo.publicSourceDir;
    384             dataDir = aInfo.applicationInfo.dataDir;
    385             nonLocalizedLabel = aInfo.nonLocalizedLabel;
    386             labelRes = aInfo.labelRes;
    387             if (nonLocalizedLabel == null && labelRes == 0) {
    388                 ApplicationInfo app = aInfo.applicationInfo;
    389                 nonLocalizedLabel = app.nonLocalizedLabel;
    390                 labelRes = app.labelRes;
    391             }
    392             icon = aInfo.getIconResource();
    393             theme = aInfo.getThemeResource();
    394             realTheme = theme;
    395             if (realTheme == 0) {
    396                 realTheme = aInfo.applicationInfo.targetSdkVersion
    397                         < Build.VERSION_CODES.HONEYCOMB
    398                         ? android.R.style.Theme
    399                         : android.R.style.Theme_Holo;
    400             }
    401             if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
    402                 windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
    403             }
    404             if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
    405                     && _caller != null
    406                     && (aInfo.applicationInfo.uid == Process.SYSTEM_UID
    407                             || aInfo.applicationInfo.uid == _caller.info.uid)) {
    408                 processName = _caller.processName;
    409             } else {
    410                 processName = aInfo.processName;
    411             }
    412 
    413             if (intent != null && (aInfo.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0) {
    414                 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    415             }
    416 
    417             packageName = aInfo.applicationInfo.packageName;
    418             launchMode = aInfo.launchMode;
    419 
    420             AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
    421                     realTheme, com.android.internal.R.styleable.Window, userId);
    422             fullscreen = ent != null && !ent.array.getBoolean(
    423                     com.android.internal.R.styleable.Window_windowIsFloating, false)
    424                     && !ent.array.getBoolean(
    425                     com.android.internal.R.styleable.Window_windowIsTranslucent, false);
    426             noDisplay = ent != null && ent.array.getBoolean(
    427                     com.android.internal.R.styleable.Window_windowNoDisplay, false);
    428 
    429             if (!_componentSpecified || _launchedFromUid == Process.myUid()
    430                     || _launchedFromUid == 0) {
    431                 // If we know the system has determined the component, then
    432                 // we can consider this to be a home activity...
    433                 if (Intent.ACTION_MAIN.equals(_intent.getAction()) &&
    434                         _intent.hasCategory(Intent.CATEGORY_HOME) &&
    435                         _intent.getCategories().size() == 1 &&
    436                         _intent.getData() == null &&
    437                         _intent.getType() == null &&
    438                         (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
    439                         !ResolverActivity.class.getName().equals(realActivity.getClassName())) {
    440                     // This sure looks like a home activity!
    441                     // Note the last check is so we don't count the resolver
    442                     // activity as being home...  really, we don't care about
    443                     // doing anything special with something that comes from
    444                     // the core framework package.
    445                     isHomeActivity = true;
    446                 } else {
    447                     isHomeActivity = false;
    448                 }
    449             } else {
    450                 isHomeActivity = false;
    451             }
    452 
    453             immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;
    454         } else {
    455             realActivity = null;
    456             taskAffinity = null;
    457             stateNotNeeded = false;
    458             baseDir = null;
    459             resDir = null;
    460             dataDir = null;
    461             processName = null;
    462             packageName = null;
    463             fullscreen = true;
    464             noDisplay = false;
    465             isHomeActivity = false;
    466             immersive = false;
    467         }
    468     }
    469 
    470     void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) {
    471         if (inHistory && !finishing) {
    472             if (task != null) {
    473                 task.numActivities--;
    474             }
    475             if (newTask != null) {
    476                 newTask.numActivities++;
    477             }
    478         }
    479         if (newThumbHolder == null) {
    480             newThumbHolder = newTask;
    481         }
    482         task = newTask;
    483         if (!isRoot && (intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
    484             // This is the start of a new sub-task.
    485             if (thumbHolder == null) {
    486                 thumbHolder = new ThumbnailHolder();
    487             }
    488         } else {
    489             thumbHolder = newThumbHolder;
    490         }
    491     }
    492 
    493     void putInHistory() {
    494         if (!inHistory) {
    495             inHistory = true;
    496             if (task != null && !finishing) {
    497                 task.numActivities++;
    498             }
    499         }
    500     }
    501 
    502     void takeFromHistory() {
    503         if (inHistory) {
    504             inHistory = false;
    505             if (task != null && !finishing) {
    506                 task.numActivities--;
    507             }
    508             clearOptionsLocked();
    509         }
    510     }
    511 
    512     boolean isInHistory() {
    513         return inHistory;
    514     }
    515 
    516     void makeFinishing() {
    517         if (!finishing) {
    518             finishing = true;
    519             if (task != null && inHistory) {
    520                 task.numActivities--;
    521             }
    522             if (stopped) {
    523                 clearOptionsLocked();
    524             }
    525         }
    526     }
    527 
    528     UriPermissionOwner getUriPermissionsLocked() {
    529         if (uriPermissions == null) {
    530             uriPermissions = new UriPermissionOwner(service, this);
    531         }
    532         return uriPermissions;
    533     }
    534 
    535     void addResultLocked(ActivityRecord from, String resultWho,
    536             int requestCode, int resultCode,
    537             Intent resultData) {
    538         ActivityResult r = new ActivityResult(from, resultWho,
    539         		requestCode, resultCode, resultData);
    540         if (results == null) {
    541             results = new ArrayList();
    542         }
    543         results.add(r);
    544     }
    545 
    546     void removeResultsLocked(ActivityRecord from, String resultWho,
    547             int requestCode) {
    548         if (results != null) {
    549             for (int i=results.size()-1; i>=0; i--) {
    550                 ActivityResult r = (ActivityResult)results.get(i);
    551                 if (r.mFrom != from) continue;
    552                 if (r.mResultWho == null) {
    553                     if (resultWho != null) continue;
    554                 } else {
    555                     if (!r.mResultWho.equals(resultWho)) continue;
    556                 }
    557                 if (r.mRequestCode != requestCode) continue;
    558 
    559                 results.remove(i);
    560             }
    561         }
    562     }
    563 
    564     void addNewIntentLocked(Intent intent) {
    565         if (newIntents == null) {
    566             newIntents = new ArrayList();
    567         }
    568         newIntents.add(intent);
    569     }
    570 
    571     /**
    572      * Deliver a new Intent to an existing activity, so that its onNewIntent()
    573      * method will be called at the proper time.
    574      */
    575     final void deliverNewIntentLocked(int callingUid, Intent intent) {
    576         boolean sent = false;
    577         // The activity now gets access to the data associated with this Intent.
    578         service.grantUriPermissionFromIntentLocked(callingUid, packageName,
    579                 intent, getUriPermissionsLocked());
    580         // We want to immediately deliver the intent to the activity if
    581         // it is currently the top resumed activity...  however, if the
    582         // device is sleeping, then all activities are stopped, so in that
    583         // case we will deliver it if this is the current top activity on its
    584         // stack.
    585         if ((state == ActivityState.RESUMED || (service.mSleeping
    586                         && stack.topRunningActivityLocked(null) == this))
    587                 && app != null && app.thread != null) {
    588             try {
    589                 ArrayList<Intent> ar = new ArrayList<Intent>();
    590                 intent = new Intent(intent);
    591                 ar.add(intent);
    592                 app.thread.scheduleNewIntent(ar, appToken);
    593                 sent = true;
    594             } catch (RemoteException e) {
    595                 Slog.w(ActivityManagerService.TAG,
    596                         "Exception thrown sending new intent to " + this, e);
    597             } catch (NullPointerException e) {
    598                 Slog.w(ActivityManagerService.TAG,
    599                         "Exception thrown sending new intent to " + this, e);
    600             }
    601         }
    602         if (!sent) {
    603             addNewIntentLocked(new Intent(intent));
    604         }
    605     }
    606 
    607     void updateOptionsLocked(Bundle options) {
    608         if (options != null) {
    609             if (pendingOptions != null) {
    610                 pendingOptions.abort();
    611             }
    612             pendingOptions = new ActivityOptions(options);
    613         }
    614     }
    615 
    616     void updateOptionsLocked(ActivityOptions options) {
    617         if (options != null) {
    618             if (pendingOptions != null) {
    619                 pendingOptions.abort();
    620             }
    621             pendingOptions = options;
    622         }
    623     }
    624 
    625     void applyOptionsLocked() {
    626         if (pendingOptions != null) {
    627             final int animationType = pendingOptions.getAnimationType();
    628             switch (animationType) {
    629                 case ActivityOptions.ANIM_CUSTOM:
    630                     service.mWindowManager.overridePendingAppTransition(
    631                             pendingOptions.getPackageName(),
    632                             pendingOptions.getCustomEnterResId(),
    633                             pendingOptions.getCustomExitResId(),
    634                             pendingOptions.getOnAnimationStartListener());
    635                     break;
    636                 case ActivityOptions.ANIM_SCALE_UP:
    637                     service.mWindowManager.overridePendingAppTransitionScaleUp(
    638                             pendingOptions.getStartX(), pendingOptions.getStartY(),
    639                             pendingOptions.getStartWidth(), pendingOptions.getStartHeight());
    640                     if (intent.getSourceBounds() == null) {
    641                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
    642                                 pendingOptions.getStartY(),
    643                                 pendingOptions.getStartX()+pendingOptions.getStartWidth(),
    644                                 pendingOptions.getStartY()+pendingOptions.getStartHeight()));
    645                     }
    646                     break;
    647                 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
    648                 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
    649                     boolean scaleUp = (animationType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
    650                     service.mWindowManager.overridePendingAppTransitionThumb(
    651                             pendingOptions.getThumbnail(),
    652                             pendingOptions.getStartX(), pendingOptions.getStartY(),
    653                             pendingOptions.getOnAnimationStartListener(),
    654                             scaleUp);
    655                     if (intent.getSourceBounds() == null) {
    656                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
    657                                 pendingOptions.getStartY(),
    658                                 pendingOptions.getStartX()
    659                                         + pendingOptions.getThumbnail().getWidth(),
    660                                 pendingOptions.getStartY()
    661                                         + pendingOptions.getThumbnail().getHeight()));
    662                     }
    663                     break;
    664             }
    665             pendingOptions = null;
    666         }
    667     }
    668 
    669     void clearOptionsLocked() {
    670         if (pendingOptions != null) {
    671             pendingOptions.abort();
    672             pendingOptions = null;
    673         }
    674     }
    675 
    676     ActivityOptions takeOptionsLocked() {
    677         ActivityOptions opts = pendingOptions;
    678         pendingOptions = null;
    679         return opts;
    680     }
    681 
    682     void removeUriPermissionsLocked() {
    683         if (uriPermissions != null) {
    684             uriPermissions.removeUriPermissionsLocked();
    685             uriPermissions = null;
    686         }
    687     }
    688 
    689     void pauseKeyDispatchingLocked() {
    690         if (!keysPaused) {
    691             keysPaused = true;
    692             service.mWindowManager.pauseKeyDispatching(appToken);
    693         }
    694     }
    695 
    696     void resumeKeyDispatchingLocked() {
    697         if (keysPaused) {
    698             keysPaused = false;
    699             service.mWindowManager.resumeKeyDispatching(appToken);
    700         }
    701     }
    702 
    703     void updateThumbnail(Bitmap newThumbnail, CharSequence description) {
    704         if ((intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
    705             // This is a logical break in the task; it repre
    706         }
    707         if (thumbHolder != null) {
    708             if (newThumbnail != null) {
    709                 if (ActivityManagerService.DEBUG_THUMBNAILS) Slog.i(ActivityManagerService.TAG,
    710                         "Setting thumbnail of " + this + " holder " + thumbHolder
    711                         + " to " + newThumbnail);
    712                 thumbHolder.lastThumbnail = newThumbnail;
    713             }
    714             thumbHolder.lastDescription = description;
    715         }
    716     }
    717 
    718     void startLaunchTickingLocked() {
    719         if (ActivityManagerService.IS_USER_BUILD) {
    720             return;
    721         }
    722         if (launchTickTime == 0) {
    723             launchTickTime = SystemClock.uptimeMillis();
    724             continueLaunchTickingLocked();
    725         }
    726     }
    727 
    728     boolean continueLaunchTickingLocked() {
    729         if (launchTickTime != 0) {
    730             Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG);
    731             msg.obj = this;
    732             stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
    733             stack.mHandler.sendMessageDelayed(msg, ActivityStack.LAUNCH_TICK);
    734             return true;
    735         }
    736         return false;
    737     }
    738 
    739     void finishLaunchTickingLocked() {
    740         launchTickTime = 0;
    741         stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
    742     }
    743 
    744     // IApplicationToken
    745 
    746     public boolean mayFreezeScreenLocked(ProcessRecord app) {
    747         // Only freeze the screen if this activity is currently attached to
    748         // an application, and that application is not blocked or unresponding.
    749         // In any other case, we can't count on getting the screen unfrozen,
    750         // so it is best to leave as-is.
    751         return app != null && !app.crashing && !app.notResponding;
    752     }
    753 
    754     public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
    755         if (mayFreezeScreenLocked(app)) {
    756             service.mWindowManager.startAppFreezingScreen(appToken, configChanges);
    757         }
    758     }
    759 
    760     public void stopFreezingScreenLocked(boolean force) {
    761         if (force || frozenBeforeDestroy) {
    762             frozenBeforeDestroy = false;
    763             service.mWindowManager.stopAppFreezingScreen(appToken, force);
    764         }
    765     }
    766 
    767     public void windowsDrawn() {
    768         synchronized(service) {
    769             if (launchTime != 0) {
    770                 final long curTime = SystemClock.uptimeMillis();
    771                 final long thisTime = curTime - launchTime;
    772                 final long totalTime = stack.mInitialStartTime != 0
    773                         ? (curTime - stack.mInitialStartTime) : thisTime;
    774                 if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
    775                     EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
    776                             userId, System.identityHashCode(this), shortComponentName,
    777                             thisTime, totalTime);
    778                     StringBuilder sb = service.mStringBuilder;
    779                     sb.setLength(0);
    780                     sb.append("Displayed ");
    781                     sb.append(shortComponentName);
    782                     sb.append(": ");
    783                     TimeUtils.formatDuration(thisTime, sb);
    784                     if (thisTime != totalTime) {
    785                         sb.append(" (total ");
    786                         TimeUtils.formatDuration(totalTime, sb);
    787                         sb.append(")");
    788                     }
    789                     Log.i(ActivityManagerService.TAG, sb.toString());
    790                 }
    791                 stack.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
    792                 if (totalTime > 0) {
    793                     service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
    794                 }
    795                 launchTime = 0;
    796                 stack.mInitialStartTime = 0;
    797             }
    798             startTime = 0;
    799             finishLaunchTickingLocked();
    800         }
    801     }
    802 
    803     public void windowsVisible() {
    804         synchronized(service) {
    805             stack.reportActivityVisibleLocked(this);
    806             if (ActivityManagerService.DEBUG_SWITCH) Log.v(
    807                     ActivityManagerService.TAG, "windowsVisible(): " + this);
    808             if (!nowVisible) {
    809                 nowVisible = true;
    810                 lastVisibleTime = SystemClock.uptimeMillis();
    811                 if (!idle) {
    812                     // Instead of doing the full stop routine here, let's just
    813                     // hide any activities we now can, and let them stop when
    814                     // the normal idle happens.
    815                     stack.processStoppingActivitiesLocked(false);
    816                 } else {
    817                     // If this activity was already idle, then we now need to
    818                     // make sure we perform the full stop of any activities
    819                     // that are waiting to do so.  This is because we won't
    820                     // do that while they are still waiting for this one to
    821                     // become visible.
    822                     final int N = stack.mWaitingVisibleActivities.size();
    823                     if (N > 0) {
    824                         for (int i=0; i<N; i++) {
    825                             ActivityRecord r = (ActivityRecord)
    826                                 stack.mWaitingVisibleActivities.get(i);
    827                             r.waitingVisible = false;
    828                             if (ActivityManagerService.DEBUG_SWITCH) Log.v(
    829                                     ActivityManagerService.TAG,
    830                                     "Was waiting for visible: " + r);
    831                         }
    832                         stack.mWaitingVisibleActivities.clear();
    833                         Message msg = Message.obtain();
    834                         msg.what = ActivityStack.IDLE_NOW_MSG;
    835                         stack.mHandler.sendMessage(msg);
    836                     }
    837                 }
    838                 service.scheduleAppGcsLocked();
    839             }
    840         }
    841     }
    842 
    843     public void windowsGone() {
    844         if (ActivityManagerService.DEBUG_SWITCH) Log.v(
    845                 ActivityManagerService.TAG, "windowsGone(): " + this);
    846         nowVisible = false;
    847     }
    848 
    849     private ActivityRecord getWaitingHistoryRecordLocked() {
    850         // First find the real culprit...  if we are waiting
    851         // for another app to start, then we have paused dispatching
    852         // for this activity.
    853         ActivityRecord r = this;
    854         if (r.waitingVisible) {
    855             // Hmmm, who might we be waiting for?
    856             r = stack.mResumedActivity;
    857             if (r == null) {
    858                 r = stack.mPausingActivity;
    859             }
    860             // Both of those null?  Fall back to 'this' again
    861             if (r == null) {
    862                 r = this;
    863             }
    864         }
    865 
    866         return r;
    867     }
    868 
    869     public boolean keyDispatchingTimedOut() {
    870         ActivityRecord r;
    871         ProcessRecord anrApp;
    872         synchronized(service) {
    873             r = getWaitingHistoryRecordLocked();
    874             anrApp = r != null ? r.app : null;
    875         }
    876         return service.inputDispatchingTimedOut(anrApp, r, this, false);
    877     }
    878 
    879     /** Returns the key dispatching timeout for this application token. */
    880     public long getKeyDispatchingTimeout() {
    881         synchronized(service) {
    882             ActivityRecord r = getWaitingHistoryRecordLocked();
    883             return ActivityManagerService.getInputDispatchingTimeoutLocked(r);
    884         }
    885     }
    886 
    887     /**
    888      * This method will return true if the activity is either visible, is becoming visible, is
    889      * currently pausing, or is resumed.
    890      */
    891     public boolean isInterestingToUserLocked() {
    892         return visible || nowVisible || state == ActivityState.PAUSING ||
    893                 state == ActivityState.RESUMED;
    894     }
    895 
    896     public void setSleeping(boolean _sleeping) {
    897         if (sleeping == _sleeping) {
    898             return;
    899         }
    900         if (app != null && app.thread != null) {
    901             try {
    902                 app.thread.scheduleSleeping(appToken, _sleeping);
    903                 if (sleeping && !stack.mGoingToSleepActivities.contains(this)) {
    904                     stack.mGoingToSleepActivities.add(this);
    905                 }
    906                 sleeping = _sleeping;
    907             } catch (RemoteException e) {
    908                 Slog.w(ActivityStack.TAG, "Exception thrown when sleeping: "
    909                         + intent.getComponent(), e);
    910             }
    911         }
    912     }
    913 
    914     public String toString() {
    915         if (stringName != null) {
    916             return stringName;
    917         }
    918         StringBuilder sb = new StringBuilder(128);
    919         sb.append("ActivityRecord{");
    920         sb.append(Integer.toHexString(System.identityHashCode(this)));
    921         sb.append(" u");
    922         sb.append(userId);
    923         sb.append(' ');
    924         sb.append(intent.getComponent().flattenToShortString());
    925         sb.append('}');
    926         return stringName = sb.toString();
    927     }
    928 }
    929