blob: b4e426fa416ba6b962c34351d433dd63f8bccd29 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package com.android.server.am;
18
19import com.android.server.AttributeCache;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070020import com.android.server.am.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021
22import android.app.Activity;
23import android.content.ComponentName;
24import android.content.Intent;
25import android.content.pm.ActivityInfo;
26import android.content.pm.ApplicationInfo;
27import android.content.res.Configuration;
28import android.graphics.Bitmap;
29import android.os.Bundle;
30import android.os.Message;
31import android.os.Process;
Dianne Hackborn39792d22010-08-19 18:01:52 -070032import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.os.SystemClock;
34import android.util.EventLog;
35import android.util.Log;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070036import android.util.Slog;
Dianne Hackborn0dad3642010-09-09 21:25:35 -070037import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.view.IApplicationToken;
Dianne Hackborn7eec10e2010-11-12 18:03:47 -080039import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040
41import java.io.PrintWriter;
42import java.lang.ref.WeakReference;
43import java.util.ArrayList;
44import java.util.HashSet;
45
46/**
47 * An entry in the history stack, representing an activity.
48 */
Dianne Hackborn7e269642010-08-25 19:50:20 -070049class ActivityRecord extends IApplicationToken.Stub {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 final ActivityManagerService service; // owner
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070051 final ActivityStack stack; // owner
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052 final ActivityInfo info; // all about me
53 final int launchedFromUid; // always the uid who started the activity.
54 final Intent intent; // the original intent that generated us
55 final ComponentName realActivity; // the intent component, or target of an alias.
56 final String shortComponentName; // the short component name of the intent
57 final String resolvedType; // as per original caller;
58 final String packageName; // the package implementing intent's component
59 final String processName; // process where this component wants to run
60 final String taskAffinity; // as per ActivityInfo.taskAffinity
61 final boolean stateNotNeeded; // As per ActivityInfo.flags
62 final boolean fullscreen; // covers the full screen?
The Android Open Source Project4df24232009-03-05 14:34:35 -080063 final boolean componentSpecified; // did caller specifiy an explicit component?
64 final boolean isHomeActivity; // do we consider this to be a home activity?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 final String baseDir; // where activity source (resources etc) located
66 final String resDir; // where public activity source (public resources etc) located
67 final String dataDir; // where activity data should go
68 CharSequence nonLocalizedLabel; // the label information from the package mgr.
69 int labelRes; // the label information from the package mgr.
70 int icon; // resource identifier of activity's icon.
71 int theme; // resource identifier of activity's theme.
Dianne Hackborn7eec10e2010-11-12 18:03:47 -080072 int windowFlags; // custom window flags for preview window.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 TaskRecord task; // the task this is in.
Dianne Hackborn0dad3642010-09-09 21:25:35 -070074 long launchTime; // when we starting launching this activity
75 long startTime; // last time this activity was started
Amith Yamasanieaeb6632009-06-03 15:16:10 -070076 long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 Configuration configuration; // configuration activity was last running in
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070078 ActivityRecord resultTo; // who started this entry, so will get our reply
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 final String resultWho; // additional identifier for use by resultTo.
80 final int requestCode; // code given by requester (resultTo)
81 ArrayList results; // pending ActivityResult objs we have received
82 HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
83 ArrayList newIntents; // any pending new intents for single-top mode
84 HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
Dianne Hackborn7e269642010-08-25 19:50:20 -070085 UriPermissionOwner uriPermissions; // current special URI access perms.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 ProcessRecord app; // if non-null, hosting application
87 Bitmap thumbnail; // icon representation of paused screen
88 CharSequence description; // textual description of paused screen
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070089 ActivityState state; // current state we are in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 Bundle icicle; // last saved activity state
91 boolean frontOfTask; // is this the root activity of its task?
92 boolean launchFailed; // set if a launched failed, to abort on 2nd try
93 boolean haveState; // have we gotten the last activity state?
94 boolean stopped; // is activity pause finished?
Dianne Hackborn95fc68f2009-05-19 18:37:45 -070095 boolean delayedResume; // not yet resumed because of stopped app switches?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 boolean finishing; // activity in pending finish list?
97 boolean configDestroy; // need to destroy due to config change?
98 int configChangeFlags; // which config values have changed
99 boolean keysPaused; // has key dispatching been paused for it?
100 boolean inHistory; // are we in the history stack?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 int launchMode; // the launch mode activity attribute.
102 boolean visible; // does this activity's window need to be shown?
103 boolean waitingVisible; // true if waiting for a new act to become vis
104 boolean nowVisible; // is this activity's window visible?
105 boolean thumbnailNeeded;// has someone requested a thumbnail?
106 boolean idle; // has the activity gone idle?
107 boolean hasBeenLaunched;// has this activity ever been launched?
108 boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
Daniel Sandler69a48172010-06-23 16:29:36 -0400109 boolean immersive; // immersive mode (don't interrupt if possible)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700111 String stringName; // for caching of toString().
112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 void dump(PrintWriter pw, String prefix) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700114 pw.print(prefix); pw.print("packageName="); pw.print(packageName);
115 pw.print(" processName="); pw.println(processName);
116 pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
117 pw.print(" app="); pw.println(app);
118 pw.print(prefix); pw.println(intent);
119 pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
120 pw.print(" task="); pw.println(task);
121 pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700122 pw.print(prefix); pw.print("realActivity=");
123 pw.println(realActivity.flattenToShortString());
124 pw.print(prefix); pw.print("base="); pw.print(baseDir);
125 if (!resDir.equals(baseDir)) pw.print(" res="); pw.print(resDir);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700126 pw.print(" data="); pw.println(dataDir);
127 pw.print(prefix); pw.print("labelRes=0x");
128 pw.print(Integer.toHexString(labelRes));
129 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
130 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
131 pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
132 pw.print(" componentSpecified="); pw.print(componentSpecified);
133 pw.print(" isHomeActivity="); pw.println(isHomeActivity);
134 pw.print(prefix); pw.print("configuration="); pw.println(configuration);
135 if (resultTo != null || resultWho != null) {
136 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
137 pw.print(" resultWho="); pw.print(resultWho);
138 pw.print(" resultCode="); pw.println(requestCode);
139 }
140 if (results != null) {
141 pw.print(prefix); pw.print("results="); pw.println(results);
142 }
143 if (pendingResults != null) {
144 pw.print(prefix); pw.print("pendingResults="); pw.println(pendingResults);
145 }
Dianne Hackborn7e269642010-08-25 19:50:20 -0700146 if (uriPermissions != null) {
147 if (uriPermissions.readUriPermissions != null) {
148 pw.print(prefix); pw.print("readUriPermissions=");
149 pw.println(uriPermissions.readUriPermissions);
150 }
151 if (uriPermissions.writeUriPermissions != null) {
152 pw.print(prefix); pw.print("writeUriPermissions=");
153 pw.println(uriPermissions.writeUriPermissions);
154 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700155 }
156 pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
157 pw.print(" haveState="); pw.print(haveState);
158 pw.print(" icicle="); pw.println(icicle);
159 pw.print(prefix); pw.print("state="); pw.print(state);
160 pw.print(" stopped="); pw.print(stopped);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700161 pw.print(" delayedResume="); pw.print(delayedResume);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700162 pw.print(" finishing="); pw.println(finishing);
163 pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
164 pw.print(" inHistory="); pw.print(inHistory);
Daniel Sandler69a48172010-06-23 16:29:36 -0400165 pw.print(" immersive="); pw.print(immersive);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700166 pw.print(" launchMode="); pw.println(launchMode);
167 pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
168 pw.print(" visible="); pw.print(visible);
169 pw.print(" frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
170 pw.print(" thumbnailNeeded="); pw.print(thumbnailNeeded);
171 pw.print(" idle="); pw.println(idle);
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700172 if (launchTime != 0 || startTime != 0) {
173 pw.print(prefix); pw.print("launchTime=");
174 TimeUtils.formatDuration(launchTime, pw); pw.print(" startTime=");
175 TimeUtils.formatDuration(startTime, pw); pw.println("");
176 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700177 if (waitingVisible || nowVisible) {
178 pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
179 pw.print(" nowVisible="); pw.println(nowVisible);
180 }
181 if (configDestroy || configChangeFlags != 0) {
182 pw.print(prefix); pw.print("configDestroy="); pw.print(configDestroy);
183 pw.print(" configChangeFlags=");
184 pw.println(Integer.toHexString(configChangeFlags));
185 }
186 if (connections != null) {
187 pw.print(prefix); pw.print("connections="); pw.println(connections);
188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 }
190
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700191 ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 int _launchedFromUid, Intent _intent, String _resolvedType,
193 ActivityInfo aInfo, Configuration _configuration,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700194 ActivityRecord _resultTo, String _resultWho, int _reqCode,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800195 boolean _componentSpecified) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 service = _service;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700197 stack = _stack;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 info = aInfo;
199 launchedFromUid = _launchedFromUid;
200 intent = _intent;
201 shortComponentName = _intent.getComponent().flattenToShortString();
202 resolvedType = _resolvedType;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800203 componentSpecified = _componentSpecified;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 configuration = _configuration;
205 resultTo = _resultTo;
206 resultWho = _resultWho;
207 requestCode = _reqCode;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700208 state = ActivityState.INITIALIZING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 frontOfTask = false;
210 launchFailed = false;
211 haveState = false;
212 stopped = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700213 delayedResume = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 finishing = false;
215 configDestroy = false;
216 keysPaused = false;
217 inHistory = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 visible = true;
219 waitingVisible = false;
220 nowVisible = false;
221 thumbnailNeeded = false;
222 idle = false;
223 hasBeenLaunched = false;
224
225 if (aInfo != null) {
226 if (aInfo.targetActivity == null
227 || aInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE
228 || aInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
229 realActivity = _intent.getComponent();
230 } else {
231 realActivity = new ComponentName(aInfo.packageName,
232 aInfo.targetActivity);
233 }
234 taskAffinity = aInfo.taskAffinity;
235 stateNotNeeded = (aInfo.flags&
236 ActivityInfo.FLAG_STATE_NOT_NEEDED) != 0;
237 baseDir = aInfo.applicationInfo.sourceDir;
238 resDir = aInfo.applicationInfo.publicSourceDir;
239 dataDir = aInfo.applicationInfo.dataDir;
240 nonLocalizedLabel = aInfo.nonLocalizedLabel;
241 labelRes = aInfo.labelRes;
242 if (nonLocalizedLabel == null && labelRes == 0) {
243 ApplicationInfo app = aInfo.applicationInfo;
244 nonLocalizedLabel = app.nonLocalizedLabel;
245 labelRes = app.labelRes;
246 }
247 icon = aInfo.getIconResource();
248 theme = aInfo.getThemeResource();
Dianne Hackborn7eec10e2010-11-12 18:03:47 -0800249 if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
250 windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
253 && _caller != null
254 && (aInfo.applicationInfo.uid == Process.SYSTEM_UID
255 || aInfo.applicationInfo.uid == _caller.info.uid)) {
256 processName = _caller.processName;
257 } else {
258 processName = aInfo.processName;
259 }
260
261 if (intent != null && (aInfo.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0) {
262 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
263 }
264
265 packageName = aInfo.applicationInfo.packageName;
266 launchMode = aInfo.launchMode;
267
268 AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
269 theme != 0 ? theme : android.R.style.Theme,
270 com.android.internal.R.styleable.Window);
271 fullscreen = ent != null && !ent.array.getBoolean(
272 com.android.internal.R.styleable.Window_windowIsFloating, false)
273 && !ent.array.getBoolean(
274 com.android.internal.R.styleable.Window_windowIsTranslucent, false);
275
The Android Open Source Project4df24232009-03-05 14:34:35 -0800276 if (!_componentSpecified || _launchedFromUid == Process.myUid()
277 || _launchedFromUid == 0) {
278 // If we know the system has determined the component, then
279 // we can consider this to be a home activity...
280 if (Intent.ACTION_MAIN.equals(_intent.getAction()) &&
281 _intent.hasCategory(Intent.CATEGORY_HOME) &&
282 _intent.getCategories().size() == 1 &&
283 _intent.getData() == null &&
284 _intent.getType() == null &&
285 (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
286 !"android".equals(realActivity.getClassName())) {
287 // This sure looks like a home activity!
288 // Note the last check is so we don't count the resolver
289 // activity as being home... really, we don't care about
290 // doing anything special with something that comes from
291 // the core framework package.
292 isHomeActivity = true;
293 } else {
294 isHomeActivity = false;
295 }
296 } else {
297 isHomeActivity = false;
298 }
Daniel Sandler69a48172010-06-23 16:29:36 -0400299
300 immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 } else {
302 realActivity = null;
303 taskAffinity = null;
304 stateNotNeeded = false;
305 baseDir = null;
306 resDir = null;
307 dataDir = null;
308 processName = null;
309 packageName = null;
310 fullscreen = true;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800311 isHomeActivity = false;
Daniel Sandler69a48172010-06-23 16:29:36 -0400312 immersive = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 }
314 }
315
Dianne Hackborn7e269642010-08-25 19:50:20 -0700316 UriPermissionOwner getUriPermissionsLocked() {
317 if (uriPermissions == null) {
318 uriPermissions = new UriPermissionOwner(service, this);
319 }
320 return uriPermissions;
321 }
322
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700323 void addResultLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 int requestCode, int resultCode,
325 Intent resultData) {
326 ActivityResult r = new ActivityResult(from, resultWho,
327 requestCode, resultCode, resultData);
328 if (results == null) {
329 results = new ArrayList();
330 }
331 results.add(r);
332 }
333
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700334 void removeResultsLocked(ActivityRecord from, String resultWho,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 int requestCode) {
336 if (results != null) {
337 for (int i=results.size()-1; i>=0; i--) {
338 ActivityResult r = (ActivityResult)results.get(i);
339 if (r.mFrom != from) continue;
340 if (r.mResultWho == null) {
341 if (resultWho != null) continue;
342 } else {
343 if (!r.mResultWho.equals(resultWho)) continue;
344 }
345 if (r.mRequestCode != requestCode) continue;
346
347 results.remove(i);
348 }
349 }
350 }
351
352 void addNewIntentLocked(Intent intent) {
353 if (newIntents == null) {
354 newIntents = new ArrayList();
355 }
356 newIntents.add(intent);
357 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700358
359 /**
360 * Deliver a new Intent to an existing activity, so that its onNewIntent()
361 * method will be called at the proper time.
362 */
Dianne Hackborn39792d22010-08-19 18:01:52 -0700363 final void deliverNewIntentLocked(int callingUid, Intent intent) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700364 boolean sent = false;
365 if (state == ActivityState.RESUMED
366 && app != null && app.thread != null) {
367 try {
368 ArrayList<Intent> ar = new ArrayList<Intent>();
Dianne Hackborn39792d22010-08-19 18:01:52 -0700369 intent = new Intent(intent);
370 ar.add(intent);
371 service.grantUriPermissionFromIntentLocked(callingUid, packageName,
Dianne Hackborn7e269642010-08-25 19:50:20 -0700372 intent, getUriPermissionsLocked());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700373 app.thread.scheduleNewIntent(ar, this);
374 sent = true;
Dianne Hackborn39792d22010-08-19 18:01:52 -0700375 } catch (RemoteException e) {
376 Slog.w(ActivityManagerService.TAG,
377 "Exception thrown sending new intent to " + this, e);
378 } catch (NullPointerException e) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700379 Slog.w(ActivityManagerService.TAG,
380 "Exception thrown sending new intent to " + this, e);
381 }
382 }
383 if (!sent) {
384 addNewIntentLocked(new Intent(intent));
385 }
386 }
387
388 void removeUriPermissionsLocked() {
Dianne Hackborn7e269642010-08-25 19:50:20 -0700389 if (uriPermissions != null) {
390 uriPermissions.removeUriPermissionsLocked();
391 uriPermissions = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700392 }
393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394
395 void pauseKeyDispatchingLocked() {
396 if (!keysPaused) {
397 keysPaused = true;
398 service.mWindowManager.pauseKeyDispatching(this);
399 }
400 }
401
402 void resumeKeyDispatchingLocked() {
403 if (keysPaused) {
404 keysPaused = false;
405 service.mWindowManager.resumeKeyDispatching(this);
406 }
407 }
408
409 // IApplicationToken
410
411 public boolean mayFreezeScreenLocked(ProcessRecord app) {
412 // Only freeze the screen if this activity is currently attached to
413 // an application, and that application is not blocked or unresponding.
414 // In any other case, we can't count on getting the screen unfrozen,
415 // so it is best to leave as-is.
416 return app == null || (!app.crashing && !app.notResponding);
417 }
418
419 public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
420 if (mayFreezeScreenLocked(app)) {
421 service.mWindowManager.startAppFreezingScreen(this, configChanges);
422 }
423 }
424
425 public void stopFreezingScreenLocked(boolean force) {
426 if (force || frozenBeforeDestroy) {
427 frozenBeforeDestroy = false;
428 service.mWindowManager.stopAppFreezingScreen(this, force);
429 }
430 }
431
432 public void windowsVisible() {
433 synchronized(service) {
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700434 if (launchTime != 0) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700435 final long curTime = SystemClock.uptimeMillis();
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700436 final long thisTime = curTime - launchTime;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700437 final long totalTime = stack.mInitialStartTime != 0
438 ? (curTime - stack.mInitialStartTime) : thisTime;
Dianne Hackborn6447ca32009-04-07 19:50:08 -0700439 if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
Doug Zongker2bec3d42009-12-04 12:52:44 -0800440 EventLog.writeEvent(EventLogTags.ACTIVITY_LAUNCH_TIME,
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700441 System.identityHashCode(this), shortComponentName,
442 thisTime, totalTime);
443 StringBuilder sb = service.mStringBuilder;
444 sb.setLength(0);
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700445 sb.append("Displayed ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700446 sb.append(shortComponentName);
447 sb.append(": ");
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700448 TimeUtils.formatDuration(thisTime, sb);
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700449 if (thisTime != totalTime) {
450 sb.append(" (total ");
451 TimeUtils.formatDuration(totalTime, sb);
452 sb.append(")");
453 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700454 Log.i(ActivityManagerService.TAG, sb.toString());
Dianne Hackborn6447ca32009-04-07 19:50:08 -0700455 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700456 stack.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700457 if (totalTime > 0) {
458 service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
Dianne Hackborn6447ca32009-04-07 19:50:08 -0700459 }
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700460 launchTime = 0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700461 stack.mInitialStartTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 }
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700463 startTime = 0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700464 stack.reportActivityVisibleLocked(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 if (ActivityManagerService.DEBUG_SWITCH) Log.v(
466 ActivityManagerService.TAG, "windowsVisible(): " + this);
467 if (!nowVisible) {
468 nowVisible = true;
469 if (!idle) {
470 // Instead of doing the full stop routine here, let's just
471 // hide any activities we now can, and let them stop when
472 // the normal idle happens.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700473 stack.processStoppingActivitiesLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 } else {
475 // If this activity was already idle, then we now need to
476 // make sure we perform the full stop of any activities
477 // that are waiting to do so. This is because we won't
478 // do that while they are still waiting for this one to
479 // become visible.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700480 final int N = stack.mWaitingVisibleActivities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 if (N > 0) {
482 for (int i=0; i<N; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700483 ActivityRecord r = (ActivityRecord)
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700484 stack.mWaitingVisibleActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 r.waitingVisible = false;
486 if (ActivityManagerService.DEBUG_SWITCH) Log.v(
487 ActivityManagerService.TAG,
488 "Was waiting for visible: " + r);
489 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700490 stack.mWaitingVisibleActivities.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 Message msg = Message.obtain();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700492 msg.what = ActivityStack.IDLE_NOW_MSG;
493 stack.mHandler.sendMessage(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 }
495 }
496 service.scheduleAppGcsLocked();
497 }
498 }
499 }
500
501 public void windowsGone() {
502 if (ActivityManagerService.DEBUG_SWITCH) Log.v(
503 ActivityManagerService.TAG, "windowsGone(): " + this);
504 nowVisible = false;
505 }
506
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700507 private ActivityRecord getWaitingHistoryRecordLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 // First find the real culprit... if we are waiting
509 // for another app to start, then we have paused dispatching
510 // for this activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700511 ActivityRecord r = this;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 if (r.waitingVisible) {
513 // Hmmm, who might we be waiting for?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700514 r = stack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700516 r = stack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 }
518 // Both of those null? Fall back to 'this' again
519 if (r == null) {
520 r = this;
521 }
522 }
523
524 return r;
525 }
526
527 public boolean keyDispatchingTimedOut() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700528 ActivityRecord r;
Dianne Hackbornad5499d2010-03-29 18:08:45 -0700529 ProcessRecord anrApp = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 synchronized(service) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -0700531 r = getWaitingHistoryRecordLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 if (r != null && r.app != null) {
533 if (r.app.debugging) {
534 return false;
535 }
536
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700537 if (service.mDidDexOpt) {
538 // Give more time since we were dexopting.
539 service.mDidDexOpt = false;
540 return false;
541 }
542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 if (r.app.instrumentationClass == null) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -0700544 anrApp = r.app;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 } else {
546 Bundle info = new Bundle();
547 info.putString("shortMsg", "keyDispatchingTimedOut");
548 info.putString("longMsg", "Timed out while dispatching key event");
549 service.finishInstrumentationLocked(
550 r.app, Activity.RESULT_CANCELED, info);
551 }
552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -0700554
555 if (anrApp != null) {
556 service.appNotResponding(anrApp, r, this,
557 "keyDispatchingTimedOut");
558 }
559
560 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 }
562
563 /** Returns the key dispatching timeout for this application token. */
564 public long getKeyDispatchingTimeout() {
565 synchronized(service) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700566 ActivityRecord r = getWaitingHistoryRecordLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 if (r == null || r.app == null
568 || r.app.instrumentationClass == null) {
569 return ActivityManagerService.KEY_DISPATCHING_TIMEOUT;
570 }
571
572 return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
573 }
574 }
575
576 /**
577 * This method will return true if the activity is either visible, is becoming visible, is
578 * currently pausing, or is resumed.
579 */
580 public boolean isInterestingToUserLocked() {
581 return visible || nowVisible || state == ActivityState.PAUSING ||
582 state == ActivityState.RESUMED;
583 }
584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 public String toString() {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700586 if (stringName != null) {
587 return stringName;
588 }
589 StringBuilder sb = new StringBuilder(128);
Dianne Hackborn30d71892010-12-11 10:37:55 -0800590 sb.append("ActivityRecord{");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700591 sb.append(Integer.toHexString(System.identityHashCode(this)));
592 sb.append(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700593 sb.append(intent.getComponent().flattenToShortString());
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700594 sb.append('}');
595 return stringName = sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
597}