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 android.app; 18 19 import android.app.backup.BackupAgent; 20 import android.content.BroadcastReceiver; 21 import android.content.ComponentCallbacks2; 22 import android.content.ComponentName; 23 import android.content.ContentProvider; 24 import android.content.Context; 25 import android.content.IContentProvider; 26 import android.content.Intent; 27 import android.content.IIntentReceiver; 28 import android.content.pm.ActivityInfo; 29 import android.content.pm.ApplicationInfo; 30 import android.content.pm.IPackageManager; 31 import android.content.pm.InstrumentationInfo; 32 import android.content.pm.PackageInfo; 33 import android.content.pm.PackageManager; 34 import android.content.pm.PackageManager.NameNotFoundException; 35 import android.content.pm.ProviderInfo; 36 import android.content.pm.ServiceInfo; 37 import android.content.res.AssetManager; 38 import android.content.res.CompatibilityInfo; 39 import android.content.res.Configuration; 40 import android.content.res.Resources; 41 import android.database.sqlite.SQLiteDatabase; 42 import android.database.sqlite.SQLiteDebug; 43 import android.database.sqlite.SQLiteDebug.DbStats; 44 import android.graphics.Bitmap; 45 import android.graphics.Canvas; 46 import android.hardware.display.DisplayManagerGlobal; 47 import android.net.IConnectivityManager; 48 import android.net.Proxy; 49 import android.net.ProxyProperties; 50 import android.opengl.GLUtils; 51 import android.os.AsyncTask; 52 import android.os.Binder; 53 import android.os.Bundle; 54 import android.os.Debug; 55 import android.os.DropBoxManager; 56 import android.os.Environment; 57 import android.os.Handler; 58 import android.os.IBinder; 59 import android.os.Looper; 60 import android.os.Message; 61 import android.os.MessageQueue; 62 import android.os.ParcelFileDescriptor; 63 import android.os.Process; 64 import android.os.RemoteException; 65 import android.os.ServiceManager; 66 import android.os.StrictMode; 67 import android.os.SystemClock; 68 import android.os.SystemProperties; 69 import android.os.Trace; 70 import android.os.UserHandle; 71 import android.util.AndroidRuntimeException; 72 import android.util.ArrayMap; 73 import android.util.DisplayMetrics; 74 import android.util.EventLog; 75 import android.util.Log; 76 import android.util.LogPrinter; 77 import android.util.PrintWriterPrinter; 78 import android.util.Slog; 79 import android.util.SuperNotCalledException; 80 import android.view.Display; 81 import android.view.HardwareRenderer; 82 import android.view.View; 83 import android.view.ViewDebug; 84 import android.view.ViewManager; 85 import android.view.ViewRootImpl; 86 import android.view.Window; 87 import android.view.WindowManager; 88 import android.view.WindowManagerGlobal; 89 import android.renderscript.RenderScript; 90 import android.security.AndroidKeyStoreProvider; 91 92 import com.android.internal.os.BinderInternal; 93 import com.android.internal.os.RuntimeInit; 94 import com.android.internal.os.SamplingProfilerIntegration; 95 import com.android.internal.util.FastPrintWriter; 96 import com.android.internal.util.Objects; 97 import com.android.org.conscrypt.OpenSSLSocketImpl; 98 import com.google.android.collect.Lists; 99 100 import java.io.File; 101 import java.io.FileDescriptor; 102 import java.io.FileOutputStream; 103 import java.io.IOException; 104 import java.io.PrintWriter; 105 import java.lang.ref.WeakReference; 106 import java.net.InetAddress; 107 import java.security.Security; 108 import java.util.ArrayList; 109 import java.util.List; 110 import java.util.Locale; 111 import java.util.Map; 112 import java.util.TimeZone; 113 import java.util.regex.Pattern; 114 115 import libcore.io.DropBox; 116 import libcore.io.EventLogger; 117 import libcore.io.IoUtils; 118 119 import dalvik.system.CloseGuard; 120 121 final class RemoteServiceException extends AndroidRuntimeException { 122 public RemoteServiceException(String msg) { 123 super(msg); 124 } 125 } 126 127 /** 128 * This manages the execution of the main thread in an 129 * application process, scheduling and executing activities, 130 * broadcasts, and other operations on it as the activity 131 * manager requests. 132 * 133 * {@hide} 134 */ 135 public final class ActivityThread { 136 /** @hide */ 137 public static final String TAG = "ActivityThread"; 138 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565; 139 static final boolean localLOGV = false; 140 static final boolean DEBUG_MESSAGES = false; 141 /** @hide */ 142 public static final boolean DEBUG_BROADCAST = false; 143 private static final boolean DEBUG_RESULTS = false; 144 private static final boolean DEBUG_BACKUP = false; 145 public static final boolean DEBUG_CONFIGURATION = false; 146 private static final boolean DEBUG_SERVICE = false; 147 private static final boolean DEBUG_MEMORY_TRIM = false; 148 private static final boolean DEBUG_PROVIDER = false; 149 private static final long MIN_TIME_BETWEEN_GCS = 5*1000; 150 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";"); 151 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; 152 private static final int LOG_ON_PAUSE_CALLED = 30021; 153 private static final int LOG_ON_RESUME_CALLED = 30022; 154 155 private ContextImpl mSystemContext; 156 157 static IPackageManager sPackageManager; 158 159 final ApplicationThread mAppThread = new ApplicationThread(); 160 final Looper mLooper = Looper.myLooper(); 161 final H mH = new H(); 162 final ArrayMap<IBinder, ActivityClientRecord> mActivities 163 = new ArrayMap<IBinder, ActivityClientRecord>(); 164 // List of new activities (via ActivityRecord.nextIdle) that should 165 // be reported when next we idle. 166 ActivityClientRecord mNewActivities = null; 167 // Number of activities that are currently visible on-screen. 168 int mNumVisibleActivities = 0; 169 final ArrayMap<IBinder, Service> mServices 170 = new ArrayMap<IBinder, Service>(); 171 AppBindData mBoundApplication; 172 Profiler mProfiler; 173 int mCurDefaultDisplayDpi; 174 boolean mDensityCompatMode; 175 Configuration mConfiguration; 176 Configuration mCompatConfiguration; 177 Application mInitialApplication; 178 final ArrayList<Application> mAllApplications 179 = new ArrayList<Application>(); 180 // set of instantiated backup agents, keyed by package name 181 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>(); 182 /** Reference to singleton {@link ActivityThread} */ 183 private static ActivityThread sCurrentActivityThread; 184 Instrumentation mInstrumentation; 185 String mInstrumentationAppDir = null; 186 String mInstrumentationAppLibraryDir = null; 187 String mInstrumentationAppPackage = null; 188 String mInstrumentedAppDir = null; 189 String mInstrumentedAppLibraryDir = null; 190 boolean mSystemThread = false; 191 boolean mJitEnabled = false; 192 193 // These can be accessed by multiple threads; mPackages is the lock. 194 // XXX For now we keep around information about all packages we have 195 // seen, not removing entries from this map. 196 // NOTE: The activity and window managers need to call in to 197 // ActivityThread to do things like update resource configurations, 198 // which means this lock gets held while the activity and window managers 199 // holds their own lock. Thus you MUST NEVER call back into the activity manager 200 // or window manager or anything that depends on them while holding this lock. 201 final ArrayMap<String, WeakReference<LoadedApk>> mPackages 202 = new ArrayMap<String, WeakReference<LoadedApk>>(); 203 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages 204 = new ArrayMap<String, WeakReference<LoadedApk>>(); 205 final ArrayList<ActivityClientRecord> mRelaunchingActivities 206 = new ArrayList<ActivityClientRecord>(); 207 Configuration mPendingConfiguration = null; 208 209 private final ResourcesManager mResourcesManager; 210 211 private static final class ProviderKey { 212 final String authority; 213 final int userId; 214 215 public ProviderKey(String authority, int userId) { 216 this.authority = authority; 217 this.userId = userId; 218 } 219 220 @Override 221 public boolean equals(Object o) { 222 if (o instanceof ProviderKey) { 223 final ProviderKey other = (ProviderKey) o; 224 return Objects.equal(authority, other.authority) && userId == other.userId; 225 } 226 return false; 227 } 228 229 @Override 230 public int hashCode() { 231 return ((authority != null) ? authority.hashCode() : 0) ^ userId; 232 } 233 } 234 235 // The lock of mProviderMap protects the following variables. 236 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap 237 = new ArrayMap<ProviderKey, ProviderClientRecord>(); 238 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap 239 = new ArrayMap<IBinder, ProviderRefCount>(); 240 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders 241 = new ArrayMap<IBinder, ProviderClientRecord>(); 242 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName 243 = new ArrayMap<ComponentName, ProviderClientRecord>(); 244 245 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners 246 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); 247 248 final GcIdler mGcIdler = new GcIdler(); 249 boolean mGcIdlerScheduled = false; 250 251 static Handler sMainThreadHandler; // set once in main() 252 253 Bundle mCoreSettings = null; 254 255 static final class ActivityClientRecord { 256 IBinder token; 257 int ident; 258 Intent intent; 259 Bundle state; 260 Activity activity; 261 Window window; 262 Activity parent; 263 String embeddedID; 264 Activity.NonConfigurationInstances lastNonConfigurationInstances; 265 boolean paused; 266 boolean stopped; 267 boolean hideForNow; 268 Configuration newConfig; 269 Configuration createdConfig; 270 ActivityClientRecord nextIdle; 271 272 String profileFile; 273 ParcelFileDescriptor profileFd; 274 boolean autoStopProfiler; 275 276 ActivityInfo activityInfo; 277 CompatibilityInfo compatInfo; 278 LoadedApk packageInfo; 279 280 List<ResultInfo> pendingResults; 281 List<Intent> pendingIntents; 282 283 boolean startsNotResumed; 284 boolean isForward; 285 int pendingConfigChanges; 286 boolean onlyLocalRequest; 287 288 View mPendingRemoveWindow; 289 WindowManager mPendingRemoveWindowManager; 290 291 ActivityClientRecord() { 292 parent = null; 293 embeddedID = null; 294 paused = false; 295 stopped = false; 296 hideForNow = false; 297 nextIdle = null; 298 } 299 300 public boolean isPreHoneycomb() { 301 if (activity != null) { 302 return activity.getApplicationInfo().targetSdkVersion 303 < android.os.Build.VERSION_CODES.HONEYCOMB; 304 } 305 return false; 306 } 307 308 public String toString() { 309 ComponentName componentName = intent != null ? intent.getComponent() : null; 310 return "ActivityRecord{" 311 + Integer.toHexString(System.identityHashCode(this)) 312 + " token=" + token + " " + (componentName == null 313 ? "no component name" : componentName.toShortString()) 314 + "}"; 315 } 316 } 317 318 final class ProviderClientRecord { 319 final String[] mNames; 320 final IContentProvider mProvider; 321 final ContentProvider mLocalProvider; 322 final IActivityManager.ContentProviderHolder mHolder; 323 324 ProviderClientRecord(String[] names, IContentProvider provider, 325 ContentProvider localProvider, 326 IActivityManager.ContentProviderHolder holder) { 327 mNames = names; 328 mProvider = provider; 329 mLocalProvider = localProvider; 330 mHolder = holder; 331 } 332 } 333 334 static final class NewIntentData { 335 List<Intent> intents; 336 IBinder token; 337 public String toString() { 338 return "NewIntentData{intents=" + intents + " token=" + token + "}"; 339 } 340 } 341 342 static final class ReceiverData extends BroadcastReceiver.PendingResult { 343 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras, 344 boolean ordered, boolean sticky, IBinder token, int sendingUser) { 345 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, 346 token, sendingUser); 347 this.intent = intent; 348 } 349 350 Intent intent; 351 ActivityInfo info; 352 CompatibilityInfo compatInfo; 353 public String toString() { 354 return "ReceiverData{intent=" + intent + " packageName=" + 355 info.packageName + " resultCode=" + getResultCode() 356 + " resultData=" + getResultData() + " resultExtras=" 357 + getResultExtras(false) + "}"; 358 } 359 } 360 361 static final class CreateBackupAgentData { 362 ApplicationInfo appInfo; 363 CompatibilityInfo compatInfo; 364 int backupMode; 365 public String toString() { 366 return "CreateBackupAgentData{appInfo=" + appInfo 367 + " backupAgent=" + appInfo.backupAgentName 368 + " mode=" + backupMode + "}"; 369 } 370 } 371 372 static final class CreateServiceData { 373 IBinder token; 374 ServiceInfo info; 375 CompatibilityInfo compatInfo; 376 Intent intent; 377 public String toString() { 378 return "CreateServiceData{token=" + token + " className=" 379 + info.name + " packageName=" + info.packageName 380 + " intent=" + intent + "}"; 381 } 382 } 383 384 static final class BindServiceData { 385 IBinder token; 386 Intent intent; 387 boolean rebind; 388 public String toString() { 389 return "BindServiceData{token=" + token + " intent=" + intent + "}"; 390 } 391 } 392 393 static final class ServiceArgsData { 394 IBinder token; 395 boolean taskRemoved; 396 int startId; 397 int flags; 398 Intent args; 399 public String toString() { 400 return "ServiceArgsData{token=" + token + " startId=" + startId 401 + " args=" + args + "}"; 402 } 403 } 404 405 static final class AppBindData { 406 LoadedApk info; 407 String processName; 408 ApplicationInfo appInfo; 409 List<ProviderInfo> providers; 410 ComponentName instrumentationName; 411 Bundle instrumentationArgs; 412 IInstrumentationWatcher instrumentationWatcher; 413 IUiAutomationConnection instrumentationUiAutomationConnection; 414 int debugMode; 415 boolean enableOpenGlTrace; 416 boolean restrictedBackupMode; 417 boolean persistent; 418 Configuration config; 419 CompatibilityInfo compatInfo; 420 421 /** Initial values for {@link Profiler}. */ 422 String initProfileFile; 423 ParcelFileDescriptor initProfileFd; 424 boolean initAutoStopProfiler; 425 426 public String toString() { 427 return "AppBindData{appInfo=" + appInfo + "}"; 428 } 429 } 430 431 static final class Profiler { 432 String profileFile; 433 ParcelFileDescriptor profileFd; 434 boolean autoStopProfiler; 435 boolean profiling; 436 boolean handlingProfiling; 437 public void setProfiler(String file, ParcelFileDescriptor fd) { 438 if (profiling) { 439 if (fd != null) { 440 try { 441 fd.close(); 442 } catch (IOException e) { 443 // Ignore 444 } 445 } 446 return; 447 } 448 if (profileFd != null) { 449 try { 450 profileFd.close(); 451 } catch (IOException e) { 452 // Ignore 453 } 454 } 455 profileFile = file; 456 profileFd = fd; 457 } 458 public void startProfiling() { 459 if (profileFd == null || profiling) { 460 return; 461 } 462 try { 463 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(), 464 8 * 1024 * 1024, 0); 465 profiling = true; 466 } catch (RuntimeException e) { 467 Slog.w(TAG, "Profiling failed on path " + profileFile); 468 try { 469 profileFd.close(); 470 profileFd = null; 471 } catch (IOException e2) { 472 Slog.w(TAG, "Failure closing profile fd", e2); 473 } 474 } 475 } 476 public void stopProfiling() { 477 if (profiling) { 478 profiling = false; 479 Debug.stopMethodTracing(); 480 if (profileFd != null) { 481 try { 482 profileFd.close(); 483 } catch (IOException e) { 484 } 485 } 486 profileFd = null; 487 profileFile = null; 488 } 489 } 490 } 491 492 static final class DumpComponentInfo { 493 ParcelFileDescriptor fd; 494 IBinder token; 495 String prefix; 496 String[] args; 497 } 498 499 static final class ResultData { 500 IBinder token; 501 List<ResultInfo> results; 502 public String toString() { 503 return "ResultData{token=" + token + " results" + results + "}"; 504 } 505 } 506 507 static final class ContextCleanupInfo { 508 ContextImpl context; 509 String what; 510 String who; 511 } 512 513 static final class ProfilerControlData { 514 String path; 515 ParcelFileDescriptor fd; 516 } 517 518 static final class DumpHeapData { 519 String path; 520 ParcelFileDescriptor fd; 521 } 522 523 static final class UpdateCompatibilityData { 524 String pkg; 525 CompatibilityInfo info; 526 } 527 528 static final class RequestAssistContextExtras { 529 IBinder activityToken; 530 IBinder requestToken; 531 int requestType; 532 } 533 534 private native void dumpGraphicsInfo(FileDescriptor fd); 535 536 private class ApplicationThread extends ApplicationThreadNative { 537 private static final String ONE_COUNT_COLUMN = "%21s %8d"; 538 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d"; 539 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; 540 541 private int mLastProcessState = -1; 542 543 private void updatePendingConfiguration(Configuration config) { 544 synchronized (mResourcesManager) { 545 if (mPendingConfiguration == null || 546 mPendingConfiguration.isOtherSeqNewer(config)) { 547 mPendingConfiguration = config; 548 } 549 } 550 } 551 552 public final void schedulePauseActivity(IBinder token, boolean finished, 553 boolean userLeaving, int configChanges) { 554 sendMessage( 555 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, 556 token, 557 (userLeaving ? 1 : 0), 558 configChanges); 559 } 560 561 public final void scheduleStopActivity(IBinder token, boolean showWindow, 562 int configChanges) { 563 sendMessage( 564 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, 565 token, 0, configChanges); 566 } 567 568 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) { 569 sendMessage( 570 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW, 571 token); 572 } 573 574 public final void scheduleSleeping(IBinder token, boolean sleeping) { 575 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); 576 } 577 578 public final void scheduleResumeActivity(IBinder token, int processState, 579 boolean isForward) { 580 updateProcessState(processState, false); 581 sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0); 582 } 583 584 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) { 585 ResultData res = new ResultData(); 586 res.token = token; 587 res.results = results; 588 sendMessage(H.SEND_RESULT, res); 589 } 590 591 // we use token to identify this activity without having to send the 592 // activity itself back to the activity manager. (matters more with ipc) 593 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 594 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, 595 int procState, Bundle state, List<ResultInfo> pendingResults, 596 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, 597 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 598 599 updateProcessState(procState, false); 600 601 ActivityClientRecord r = new ActivityClientRecord(); 602 603 r.token = token; 604 r.ident = ident; 605 r.intent = intent; 606 r.activityInfo = info; 607 r.compatInfo = compatInfo; 608 r.state = state; 609 610 r.pendingResults = pendingResults; 611 r.pendingIntents = pendingNewIntents; 612 613 r.startsNotResumed = notResumed; 614 r.isForward = isForward; 615 616 r.profileFile = profileName; 617 r.profileFd = profileFd; 618 r.autoStopProfiler = autoStopProfiler; 619 620 updatePendingConfiguration(curConfig); 621 622 sendMessage(H.LAUNCH_ACTIVITY, r); 623 } 624 625 public final void scheduleRelaunchActivity(IBinder token, 626 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 627 int configChanges, boolean notResumed, Configuration config) { 628 requestRelaunchActivity(token, pendingResults, pendingNewIntents, 629 configChanges, notResumed, config, true); 630 } 631 632 public final void scheduleNewIntent(List<Intent> intents, IBinder token) { 633 NewIntentData data = new NewIntentData(); 634 data.intents = intents; 635 data.token = token; 636 637 sendMessage(H.NEW_INTENT, data); 638 } 639 640 public final void scheduleDestroyActivity(IBinder token, boolean finishing, 641 int configChanges) { 642 sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0, 643 configChanges); 644 } 645 646 public final void scheduleReceiver(Intent intent, ActivityInfo info, 647 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, 648 boolean sync, int sendingUser, int processState) { 649 updateProcessState(processState, false); 650 ReceiverData r = new ReceiverData(intent, resultCode, data, extras, 651 sync, false, mAppThread.asBinder(), sendingUser); 652 r.info = info; 653 r.compatInfo = compatInfo; 654 sendMessage(H.RECEIVER, r); 655 } 656 657 public final void scheduleCreateBackupAgent(ApplicationInfo app, 658 CompatibilityInfo compatInfo, int backupMode) { 659 CreateBackupAgentData d = new CreateBackupAgentData(); 660 d.appInfo = app; 661 d.compatInfo = compatInfo; 662 d.backupMode = backupMode; 663 664 sendMessage(H.CREATE_BACKUP_AGENT, d); 665 } 666 667 public final void scheduleDestroyBackupAgent(ApplicationInfo app, 668 CompatibilityInfo compatInfo) { 669 CreateBackupAgentData d = new CreateBackupAgentData(); 670 d.appInfo = app; 671 d.compatInfo = compatInfo; 672 673 sendMessage(H.DESTROY_BACKUP_AGENT, d); 674 } 675 676 public final void scheduleCreateService(IBinder token, 677 ServiceInfo info, CompatibilityInfo compatInfo, int processState) { 678 updateProcessState(processState, false); 679 CreateServiceData s = new CreateServiceData(); 680 s.token = token; 681 s.info = info; 682 s.compatInfo = compatInfo; 683 684 sendMessage(H.CREATE_SERVICE, s); 685 } 686 687 public final void scheduleBindService(IBinder token, Intent intent, 688 boolean rebind, int processState) { 689 updateProcessState(processState, false); 690 BindServiceData s = new BindServiceData(); 691 s.token = token; 692 s.intent = intent; 693 s.rebind = rebind; 694 695 if (DEBUG_SERVICE) 696 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" 697 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); 698 sendMessage(H.BIND_SERVICE, s); 699 } 700 701 public final void scheduleUnbindService(IBinder token, Intent intent) { 702 BindServiceData s = new BindServiceData(); 703 s.token = token; 704 s.intent = intent; 705 706 sendMessage(H.UNBIND_SERVICE, s); 707 } 708 709 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, 710 int flags ,Intent args) { 711 ServiceArgsData s = new ServiceArgsData(); 712 s.token = token; 713 s.taskRemoved = taskRemoved; 714 s.startId = startId; 715 s.flags = flags; 716 s.args = args; 717 718 sendMessage(H.SERVICE_ARGS, s); 719 } 720 721 public final void scheduleStopService(IBinder token) { 722 sendMessage(H.STOP_SERVICE, token); 723 } 724 725 public final void bindApplication(String processName, 726 ApplicationInfo appInfo, List<ProviderInfo> providers, 727 ComponentName instrumentationName, String profileFile, 728 ParcelFileDescriptor profileFd, boolean autoStopProfiler, 729 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, 730 IUiAutomationConnection instrumentationUiConnection, int debugMode, 731 boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent, 732 Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, 733 Bundle coreSettings) { 734 735 if (services != null) { 736 // Setup the service cache in the ServiceManager 737 ServiceManager.initServiceCache(services); 738 } 739 740 setCoreSettings(coreSettings); 741 742 AppBindData data = new AppBindData(); 743 data.processName = processName; 744 data.appInfo = appInfo; 745 data.providers = providers; 746 data.instrumentationName = instrumentationName; 747 data.instrumentationArgs = instrumentationArgs; 748 data.instrumentationWatcher = instrumentationWatcher; 749 data.instrumentationUiAutomationConnection = instrumentationUiConnection; 750 data.debugMode = debugMode; 751 data.enableOpenGlTrace = enableOpenGlTrace; 752 data.restrictedBackupMode = isRestrictedBackupMode; 753 data.persistent = persistent; 754 data.config = config; 755 data.compatInfo = compatInfo; 756 data.initProfileFile = profileFile; 757 data.initProfileFd = profileFd; 758 data.initAutoStopProfiler = false; 759 sendMessage(H.BIND_APPLICATION, data); 760 } 761 762 public final void scheduleExit() { 763 sendMessage(H.EXIT_APPLICATION, null); 764 } 765 766 public final void scheduleSuicide() { 767 sendMessage(H.SUICIDE, null); 768 } 769 770 public void requestThumbnail(IBinder token) { 771 sendMessage(H.REQUEST_THUMBNAIL, token); 772 } 773 774 public void scheduleConfigurationChanged(Configuration config) { 775 updatePendingConfiguration(config); 776 sendMessage(H.CONFIGURATION_CHANGED, config); 777 } 778 779 public void updateTimeZone() { 780 TimeZone.setDefault(null); 781 } 782 783 public void clearDnsCache() { 784 // a non-standard API to get this to libcore 785 InetAddress.clearDnsCache(); 786 } 787 788 public void setHttpProxy(String host, String port, String exclList, String pacFileUrl) { 789 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl); 790 } 791 792 public void processInBackground() { 793 mH.removeMessages(H.GC_WHEN_IDLE); 794 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE)); 795 } 796 797 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) { 798 DumpComponentInfo data = new DumpComponentInfo(); 799 try { 800 data.fd = ParcelFileDescriptor.dup(fd); 801 data.token = servicetoken; 802 data.args = args; 803 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/); 804 } catch (IOException e) { 805 Slog.w(TAG, "dumpService failed", e); 806 } 807 } 808 809 // This function exists to make sure all receiver dispatching is 810 // correctly ordered, since these are one-way calls and the binder driver 811 // applies transaction ordering per object for such calls. 812 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, 813 int resultCode, String dataStr, Bundle extras, boolean ordered, 814 boolean sticky, int sendingUser, int processState) throws RemoteException { 815 updateProcessState(processState, false); 816 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, 817 sticky, sendingUser); 818 } 819 820 public void scheduleLowMemory() { 821 sendMessage(H.LOW_MEMORY, null); 822 } 823 824 public void scheduleActivityConfigurationChanged(IBinder token) { 825 sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token); 826 } 827 828 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd, 829 int profileType) { 830 ProfilerControlData pcd = new ProfilerControlData(); 831 pcd.path = path; 832 pcd.fd = fd; 833 sendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType); 834 } 835 836 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) { 837 DumpHeapData dhd = new DumpHeapData(); 838 dhd.path = path; 839 dhd.fd = fd; 840 sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/); 841 } 842 843 public void setSchedulingGroup(int group) { 844 // Note: do this immediately, since going into the foreground 845 // should happen regardless of what pending work we have to do 846 // and the activity manager will wait for us to report back that 847 // we are done before sending us to the background. 848 try { 849 Process.setProcessGroup(Process.myPid(), group); 850 } catch (Exception e) { 851 Slog.w(TAG, "Failed setting process group to " + group, e); 852 } 853 } 854 855 public void dispatchPackageBroadcast(int cmd, String[] packages) { 856 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd); 857 } 858 859 public void scheduleCrash(String msg) { 860 sendMessage(H.SCHEDULE_CRASH, msg); 861 } 862 863 public void dumpActivity(FileDescriptor fd, IBinder activitytoken, 864 String prefix, String[] args) { 865 DumpComponentInfo data = new DumpComponentInfo(); 866 try { 867 data.fd = ParcelFileDescriptor.dup(fd); 868 data.token = activitytoken; 869 data.prefix = prefix; 870 data.args = args; 871 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/); 872 } catch (IOException e) { 873 Slog.w(TAG, "dumpActivity failed", e); 874 } 875 } 876 877 public void dumpProvider(FileDescriptor fd, IBinder providertoken, 878 String[] args) { 879 DumpComponentInfo data = new DumpComponentInfo(); 880 try { 881 data.fd = ParcelFileDescriptor.dup(fd); 882 data.token = providertoken; 883 data.args = args; 884 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/); 885 } catch (IOException e) { 886 Slog.w(TAG, "dumpProvider failed", e); 887 } 888 } 889 890 @Override 891 public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, 892 boolean dumpFullInfo, boolean dumpDalvik, String[] args) { 893 FileOutputStream fout = new FileOutputStream(fd); 894 PrintWriter pw = new FastPrintWriter(fout); 895 try { 896 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik); 897 } finally { 898 pw.flush(); 899 } 900 } 901 902 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 903 boolean dumpFullInfo, boolean dumpDalvik) { 904 long nativeMax = Debug.getNativeHeapSize() / 1024; 905 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; 906 long nativeFree = Debug.getNativeHeapFreeSize() / 1024; 907 908 Runtime runtime = Runtime.getRuntime(); 909 910 long dalvikMax = runtime.totalMemory() / 1024; 911 long dalvikFree = runtime.freeMemory() / 1024; 912 long dalvikAllocated = dalvikMax - dalvikFree; 913 long viewInstanceCount = ViewDebug.getViewInstanceCount(); 914 long viewRootInstanceCount = ViewDebug.getViewRootImplCount(); 915 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class); 916 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class); 917 int globalAssetCount = AssetManager.getGlobalAssetCount(); 918 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount(); 919 int binderLocalObjectCount = Debug.getBinderLocalObjectCount(); 920 int binderProxyObjectCount = Debug.getBinderProxyObjectCount(); 921 int binderDeathObjectCount = Debug.getBinderDeathObjectCount(); 922 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class); 923 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 924 925 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, Process.myPid(), 926 (mBoundApplication != null) ? mBoundApplication.processName : "unknown", 927 nativeMax, nativeAllocated, nativeFree, 928 dalvikMax, dalvikAllocated, dalvikFree); 929 930 if (checkin) { 931 // NOTE: if you change anything significant below, also consider changing 932 // ACTIVITY_THREAD_CHECKIN_VERSION. 933 934 // Object counts 935 pw.print(viewInstanceCount); pw.print(','); 936 pw.print(viewRootInstanceCount); pw.print(','); 937 pw.print(appContextInstanceCount); pw.print(','); 938 pw.print(activityInstanceCount); pw.print(','); 939 940 pw.print(globalAssetCount); pw.print(','); 941 pw.print(globalAssetManagerCount); pw.print(','); 942 pw.print(binderLocalObjectCount); pw.print(','); 943 pw.print(binderProxyObjectCount); pw.print(','); 944 945 pw.print(binderDeathObjectCount); pw.print(','); 946 pw.print(openSslSocketCount); pw.print(','); 947 948 // SQL 949 pw.print(stats.memoryUsed / 1024); pw.print(','); 950 pw.print(stats.memoryUsed / 1024); pw.print(','); 951 pw.print(stats.pageCacheOverflow / 1024); pw.print(','); 952 pw.print(stats.largestMemAlloc / 1024); 953 for (int i = 0; i < stats.dbStats.size(); i++) { 954 DbStats dbStats = stats.dbStats.get(i); 955 pw.print(','); pw.print(dbStats.dbName); 956 pw.print(','); pw.print(dbStats.pageSize); 957 pw.print(','); pw.print(dbStats.dbSize); 958 pw.print(','); pw.print(dbStats.lookaside); 959 pw.print(','); pw.print(dbStats.cache); 960 pw.print(','); pw.print(dbStats.cache); 961 } 962 pw.println(); 963 964 return; 965 } 966 967 pw.println(" "); 968 pw.println(" Objects"); 969 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:", 970 viewRootInstanceCount); 971 972 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount, 973 "Activities:", activityInstanceCount); 974 975 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount, 976 "AssetManagers:", globalAssetManagerCount); 977 978 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount, 979 "Proxy Binders:", binderProxyObjectCount); 980 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount); 981 982 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount); 983 984 // SQLite mem info 985 pw.println(" "); 986 pw.println(" SQL"); 987 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024); 988 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:", 989 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024); 990 pw.println(" "); 991 int N = stats.dbStats.size(); 992 if (N > 0) { 993 pw.println(" DATABASES"); 994 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache", 995 "Dbname"); 996 for (int i = 0; i < N; i++) { 997 DbStats dbStats = stats.dbStats.get(i); 998 printRow(pw, DB_INFO_FORMAT, 999 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ", 1000 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ", 1001 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ", 1002 dbStats.cache, dbStats.dbName); 1003 } 1004 } 1005 1006 // Asset details. 1007 String assetAlloc = AssetManager.getAssetAllocations(); 1008 if (assetAlloc != null) { 1009 pw.println(" "); 1010 pw.println(" Asset Allocations"); 1011 pw.print(assetAlloc); 1012 } 1013 } 1014 1015 @Override 1016 public void dumpGfxInfo(FileDescriptor fd, String[] args) { 1017 dumpGraphicsInfo(fd); 1018 WindowManagerGlobal.getInstance().dumpGfxInfo(fd); 1019 } 1020 1021 @Override 1022 public void dumpDbInfo(FileDescriptor fd, String[] args) { 1023 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd)); 1024 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 1025 SQLiteDebug.dump(printer, args); 1026 pw.flush(); 1027 } 1028 1029 @Override 1030 public void unstableProviderDied(IBinder provider) { 1031 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider); 1032 } 1033 1034 @Override 1035 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, 1036 int requestType) { 1037 RequestAssistContextExtras cmd = new RequestAssistContextExtras(); 1038 cmd.activityToken = activityToken; 1039 cmd.requestToken = requestToken; 1040 cmd.requestType = requestType; 1041 sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd); 1042 } 1043 1044 public void setCoreSettings(Bundle coreSettings) { 1045 sendMessage(H.SET_CORE_SETTINGS, coreSettings); 1046 } 1047 1048 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) { 1049 UpdateCompatibilityData ucd = new UpdateCompatibilityData(); 1050 ucd.pkg = pkg; 1051 ucd.info = info; 1052 sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd); 1053 } 1054 1055 public void scheduleTrimMemory(int level) { 1056 sendMessage(H.TRIM_MEMORY, null, level); 1057 } 1058 1059 public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 1060 sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0); 1061 } 1062 1063 public void setProcessState(int state) { 1064 updateProcessState(state, true); 1065 } 1066 1067 public void updateProcessState(int processState, boolean fromIpc) { 1068 synchronized (this) { 1069 if (mLastProcessState != processState) { 1070 mLastProcessState = processState; 1071 1072 // Update Dalvik state here based on ActivityManager.PROCESS_STATE_* constants. 1073 if (false) { 1074 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState 1075 + (fromIpc ? " (from ipc": "")); 1076 } 1077 } 1078 } 1079 } 1080 1081 @Override 1082 public void scheduleInstallProvider(ProviderInfo provider) { 1083 sendMessage(H.INSTALL_PROVIDER, provider); 1084 } 1085 } 1086 1087 private class H extends Handler { 1088 public static final int LAUNCH_ACTIVITY = 100; 1089 public static final int PAUSE_ACTIVITY = 101; 1090 public static final int PAUSE_ACTIVITY_FINISHING= 102; 1091 public static final int STOP_ACTIVITY_SHOW = 103; 1092 public static final int STOP_ACTIVITY_HIDE = 104; 1093 public static final int SHOW_WINDOW = 105; 1094 public static final int HIDE_WINDOW = 106; 1095 public static final int RESUME_ACTIVITY = 107; 1096 public static final int SEND_RESULT = 108; 1097 public static final int DESTROY_ACTIVITY = 109; 1098 public static final int BIND_APPLICATION = 110; 1099 public static final int EXIT_APPLICATION = 111; 1100 public static final int NEW_INTENT = 112; 1101 public static final int RECEIVER = 113; 1102 public static final int CREATE_SERVICE = 114; 1103 public static final int SERVICE_ARGS = 115; 1104 public static final int STOP_SERVICE = 116; 1105 public static final int REQUEST_THUMBNAIL = 117; 1106 public static final int CONFIGURATION_CHANGED = 118; 1107 public static final int CLEAN_UP_CONTEXT = 119; 1108 public static final int GC_WHEN_IDLE = 120; 1109 public static final int BIND_SERVICE = 121; 1110 public static final int UNBIND_SERVICE = 122; 1111 public static final int DUMP_SERVICE = 123; 1112 public static final int LOW_MEMORY = 124; 1113 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125; 1114 public static final int RELAUNCH_ACTIVITY = 126; 1115 public static final int PROFILER_CONTROL = 127; 1116 public static final int CREATE_BACKUP_AGENT = 128; 1117 public static final int DESTROY_BACKUP_AGENT = 129; 1118 public static final int SUICIDE = 130; 1119 public static final int REMOVE_PROVIDER = 131; 1120 public static final int ENABLE_JIT = 132; 1121 public static final int DISPATCH_PACKAGE_BROADCAST = 133; 1122 public static final int SCHEDULE_CRASH = 134; 1123 public static final int DUMP_HEAP = 135; 1124 public static final int DUMP_ACTIVITY = 136; 1125 public static final int SLEEPING = 137; 1126 public static final int SET_CORE_SETTINGS = 138; 1127 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139; 1128 public static final int TRIM_MEMORY = 140; 1129 public static final int DUMP_PROVIDER = 141; 1130 public static final int UNSTABLE_PROVIDER_DIED = 142; 1131 public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143; 1132 public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144; 1133 public static final int INSTALL_PROVIDER = 145; 1134 String codeToString(int code) { 1135 if (DEBUG_MESSAGES) { 1136 switch (code) { 1137 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY"; 1138 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY"; 1139 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING"; 1140 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW"; 1141 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE"; 1142 case SHOW_WINDOW: return "SHOW_WINDOW"; 1143 case HIDE_WINDOW: return "HIDE_WINDOW"; 1144 case RESUME_ACTIVITY: return "RESUME_ACTIVITY"; 1145 case SEND_RESULT: return "SEND_RESULT"; 1146 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY"; 1147 case BIND_APPLICATION: return "BIND_APPLICATION"; 1148 case EXIT_APPLICATION: return "EXIT_APPLICATION"; 1149 case NEW_INTENT: return "NEW_INTENT"; 1150 case RECEIVER: return "RECEIVER"; 1151 case CREATE_SERVICE: return "CREATE_SERVICE"; 1152 case SERVICE_ARGS: return "SERVICE_ARGS"; 1153 case STOP_SERVICE: return "STOP_SERVICE"; 1154 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL"; 1155 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED"; 1156 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT"; 1157 case GC_WHEN_IDLE: return "GC_WHEN_IDLE"; 1158 case BIND_SERVICE: return "BIND_SERVICE"; 1159 case UNBIND_SERVICE: return "UNBIND_SERVICE"; 1160 case DUMP_SERVICE: return "DUMP_SERVICE"; 1161 case LOW_MEMORY: return "LOW_MEMORY"; 1162 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED"; 1163 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; 1164 case PROFILER_CONTROL: return "PROFILER_CONTROL"; 1165 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; 1166 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; 1167 case SUICIDE: return "SUICIDE"; 1168 case REMOVE_PROVIDER: return "REMOVE_PROVIDER"; 1169 case ENABLE_JIT: return "ENABLE_JIT"; 1170 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST"; 1171 case SCHEDULE_CRASH: return "SCHEDULE_CRASH"; 1172 case DUMP_HEAP: return "DUMP_HEAP"; 1173 case DUMP_ACTIVITY: return "DUMP_ACTIVITY"; 1174 case SLEEPING: return "SLEEPING"; 1175 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS"; 1176 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO"; 1177 case TRIM_MEMORY: return "TRIM_MEMORY"; 1178 case DUMP_PROVIDER: return "DUMP_PROVIDER"; 1179 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED"; 1180 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS"; 1181 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE"; 1182 case INSTALL_PROVIDER: return "INSTALL_PROVIDER"; 1183 } 1184 } 1185 return Integer.toString(code); 1186 } 1187 public void handleMessage(Message msg) { 1188 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1189 switch (msg.what) { 1190 case LAUNCH_ACTIVITY: { 1191 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 1192 ActivityClientRecord r = (ActivityClientRecord)msg.obj; 1193 1194 r.packageInfo = getPackageInfoNoCheck( 1195 r.activityInfo.applicationInfo, r.compatInfo); 1196 handleLaunchActivity(r, null); 1197 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1198 } break; 1199 case RELAUNCH_ACTIVITY: { 1200 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); 1201 ActivityClientRecord r = (ActivityClientRecord)msg.obj; 1202 handleRelaunchActivity(r); 1203 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1204 } break; 1205 case PAUSE_ACTIVITY: 1206 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 1207 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2); 1208 maybeSnapshot(); 1209 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1210 break; 1211 case PAUSE_ACTIVITY_FINISHING: 1212 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 1213 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2); 1214 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1215 break; 1216 case STOP_ACTIVITY_SHOW: 1217 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 1218 handleStopActivity((IBinder)msg.obj, true, msg.arg2); 1219 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1220 break; 1221 case STOP_ACTIVITY_HIDE: 1222 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 1223 handleStopActivity((IBinder)msg.obj, false, msg.arg2); 1224 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1225 break; 1226 case SHOW_WINDOW: 1227 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow"); 1228 handleWindowVisibility((IBinder)msg.obj, true); 1229 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1230 break; 1231 case HIDE_WINDOW: 1232 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow"); 1233 handleWindowVisibility((IBinder)msg.obj, false); 1234 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1235 break; 1236 case RESUME_ACTIVITY: 1237 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); 1238 handleResumeActivity((IBinder)msg.obj, true, 1239 msg.arg1 != 0, true); 1240 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1241 break; 1242 case SEND_RESULT: 1243 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult"); 1244 handleSendResult((ResultData)msg.obj); 1245 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1246 break; 1247 case DESTROY_ACTIVITY: 1248 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy"); 1249 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0, 1250 msg.arg2, false); 1251 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1252 break; 1253 case BIND_APPLICATION: 1254 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); 1255 AppBindData data = (AppBindData)msg.obj; 1256 handleBindApplication(data); 1257 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1258 break; 1259 case EXIT_APPLICATION: 1260 if (mInitialApplication != null) { 1261 mInitialApplication.onTerminate(); 1262 } 1263 Looper.myLooper().quit(); 1264 break; 1265 case NEW_INTENT: 1266 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent"); 1267 handleNewIntent((NewIntentData)msg.obj); 1268 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1269 break; 1270 case RECEIVER: 1271 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp"); 1272 handleReceiver((ReceiverData)msg.obj); 1273 maybeSnapshot(); 1274 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1275 break; 1276 case CREATE_SERVICE: 1277 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); 1278 handleCreateService((CreateServiceData)msg.obj); 1279 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1280 break; 1281 case BIND_SERVICE: 1282 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); 1283 handleBindService((BindServiceData)msg.obj); 1284 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1285 break; 1286 case UNBIND_SERVICE: 1287 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind"); 1288 handleUnbindService((BindServiceData)msg.obj); 1289 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1290 break; 1291 case SERVICE_ARGS: 1292 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart"); 1293 handleServiceArgs((ServiceArgsData)msg.obj); 1294 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1295 break; 1296 case STOP_SERVICE: 1297 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop"); 1298 handleStopService((IBinder)msg.obj); 1299 maybeSnapshot(); 1300 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1301 break; 1302 case REQUEST_THUMBNAIL: 1303 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail"); 1304 handleRequestThumbnail((IBinder)msg.obj); 1305 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1306 break; 1307 case CONFIGURATION_CHANGED: 1308 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged"); 1309 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi; 1310 handleConfigurationChanged((Configuration)msg.obj, null); 1311 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1312 break; 1313 case CLEAN_UP_CONTEXT: 1314 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj; 1315 cci.context.performFinalCleanup(cci.who, cci.what); 1316 break; 1317 case GC_WHEN_IDLE: 1318 scheduleGcIdler(); 1319 break; 1320 case DUMP_SERVICE: 1321 handleDumpService((DumpComponentInfo)msg.obj); 1322 break; 1323 case LOW_MEMORY: 1324 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory"); 1325 handleLowMemory(); 1326 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1327 break; 1328 case ACTIVITY_CONFIGURATION_CHANGED: 1329 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged"); 1330 handleActivityConfigurationChanged((IBinder)msg.obj); 1331 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1332 break; 1333 case PROFILER_CONTROL: 1334 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2); 1335 break; 1336 case CREATE_BACKUP_AGENT: 1337 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent"); 1338 handleCreateBackupAgent((CreateBackupAgentData)msg.obj); 1339 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1340 break; 1341 case DESTROY_BACKUP_AGENT: 1342 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent"); 1343 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj); 1344 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1345 break; 1346 case SUICIDE: 1347 Process.killProcess(Process.myPid()); 1348 break; 1349 case REMOVE_PROVIDER: 1350 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove"); 1351 completeRemoveProvider((ProviderRefCount)msg.obj); 1352 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1353 break; 1354 case ENABLE_JIT: 1355 ensureJitEnabled(); 1356 break; 1357 case DISPATCH_PACKAGE_BROADCAST: 1358 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage"); 1359 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj); 1360 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1361 break; 1362 case SCHEDULE_CRASH: 1363 throw new RemoteServiceException((String)msg.obj); 1364 case DUMP_HEAP: 1365 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj); 1366 break; 1367 case DUMP_ACTIVITY: 1368 handleDumpActivity((DumpComponentInfo)msg.obj); 1369 break; 1370 case DUMP_PROVIDER: 1371 handleDumpProvider((DumpComponentInfo)msg.obj); 1372 break; 1373 case SLEEPING: 1374 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping"); 1375 handleSleeping((IBinder)msg.obj, msg.arg1 != 0); 1376 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1377 break; 1378 case SET_CORE_SETTINGS: 1379 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings"); 1380 handleSetCoreSettings((Bundle) msg.obj); 1381 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1382 break; 1383 case UPDATE_PACKAGE_COMPATIBILITY_INFO: 1384 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj); 1385 break; 1386 case TRIM_MEMORY: 1387 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory"); 1388 handleTrimMemory(msg.arg1); 1389 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1390 break; 1391 case UNSTABLE_PROVIDER_DIED: 1392 handleUnstableProviderDied((IBinder)msg.obj, false); 1393 break; 1394 case REQUEST_ASSIST_CONTEXT_EXTRAS: 1395 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj); 1396 break; 1397 case TRANSLUCENT_CONVERSION_COMPLETE: 1398 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1); 1399 break; 1400 case INSTALL_PROVIDER: 1401 handleInstallProvider((ProviderInfo) msg.obj); 1402 break; 1403 } 1404 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); 1405 } 1406 1407 private void maybeSnapshot() { 1408 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) { 1409 // convert the *private* ActivityThread.PackageInfo to *public* known 1410 // android.content.pm.PackageInfo 1411 String packageName = mBoundApplication.info.mPackageName; 1412 android.content.pm.PackageInfo packageInfo = null; 1413 try { 1414 Context context = getSystemContext(); 1415 if(context == null) { 1416 Log.e(TAG, "cannot get a valid context"); 1417 return; 1418 } 1419 PackageManager pm = context.getPackageManager(); 1420 if(pm == null) { 1421 Log.e(TAG, "cannot get a valid PackageManager"); 1422 return; 1423 } 1424 packageInfo = pm.getPackageInfo( 1425 packageName, PackageManager.GET_ACTIVITIES); 1426 } catch (NameNotFoundException e) { 1427 Log.e(TAG, "cannot get package info for " + packageName, e); 1428 } 1429 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo); 1430 } 1431 } 1432 } 1433 1434 private class Idler implements MessageQueue.IdleHandler { 1435 @Override 1436 public final boolean queueIdle() { 1437 ActivityClientRecord a = mNewActivities; 1438 boolean stopProfiling = false; 1439 if (mBoundApplication != null && mProfiler.profileFd != null 1440 && mProfiler.autoStopProfiler) { 1441 stopProfiling = true; 1442 } 1443 if (a != null) { 1444 mNewActivities = null; 1445 IActivityManager am = ActivityManagerNative.getDefault(); 1446 ActivityClientRecord prev; 1447 do { 1448 if (localLOGV) Slog.v( 1449 TAG, "Reporting idle of " + a + 1450 " finished=" + 1451 (a.activity != null && a.activity.mFinished)); 1452 if (a.activity != null && !a.activity.mFinished) { 1453 try { 1454 am.activityIdle(a.token, a.createdConfig, stopProfiling); 1455 a.createdConfig = null; 1456 } catch (RemoteException ex) { 1457 // Ignore 1458 } 1459 } 1460 prev = a; 1461 a = a.nextIdle; 1462 prev.nextIdle = null; 1463 } while (a != null); 1464 } 1465 if (stopProfiling) { 1466 mProfiler.stopProfiling(); 1467 } 1468 ensureJitEnabled(); 1469 return false; 1470 } 1471 } 1472 1473 final class GcIdler implements MessageQueue.IdleHandler { 1474 @Override 1475 public final boolean queueIdle() { 1476 doGcIfNeeded(); 1477 return false; 1478 } 1479 } 1480 1481 public static ActivityThread currentActivityThread() { 1482 return sCurrentActivityThread; 1483 } 1484 1485 public static String currentPackageName() { 1486 ActivityThread am = currentActivityThread(); 1487 return (am != null && am.mBoundApplication != null) 1488 ? am.mBoundApplication.appInfo.packageName : null; 1489 } 1490 1491 public static String currentProcessName() { 1492 ActivityThread am = currentActivityThread(); 1493 return (am != null && am.mBoundApplication != null) 1494 ? am.mBoundApplication.processName : null; 1495 } 1496 1497 public static Application currentApplication() { 1498 ActivityThread am = currentActivityThread(); 1499 return am != null ? am.mInitialApplication : null; 1500 } 1501 1502 public static IPackageManager getPackageManager() { 1503 if (sPackageManager != null) { 1504 //Slog.v("PackageManager", "returning cur default = " + sPackageManager); 1505 return sPackageManager; 1506 } 1507 IBinder b = ServiceManager.getService("package"); 1508 //Slog.v("PackageManager", "default service binder = " + b); 1509 sPackageManager = IPackageManager.Stub.asInterface(b); 1510 //Slog.v("PackageManager", "default service = " + sPackageManager); 1511 return sPackageManager; 1512 } 1513 1514 private Configuration mMainThreadConfig = new Configuration(); 1515 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config, 1516 CompatibilityInfo compat) { 1517 if (config == null) { 1518 return null; 1519 } 1520 if (!compat.supportsScreen()) { 1521 mMainThreadConfig.setTo(config); 1522 config = mMainThreadConfig; 1523 compat.applyToConfiguration(displayDensity, config); 1524 } 1525 return config; 1526 } 1527 1528 /** 1529 * Creates the top level resources for the given package. 1530 */ 1531 Resources getTopLevelResources(String resDir, 1532 int displayId, Configuration overrideConfiguration, 1533 LoadedApk pkgInfo) { 1534 return mResourcesManager.getTopLevelResources(resDir, displayId, overrideConfiguration, 1535 pkgInfo.getCompatibilityInfo(), null); 1536 } 1537 1538 final Handler getHandler() { 1539 return mH; 1540 } 1541 1542 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, 1543 int flags) { 1544 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); 1545 } 1546 1547 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, 1548 int flags, int userId) { 1549 synchronized (mResourcesManager) { 1550 WeakReference<LoadedApk> ref; 1551 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) { 1552 ref = mPackages.get(packageName); 1553 } else { 1554 ref = mResourcePackages.get(packageName); 1555 } 1556 LoadedApk packageInfo = ref != null ? ref.get() : null; 1557 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo); 1558 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir 1559 // + ": " + packageInfo.mResources.getAssets().isUpToDate()); 1560 if (packageInfo != null && (packageInfo.mResources == null 1561 || packageInfo.mResources.getAssets().isUpToDate())) { 1562 if (packageInfo.isSecurityViolation() 1563 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) { 1564 throw new SecurityException( 1565 "Requesting code from " + packageName 1566 + " to be run in process " 1567 + mBoundApplication.processName 1568 + "/" + mBoundApplication.appInfo.uid); 1569 } 1570 return packageInfo; 1571 } 1572 } 1573 1574 ApplicationInfo ai = null; 1575 try { 1576 ai = getPackageManager().getApplicationInfo(packageName, 1577 PackageManager.GET_SHARED_LIBRARY_FILES, userId); 1578 } catch (RemoteException e) { 1579 // Ignore 1580 } 1581 1582 if (ai != null) { 1583 return getPackageInfo(ai, compatInfo, flags); 1584 } 1585 1586 return null; 1587 } 1588 1589 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, 1590 int flags) { 1591 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; 1592 boolean securityViolation = includeCode && ai.uid != 0 1593 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null 1594 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid) 1595 : true); 1596 if ((flags&(Context.CONTEXT_INCLUDE_CODE 1597 |Context.CONTEXT_IGNORE_SECURITY)) 1598 == Context.CONTEXT_INCLUDE_CODE) { 1599 if (securityViolation) { 1600 String msg = "Requesting code from " + ai.packageName 1601 + " (with uid " + ai.uid + ")"; 1602 if (mBoundApplication != null) { 1603 msg = msg + " to be run in process " 1604 + mBoundApplication.processName + " (with uid " 1605 + mBoundApplication.appInfo.uid + ")"; 1606 } 1607 throw new SecurityException(msg); 1608 } 1609 } 1610 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode); 1611 } 1612 1613 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, 1614 CompatibilityInfo compatInfo) { 1615 return getPackageInfo(ai, compatInfo, null, false, true); 1616 } 1617 1618 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) { 1619 synchronized (mResourcesManager) { 1620 WeakReference<LoadedApk> ref; 1621 if (includeCode) { 1622 ref = mPackages.get(packageName); 1623 } else { 1624 ref = mResourcePackages.get(packageName); 1625 } 1626 return ref != null ? ref.get() : null; 1627 } 1628 } 1629 1630 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, 1631 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) { 1632 synchronized (mResourcesManager) { 1633 WeakReference<LoadedApk> ref; 1634 if (includeCode) { 1635 ref = mPackages.get(aInfo.packageName); 1636 } else { 1637 ref = mResourcePackages.get(aInfo.packageName); 1638 } 1639 LoadedApk packageInfo = ref != null ? ref.get() : null; 1640 if (packageInfo == null || (packageInfo.mResources != null 1641 && !packageInfo.mResources.getAssets().isUpToDate())) { 1642 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package " 1643 : "Loading resource-only package ") + aInfo.packageName 1644 + " (in " + (mBoundApplication != null 1645 ? mBoundApplication.processName : null) 1646 + ")"); 1647 packageInfo = 1648 new LoadedApk(this, aInfo, compatInfo, baseLoader, 1649 securityViolation, includeCode && 1650 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0); 1651 if (includeCode) { 1652 mPackages.put(aInfo.packageName, 1653 new WeakReference<LoadedApk>(packageInfo)); 1654 } else { 1655 mResourcePackages.put(aInfo.packageName, 1656 new WeakReference<LoadedApk>(packageInfo)); 1657 } 1658 } 1659 return packageInfo; 1660 } 1661 } 1662 1663 ActivityThread() { 1664 mResourcesManager = ResourcesManager.getInstance(); 1665 } 1666 1667 public ApplicationThread getApplicationThread() 1668 { 1669 return mAppThread; 1670 } 1671 1672 public Instrumentation getInstrumentation() 1673 { 1674 return mInstrumentation; 1675 } 1676 1677 public boolean isProfiling() { 1678 return mProfiler != null && mProfiler.profileFile != null 1679 && mProfiler.profileFd == null; 1680 } 1681 1682 public String getProfileFilePath() { 1683 return mProfiler.profileFile; 1684 } 1685 1686 public Looper getLooper() { 1687 return mLooper; 1688 } 1689 1690 public Application getApplication() { 1691 return mInitialApplication; 1692 } 1693 1694 public String getProcessName() { 1695 return mBoundApplication.processName; 1696 } 1697 1698 public ContextImpl getSystemContext() { 1699 synchronized (this) { 1700 if (mSystemContext == null) { 1701 mSystemContext = ContextImpl.createSystemContext(this); 1702 } 1703 return mSystemContext; 1704 } 1705 } 1706 1707 public void installSystemApplicationInfo(ApplicationInfo info) { 1708 synchronized (this) { 1709 getSystemContext().installSystemApplicationInfo(info); 1710 1711 // give ourselves a default profiler 1712 mProfiler = new Profiler(); 1713 } 1714 } 1715 1716 void ensureJitEnabled() { 1717 if (!mJitEnabled) { 1718 mJitEnabled = true; 1719 dalvik.system.VMRuntime.getRuntime().startJitCompilation(); 1720 } 1721 } 1722 1723 void scheduleGcIdler() { 1724 if (!mGcIdlerScheduled) { 1725 mGcIdlerScheduled = true; 1726 Looper.myQueue().addIdleHandler(mGcIdler); 1727 } 1728 mH.removeMessages(H.GC_WHEN_IDLE); 1729 } 1730 1731 void unscheduleGcIdler() { 1732 if (mGcIdlerScheduled) { 1733 mGcIdlerScheduled = false; 1734 Looper.myQueue().removeIdleHandler(mGcIdler); 1735 } 1736 mH.removeMessages(H.GC_WHEN_IDLE); 1737 } 1738 1739 void doGcIfNeeded() { 1740 mGcIdlerScheduled = false; 1741 final long now = SystemClock.uptimeMillis(); 1742 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime() 1743 // + "m now=" + now); 1744 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) { 1745 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!"); 1746 BinderInternal.forceGc("bg"); 1747 } 1748 } 1749 1750 private static final String HEAP_FULL_COLUMN 1751 = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; 1752 private static final String HEAP_COLUMN 1753 = "%13s %8s %8s %8s %8s %8s %8s %8s"; 1754 1755 // Formatting for checkin service - update version if row format changes 1756 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3; 1757 1758 static void printRow(PrintWriter pw, String format, Object...objs) { 1759 pw.println(String.format(format, objs)); 1760 } 1761 1762 public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 1763 boolean dumpFullInfo, boolean dumpDalvik, int pid, String processName, 1764 long nativeMax, long nativeAllocated, long nativeFree, 1765 long dalvikMax, long dalvikAllocated, long dalvikFree) { 1766 1767 // For checkin, we print one long comma-separated list of values 1768 if (checkin) { 1769 // NOTE: if you change anything significant below, also consider changing 1770 // ACTIVITY_THREAD_CHECKIN_VERSION. 1771 1772 // Header 1773 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(','); 1774 pw.print(pid); pw.print(','); 1775 pw.print(processName); pw.print(','); 1776 1777 // Heap info - max 1778 pw.print(nativeMax); pw.print(','); 1779 pw.print(dalvikMax); pw.print(','); 1780 pw.print("N/A,"); 1781 pw.print(nativeMax + dalvikMax); pw.print(','); 1782 1783 // Heap info - allocated 1784 pw.print(nativeAllocated); pw.print(','); 1785 pw.print(dalvikAllocated); pw.print(','); 1786 pw.print("N/A,"); 1787 pw.print(nativeAllocated + dalvikAllocated); pw.print(','); 1788 1789 // Heap info - free 1790 pw.print(nativeFree); pw.print(','); 1791 pw.print(dalvikFree); pw.print(','); 1792 pw.print("N/A,"); 1793 pw.print(nativeFree + dalvikFree); pw.print(','); 1794 1795 // Heap info - proportional set size 1796 pw.print(memInfo.nativePss); pw.print(','); 1797 pw.print(memInfo.dalvikPss); pw.print(','); 1798 pw.print(memInfo.otherPss); pw.print(','); 1799 pw.print(memInfo.getTotalPss()); pw.print(','); 1800 1801 // Heap info - swappable set size 1802 pw.print(memInfo.nativeSwappablePss); pw.print(','); 1803 pw.print(memInfo.dalvikSwappablePss); pw.print(','); 1804 pw.print(memInfo.otherSwappablePss); pw.print(','); 1805 pw.print(memInfo.getTotalSwappablePss()); pw.print(','); 1806 1807 // Heap info - shared dirty 1808 pw.print(memInfo.nativeSharedDirty); pw.print(','); 1809 pw.print(memInfo.dalvikSharedDirty); pw.print(','); 1810 pw.print(memInfo.otherSharedDirty); pw.print(','); 1811 pw.print(memInfo.getTotalSharedDirty()); pw.print(','); 1812 1813 // Heap info - shared clean 1814 pw.print(memInfo.nativeSharedClean); pw.print(','); 1815 pw.print(memInfo.dalvikSharedClean); pw.print(','); 1816 pw.print(memInfo.otherSharedClean); pw.print(','); 1817 pw.print(memInfo.getTotalSharedClean()); pw.print(','); 1818 1819 // Heap info - private Dirty 1820 pw.print(memInfo.nativePrivateDirty); pw.print(','); 1821 pw.print(memInfo.dalvikPrivateDirty); pw.print(','); 1822 pw.print(memInfo.otherPrivateDirty); pw.print(','); 1823 pw.print(memInfo.getTotalPrivateDirty()); pw.print(','); 1824 1825 // Heap info - private Clean 1826 pw.print(memInfo.nativePrivateClean); pw.print(','); 1827 pw.print(memInfo.dalvikPrivateClean); pw.print(','); 1828 pw.print(memInfo.otherPrivateClean); pw.print(','); 1829 pw.print(memInfo.getTotalPrivateClean()); pw.print(','); 1830 1831 // Heap info - other areas 1832 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { 1833 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(','); 1834 pw.print(memInfo.getOtherPss(i)); pw.print(','); 1835 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(','); 1836 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(','); 1837 pw.print(memInfo.getOtherSharedClean(i)); pw.print(','); 1838 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(','); 1839 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(','); 1840 } 1841 return; 1842 } 1843 1844 // otherwise, show human-readable format 1845 if (dumpFullInfo) { 1846 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", 1847 "Shared", "Private", "Swapped", "Heap", "Heap", "Heap"); 1848 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", 1849 "Clean", "Clean", "Dirty", "Size", "Alloc", "Free"); 1850 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------", 1851 "------", "------", "------", "------", "------", "------"); 1852 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss, 1853 memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, 1854 memInfo.nativePrivateDirty, memInfo.nativeSharedClean, 1855 memInfo.nativePrivateClean, memInfo.nativeSwappedOut, 1856 nativeMax, nativeAllocated, nativeFree); 1857 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss, 1858 memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, 1859 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, 1860 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut, 1861 dalvikMax, dalvikAllocated, dalvikFree); 1862 } else { 1863 printRow(pw, HEAP_COLUMN, "", "Pss", "Private", 1864 "Private", "Swapped", "Heap", "Heap", "Heap"); 1865 printRow(pw, HEAP_COLUMN, "", "Total", "Dirty", 1866 "Clean", "Dirty", "Size", "Alloc", "Free"); 1867 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", 1868 "------", "------", "------", "------", "------"); 1869 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, 1870 memInfo.nativePrivateDirty, 1871 memInfo.nativePrivateClean, memInfo.nativeSwappedOut, 1872 nativeMax, nativeAllocated, nativeFree); 1873 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, 1874 memInfo.dalvikPrivateDirty, 1875 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut, 1876 dalvikMax, dalvikAllocated, dalvikFree); 1877 } 1878 1879 int otherPss = memInfo.otherPss; 1880 int otherSwappablePss = memInfo.otherSwappablePss; 1881 int otherSharedDirty = memInfo.otherSharedDirty; 1882 int otherPrivateDirty = memInfo.otherPrivateDirty; 1883 int otherSharedClean = memInfo.otherSharedClean; 1884 int otherPrivateClean = memInfo.otherPrivateClean; 1885 int otherSwappedOut = memInfo.otherSwappedOut; 1886 1887 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { 1888 final int myPss = memInfo.getOtherPss(i); 1889 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 1890 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 1891 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 1892 final int mySharedClean = memInfo.getOtherSharedClean(i); 1893 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 1894 final int mySwappedOut = memInfo.getOtherSwappedOut(i); 1895 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 1896 || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) { 1897 if (dumpFullInfo) { 1898 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 1899 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 1900 mySharedClean, myPrivateClean, mySwappedOut, "", "", ""); 1901 } else { 1902 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 1903 myPss, myPrivateDirty, 1904 myPrivateClean, mySwappedOut, "", "", ""); 1905 } 1906 otherPss -= myPss; 1907 otherSwappablePss -= mySwappablePss; 1908 otherSharedDirty -= mySharedDirty; 1909 otherPrivateDirty -= myPrivateDirty; 1910 otherSharedClean -= mySharedClean; 1911 otherPrivateClean -= myPrivateClean; 1912 otherSwappedOut -= mySwappedOut; 1913 } 1914 } 1915 1916 if (dumpFullInfo) { 1917 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss, 1918 otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean, 1919 otherSwappedOut, "", "", ""); 1920 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(), 1921 memInfo.getTotalSwappablePss(), 1922 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), 1923 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), 1924 memInfo.getTotalSwappedOut(), nativeMax+dalvikMax, 1925 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); 1926 } else { 1927 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, 1928 otherPrivateDirty, otherPrivateClean, otherSwappedOut, 1929 "", "", ""); 1930 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), 1931 memInfo.getTotalPrivateDirty(), 1932 memInfo.getTotalPrivateClean(), 1933 memInfo.getTotalSwappedOut(), 1934 nativeMax+dalvikMax, 1935 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); 1936 } 1937 1938 if (dumpDalvik) { 1939 pw.println(" "); 1940 pw.println(" Dalvik Details"); 1941 1942 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS; 1943 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) { 1944 final int myPss = memInfo.getOtherPss(i); 1945 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 1946 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 1947 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 1948 final int mySharedClean = memInfo.getOtherSharedClean(i); 1949 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 1950 final int mySwappedOut = memInfo.getOtherSwappedOut(i); 1951 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 1952 || mySharedClean != 0 || myPrivateClean != 0) { 1953 if (dumpFullInfo) { 1954 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 1955 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 1956 mySharedClean, myPrivateClean, mySwappedOut, "", "", ""); 1957 } else { 1958 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 1959 myPss, myPrivateDirty, 1960 myPrivateClean, mySwappedOut, "", "", ""); 1961 } 1962 } 1963 } 1964 } 1965 } 1966 1967 public void registerOnActivityPausedListener(Activity activity, 1968 OnActivityPausedListener listener) { 1969 synchronized (mOnPauseListeners) { 1970 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity); 1971 if (list == null) { 1972 list = new ArrayList<OnActivityPausedListener>(); 1973 mOnPauseListeners.put(activity, list); 1974 } 1975 list.add(listener); 1976 } 1977 } 1978 1979 public void unregisterOnActivityPausedListener(Activity activity, 1980 OnActivityPausedListener listener) { 1981 synchronized (mOnPauseListeners) { 1982 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity); 1983 if (list != null) { 1984 list.remove(listener); 1985 } 1986 } 1987 } 1988 1989 public final ActivityInfo resolveActivityInfo(Intent intent) { 1990 ActivityInfo aInfo = intent.resolveActivityInfo( 1991 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES); 1992 if (aInfo == null) { 1993 // Throw an exception. 1994 Instrumentation.checkStartActivityResult( 1995 ActivityManager.START_CLASS_NOT_FOUND, intent); 1996 } 1997 return aInfo; 1998 } 1999 2000 public final Activity startActivityNow(Activity parent, String id, 2001 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state, 2002 Activity.NonConfigurationInstances lastNonConfigurationInstances) { 2003 ActivityClientRecord r = new ActivityClientRecord(); 2004 r.token = token; 2005 r.ident = 0; 2006 r.intent = intent; 2007 r.state = state; 2008 r.parent = parent; 2009 r.embeddedID = id; 2010 r.activityInfo = activityInfo; 2011 r.lastNonConfigurationInstances = lastNonConfigurationInstances; 2012 if (localLOGV) { 2013 ComponentName compname = intent.getComponent(); 2014 String name; 2015 if (compname != null) { 2016 name = compname.toShortString(); 2017 } else { 2018 name = "(Intent " + intent + ").getComponent() returned null"; 2019 } 2020 Slog.v(TAG, "Performing launch: action=" + intent.getAction() 2021 + ", comp=" + name 2022 + ", token=" + token); 2023 } 2024 return performLaunchActivity(r, null); 2025 } 2026 2027 public final Activity getActivity(IBinder token) { 2028 return mActivities.get(token).activity; 2029 } 2030 2031 public final void sendActivityResult( 2032 IBinder token, String id, int requestCode, 2033 int resultCode, Intent data) { 2034 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id 2035 + " req=" + requestCode + " res=" + resultCode + " data=" + data); 2036 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 2037 list.add(new ResultInfo(id, requestCode, resultCode, data)); 2038 mAppThread.scheduleSendResult(token, list); 2039 } 2040 2041 private void sendMessage(int what, Object obj) { 2042 sendMessage(what, obj, 0, 0, false); 2043 } 2044 2045 private void sendMessage(int what, Object obj, int arg1) { 2046 sendMessage(what, obj, arg1, 0, false); 2047 } 2048 2049 private void sendMessage(int what, Object obj, int arg1, int arg2) { 2050 sendMessage(what, obj, arg1, arg2, false); 2051 } 2052 2053 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { 2054 if (DEBUG_MESSAGES) Slog.v( 2055 TAG, "SCHEDULE " + what + " " + mH.codeToString(what) 2056 + ": " + arg1 + " / " + obj); 2057 Message msg = Message.obtain(); 2058 msg.what = what; 2059 msg.obj = obj; 2060 msg.arg1 = arg1; 2061 msg.arg2 = arg2; 2062 if (async) { 2063 msg.setAsynchronous(true); 2064 } 2065 mH.sendMessage(msg); 2066 } 2067 2068 final void scheduleContextCleanup(ContextImpl context, String who, 2069 String what) { 2070 ContextCleanupInfo cci = new ContextCleanupInfo(); 2071 cci.context = context; 2072 cci.who = who; 2073 cci.what = what; 2074 sendMessage(H.CLEAN_UP_CONTEXT, cci); 2075 } 2076 2077 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2078 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); 2079 2080 ActivityInfo aInfo = r.activityInfo; 2081 if (r.packageInfo == null) { 2082 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 2083 Context.CONTEXT_INCLUDE_CODE); 2084 } 2085 2086 ComponentName component = r.intent.getComponent(); 2087 if (component == null) { 2088 component = r.intent.resolveActivity( 2089 mInitialApplication.getPackageManager()); 2090 r.intent.setComponent(component); 2091 } 2092 2093 if (r.activityInfo.targetActivity != null) { 2094 component = new ComponentName(r.activityInfo.packageName, 2095 r.activityInfo.targetActivity); 2096 } 2097 2098 Activity activity = null; 2099 try { 2100 java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); 2101 activity = mInstrumentation.newActivity( 2102 cl, component.getClassName(), r.intent); 2103 StrictMode.incrementExpectedActivityCount(activity.getClass()); 2104 r.intent.setExtrasClassLoader(cl); 2105 if (r.state != null) { 2106 r.state.setClassLoader(cl); 2107 } 2108 } catch (Exception e) { 2109 if (!mInstrumentation.onException(activity, e)) { 2110 throw new RuntimeException( 2111 "Unable to instantiate activity " + component 2112 + ": " + e.toString(), e); 2113 } 2114 } 2115 2116 try { 2117 Application app = r.packageInfo.makeApplication(false, mInstrumentation); 2118 2119 if (localLOGV) Slog.v(TAG, "Performing launch of " + r); 2120 if (localLOGV) Slog.v( 2121 TAG, r + ": app=" + app 2122 + ", appName=" + app.getPackageName() 2123 + ", pkg=" + r.packageInfo.getPackageName() 2124 + ", comp=" + r.intent.getComponent().toShortString() 2125 + ", dir=" + r.packageInfo.getAppDir()); 2126 2127 if (activity != null) { 2128 Context appContext = createBaseContextForActivity(r, activity); 2129 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); 2130 Configuration config = new Configuration(mCompatConfiguration); 2131 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " 2132 + r.activityInfo.name + " with config " + config); 2133 activity.attach(appContext, this, getInstrumentation(), r.token, 2134 r.ident, app, r.intent, r.activityInfo, title, r.parent, 2135 r.embeddedID, r.lastNonConfigurationInstances, config); 2136 2137 if (customIntent != null) { 2138 activity.mIntent = customIntent; 2139 } 2140 r.lastNonConfigurationInstances = null; 2141 activity.mStartedActivity = false; 2142 int theme = r.activityInfo.getThemeResource(); 2143 if (theme != 0) { 2144 activity.setTheme(theme); 2145 } 2146 2147 activity.mCalled = false; 2148 mInstrumentation.callActivityOnCreate(activity, r.state); 2149 if (!activity.mCalled) { 2150 throw new SuperNotCalledException( 2151 "Activity " + r.intent.getComponent().toShortString() + 2152 " did not call through to super.onCreate()"); 2153 } 2154 r.activity = activity; 2155 r.stopped = true; 2156 if (!r.activity.mFinished) { 2157 activity.performStart(); 2158 r.stopped = false; 2159 } 2160 if (!r.activity.mFinished) { 2161 if (r.state != null) { 2162 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); 2163 } 2164 } 2165 if (!r.activity.mFinished) { 2166 activity.mCalled = false; 2167 mInstrumentation.callActivityOnPostCreate(activity, r.state); 2168 if (!activity.mCalled) { 2169 throw new SuperNotCalledException( 2170 "Activity " + r.intent.getComponent().toShortString() + 2171 " did not call through to super.onPostCreate()"); 2172 } 2173 } 2174 } 2175 r.paused = true; 2176 2177 mActivities.put(r.token, r); 2178 2179 } catch (SuperNotCalledException e) { 2180 throw e; 2181 2182 } catch (Exception e) { 2183 if (!mInstrumentation.onException(activity, e)) { 2184 throw new RuntimeException( 2185 "Unable to start activity " + component 2186 + ": " + e.toString(), e); 2187 } 2188 } 2189 2190 return activity; 2191 } 2192 2193 private Context createBaseContextForActivity(ActivityClientRecord r, 2194 final Activity activity) { 2195 ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token); 2196 appContext.setOuterContext(activity); 2197 2198 // For debugging purposes, if the activity's package name contains the value of 2199 // the "debug.use-second-display" system property as a substring, then show 2200 // its content on a secondary display if there is one. 2201 Context baseContext = appContext; 2202 String pkgName = SystemProperties.get("debug.second-display.pkg"); 2203 if (pkgName != null && !pkgName.isEmpty() 2204 && r.packageInfo.mPackageName.contains(pkgName)) { 2205 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 2206 for (int displayId : dm.getDisplayIds()) { 2207 if (displayId != Display.DEFAULT_DISPLAY) { 2208 Display display = dm.getRealDisplay(displayId, r.token); 2209 baseContext = appContext.createDisplayContext(display); 2210 break; 2211 } 2212 } 2213 } 2214 return baseContext; 2215 } 2216 2217 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2218 // If we are getting ready to gc after going to the background, well 2219 // we are back active so skip it. 2220 unscheduleGcIdler(); 2221 2222 if (r.profileFd != null) { 2223 mProfiler.setProfiler(r.profileFile, r.profileFd); 2224 mProfiler.startProfiling(); 2225 mProfiler.autoStopProfiler = r.autoStopProfiler; 2226 } 2227 2228 // Make sure we are running with the most recent config. 2229 handleConfigurationChanged(null, null); 2230 2231 if (localLOGV) Slog.v( 2232 TAG, "Handling launch of " + r); 2233 Activity a = performLaunchActivity(r, customIntent); 2234 2235 if (a != null) { 2236 r.createdConfig = new Configuration(mConfiguration); 2237 Bundle oldState = r.state; 2238 handleResumeActivity(r.token, false, r.isForward, 2239 !r.activity.mFinished && !r.startsNotResumed); 2240 2241 if (!r.activity.mFinished && r.startsNotResumed) { 2242 // The activity manager actually wants this one to start out 2243 // paused, because it needs to be visible but isn't in the 2244 // foreground. We accomplish this by going through the 2245 // normal startup (because activities expect to go through 2246 // onResume() the first time they run, before their window 2247 // is displayed), and then pausing it. However, in this case 2248 // we do -not- need to do the full pause cycle (of freezing 2249 // and such) because the activity manager assumes it can just 2250 // retain the current state it has. 2251 try { 2252 r.activity.mCalled = false; 2253 mInstrumentation.callActivityOnPause(r.activity); 2254 // We need to keep around the original state, in case 2255 // we need to be created again. But we only do this 2256 // for pre-Honeycomb apps, which always save their state 2257 // when pausing, so we can not have them save their state 2258 // when restarting from a paused state. For HC and later, 2259 // we want to (and can) let the state be saved as the normal 2260 // part of stopping the activity. 2261 if (r.isPreHoneycomb()) { 2262 r.state = oldState; 2263 } 2264 if (!r.activity.mCalled) { 2265 throw new SuperNotCalledException( 2266 "Activity " + r.intent.getComponent().toShortString() + 2267 " did not call through to super.onPause()"); 2268 } 2269 2270 } catch (SuperNotCalledException e) { 2271 throw e; 2272 2273 } catch (Exception e) { 2274 if (!mInstrumentation.onException(r.activity, e)) { 2275 throw new RuntimeException( 2276 "Unable to pause activity " 2277 + r.intent.getComponent().toShortString() 2278 + ": " + e.toString(), e); 2279 } 2280 } 2281 r.paused = true; 2282 } 2283 } else { 2284 // If there was an error, for any reason, tell the activity 2285 // manager to stop us. 2286 try { 2287 ActivityManagerNative.getDefault() 2288 .finishActivity(r.token, Activity.RESULT_CANCELED, null); 2289 } catch (RemoteException ex) { 2290 // Ignore 2291 } 2292 } 2293 } 2294 2295 private void deliverNewIntents(ActivityClientRecord r, 2296 List<Intent> intents) { 2297 final int N = intents.size(); 2298 for (int i=0; i<N; i++) { 2299 Intent intent = intents.get(i); 2300 intent.setExtrasClassLoader(r.activity.getClassLoader()); 2301 r.activity.mFragments.noteStateNotSaved(); 2302 mInstrumentation.callActivityOnNewIntent(r.activity, intent); 2303 } 2304 } 2305 2306 public final void performNewIntents(IBinder token, 2307 List<Intent> intents) { 2308 ActivityClientRecord r = mActivities.get(token); 2309 if (r != null) { 2310 final boolean resumed = !r.paused; 2311 if (resumed) { 2312 r.activity.mTemporaryPause = true; 2313 mInstrumentation.callActivityOnPause(r.activity); 2314 } 2315 deliverNewIntents(r, intents); 2316 if (resumed) { 2317 r.activity.performResume(); 2318 r.activity.mTemporaryPause = false; 2319 } 2320 } 2321 } 2322 2323 private void handleNewIntent(NewIntentData data) { 2324 performNewIntents(data.token, data.intents); 2325 } 2326 2327 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { 2328 Bundle data = new Bundle(); 2329 ActivityClientRecord r = mActivities.get(cmd.activityToken); 2330 if (r != null) { 2331 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 2332 r.activity.onProvideAssistData(data); 2333 } 2334 if (data.isEmpty()) { 2335 data = null; 2336 } 2337 IActivityManager mgr = ActivityManagerNative.getDefault(); 2338 try { 2339 mgr.reportAssistContextExtras(cmd.requestToken, data); 2340 } catch (RemoteException e) { 2341 } 2342 } 2343 2344 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 2345 ActivityClientRecord r = mActivities.get(token); 2346 if (r != null) { 2347 r.activity.onTranslucentConversionComplete(drawComplete); 2348 } 2349 } 2350 2351 public void handleInstallProvider(ProviderInfo info) { 2352 installContentProviders(mInitialApplication, Lists.newArrayList(info)); 2353 } 2354 2355 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 2356 2357 /** 2358 * Return the Intent that's currently being handled by a 2359 * BroadcastReceiver on this thread, or null if none. 2360 * @hide 2361 */ 2362 public static Intent getIntentBeingBroadcast() { 2363 return sCurrentBroadcastIntent.get(); 2364 } 2365 2366 private void handleReceiver(ReceiverData data) { 2367 // If we are getting ready to gc after going to the background, well 2368 // we are back active so skip it. 2369 unscheduleGcIdler(); 2370 2371 String component = data.intent.getComponent().getClassName(); 2372 2373 LoadedApk packageInfo = getPackageInfoNoCheck( 2374 data.info.applicationInfo, data.compatInfo); 2375 2376 IActivityManager mgr = ActivityManagerNative.getDefault(); 2377 2378 BroadcastReceiver receiver; 2379 try { 2380 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2381 data.intent.setExtrasClassLoader(cl); 2382 data.setExtrasClassLoader(cl); 2383 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance(); 2384 } catch (Exception e) { 2385 if (DEBUG_BROADCAST) Slog.i(TAG, 2386 "Finishing failed broadcast to " + data.intent.getComponent()); 2387 data.sendFinished(mgr); 2388 throw new RuntimeException( 2389 "Unable to instantiate receiver " + component 2390 + ": " + e.toString(), e); 2391 } 2392 2393 try { 2394 Application app = packageInfo.makeApplication(false, mInstrumentation); 2395 2396 if (localLOGV) Slog.v( 2397 TAG, "Performing receive of " + data.intent 2398 + ": app=" + app 2399 + ", appName=" + app.getPackageName() 2400 + ", pkg=" + packageInfo.getPackageName() 2401 + ", comp=" + data.intent.getComponent().toShortString() 2402 + ", dir=" + packageInfo.getAppDir()); 2403 2404 ContextImpl context = (ContextImpl)app.getBaseContext(); 2405 sCurrentBroadcastIntent.set(data.intent); 2406 receiver.setPendingResult(data); 2407 receiver.onReceive(context.getReceiverRestrictedContext(), 2408 data.intent); 2409 } catch (Exception e) { 2410 if (DEBUG_BROADCAST) Slog.i(TAG, 2411 "Finishing failed broadcast to " + data.intent.getComponent()); 2412 data.sendFinished(mgr); 2413 if (!mInstrumentation.onException(receiver, e)) { 2414 throw new RuntimeException( 2415 "Unable to start receiver " + component 2416 + ": " + e.toString(), e); 2417 } 2418 } finally { 2419 sCurrentBroadcastIntent.set(null); 2420 } 2421 2422 if (receiver.getPendingResult() != null) { 2423 data.finish(); 2424 } 2425 } 2426 2427 // Instantiate a BackupAgent and tell it that it's alive 2428 private void handleCreateBackupAgent(CreateBackupAgentData data) { 2429 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 2430 2431 // Sanity check the requested target package's uid against ours 2432 try { 2433 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 2434 data.appInfo.packageName, 0, UserHandle.myUserId()); 2435 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 2436 Slog.w(TAG, "Asked to instantiate non-matching package " 2437 + data.appInfo.packageName); 2438 return; 2439 } 2440 } catch (RemoteException e) { 2441 Slog.e(TAG, "Can't reach package manager", e); 2442 return; 2443 } 2444 2445 // no longer idle; we have backup work to do 2446 unscheduleGcIdler(); 2447 2448 // instantiate the BackupAgent class named in the manifest 2449 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2450 String packageName = packageInfo.mPackageName; 2451 if (packageName == null) { 2452 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 2453 return; 2454 } 2455 2456 if (mBackupAgents.get(packageName) != null) { 2457 Slog.d(TAG, "BackupAgent " + " for " + packageName 2458 + " already exists"); 2459 return; 2460 } 2461 2462 BackupAgent agent = null; 2463 String classname = data.appInfo.backupAgentName; 2464 2465 // full backup operation but no app-supplied agent? use the default implementation 2466 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL 2467 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) { 2468 classname = "android.app.backup.FullBackupAgent"; 2469 } 2470 2471 try { 2472 IBinder binder = null; 2473 try { 2474 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 2475 2476 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2477 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 2478 2479 // set up the agent's context 2480 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 2481 context.setOuterContext(agent); 2482 agent.attach(context); 2483 2484 agent.onCreate(); 2485 binder = agent.onBind(); 2486 mBackupAgents.put(packageName, agent); 2487 } catch (Exception e) { 2488 // If this is during restore, fail silently; otherwise go 2489 // ahead and let the user see the crash. 2490 Slog.e(TAG, "Agent threw during creation: " + e); 2491 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE 2492 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) { 2493 throw e; 2494 } 2495 // falling through with 'binder' still null 2496 } 2497 2498 // tell the OS that we're live now 2499 try { 2500 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder); 2501 } catch (RemoteException e) { 2502 // nothing to do. 2503 } 2504 } catch (Exception e) { 2505 throw new RuntimeException("Unable to create BackupAgent " 2506 + classname + ": " + e.toString(), e); 2507 } 2508 } 2509 2510 // Tear down a BackupAgent 2511 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 2512 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 2513 2514 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2515 String packageName = packageInfo.mPackageName; 2516 BackupAgent agent = mBackupAgents.get(packageName); 2517 if (agent != null) { 2518 try { 2519 agent.onDestroy(); 2520 } catch (Exception e) { 2521 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 2522 e.printStackTrace(); 2523 } 2524 mBackupAgents.remove(packageName); 2525 } else { 2526 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 2527 } 2528 } 2529 2530 private void handleCreateService(CreateServiceData data) { 2531 // If we are getting ready to gc after going to the background, well 2532 // we are back active so skip it. 2533 unscheduleGcIdler(); 2534 2535 LoadedApk packageInfo = getPackageInfoNoCheck( 2536 data.info.applicationInfo, data.compatInfo); 2537 Service service = null; 2538 try { 2539 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2540 service = (Service) cl.loadClass(data.info.name).newInstance(); 2541 } catch (Exception e) { 2542 if (!mInstrumentation.onException(service, e)) { 2543 throw new RuntimeException( 2544 "Unable to instantiate service " + data.info.name 2545 + ": " + e.toString(), e); 2546 } 2547 } 2548 2549 try { 2550 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 2551 2552 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 2553 context.setOuterContext(service); 2554 2555 Application app = packageInfo.makeApplication(false, mInstrumentation); 2556 service.attach(context, this, data.info.name, data.token, app, 2557 ActivityManagerNative.getDefault()); 2558 service.onCreate(); 2559 mServices.put(data.token, service); 2560 try { 2561 ActivityManagerNative.getDefault().serviceDoneExecuting( 2562 data.token, 0, 0, 0); 2563 } catch (RemoteException e) { 2564 // nothing to do. 2565 } 2566 } catch (Exception e) { 2567 if (!mInstrumentation.onException(service, e)) { 2568 throw new RuntimeException( 2569 "Unable to create service " + data.info.name 2570 + ": " + e.toString(), e); 2571 } 2572 } 2573 } 2574 2575 private void handleBindService(BindServiceData data) { 2576 Service s = mServices.get(data.token); 2577 if (DEBUG_SERVICE) 2578 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 2579 if (s != null) { 2580 try { 2581 data.intent.setExtrasClassLoader(s.getClassLoader()); 2582 try { 2583 if (!data.rebind) { 2584 IBinder binder = s.onBind(data.intent); 2585 ActivityManagerNative.getDefault().publishService( 2586 data.token, data.intent, binder); 2587 } else { 2588 s.onRebind(data.intent); 2589 ActivityManagerNative.getDefault().serviceDoneExecuting( 2590 data.token, 0, 0, 0); 2591 } 2592 ensureJitEnabled(); 2593 } catch (RemoteException ex) { 2594 } 2595 } catch (Exception e) { 2596 if (!mInstrumentation.onException(s, e)) { 2597 throw new RuntimeException( 2598 "Unable to bind to service " + s 2599 + " with " + data.intent + ": " + e.toString(), e); 2600 } 2601 } 2602 } 2603 } 2604 2605 private void handleUnbindService(BindServiceData data) { 2606 Service s = mServices.get(data.token); 2607 if (s != null) { 2608 try { 2609 data.intent.setExtrasClassLoader(s.getClassLoader()); 2610 boolean doRebind = s.onUnbind(data.intent); 2611 try { 2612 if (doRebind) { 2613 ActivityManagerNative.getDefault().unbindFinished( 2614 data.token, data.intent, doRebind); 2615 } else { 2616 ActivityManagerNative.getDefault().serviceDoneExecuting( 2617 data.token, 0, 0, 0); 2618 } 2619 } catch (RemoteException ex) { 2620 } 2621 } catch (Exception e) { 2622 if (!mInstrumentation.onException(s, e)) { 2623 throw new RuntimeException( 2624 "Unable to unbind to service " + s 2625 + " with " + data.intent + ": " + e.toString(), e); 2626 } 2627 } 2628 } 2629 } 2630 2631 private void handleDumpService(DumpComponentInfo info) { 2632 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2633 try { 2634 Service s = mServices.get(info.token); 2635 if (s != null) { 2636 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2637 info.fd.getFileDescriptor())); 2638 s.dump(info.fd.getFileDescriptor(), pw, info.args); 2639 pw.flush(); 2640 } 2641 } finally { 2642 IoUtils.closeQuietly(info.fd); 2643 StrictMode.setThreadPolicy(oldPolicy); 2644 } 2645 } 2646 2647 private void handleDumpActivity(DumpComponentInfo info) { 2648 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2649 try { 2650 ActivityClientRecord r = mActivities.get(info.token); 2651 if (r != null && r.activity != null) { 2652 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2653 info.fd.getFileDescriptor())); 2654 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 2655 pw.flush(); 2656 } 2657 } finally { 2658 IoUtils.closeQuietly(info.fd); 2659 StrictMode.setThreadPolicy(oldPolicy); 2660 } 2661 } 2662 2663 private void handleDumpProvider(DumpComponentInfo info) { 2664 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2665 try { 2666 ProviderClientRecord r = mLocalProviders.get(info.token); 2667 if (r != null && r.mLocalProvider != null) { 2668 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2669 info.fd.getFileDescriptor())); 2670 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 2671 pw.flush(); 2672 } 2673 } finally { 2674 IoUtils.closeQuietly(info.fd); 2675 StrictMode.setThreadPolicy(oldPolicy); 2676 } 2677 } 2678 2679 private void handleServiceArgs(ServiceArgsData data) { 2680 Service s = mServices.get(data.token); 2681 if (s != null) { 2682 try { 2683 if (data.args != null) { 2684 data.args.setExtrasClassLoader(s.getClassLoader()); 2685 } 2686 int res; 2687 if (!data.taskRemoved) { 2688 res = s.onStartCommand(data.args, data.flags, data.startId); 2689 } else { 2690 s.onTaskRemoved(data.args); 2691 res = Service.START_TASK_REMOVED_COMPLETE; 2692 } 2693 2694 QueuedWork.waitToFinish(); 2695 2696 try { 2697 ActivityManagerNative.getDefault().serviceDoneExecuting( 2698 data.token, 1, data.startId, res); 2699 } catch (RemoteException e) { 2700 // nothing to do. 2701 } 2702 ensureJitEnabled(); 2703 } catch (Exception e) { 2704 if (!mInstrumentation.onException(s, e)) { 2705 throw new RuntimeException( 2706 "Unable to start service " + s 2707 + " with " + data.args + ": " + e.toString(), e); 2708 } 2709 } 2710 } 2711 } 2712 2713 private void handleStopService(IBinder token) { 2714 Service s = mServices.remove(token); 2715 if (s != null) { 2716 try { 2717 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 2718 s.onDestroy(); 2719 Context context = s.getBaseContext(); 2720 if (context instanceof ContextImpl) { 2721 final String who = s.getClassName(); 2722 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 2723 } 2724 2725 QueuedWork.waitToFinish(); 2726 2727 try { 2728 ActivityManagerNative.getDefault().serviceDoneExecuting( 2729 token, 0, 0, 0); 2730 } catch (RemoteException e) { 2731 // nothing to do. 2732 } 2733 } catch (Exception e) { 2734 if (!mInstrumentation.onException(s, e)) { 2735 throw new RuntimeException( 2736 "Unable to stop service " + s 2737 + ": " + e.toString(), e); 2738 } 2739 } 2740 } 2741 //Slog.i(TAG, "Running services: " + mServices); 2742 } 2743 2744 public final ActivityClientRecord performResumeActivity(IBinder token, 2745 boolean clearHide) { 2746 ActivityClientRecord r = mActivities.get(token); 2747 if (localLOGV) Slog.v(TAG, "Performing resume of " + r 2748 + " finished=" + r.activity.mFinished); 2749 if (r != null && !r.activity.mFinished) { 2750 if (clearHide) { 2751 r.hideForNow = false; 2752 r.activity.mStartedActivity = false; 2753 } 2754 try { 2755 r.activity.mFragments.noteStateNotSaved(); 2756 if (r.pendingIntents != null) { 2757 deliverNewIntents(r, r.pendingIntents); 2758 r.pendingIntents = null; 2759 } 2760 if (r.pendingResults != null) { 2761 deliverResults(r, r.pendingResults); 2762 r.pendingResults = null; 2763 } 2764 r.activity.performResume(); 2765 2766 EventLog.writeEvent(LOG_ON_RESUME_CALLED, 2767 UserHandle.myUserId(), r.activity.getComponentName().getClassName()); 2768 2769 r.paused = false; 2770 r.stopped = false; 2771 r.state = null; 2772 } catch (Exception e) { 2773 if (!mInstrumentation.onException(r.activity, e)) { 2774 throw new RuntimeException( 2775 "Unable to resume activity " 2776 + r.intent.getComponent().toShortString() 2777 + ": " + e.toString(), e); 2778 } 2779 } 2780 } 2781 return r; 2782 } 2783 2784 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) { 2785 if (r.mPendingRemoveWindow != null) { 2786 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow); 2787 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken(); 2788 if (wtoken != null) { 2789 WindowManagerGlobal.getInstance().closeAll(wtoken, 2790 r.activity.getClass().getName(), "Activity"); 2791 } 2792 } 2793 r.mPendingRemoveWindow = null; 2794 r.mPendingRemoveWindowManager = null; 2795 } 2796 2797 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, 2798 boolean reallyResume) { 2799 // If we are getting ready to gc after going to the background, well 2800 // we are back active so skip it. 2801 unscheduleGcIdler(); 2802 2803 ActivityClientRecord r = performResumeActivity(token, clearHide); 2804 2805 if (r != null) { 2806 final Activity a = r.activity; 2807 2808 if (localLOGV) Slog.v( 2809 TAG, "Resume " + r + " started activity: " + 2810 a.mStartedActivity + ", hideForNow: " + r.hideForNow 2811 + ", finished: " + a.mFinished); 2812 2813 final int forwardBit = isForward ? 2814 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 2815 2816 // If the window hasn't yet been added to the window manager, 2817 // and this guy didn't finish itself or start another activity, 2818 // then go ahead and add the window. 2819 boolean willBeVisible = !a.mStartedActivity; 2820 if (!willBeVisible) { 2821 try { 2822 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( 2823 a.getActivityToken()); 2824 } catch (RemoteException e) { 2825 } 2826 } 2827 if (r.window == null && !a.mFinished && willBeVisible) { 2828 r.window = r.activity.getWindow(); 2829 View decor = r.window.getDecorView(); 2830 decor.setVisibility(View.INVISIBLE); 2831 ViewManager wm = a.getWindowManager(); 2832 WindowManager.LayoutParams l = r.window.getAttributes(); 2833 a.mDecor = decor; 2834 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 2835 l.softInputMode |= forwardBit; 2836 if (a.mVisibleFromClient) { 2837 a.mWindowAdded = true; 2838 wm.addView(decor, l); 2839 } 2840 2841 // If the window has already been added, but during resume 2842 // we started another activity, then don't yet make the 2843 // window visible. 2844 } else if (!willBeVisible) { 2845 if (localLOGV) Slog.v( 2846 TAG, "Launch " + r + " mStartedActivity set"); 2847 r.hideForNow = true; 2848 } 2849 2850 // Get rid of anything left hanging around. 2851 cleanUpPendingRemoveWindows(r); 2852 2853 // The window is now visible if it has been added, we are not 2854 // simply finishing, and we are not starting another activity. 2855 if (!r.activity.mFinished && willBeVisible 2856 && r.activity.mDecor != null && !r.hideForNow) { 2857 if (r.newConfig != null) { 2858 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 2859 + r.activityInfo.name + " with newConfig " + r.newConfig); 2860 performConfigurationChanged(r.activity, r.newConfig); 2861 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 2862 r.newConfig = null; 2863 } 2864 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 2865 + isForward); 2866 WindowManager.LayoutParams l = r.window.getAttributes(); 2867 if ((l.softInputMode 2868 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 2869 != forwardBit) { 2870 l.softInputMode = (l.softInputMode 2871 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 2872 | forwardBit; 2873 if (r.activity.mVisibleFromClient) { 2874 ViewManager wm = a.getWindowManager(); 2875 View decor = r.window.getDecorView(); 2876 wm.updateViewLayout(decor, l); 2877 } 2878 } 2879 r.activity.mVisibleFromServer = true; 2880 mNumVisibleActivities++; 2881 if (r.activity.mVisibleFromClient) { 2882 r.activity.makeVisible(); 2883 } 2884 } 2885 2886 if (!r.onlyLocalRequest) { 2887 r.nextIdle = mNewActivities; 2888 mNewActivities = r; 2889 if (localLOGV) Slog.v( 2890 TAG, "Scheduling idle handler for " + r); 2891 Looper.myQueue().addIdleHandler(new Idler()); 2892 } 2893 r.onlyLocalRequest = false; 2894 2895 // Tell the activity manager we have resumed. 2896 if (reallyResume) { 2897 try { 2898 ActivityManagerNative.getDefault().activityResumed(token); 2899 } catch (RemoteException ex) { 2900 } 2901 } 2902 2903 } else { 2904 // If an exception was thrown when trying to resume, then 2905 // just end this activity. 2906 try { 2907 ActivityManagerNative.getDefault() 2908 .finishActivity(token, Activity.RESULT_CANCELED, null); 2909 } catch (RemoteException ex) { 2910 } 2911 } 2912 } 2913 2914 private int mThumbnailWidth = -1; 2915 private int mThumbnailHeight = -1; 2916 private Bitmap mAvailThumbnailBitmap = null; 2917 private Canvas mThumbnailCanvas = null; 2918 2919 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 2920 Bitmap thumbnail = mAvailThumbnailBitmap; 2921 try { 2922 if (thumbnail == null) { 2923 int w = mThumbnailWidth; 2924 int h; 2925 if (w < 0) { 2926 Resources res = r.activity.getResources(); 2927 mThumbnailHeight = h = 2928 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2929 2930 mThumbnailWidth = w = 2931 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2932 } else { 2933 h = mThumbnailHeight; 2934 } 2935 2936 // On platforms where we don't want thumbnails, set dims to (0,0) 2937 if ((w > 0) && (h > 0)) { 2938 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 2939 w, h, THUMBNAIL_FORMAT); 2940 thumbnail.eraseColor(0); 2941 } 2942 } 2943 2944 if (thumbnail != null) { 2945 Canvas cv = mThumbnailCanvas; 2946 if (cv == null) { 2947 mThumbnailCanvas = cv = new Canvas(); 2948 } 2949 2950 cv.setBitmap(thumbnail); 2951 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 2952 mAvailThumbnailBitmap = thumbnail; 2953 thumbnail = null; 2954 } 2955 cv.setBitmap(null); 2956 } 2957 2958 } catch (Exception e) { 2959 if (!mInstrumentation.onException(r.activity, e)) { 2960 throw new RuntimeException( 2961 "Unable to create thumbnail of " 2962 + r.intent.getComponent().toShortString() 2963 + ": " + e.toString(), e); 2964 } 2965 thumbnail = null; 2966 } 2967 2968 return thumbnail; 2969 } 2970 2971 private void handlePauseActivity(IBinder token, boolean finished, 2972 boolean userLeaving, int configChanges) { 2973 ActivityClientRecord r = mActivities.get(token); 2974 if (r != null) { 2975 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 2976 if (userLeaving) { 2977 performUserLeavingActivity(r); 2978 } 2979 2980 r.activity.mConfigChangeFlags |= configChanges; 2981 performPauseActivity(token, finished, r.isPreHoneycomb()); 2982 2983 // Make sure any pending writes are now committed. 2984 if (r.isPreHoneycomb()) { 2985 QueuedWork.waitToFinish(); 2986 } 2987 2988 // Tell the activity manager we have paused. 2989 try { 2990 ActivityManagerNative.getDefault().activityPaused(token); 2991 } catch (RemoteException ex) { 2992 } 2993 } 2994 } 2995 2996 final void performUserLeavingActivity(ActivityClientRecord r) { 2997 mInstrumentation.callActivityOnUserLeaving(r.activity); 2998 } 2999 3000 final Bundle performPauseActivity(IBinder token, boolean finished, 3001 boolean saveState) { 3002 ActivityClientRecord r = mActivities.get(token); 3003 return r != null ? performPauseActivity(r, finished, saveState) : null; 3004 } 3005 3006 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3007 boolean saveState) { 3008 if (r.paused) { 3009 if (r.activity.mFinished) { 3010 // If we are finishing, we won't call onResume() in certain cases. 3011 // So here we likewise don't want to call onPause() if the activity 3012 // isn't resumed. 3013 return null; 3014 } 3015 RuntimeException e = new RuntimeException( 3016 "Performing pause of activity that is not resumed: " 3017 + r.intent.getComponent().toShortString()); 3018 Slog.e(TAG, e.getMessage(), e); 3019 } 3020 Bundle state = null; 3021 if (finished) { 3022 r.activity.mFinished = true; 3023 } 3024 try { 3025 // Next have the activity save its current state and managed dialogs... 3026 if (!r.activity.mFinished && saveState) { 3027 state = new Bundle(); 3028 state.setAllowFds(false); 3029 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 3030 r.state = state; 3031 } 3032 // Now we are idle. 3033 r.activity.mCalled = false; 3034 mInstrumentation.callActivityOnPause(r.activity); 3035 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3036 r.activity.getComponentName().getClassName()); 3037 if (!r.activity.mCalled) { 3038 throw new SuperNotCalledException( 3039 "Activity " + r.intent.getComponent().toShortString() + 3040 " did not call through to super.onPause()"); 3041 } 3042 3043 } catch (SuperNotCalledException e) { 3044 throw e; 3045 3046 } catch (Exception e) { 3047 if (!mInstrumentation.onException(r.activity, e)) { 3048 throw new RuntimeException( 3049 "Unable to pause activity " 3050 + r.intent.getComponent().toShortString() 3051 + ": " + e.toString(), e); 3052 } 3053 } 3054 r.paused = true; 3055 3056 // Notify any outstanding on paused listeners 3057 ArrayList<OnActivityPausedListener> listeners; 3058 synchronized (mOnPauseListeners) { 3059 listeners = mOnPauseListeners.remove(r.activity); 3060 } 3061 int size = (listeners != null ? listeners.size() : 0); 3062 for (int i = 0; i < size; i++) { 3063 listeners.get(i).onPaused(r.activity); 3064 } 3065 3066 return state; 3067 } 3068 3069 final void performStopActivity(IBinder token, boolean saveState) { 3070 ActivityClientRecord r = mActivities.get(token); 3071 performStopActivityInner(r, null, false, saveState); 3072 } 3073 3074 private static class StopInfo implements Runnable { 3075 ActivityClientRecord activity; 3076 Bundle state; 3077 Bitmap thumbnail; 3078 CharSequence description; 3079 3080 @Override public void run() { 3081 // Tell activity manager we have been stopped. 3082 try { 3083 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3084 ActivityManagerNative.getDefault().activityStopped( 3085 activity.token, state, thumbnail, description); 3086 } catch (RemoteException ex) { 3087 } 3088 } 3089 } 3090 3091 private static final class ProviderRefCount { 3092 public final IActivityManager.ContentProviderHolder holder; 3093 public final ProviderClientRecord client; 3094 public int stableCount; 3095 public int unstableCount; 3096 3097 // When this is set, the stable and unstable ref counts are 0 and 3098 // we have a pending operation scheduled to remove the ref count 3099 // from the activity manager. On the activity manager we are still 3100 // holding an unstable ref, though it is not reflected in the counts 3101 // here. 3102 public boolean removePending; 3103 3104 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3105 ProviderClientRecord inClient, int sCount, int uCount) { 3106 holder = inHolder; 3107 client = inClient; 3108 stableCount = sCount; 3109 unstableCount = uCount; 3110 } 3111 } 3112 3113 /** 3114 * Core implementation of stopping an activity. Note this is a little 3115 * tricky because the server's meaning of stop is slightly different 3116 * than our client -- for the server, stop means to save state and give 3117 * it the result when it is done, but the window may still be visible. 3118 * For the client, we want to call onStop()/onStart() to indicate when 3119 * the activity's UI visibillity changes. 3120 */ 3121 private void performStopActivityInner(ActivityClientRecord r, 3122 StopInfo info, boolean keepShown, boolean saveState) { 3123 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3124 Bundle state = null; 3125 if (r != null) { 3126 if (!keepShown && r.stopped) { 3127 if (r.activity.mFinished) { 3128 // If we are finishing, we won't call onResume() in certain 3129 // cases. So here we likewise don't want to call onStop() 3130 // if the activity isn't resumed. 3131 return; 3132 } 3133 RuntimeException e = new RuntimeException( 3134 "Performing stop of activity that is not resumed: " 3135 + r.intent.getComponent().toShortString()); 3136 Slog.e(TAG, e.getMessage(), e); 3137 } 3138 3139 if (info != null) { 3140 try { 3141 // First create a thumbnail for the activity... 3142 // For now, don't create the thumbnail here; we are 3143 // doing that by doing a screen snapshot. 3144 info.thumbnail = null; //createThumbnailBitmap(r); 3145 info.description = r.activity.onCreateDescription(); 3146 } catch (Exception e) { 3147 if (!mInstrumentation.onException(r.activity, e)) { 3148 throw new RuntimeException( 3149 "Unable to save state of activity " 3150 + r.intent.getComponent().toShortString() 3151 + ": " + e.toString(), e); 3152 } 3153 } 3154 } 3155 3156 // Next have the activity save its current state and managed dialogs... 3157 if (!r.activity.mFinished && saveState) { 3158 if (r.state == null) { 3159 state = new Bundle(); 3160 state.setAllowFds(false); 3161 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 3162 r.state = state; 3163 } else { 3164 state = r.state; 3165 } 3166 } 3167 3168 if (!keepShown) { 3169 try { 3170 // Now we are idle. 3171 r.activity.performStop(); 3172 } catch (Exception e) { 3173 if (!mInstrumentation.onException(r.activity, e)) { 3174 throw new RuntimeException( 3175 "Unable to stop activity " 3176 + r.intent.getComponent().toShortString() 3177 + ": " + e.toString(), e); 3178 } 3179 } 3180 r.stopped = true; 3181 } 3182 3183 r.paused = true; 3184 } 3185 } 3186 3187 private void updateVisibility(ActivityClientRecord r, boolean show) { 3188 View v = r.activity.mDecor; 3189 if (v != null) { 3190 if (show) { 3191 if (!r.activity.mVisibleFromServer) { 3192 r.activity.mVisibleFromServer = true; 3193 mNumVisibleActivities++; 3194 if (r.activity.mVisibleFromClient) { 3195 r.activity.makeVisible(); 3196 } 3197 } 3198 if (r.newConfig != null) { 3199 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3200 + r.activityInfo.name + " with new config " + r.newConfig); 3201 performConfigurationChanged(r.activity, r.newConfig); 3202 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 3203 r.newConfig = null; 3204 } 3205 } else { 3206 if (r.activity.mVisibleFromServer) { 3207 r.activity.mVisibleFromServer = false; 3208 mNumVisibleActivities--; 3209 v.setVisibility(View.INVISIBLE); 3210 } 3211 } 3212 } 3213 } 3214 3215 private void handleStopActivity(IBinder token, boolean show, int configChanges) { 3216 ActivityClientRecord r = mActivities.get(token); 3217 r.activity.mConfigChangeFlags |= configChanges; 3218 3219 StopInfo info = new StopInfo(); 3220 performStopActivityInner(r, info, show, true); 3221 3222 if (localLOGV) Slog.v( 3223 TAG, "Finishing stop of " + r + ": show=" + show 3224 + " win=" + r.window); 3225 3226 updateVisibility(r, show); 3227 3228 // Make sure any pending writes are now committed. 3229 if (!r.isPreHoneycomb()) { 3230 QueuedWork.waitToFinish(); 3231 } 3232 3233 // Schedule the call to tell the activity manager we have 3234 // stopped. We don't do this immediately, because we want to 3235 // have a chance for any other pending work (in particular memory 3236 // trim requests) to complete before you tell the activity 3237 // manager to proceed and allow us to go fully into the background. 3238 info.activity = r; 3239 info.state = r.state; 3240 mH.post(info); 3241 } 3242 3243 final void performRestartActivity(IBinder token) { 3244 ActivityClientRecord r = mActivities.get(token); 3245 if (r.stopped) { 3246 r.activity.performRestart(); 3247 r.stopped = false; 3248 } 3249 } 3250 3251 private void handleWindowVisibility(IBinder token, boolean show) { 3252 ActivityClientRecord r = mActivities.get(token); 3253 3254 if (r == null) { 3255 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3256 return; 3257 } 3258 3259 if (!show && !r.stopped) { 3260 performStopActivityInner(r, null, show, false); 3261 } else if (show && r.stopped) { 3262 // If we are getting ready to gc after going to the background, well 3263 // we are back active so skip it. 3264 unscheduleGcIdler(); 3265 3266 r.activity.performRestart(); 3267 r.stopped = false; 3268 } 3269 if (r.activity.mDecor != null) { 3270 if (false) Slog.v( 3271 TAG, "Handle window " + r + " visibility: " + show); 3272 updateVisibility(r, show); 3273 } 3274 } 3275 3276 private void handleSleeping(IBinder token, boolean sleeping) { 3277 ActivityClientRecord r = mActivities.get(token); 3278 3279 if (r == null) { 3280 Log.w(TAG, "handleSleeping: no activity for token " + token); 3281 return; 3282 } 3283 3284 if (sleeping) { 3285 if (!r.stopped && !r.isPreHoneycomb()) { 3286 try { 3287 // Now we are idle. 3288 r.activity.performStop(); 3289 } catch (Exception e) { 3290 if (!mInstrumentation.onException(r.activity, e)) { 3291 throw new RuntimeException( 3292 "Unable to stop activity " 3293 + r.intent.getComponent().toShortString() 3294 + ": " + e.toString(), e); 3295 } 3296 } 3297 r.stopped = true; 3298 } 3299 3300 // Make sure any pending writes are now committed. 3301 if (!r.isPreHoneycomb()) { 3302 QueuedWork.waitToFinish(); 3303 } 3304 3305 // Tell activity manager we slept. 3306 try { 3307 ActivityManagerNative.getDefault().activitySlept(r.token); 3308 } catch (RemoteException ex) { 3309 } 3310 } else { 3311 if (r.stopped && r.activity.mVisibleFromServer) { 3312 r.activity.performRestart(); 3313 r.stopped = false; 3314 } 3315 } 3316 } 3317 3318 private void handleSetCoreSettings(Bundle coreSettings) { 3319 synchronized (mResourcesManager) { 3320 mCoreSettings = coreSettings; 3321 } 3322 } 3323 3324 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3325 LoadedApk apk = peekPackageInfo(data.pkg, false); 3326 if (apk != null) { 3327 apk.setCompatibilityInfo(data.info); 3328 } 3329 apk = peekPackageInfo(data.pkg, true); 3330 if (apk != null) { 3331 apk.setCompatibilityInfo(data.info); 3332 } 3333 handleConfigurationChanged(mConfiguration, data.info); 3334 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3335 } 3336 3337 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3338 final int N = results.size(); 3339 for (int i=0; i<N; i++) { 3340 ResultInfo ri = results.get(i); 3341 try { 3342 if (ri.mData != null) { 3343 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3344 } 3345 if (DEBUG_RESULTS) Slog.v(TAG, 3346 "Delivering result to activity " + r + " : " + ri); 3347 r.activity.dispatchActivityResult(ri.mResultWho, 3348 ri.mRequestCode, ri.mResultCode, ri.mData); 3349 } catch (Exception e) { 3350 if (!mInstrumentation.onException(r.activity, e)) { 3351 throw new RuntimeException( 3352 "Failure delivering result " + ri + " to activity " 3353 + r.intent.getComponent().toShortString() 3354 + ": " + e.toString(), e); 3355 } 3356 } 3357 } 3358 } 3359 3360 private void handleSendResult(ResultData res) { 3361 ActivityClientRecord r = mActivities.get(res.token); 3362 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3363 if (r != null) { 3364 final boolean resumed = !r.paused; 3365 if (!r.activity.mFinished && r.activity.mDecor != null 3366 && r.hideForNow && resumed) { 3367 // We had hidden the activity because it started another 3368 // one... we have gotten a result back and we are not 3369 // paused, so make sure our window is visible. 3370 updateVisibility(r, true); 3371 } 3372 if (resumed) { 3373 try { 3374 // Now we are idle. 3375 r.activity.mCalled = false; 3376 r.activity.mTemporaryPause = true; 3377 mInstrumentation.callActivityOnPause(r.activity); 3378 if (!r.activity.mCalled) { 3379 throw new SuperNotCalledException( 3380 "Activity " + r.intent.getComponent().toShortString() 3381 + " did not call through to super.onPause()"); 3382 } 3383 } catch (SuperNotCalledException e) { 3384 throw e; 3385 } catch (Exception e) { 3386 if (!mInstrumentation.onException(r.activity, e)) { 3387 throw new RuntimeException( 3388 "Unable to pause activity " 3389 + r.intent.getComponent().toShortString() 3390 + ": " + e.toString(), e); 3391 } 3392 } 3393 } 3394 deliverResults(r, res.results); 3395 if (resumed) { 3396 r.activity.performResume(); 3397 r.activity.mTemporaryPause = false; 3398 } 3399 } 3400 } 3401 3402 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 3403 return performDestroyActivity(token, finishing, 0, false); 3404 } 3405 3406 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 3407 int configChanges, boolean getNonConfigInstance) { 3408 ActivityClientRecord r = mActivities.get(token); 3409 Class<? extends Activity> activityClass = null; 3410 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 3411 if (r != null) { 3412 activityClass = r.activity.getClass(); 3413 r.activity.mConfigChangeFlags |= configChanges; 3414 if (finishing) { 3415 r.activity.mFinished = true; 3416 } 3417 if (!r.paused) { 3418 try { 3419 r.activity.mCalled = false; 3420 mInstrumentation.callActivityOnPause(r.activity); 3421 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3422 r.activity.getComponentName().getClassName()); 3423 if (!r.activity.mCalled) { 3424 throw new SuperNotCalledException( 3425 "Activity " + safeToComponentShortString(r.intent) 3426 + " did not call through to super.onPause()"); 3427 } 3428 } catch (SuperNotCalledException e) { 3429 throw e; 3430 } catch (Exception e) { 3431 if (!mInstrumentation.onException(r.activity, e)) { 3432 throw new RuntimeException( 3433 "Unable to pause activity " 3434 + safeToComponentShortString(r.intent) 3435 + ": " + e.toString(), e); 3436 } 3437 } 3438 r.paused = true; 3439 } 3440 if (!r.stopped) { 3441 try { 3442 r.activity.performStop(); 3443 } catch (SuperNotCalledException e) { 3444 throw e; 3445 } catch (Exception e) { 3446 if (!mInstrumentation.onException(r.activity, e)) { 3447 throw new RuntimeException( 3448 "Unable to stop activity " 3449 + safeToComponentShortString(r.intent) 3450 + ": " + e.toString(), e); 3451 } 3452 } 3453 r.stopped = true; 3454 } 3455 if (getNonConfigInstance) { 3456 try { 3457 r.lastNonConfigurationInstances 3458 = r.activity.retainNonConfigurationInstances(); 3459 } catch (Exception e) { 3460 if (!mInstrumentation.onException(r.activity, e)) { 3461 throw new RuntimeException( 3462 "Unable to retain activity " 3463 + r.intent.getComponent().toShortString() 3464 + ": " + e.toString(), e); 3465 } 3466 } 3467 } 3468 try { 3469 r.activity.mCalled = false; 3470 mInstrumentation.callActivityOnDestroy(r.activity); 3471 if (!r.activity.mCalled) { 3472 throw new SuperNotCalledException( 3473 "Activity " + safeToComponentShortString(r.intent) + 3474 " did not call through to super.onDestroy()"); 3475 } 3476 if (r.window != null) { 3477 r.window.closeAllPanels(); 3478 } 3479 } catch (SuperNotCalledException e) { 3480 throw e; 3481 } catch (Exception e) { 3482 if (!mInstrumentation.onException(r.activity, e)) { 3483 throw new RuntimeException( 3484 "Unable to destroy activity " + safeToComponentShortString(r.intent) 3485 + ": " + e.toString(), e); 3486 } 3487 } 3488 } 3489 mActivities.remove(token); 3490 StrictMode.decrementExpectedActivityCount(activityClass); 3491 return r; 3492 } 3493 3494 private static String safeToComponentShortString(Intent intent) { 3495 ComponentName component = intent.getComponent(); 3496 return component == null ? "[Unknown]" : component.toShortString(); 3497 } 3498 3499 private void handleDestroyActivity(IBinder token, boolean finishing, 3500 int configChanges, boolean getNonConfigInstance) { 3501 ActivityClientRecord r = performDestroyActivity(token, finishing, 3502 configChanges, getNonConfigInstance); 3503 if (r != null) { 3504 cleanUpPendingRemoveWindows(r); 3505 WindowManager wm = r.activity.getWindowManager(); 3506 View v = r.activity.mDecor; 3507 if (v != null) { 3508 if (r.activity.mVisibleFromServer) { 3509 mNumVisibleActivities--; 3510 } 3511 IBinder wtoken = v.getWindowToken(); 3512 if (r.activity.mWindowAdded) { 3513 if (r.onlyLocalRequest) { 3514 // Hold off on removing this until the new activity's 3515 // window is being added. 3516 r.mPendingRemoveWindow = v; 3517 r.mPendingRemoveWindowManager = wm; 3518 } else { 3519 wm.removeViewImmediate(v); 3520 } 3521 } 3522 if (wtoken != null && r.mPendingRemoveWindow == null) { 3523 WindowManagerGlobal.getInstance().closeAll(wtoken, 3524 r.activity.getClass().getName(), "Activity"); 3525 } 3526 r.activity.mDecor = null; 3527 } 3528 if (r.mPendingRemoveWindow == null) { 3529 // If we are delaying the removal of the activity window, then 3530 // we can't clean up all windows here. Note that we can't do 3531 // so later either, which means any windows that aren't closed 3532 // by the app will leak. Well we try to warning them a lot 3533 // about leaking windows, because that is a bug, so if they are 3534 // using this recreate facility then they get to live with leaks. 3535 WindowManagerGlobal.getInstance().closeAll(token, 3536 r.activity.getClass().getName(), "Activity"); 3537 } 3538 3539 // Mocked out contexts won't be participating in the normal 3540 // process lifecycle, but if we're running with a proper 3541 // ApplicationContext we need to have it tear down things 3542 // cleanly. 3543 Context c = r.activity.getBaseContext(); 3544 if (c instanceof ContextImpl) { 3545 ((ContextImpl) c).scheduleFinalCleanup( 3546 r.activity.getClass().getName(), "Activity"); 3547 } 3548 } 3549 if (finishing) { 3550 try { 3551 ActivityManagerNative.getDefault().activityDestroyed(token); 3552 } catch (RemoteException ex) { 3553 // If the system process has died, it's game over for everyone. 3554 } 3555 } 3556 } 3557 3558 public final void requestRelaunchActivity(IBinder token, 3559 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 3560 int configChanges, boolean notResumed, Configuration config, 3561 boolean fromServer) { 3562 ActivityClientRecord target = null; 3563 3564 synchronized (mResourcesManager) { 3565 for (int i=0; i<mRelaunchingActivities.size(); i++) { 3566 ActivityClientRecord r = mRelaunchingActivities.get(i); 3567 if (r.token == token) { 3568 target = r; 3569 if (pendingResults != null) { 3570 if (r.pendingResults != null) { 3571 r.pendingResults.addAll(pendingResults); 3572 } else { 3573 r.pendingResults = pendingResults; 3574 } 3575 } 3576 if (pendingNewIntents != null) { 3577 if (r.pendingIntents != null) { 3578 r.pendingIntents.addAll(pendingNewIntents); 3579 } else { 3580 r.pendingIntents = pendingNewIntents; 3581 } 3582 } 3583 break; 3584 } 3585 } 3586 3587 if (target == null) { 3588 target = new ActivityClientRecord(); 3589 target.token = token; 3590 target.pendingResults = pendingResults; 3591 target.pendingIntents = pendingNewIntents; 3592 if (!fromServer) { 3593 ActivityClientRecord existing = mActivities.get(token); 3594 if (existing != null) { 3595 target.startsNotResumed = existing.paused; 3596 } 3597 target.onlyLocalRequest = true; 3598 } 3599 mRelaunchingActivities.add(target); 3600 sendMessage(H.RELAUNCH_ACTIVITY, target); 3601 } 3602 3603 if (fromServer) { 3604 target.startsNotResumed = notResumed; 3605 target.onlyLocalRequest = false; 3606 } 3607 if (config != null) { 3608 target.createdConfig = config; 3609 } 3610 target.pendingConfigChanges |= configChanges; 3611 } 3612 } 3613 3614 private void handleRelaunchActivity(ActivityClientRecord tmp) { 3615 // If we are getting ready to gc after going to the background, well 3616 // we are back active so skip it. 3617 unscheduleGcIdler(); 3618 3619 Configuration changedConfig = null; 3620 int configChanges = 0; 3621 3622 // First: make sure we have the most recent configuration and most 3623 // recent version of the activity, or skip it if some previous call 3624 // had taken a more recent version. 3625 synchronized (mResourcesManager) { 3626 int N = mRelaunchingActivities.size(); 3627 IBinder token = tmp.token; 3628 tmp = null; 3629 for (int i=0; i<N; i++) { 3630 ActivityClientRecord r = mRelaunchingActivities.get(i); 3631 if (r.token == token) { 3632 tmp = r; 3633 configChanges |= tmp.pendingConfigChanges; 3634 mRelaunchingActivities.remove(i); 3635 i--; 3636 N--; 3637 } 3638 } 3639 3640 if (tmp == null) { 3641 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 3642 return; 3643 } 3644 3645 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3646 + tmp.token + " with configChanges=0x" 3647 + Integer.toHexString(configChanges)); 3648 3649 if (mPendingConfiguration != null) { 3650 changedConfig = mPendingConfiguration; 3651 mPendingConfiguration = null; 3652 } 3653 } 3654 3655 if (tmp.createdConfig != null) { 3656 // If the activity manager is passing us its current config, 3657 // assume that is really what we want regardless of what we 3658 // may have pending. 3659 if (mConfiguration == null 3660 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 3661 && mConfiguration.diff(tmp.createdConfig) != 0)) { 3662 if (changedConfig == null 3663 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 3664 changedConfig = tmp.createdConfig; 3665 } 3666 } 3667 } 3668 3669 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3670 + tmp.token + ": changedConfig=" + changedConfig); 3671 3672 // If there was a pending configuration change, execute it first. 3673 if (changedConfig != null) { 3674 mCurDefaultDisplayDpi = changedConfig.densityDpi; 3675 updateDefaultDensity(); 3676 handleConfigurationChanged(changedConfig, null); 3677 } 3678 3679 ActivityClientRecord r = mActivities.get(tmp.token); 3680 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 3681 if (r == null) { 3682 return; 3683 } 3684 3685 r.activity.mConfigChangeFlags |= configChanges; 3686 r.onlyLocalRequest = tmp.onlyLocalRequest; 3687 Intent currentIntent = r.activity.mIntent; 3688 3689 r.activity.mChangingConfigurations = true; 3690 3691 // Need to ensure state is saved. 3692 if (!r.paused) { 3693 performPauseActivity(r.token, false, r.isPreHoneycomb()); 3694 } 3695 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 3696 r.state = new Bundle(); 3697 r.state.setAllowFds(false); 3698 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 3699 } 3700 3701 handleDestroyActivity(r.token, false, configChanges, true); 3702 3703 r.activity = null; 3704 r.window = null; 3705 r.hideForNow = false; 3706 r.nextIdle = null; 3707 // Merge any pending results and pending intents; don't just replace them 3708 if (tmp.pendingResults != null) { 3709 if (r.pendingResults == null) { 3710 r.pendingResults = tmp.pendingResults; 3711 } else { 3712 r.pendingResults.addAll(tmp.pendingResults); 3713 } 3714 } 3715 if (tmp.pendingIntents != null) { 3716 if (r.pendingIntents == null) { 3717 r.pendingIntents = tmp.pendingIntents; 3718 } else { 3719 r.pendingIntents.addAll(tmp.pendingIntents); 3720 } 3721 } 3722 r.startsNotResumed = tmp.startsNotResumed; 3723 3724 handleLaunchActivity(r, currentIntent); 3725 } 3726 3727 private void handleRequestThumbnail(IBinder token) { 3728 ActivityClientRecord r = mActivities.get(token); 3729 Bitmap thumbnail = createThumbnailBitmap(r); 3730 CharSequence description = null; 3731 try { 3732 description = r.activity.onCreateDescription(); 3733 } catch (Exception e) { 3734 if (!mInstrumentation.onException(r.activity, e)) { 3735 throw new RuntimeException( 3736 "Unable to create description of activity " 3737 + r.intent.getComponent().toShortString() 3738 + ": " + e.toString(), e); 3739 } 3740 } 3741 //System.out.println("Reporting top thumbnail " + thumbnail); 3742 try { 3743 ActivityManagerNative.getDefault().reportThumbnail( 3744 token, thumbnail, description); 3745 } catch (RemoteException ex) { 3746 } 3747 } 3748 3749 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 3750 boolean allActivities, Configuration newConfig) { 3751 ArrayList<ComponentCallbacks2> callbacks 3752 = new ArrayList<ComponentCallbacks2>(); 3753 3754 synchronized (mResourcesManager) { 3755 final int NAPP = mAllApplications.size(); 3756 for (int i=0; i<NAPP; i++) { 3757 callbacks.add(mAllApplications.get(i)); 3758 } 3759 final int NACT = mActivities.size(); 3760 for (int i=0; i<NACT; i++) { 3761 ActivityClientRecord ar = mActivities.valueAt(i); 3762 Activity a = ar.activity; 3763 if (a != null) { 3764 Configuration thisConfig = applyConfigCompatMainThread( 3765 mCurDefaultDisplayDpi, newConfig, 3766 ar.packageInfo.getCompatibilityInfo()); 3767 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 3768 // If the activity is currently resumed, its configuration 3769 // needs to change right now. 3770 callbacks.add(a); 3771 } else if (thisConfig != null) { 3772 // Otherwise, we will tell it about the change 3773 // the next time it is resumed or shown. Note that 3774 // the activity manager may, before then, decide the 3775 // activity needs to be destroyed to handle its new 3776 // configuration. 3777 if (DEBUG_CONFIGURATION) { 3778 Slog.v(TAG, "Setting activity " 3779 + ar.activityInfo.name + " newConfig=" + thisConfig); 3780 } 3781 ar.newConfig = thisConfig; 3782 } 3783 } 3784 } 3785 final int NSVC = mServices.size(); 3786 for (int i=0; i<NSVC; i++) { 3787 callbacks.add(mServices.valueAt(i)); 3788 } 3789 } 3790 synchronized (mProviderMap) { 3791 final int NPRV = mLocalProviders.size(); 3792 for (int i=0; i<NPRV; i++) { 3793 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 3794 } 3795 } 3796 3797 return callbacks; 3798 } 3799 3800 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { 3801 // Only for Activity objects, check that they actually call up to their 3802 // superclass implementation. ComponentCallbacks2 is an interface, so 3803 // we check the runtime type and act accordingly. 3804 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 3805 if (activity != null) { 3806 activity.mCalled = false; 3807 } 3808 3809 boolean shouldChangeConfig = false; 3810 if ((activity == null) || (activity.mCurrentConfig == null)) { 3811 shouldChangeConfig = true; 3812 } else { 3813 3814 // If the new config is the same as the config this Activity 3815 // is already running with then don't bother calling 3816 // onConfigurationChanged 3817 int diff = activity.mCurrentConfig.diff(config); 3818 if (diff != 0) { 3819 // If this activity doesn't handle any of the config changes 3820 // then don't bother calling onConfigurationChanged as we're 3821 // going to destroy it. 3822 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) { 3823 shouldChangeConfig = true; 3824 } 3825 } 3826 } 3827 3828 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 3829 + ": shouldChangeConfig=" + shouldChangeConfig); 3830 if (shouldChangeConfig) { 3831 cb.onConfigurationChanged(config); 3832 3833 if (activity != null) { 3834 if (!activity.mCalled) { 3835 throw new SuperNotCalledException( 3836 "Activity " + activity.getLocalClassName() + 3837 " did not call through to super.onConfigurationChanged()"); 3838 } 3839 activity.mConfigChangeFlags = 0; 3840 activity.mCurrentConfig = new Configuration(config); 3841 } 3842 } 3843 } 3844 3845 public final void applyConfigurationToResources(Configuration config) { 3846 synchronized (mResourcesManager) { 3847 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 3848 } 3849 } 3850 3851 final Configuration applyCompatConfiguration(int displayDensity) { 3852 Configuration config = mConfiguration; 3853 if (mCompatConfiguration == null) { 3854 mCompatConfiguration = new Configuration(); 3855 } 3856 mCompatConfiguration.setTo(mConfiguration); 3857 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { 3858 config = mCompatConfiguration; 3859 } 3860 return config; 3861 } 3862 3863 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 3864 3865 int configDiff = 0; 3866 3867 synchronized (mResourcesManager) { 3868 if (mPendingConfiguration != null) { 3869 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 3870 config = mPendingConfiguration; 3871 mCurDefaultDisplayDpi = config.densityDpi; 3872 updateDefaultDensity(); 3873 } 3874 mPendingConfiguration = null; 3875 } 3876 3877 if (config == null) { 3878 return; 3879 } 3880 3881 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 3882 + config); 3883 3884 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 3885 3886 if (mConfiguration == null) { 3887 mConfiguration = new Configuration(); 3888 } 3889 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 3890 return; 3891 } 3892 configDiff = mConfiguration.diff(config); 3893 mConfiguration.updateFrom(config); 3894 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 3895 } 3896 3897 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 3898 3899 // Cleanup hardware accelerated stuff 3900 WindowManagerGlobal.getInstance().trimLocalMemory(); 3901 3902 freeTextLayoutCachesIfNeeded(configDiff); 3903 3904 if (callbacks != null) { 3905 final int N = callbacks.size(); 3906 for (int i=0; i<N; i++) { 3907 performConfigurationChanged(callbacks.get(i), config); 3908 } 3909 } 3910 } 3911 3912 static void freeTextLayoutCachesIfNeeded(int configDiff) { 3913 if (configDiff != 0) { 3914 // Ask text layout engine to free its caches if there is a locale change 3915 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 3916 if (hasLocaleConfigChange) { 3917 Canvas.freeTextLayoutCaches(); 3918 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 3919 } 3920 } 3921 } 3922 3923 final void handleActivityConfigurationChanged(IBinder token) { 3924 ActivityClientRecord r = mActivities.get(token); 3925 if (r == null || r.activity == null) { 3926 return; 3927 } 3928 3929 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 3930 + r.activityInfo.name); 3931 3932 performConfigurationChanged(r.activity, mCompatConfiguration); 3933 3934 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 3935 } 3936 3937 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { 3938 if (start) { 3939 try { 3940 switch (profileType) { 3941 default: 3942 mProfiler.setProfiler(pcd.path, pcd.fd); 3943 mProfiler.autoStopProfiler = false; 3944 mProfiler.startProfiling(); 3945 break; 3946 } 3947 } catch (RuntimeException e) { 3948 Slog.w(TAG, "Profiling failed on path " + pcd.path 3949 + " -- can the process access this path?"); 3950 } finally { 3951 try { 3952 pcd.fd.close(); 3953 } catch (IOException e) { 3954 Slog.w(TAG, "Failure closing profile fd", e); 3955 } 3956 } 3957 } else { 3958 switch (profileType) { 3959 default: 3960 mProfiler.stopProfiling(); 3961 break; 3962 } 3963 } 3964 } 3965 3966 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 3967 if (managed) { 3968 try { 3969 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 3970 } catch (IOException e) { 3971 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 3972 + " -- can the process access this path?"); 3973 } finally { 3974 try { 3975 dhd.fd.close(); 3976 } catch (IOException e) { 3977 Slog.w(TAG, "Failure closing profile fd", e); 3978 } 3979 } 3980 } else { 3981 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 3982 } 3983 } 3984 3985 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 3986 boolean hasPkgInfo = false; 3987 if (packages != null) { 3988 for (int i=packages.length-1; i>=0; i--) { 3989 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 3990 if (!hasPkgInfo) { 3991 WeakReference<LoadedApk> ref; 3992 ref = mPackages.get(packages[i]); 3993 if (ref != null && ref.get() != null) { 3994 hasPkgInfo = true; 3995 } else { 3996 ref = mResourcePackages.get(packages[i]); 3997 if (ref != null && ref.get() != null) { 3998 hasPkgInfo = true; 3999 } 4000 } 4001 } 4002 mPackages.remove(packages[i]); 4003 mResourcePackages.remove(packages[i]); 4004 } 4005 } 4006 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4007 hasPkgInfo); 4008 } 4009 4010 final void handleLowMemory() { 4011 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4012 4013 final int N = callbacks.size(); 4014 for (int i=0; i<N; i++) { 4015 callbacks.get(i).onLowMemory(); 4016 } 4017 4018 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4019 if (Process.myUid() != Process.SYSTEM_UID) { 4020 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4021 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4022 } 4023 4024 // Ask graphics to free up as much as possible (font/image caches) 4025 Canvas.freeCaches(); 4026 4027 // Ask text layout engine to free also as much as possible 4028 Canvas.freeTextLayoutCaches(); 4029 4030 BinderInternal.forceGc("mem"); 4031 } 4032 4033 final void handleTrimMemory(int level) { 4034 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4035 4036 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance(); 4037 windowManager.startTrimMemory(level); 4038 4039 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4040 4041 final int N = callbacks.size(); 4042 for (int i = 0; i < N; i++) { 4043 callbacks.get(i).onTrimMemory(level); 4044 } 4045 4046 windowManager.endTrimMemory(); 4047 } 4048 4049 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4050 if (Process.isIsolated()) { 4051 // Isolated processes aren't going to do UI. 4052 return; 4053 } 4054 try { 4055 int uid = Process.myUid(); 4056 String[] packages = getPackageManager().getPackagesForUid(uid); 4057 4058 // If there are several packages in this application we won't 4059 // initialize the graphics disk caches 4060 if (packages != null && packages.length == 1) { 4061 HardwareRenderer.setupDiskCache(cacheDir); 4062 RenderScript.setupDiskCache(cacheDir); 4063 } 4064 } catch (RemoteException e) { 4065 // Ignore 4066 } 4067 } 4068 4069 private void updateDefaultDensity() { 4070 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED 4071 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE 4072 && !mDensityCompatMode) { 4073 Slog.i(TAG, "Switching default density from " 4074 + DisplayMetrics.DENSITY_DEVICE + " to " 4075 + mCurDefaultDisplayDpi); 4076 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; 4077 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4078 } 4079 } 4080 4081 private void handleBindApplication(AppBindData data) { 4082 mBoundApplication = data; 4083 mConfiguration = new Configuration(data.config); 4084 mCompatConfiguration = new Configuration(data.config); 4085 4086 mProfiler = new Profiler(); 4087 mProfiler.profileFile = data.initProfileFile; 4088 mProfiler.profileFd = data.initProfileFd; 4089 mProfiler.autoStopProfiler = data.initAutoStopProfiler; 4090 4091 // send up app name; do this *before* waiting for debugger 4092 Process.setArgV0(data.processName); 4093 android.ddm.DdmHandleAppName.setAppName(data.processName, 4094 UserHandle.myUserId()); 4095 4096 if (data.persistent) { 4097 // Persistent processes on low-memory devices do not get to 4098 // use hardware accelerated drawing, since this can add too much 4099 // overhead to the process. 4100 if (!ActivityManager.isHighEndGfx()) { 4101 HardwareRenderer.disable(false); 4102 } 4103 } 4104 4105 if (mProfiler.profileFd != null) { 4106 mProfiler.startProfiling(); 4107 } 4108 4109 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4110 // implementation to use the pool executor. Normally, we use the 4111 // serialized executor as the default. This has to happen in the 4112 // main thread so the main looper is set right. 4113 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4114 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4115 } 4116 4117 /* 4118 * Before spawning a new process, reset the time zone to be the system time zone. 4119 * This needs to be done because the system time zone could have changed after the 4120 * the spawning of this process. Without doing this this process would have the incorrect 4121 * system time zone. 4122 */ 4123 TimeZone.setDefault(null); 4124 4125 /* 4126 * Initialize the default locale in this process for the reasons we set the time zone. 4127 */ 4128 Locale.setDefault(data.config.locale); 4129 4130 /* 4131 * Update the system configuration since its preloaded and might not 4132 * reflect configuration changes. The configuration object passed 4133 * in AppBindData can be safely assumed to be up to date 4134 */ 4135 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4136 mCurDefaultDisplayDpi = data.config.densityDpi; 4137 applyCompatConfiguration(mCurDefaultDisplayDpi); 4138 4139 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4140 4141 /** 4142 * Switch this process to density compatibility mode if needed. 4143 */ 4144 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4145 == 0) { 4146 mDensityCompatMode = true; 4147 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4148 } 4149 updateDefaultDensity(); 4150 4151 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 4152 if (!Process.isIsolated()) { 4153 final File cacheDir = appContext.getCacheDir(); 4154 4155 if (cacheDir != null) { 4156 // Provide a usable directory for temporary files 4157 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 4158 4159 setupGraphicsSupport(data.info, cacheDir); 4160 } else { 4161 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory"); 4162 } 4163 } 4164 /** 4165 * For system applications on userdebug/eng builds, log stack 4166 * traces of disk and network access to dropbox for analysis. 4167 */ 4168 if ((data.appInfo.flags & 4169 (ApplicationInfo.FLAG_SYSTEM | 4170 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4171 StrictMode.conditionallyEnableDebugLogging(); 4172 } 4173 4174 /** 4175 * For apps targetting SDK Honeycomb or later, we don't allow 4176 * network usage on the main event loop / UI thread. 4177 * 4178 * Note to those grepping: this is what ultimately throws 4179 * NetworkOnMainThreadException ... 4180 */ 4181 if (data.appInfo.targetSdkVersion > 9) { 4182 StrictMode.enableDeathOnNetwork(); 4183 } 4184 4185 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4186 // XXX should have option to change the port. 4187 Debug.changeDebugPort(8100); 4188 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4189 Slog.w(TAG, "Application " + data.info.getPackageName() 4190 + " is waiting for the debugger on port 8100..."); 4191 4192 IActivityManager mgr = ActivityManagerNative.getDefault(); 4193 try { 4194 mgr.showWaitingForDebugger(mAppThread, true); 4195 } catch (RemoteException ex) { 4196 } 4197 4198 Debug.waitForDebugger(); 4199 4200 try { 4201 mgr.showWaitingForDebugger(mAppThread, false); 4202 } catch (RemoteException ex) { 4203 } 4204 4205 } else { 4206 Slog.w(TAG, "Application " + data.info.getPackageName() 4207 + " can be debugged on port 8100..."); 4208 } 4209 } 4210 4211 // Enable OpenGL tracing if required 4212 if (data.enableOpenGlTrace) { 4213 GLUtils.setTracingLevel(1); 4214 } 4215 4216 // Allow application-generated systrace messages if we're debuggable. 4217 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0; 4218 Trace.setAppTracingAllowed(appTracingAllowed); 4219 4220 /** 4221 * Initialize the default http proxy in this process for the reasons we set the time zone. 4222 */ 4223 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 4224 if (b != null) { 4225 // In pre-boot mode (doing initial launch to collect password), not 4226 // all system is up. This includes the connectivity service, so don't 4227 // crash if we can't get it. 4228 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4229 try { 4230 ProxyProperties proxyProperties = service.getProxy(); 4231 Proxy.setHttpProxySystemProperty(proxyProperties); 4232 } catch (RemoteException e) {} 4233 } 4234 4235 if (data.instrumentationName != null) { 4236 InstrumentationInfo ii = null; 4237 try { 4238 ii = appContext.getPackageManager(). 4239 getInstrumentationInfo(data.instrumentationName, 0); 4240 } catch (PackageManager.NameNotFoundException e) { 4241 } 4242 if (ii == null) { 4243 throw new RuntimeException( 4244 "Unable to find instrumentation info for: " 4245 + data.instrumentationName); 4246 } 4247 4248 mInstrumentationAppDir = ii.sourceDir; 4249 mInstrumentationAppLibraryDir = ii.nativeLibraryDir; 4250 mInstrumentationAppPackage = ii.packageName; 4251 mInstrumentedAppDir = data.info.getAppDir(); 4252 mInstrumentedAppLibraryDir = data.info.getLibDir(); 4253 4254 ApplicationInfo instrApp = new ApplicationInfo(); 4255 instrApp.packageName = ii.packageName; 4256 instrApp.sourceDir = ii.sourceDir; 4257 instrApp.publicSourceDir = ii.publicSourceDir; 4258 instrApp.dataDir = ii.dataDir; 4259 instrApp.nativeLibraryDir = ii.nativeLibraryDir; 4260 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 4261 appContext.getClassLoader(), false, true); 4262 ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 4263 4264 try { 4265 java.lang.ClassLoader cl = instrContext.getClassLoader(); 4266 mInstrumentation = (Instrumentation) 4267 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4268 } catch (Exception e) { 4269 throw new RuntimeException( 4270 "Unable to instantiate instrumentation " 4271 + data.instrumentationName + ": " + e.toString(), e); 4272 } 4273 4274 mInstrumentation.init(this, instrContext, appContext, 4275 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, 4276 data.instrumentationUiAutomationConnection); 4277 4278 if (mProfiler.profileFile != null && !ii.handleProfiling 4279 && mProfiler.profileFd == null) { 4280 mProfiler.handlingProfiling = true; 4281 File file = new File(mProfiler.profileFile); 4282 file.getParentFile().mkdirs(); 4283 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 4284 } 4285 4286 } else { 4287 mInstrumentation = new Instrumentation(); 4288 } 4289 4290 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 4291 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 4292 } 4293 4294 // Allow disk access during application and provider setup. This could 4295 // block processing ordered broadcasts, but later processing would 4296 // probably end up doing the same disk access. 4297 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 4298 try { 4299 // If the app is being launched for full backup or restore, bring it up in 4300 // a restricted environment with the base application class. 4301 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 4302 mInitialApplication = app; 4303 4304 // don't bring up providers in restricted mode; they may depend on the 4305 // app's custom Application class 4306 if (!data.restrictedBackupMode) { 4307 List<ProviderInfo> providers = data.providers; 4308 if (providers != null) { 4309 installContentProviders(app, providers); 4310 // For process that contains content providers, we want to 4311 // ensure that the JIT is enabled "at some point". 4312 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 4313 } 4314 } 4315 4316 // Do this after providers, since instrumentation tests generally start their 4317 // test thread at this point, and we don't want that racing. 4318 try { 4319 mInstrumentation.onCreate(data.instrumentationArgs); 4320 } 4321 catch (Exception e) { 4322 throw new RuntimeException( 4323 "Exception thrown in onCreate() of " 4324 + data.instrumentationName + ": " + e.toString(), e); 4325 } 4326 4327 try { 4328 mInstrumentation.callApplicationOnCreate(app); 4329 } catch (Exception e) { 4330 if (!mInstrumentation.onException(app, e)) { 4331 throw new RuntimeException( 4332 "Unable to create application " + app.getClass().getName() 4333 + ": " + e.toString(), e); 4334 } 4335 } 4336 } finally { 4337 StrictMode.setThreadPolicy(savedPolicy); 4338 } 4339 } 4340 4341 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 4342 IActivityManager am = ActivityManagerNative.getDefault(); 4343 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 4344 && mProfiler.profileFd == null) { 4345 Debug.stopMethodTracing(); 4346 } 4347 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 4348 // + ", app thr: " + mAppThread); 4349 try { 4350 am.finishInstrumentation(mAppThread, resultCode, results); 4351 } catch (RemoteException ex) { 4352 } 4353 } 4354 4355 private void installContentProviders( 4356 Context context, List<ProviderInfo> providers) { 4357 final ArrayList<IActivityManager.ContentProviderHolder> results = 4358 new ArrayList<IActivityManager.ContentProviderHolder>(); 4359 4360 for (ProviderInfo cpi : providers) { 4361 if (DEBUG_PROVIDER) { 4362 StringBuilder buf = new StringBuilder(128); 4363 buf.append("Pub "); 4364 buf.append(cpi.authority); 4365 buf.append(": "); 4366 buf.append(cpi.name); 4367 Log.i(TAG, buf.toString()); 4368 } 4369 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 4370 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 4371 if (cph != null) { 4372 cph.noReleaseNeeded = true; 4373 results.add(cph); 4374 } 4375 } 4376 4377 try { 4378 ActivityManagerNative.getDefault().publishContentProviders( 4379 getApplicationThread(), results); 4380 } catch (RemoteException ex) { 4381 } 4382 } 4383 4384 public final IContentProvider acquireProvider( 4385 Context c, String auth, int userId, boolean stable) { 4386 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 4387 if (provider != null) { 4388 return provider; 4389 } 4390 4391 // There is a possible race here. Another thread may try to acquire 4392 // the same provider at the same time. When this happens, we want to ensure 4393 // that the first one wins. 4394 // Note that we cannot hold the lock while acquiring and installing the 4395 // provider since it might take a long time to run and it could also potentially 4396 // be re-entrant in the case where the provider is in the same process. 4397 IActivityManager.ContentProviderHolder holder = null; 4398 try { 4399 holder = ActivityManagerNative.getDefault().getContentProvider( 4400 getApplicationThread(), auth, userId, stable); 4401 } catch (RemoteException ex) { 4402 } 4403 if (holder == null) { 4404 Slog.e(TAG, "Failed to find provider info for " + auth); 4405 return null; 4406 } 4407 4408 // Install provider will increment the reference count for us, and break 4409 // any ties in the race. 4410 holder = installProvider(c, holder, holder.info, 4411 true /*noisy*/, holder.noReleaseNeeded, stable); 4412 return holder.provider; 4413 } 4414 4415 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 4416 if (stable) { 4417 prc.stableCount += 1; 4418 if (prc.stableCount == 1) { 4419 // We are acquiring a new stable reference on the provider. 4420 int unstableDelta; 4421 if (prc.removePending) { 4422 // We have a pending remove operation, which is holding the 4423 // last unstable reference. At this point we are converting 4424 // that unstable reference to our new stable reference. 4425 unstableDelta = -1; 4426 // Cancel the removal of the provider. 4427 if (DEBUG_PROVIDER) { 4428 Slog.v(TAG, "incProviderRef: stable " 4429 + "snatched provider from the jaws of death"); 4430 } 4431 prc.removePending = false; 4432 // There is a race! It fails to remove the message, which 4433 // will be handled in completeRemoveProvider(). 4434 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4435 } else { 4436 unstableDelta = 0; 4437 } 4438 try { 4439 if (DEBUG_PROVIDER) { 4440 Slog.v(TAG, "incProviderRef Now stable - " 4441 + prc.holder.info.name + ": unstableDelta=" 4442 + unstableDelta); 4443 } 4444 ActivityManagerNative.getDefault().refContentProvider( 4445 prc.holder.connection, 1, unstableDelta); 4446 } catch (RemoteException e) { 4447 //do nothing content provider object is dead any way 4448 } 4449 } 4450 } else { 4451 prc.unstableCount += 1; 4452 if (prc.unstableCount == 1) { 4453 // We are acquiring a new unstable reference on the provider. 4454 if (prc.removePending) { 4455 // Oh look, we actually have a remove pending for the 4456 // provider, which is still holding the last unstable 4457 // reference. We just need to cancel that to take new 4458 // ownership of the reference. 4459 if (DEBUG_PROVIDER) { 4460 Slog.v(TAG, "incProviderRef: unstable " 4461 + "snatched provider from the jaws of death"); 4462 } 4463 prc.removePending = false; 4464 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4465 } else { 4466 // First unstable ref, increment our count in the 4467 // activity manager. 4468 try { 4469 if (DEBUG_PROVIDER) { 4470 Slog.v(TAG, "incProviderRef: Now unstable - " 4471 + prc.holder.info.name); 4472 } 4473 ActivityManagerNative.getDefault().refContentProvider( 4474 prc.holder.connection, 0, 1); 4475 } catch (RemoteException e) { 4476 //do nothing content provider object is dead any way 4477 } 4478 } 4479 } 4480 } 4481 } 4482 4483 public final IContentProvider acquireExistingProvider( 4484 Context c, String auth, int userId, boolean stable) { 4485 synchronized (mProviderMap) { 4486 final ProviderKey key = new ProviderKey(auth, userId); 4487 final ProviderClientRecord pr = mProviderMap.get(key); 4488 if (pr == null) { 4489 return null; 4490 } 4491 4492 IContentProvider provider = pr.mProvider; 4493 IBinder jBinder = provider.asBinder(); 4494 if (!jBinder.isBinderAlive()) { 4495 // The hosting process of the provider has died; we can't 4496 // use this one. 4497 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 4498 + ": existing object's process dead"); 4499 handleUnstableProviderDiedLocked(jBinder, true); 4500 return null; 4501 } 4502 4503 // Only increment the ref count if we have one. If we don't then the 4504 // provider is not reference counted and never needs to be released. 4505 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4506 if (prc != null) { 4507 incProviderRefLocked(prc, stable); 4508 } 4509 return provider; 4510 } 4511 } 4512 4513 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 4514 if (provider == null) { 4515 return false; 4516 } 4517 4518 IBinder jBinder = provider.asBinder(); 4519 synchronized (mProviderMap) { 4520 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4521 if (prc == null) { 4522 // The provider has no ref count, no release is needed. 4523 return false; 4524 } 4525 4526 boolean lastRef = false; 4527 if (stable) { 4528 if (prc.stableCount == 0) { 4529 if (DEBUG_PROVIDER) Slog.v(TAG, 4530 "releaseProvider: stable ref count already 0, how?"); 4531 return false; 4532 } 4533 prc.stableCount -= 1; 4534 if (prc.stableCount == 0) { 4535 // What we do at this point depends on whether there are 4536 // any unstable refs left: if there are, we just tell the 4537 // activity manager to decrement its stable count; if there 4538 // aren't, we need to enqueue this provider to be removed, 4539 // and convert to holding a single unstable ref while 4540 // doing so. 4541 lastRef = prc.unstableCount == 0; 4542 try { 4543 if (DEBUG_PROVIDER) { 4544 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 4545 + lastRef + " - " + prc.holder.info.name); 4546 } 4547 ActivityManagerNative.getDefault().refContentProvider( 4548 prc.holder.connection, -1, lastRef ? 1 : 0); 4549 } catch (RemoteException e) { 4550 //do nothing content provider object is dead any way 4551 } 4552 } 4553 } else { 4554 if (prc.unstableCount == 0) { 4555 if (DEBUG_PROVIDER) Slog.v(TAG, 4556 "releaseProvider: unstable ref count already 0, how?"); 4557 return false; 4558 } 4559 prc.unstableCount -= 1; 4560 if (prc.unstableCount == 0) { 4561 // If this is the last reference, we need to enqueue 4562 // this provider to be removed instead of telling the 4563 // activity manager to remove it at this point. 4564 lastRef = prc.stableCount == 0; 4565 if (!lastRef) { 4566 try { 4567 if (DEBUG_PROVIDER) { 4568 Slog.v(TAG, "releaseProvider: No longer unstable - " 4569 + prc.holder.info.name); 4570 } 4571 ActivityManagerNative.getDefault().refContentProvider( 4572 prc.holder.connection, 0, -1); 4573 } catch (RemoteException e) { 4574 //do nothing content provider object is dead any way 4575 } 4576 } 4577 } 4578 } 4579 4580 if (lastRef) { 4581 if (!prc.removePending) { 4582 // Schedule the actual remove asynchronously, since we don't know the context 4583 // this will be called in. 4584 // TODO: it would be nice to post a delayed message, so 4585 // if we come back and need the same provider quickly 4586 // we will still have it available. 4587 if (DEBUG_PROVIDER) { 4588 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 4589 + prc.holder.info.name); 4590 } 4591 prc.removePending = true; 4592 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 4593 mH.sendMessage(msg); 4594 } else { 4595 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 4596 } 4597 } 4598 return true; 4599 } 4600 } 4601 4602 final void completeRemoveProvider(ProviderRefCount prc) { 4603 synchronized (mProviderMap) { 4604 if (!prc.removePending) { 4605 // There was a race! Some other client managed to acquire 4606 // the provider before the removal was completed. 4607 // Abort the removal. We will do it later. 4608 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 4609 + "provider still in use"); 4610 return; 4611 } 4612 4613 // More complicated race!! Some client managed to acquire the 4614 // provider and release it before the removal was completed. 4615 // Continue the removal, and abort the next remove message. 4616 prc.removePending = false; 4617 4618 final IBinder jBinder = prc.holder.provider.asBinder(); 4619 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 4620 if (existingPrc == prc) { 4621 mProviderRefCountMap.remove(jBinder); 4622 } 4623 4624 for (int i=mProviderMap.size()-1; i>=0; i--) { 4625 ProviderClientRecord pr = mProviderMap.valueAt(i); 4626 IBinder myBinder = pr.mProvider.asBinder(); 4627 if (myBinder == jBinder) { 4628 mProviderMap.removeAt(i); 4629 } 4630 } 4631 } 4632 4633 try { 4634 if (DEBUG_PROVIDER) { 4635 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 4636 + "removeContentProvider(" + prc.holder.info.name + ")"); 4637 } 4638 ActivityManagerNative.getDefault().removeContentProvider( 4639 prc.holder.connection, false); 4640 } catch (RemoteException e) { 4641 //do nothing content provider object is dead any way 4642 } 4643 } 4644 4645 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 4646 synchronized (mProviderMap) { 4647 handleUnstableProviderDiedLocked(provider, fromClient); 4648 } 4649 } 4650 4651 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 4652 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4653 if (prc != null) { 4654 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 4655 + provider + " " + prc.holder.info.name); 4656 mProviderRefCountMap.remove(provider); 4657 for (int i=mProviderMap.size()-1; i>=0; i--) { 4658 ProviderClientRecord pr = mProviderMap.valueAt(i); 4659 if (pr != null && pr.mProvider.asBinder() == provider) { 4660 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 4661 mProviderMap.removeAt(i); 4662 } 4663 } 4664 4665 if (fromClient) { 4666 // We found out about this due to execution in our client 4667 // code. Tell the activity manager about it now, to ensure 4668 // that the next time we go to do anything with the provider 4669 // it knows it is dead (so we don't race with its death 4670 // notification). 4671 try { 4672 ActivityManagerNative.getDefault().unstableProviderDied( 4673 prc.holder.connection); 4674 } catch (RemoteException e) { 4675 //do nothing content provider object is dead any way 4676 } 4677 } 4678 } 4679 } 4680 4681 final void appNotRespondingViaProvider(IBinder provider) { 4682 synchronized (mProviderMap) { 4683 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4684 if (prc != null) { 4685 try { 4686 ActivityManagerNative.getDefault() 4687 .appNotRespondingViaProvider(prc.holder.connection); 4688 } catch (RemoteException e) { 4689 } 4690 } 4691 } 4692 } 4693 4694 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 4695 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 4696 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority); 4697 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 4698 4699 final ProviderClientRecord pcr = new ProviderClientRecord( 4700 auths, provider, localProvider, holder); 4701 for (String auth : auths) { 4702 final ProviderKey key = new ProviderKey(auth, userId); 4703 final ProviderClientRecord existing = mProviderMap.get(key); 4704 if (existing != null) { 4705 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 4706 + " already published as " + auth); 4707 } else { 4708 mProviderMap.put(key, pcr); 4709 } 4710 } 4711 return pcr; 4712 } 4713 4714 /** 4715 * Installs the provider. 4716 * 4717 * Providers that are local to the process or that come from the system server 4718 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 4719 * Other remote providers are reference counted. The initial reference count 4720 * for all reference counted providers is one. Providers that are not reference 4721 * counted do not have a reference count (at all). 4722 * 4723 * This method detects when a provider has already been installed. When this happens, 4724 * it increments the reference count of the existing provider (if appropriate) 4725 * and returns the existing provider. This can happen due to concurrent 4726 * attempts to acquire the same provider. 4727 */ 4728 private IActivityManager.ContentProviderHolder installProvider(Context context, 4729 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 4730 boolean noisy, boolean noReleaseNeeded, boolean stable) { 4731 ContentProvider localProvider = null; 4732 IContentProvider provider; 4733 if (holder == null || holder.provider == null) { 4734 if (DEBUG_PROVIDER || noisy) { 4735 Slog.d(TAG, "Loading provider " + info.authority + ": " 4736 + info.name); 4737 } 4738 Context c = null; 4739 ApplicationInfo ai = info.applicationInfo; 4740 if (context.getPackageName().equals(ai.packageName)) { 4741 c = context; 4742 } else if (mInitialApplication != null && 4743 mInitialApplication.getPackageName().equals(ai.packageName)) { 4744 c = mInitialApplication; 4745 } else { 4746 try { 4747 c = context.createPackageContext(ai.packageName, 4748 Context.CONTEXT_INCLUDE_CODE); 4749 } catch (PackageManager.NameNotFoundException e) { 4750 // Ignore 4751 } 4752 } 4753 if (c == null) { 4754 Slog.w(TAG, "Unable to get context for package " + 4755 ai.packageName + 4756 " while loading content provider " + 4757 info.name); 4758 return null; 4759 } 4760 try { 4761 final java.lang.ClassLoader cl = c.getClassLoader(); 4762 localProvider = (ContentProvider)cl. 4763 loadClass(info.name).newInstance(); 4764 provider = localProvider.getIContentProvider(); 4765 if (provider == null) { 4766 Slog.e(TAG, "Failed to instantiate class " + 4767 info.name + " from sourceDir " + 4768 info.applicationInfo.sourceDir); 4769 return null; 4770 } 4771 if (DEBUG_PROVIDER) Slog.v( 4772 TAG, "Instantiating local provider " + info.name); 4773 // XXX Need to create the correct context for this provider. 4774 localProvider.attachInfo(c, info); 4775 } catch (java.lang.Exception e) { 4776 if (!mInstrumentation.onException(null, e)) { 4777 throw new RuntimeException( 4778 "Unable to get provider " + info.name 4779 + ": " + e.toString(), e); 4780 } 4781 return null; 4782 } 4783 } else { 4784 provider = holder.provider; 4785 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 4786 + info.name); 4787 } 4788 4789 IActivityManager.ContentProviderHolder retHolder; 4790 4791 synchronized (mProviderMap) { 4792 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 4793 + " / " + info.name); 4794 IBinder jBinder = provider.asBinder(); 4795 if (localProvider != null) { 4796 ComponentName cname = new ComponentName(info.packageName, info.name); 4797 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 4798 if (pr != null) { 4799 if (DEBUG_PROVIDER) { 4800 Slog.v(TAG, "installProvider: lost the race, " 4801 + "using existing local provider"); 4802 } 4803 provider = pr.mProvider; 4804 } else { 4805 holder = new IActivityManager.ContentProviderHolder(info); 4806 holder.provider = provider; 4807 holder.noReleaseNeeded = true; 4808 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 4809 mLocalProviders.put(jBinder, pr); 4810 mLocalProvidersByName.put(cname, pr); 4811 } 4812 retHolder = pr.mHolder; 4813 } else { 4814 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4815 if (prc != null) { 4816 if (DEBUG_PROVIDER) { 4817 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 4818 } 4819 // We need to transfer our new reference to the existing 4820 // ref count, releasing the old one... but only if 4821 // release is needed (that is, it is not running in the 4822 // system process). 4823 if (!noReleaseNeeded) { 4824 incProviderRefLocked(prc, stable); 4825 try { 4826 ActivityManagerNative.getDefault().removeContentProvider( 4827 holder.connection, stable); 4828 } catch (RemoteException e) { 4829 //do nothing content provider object is dead any way 4830 } 4831 } 4832 } else { 4833 ProviderClientRecord client = installProviderAuthoritiesLocked( 4834 provider, localProvider, holder); 4835 if (noReleaseNeeded) { 4836 prc = new ProviderRefCount(holder, client, 1000, 1000); 4837 } else { 4838 prc = stable 4839 ? new ProviderRefCount(holder, client, 1, 0) 4840 : new ProviderRefCount(holder, client, 0, 1); 4841 } 4842 mProviderRefCountMap.put(jBinder, prc); 4843 } 4844 retHolder = prc.holder; 4845 } 4846 } 4847 4848 return retHolder; 4849 } 4850 4851 private void attach(boolean system) { 4852 sCurrentActivityThread = this; 4853 mSystemThread = system; 4854 if (!system) { 4855 ViewRootImpl.addFirstDrawHandler(new Runnable() { 4856 @Override 4857 public void run() { 4858 ensureJitEnabled(); 4859 } 4860 }); 4861 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 4862 UserHandle.myUserId()); 4863 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 4864 IActivityManager mgr = ActivityManagerNative.getDefault(); 4865 try { 4866 mgr.attachApplication(mAppThread); 4867 } catch (RemoteException ex) { 4868 // Ignore 4869 } 4870 } else { 4871 // Don't set application object here -- if the system crashes, 4872 // we can't display an alert, we just want to die die die. 4873 android.ddm.DdmHandleAppName.setAppName("system_process", 4874 UserHandle.myUserId()); 4875 try { 4876 mInstrumentation = new Instrumentation(); 4877 ContextImpl context = ContextImpl.createAppContext( 4878 this, getSystemContext().mPackageInfo); 4879 Application app = Instrumentation.newApplication(Application.class, context); 4880 mAllApplications.add(app); 4881 mInitialApplication = app; 4882 app.onCreate(); 4883 } catch (Exception e) { 4884 throw new RuntimeException( 4885 "Unable to instantiate Application():" + e.toString(), e); 4886 } 4887 } 4888 4889 // add dropbox logging to libcore 4890 DropBox.setReporter(new DropBoxReporter()); 4891 4892 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 4893 @Override 4894 public void onConfigurationChanged(Configuration newConfig) { 4895 synchronized (mResourcesManager) { 4896 // We need to apply this change to the resources 4897 // immediately, because upon returning the view 4898 // hierarchy will be informed about it. 4899 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 4900 // This actually changed the resources! Tell 4901 // everyone about it. 4902 if (mPendingConfiguration == null || 4903 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 4904 mPendingConfiguration = newConfig; 4905 4906 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 4907 } 4908 } 4909 } 4910 } 4911 @Override 4912 public void onLowMemory() { 4913 } 4914 @Override 4915 public void onTrimMemory(int level) { 4916 } 4917 }); 4918 } 4919 4920 public static ActivityThread systemMain() { 4921 HardwareRenderer.disable(true); 4922 ActivityThread thread = new ActivityThread(); 4923 thread.attach(true); 4924 return thread; 4925 } 4926 4927 public final void installSystemProviders(List<ProviderInfo> providers) { 4928 if (providers != null) { 4929 installContentProviders(mInitialApplication, providers); 4930 } 4931 } 4932 4933 public int getIntCoreSetting(String key, int defaultValue) { 4934 synchronized (mResourcesManager) { 4935 if (mCoreSettings != null) { 4936 return mCoreSettings.getInt(key, defaultValue); 4937 } 4938 return defaultValue; 4939 } 4940 } 4941 4942 private static class EventLoggingReporter implements EventLogger.Reporter { 4943 @Override 4944 public void report (int code, Object... list) { 4945 EventLog.writeEvent(code, list); 4946 } 4947 } 4948 4949 private class DropBoxReporter implements DropBox.Reporter { 4950 4951 private DropBoxManager dropBox; 4952 4953 public DropBoxReporter() { 4954 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 4955 } 4956 4957 @Override 4958 public void addData(String tag, byte[] data, int flags) { 4959 dropBox.addData(tag, data, flags); 4960 } 4961 4962 @Override 4963 public void addText(String tag, String data) { 4964 dropBox.addText(tag, data); 4965 } 4966 } 4967 4968 public static void main(String[] args) { 4969 SamplingProfilerIntegration.start(); 4970 4971 // CloseGuard defaults to true and can be quite spammy. We 4972 // disable it here, but selectively enable it later (via 4973 // StrictMode) on debug builds, but using DropBox, not logs. 4974 CloseGuard.setEnabled(false); 4975 4976 Environment.initForCurrentUser(); 4977 4978 // Set the reporter for event logging in libcore 4979 EventLogger.setReporter(new EventLoggingReporter()); 4980 4981 Security.addProvider(new AndroidKeyStoreProvider()); 4982 4983 Process.setArgV0("<pre-initialized>"); 4984 4985 Looper.prepareMainLooper(); 4986 4987 ActivityThread thread = new ActivityThread(); 4988 thread.attach(false); 4989 4990 if (sMainThreadHandler == null) { 4991 sMainThreadHandler = thread.getHandler(); 4992 } 4993 4994 AsyncTask.init(); 4995 4996 if (false) { 4997 Looper.myLooper().setMessageLogging(new 4998 LogPrinter(Log.DEBUG, "ActivityThread")); 4999 } 5000 5001 Looper.loop(); 5002 5003 throw new RuntimeException("Main thread loop unexpectedly exited"); 5004 } 5005 } 5006