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