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