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