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