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