• 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 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 
dump(PrintWriter pw, String prefix)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 
Token(ActivityRecord activity)268         Token(ActivityRecord activity) {
269             weakActivity = new WeakReference<ActivityRecord>(activity);
270         }
271 
windowsDrawn()272         @Override public void windowsDrawn() throws RemoteException {
273             ActivityRecord activity = weakActivity.get();
274             if (activity != null) {
275                 activity.windowsDrawn();
276             }
277         }
278 
windowsVisible()279         @Override public void windowsVisible() throws RemoteException {
280             ActivityRecord activity = weakActivity.get();
281             if (activity != null) {
282                 activity.windowsVisible();
283             }
284         }
285 
windowsGone()286         @Override public void windowsGone() throws RemoteException {
287             ActivityRecord activity = weakActivity.get();
288             if (activity != null) {
289                 activity.windowsGone();
290             }
291         }
292 
keyDispatchingTimedOut()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 
getKeyDispatchingTimeout()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 
toString()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 
forToken(IBinder token)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 
ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller, int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType, ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified)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);
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 
addNewIntentLocked(Intent intent)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      */
deliverNewIntentLocked(int callingUid, Intent intent)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 
updateOptionsLocked(Bundle options)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 
updateOptionsLocked(ActivityOptions options)616     void updateOptionsLocked(ActivityOptions options) {
617         if (options != null) {
618             if (pendingOptions != null) {
619                 pendingOptions.abort();
620             }
621             pendingOptions = options;
622         }
623     }
624 
applyOptionsLocked()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 
clearOptionsLocked()669     void clearOptionsLocked() {
670         if (pendingOptions != null) {
671             pendingOptions.abort();
672             pendingOptions = null;
673         }
674     }
675 
takeOptionsLocked()676     ActivityOptions takeOptionsLocked() {
677         ActivityOptions opts = pendingOptions;
678         pendingOptions = null;
679         return opts;
680     }
681 
removeUriPermissionsLocked()682     void removeUriPermissionsLocked() {
683         if (uriPermissions != null) {
684             uriPermissions.removeUriPermissionsLocked();
685             uriPermissions = null;
686         }
687     }
688 
pauseKeyDispatchingLocked()689     void pauseKeyDispatchingLocked() {
690         if (!keysPaused) {
691             keysPaused = true;
692             service.mWindowManager.pauseKeyDispatching(appToken);
693         }
694     }
695 
resumeKeyDispatchingLocked()696     void resumeKeyDispatchingLocked() {
697         if (keysPaused) {
698             keysPaused = false;
699             service.mWindowManager.resumeKeyDispatching(appToken);
700         }
701     }
702 
updateThumbnail(Bitmap newThumbnail, CharSequence description)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 
startLaunchTickingLocked()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 
continueLaunchTickingLocked()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 
finishLaunchTickingLocked()739     void finishLaunchTickingLocked() {
740         launchTickTime = 0;
741         stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
742     }
743 
744     // IApplicationToken
745 
mayFreezeScreenLocked(ProcessRecord app)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 
startFreezingScreenLocked(ProcessRecord app, int configChanges)754     public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
755         if (mayFreezeScreenLocked(app)) {
756             service.mWindowManager.startAppFreezingScreen(appToken, configChanges);
757         }
758     }
759 
stopFreezingScreenLocked(boolean force)760     public void stopFreezingScreenLocked(boolean force) {
761         if (force || frozenBeforeDestroy) {
762             frozenBeforeDestroy = false;
763             service.mWindowManager.stopAppFreezingScreen(appToken, force);
764         }
765     }
766 
windowsDrawn()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 
windowsVisible()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 
windowsGone()843     public void windowsGone() {
844         if (ActivityManagerService.DEBUG_SWITCH) Log.v(
845                 ActivityManagerService.TAG, "windowsGone(): " + this);
846         nowVisible = false;
847     }
848 
getWaitingHistoryRecordLocked()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 
keyDispatchingTimedOut()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. */
getKeyDispatchingTimeout()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      */
isInterestingToUserLocked()891     public boolean isInterestingToUserLocked() {
892         return visible || nowVisible || state == ActivityState.PAUSING ||
893                 state == ActivityState.RESUMED;
894     }
895 
setSleeping(boolean _sleeping)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 
toString()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