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