ActivityThread.java revision fbb32f6440ed74a4d27eec03569520580d00da42
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 Uri referrer = null; 2576 if (r != null) { 2577 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 2578 r.activity.onProvideAssistData(data); 2579 referrer = r.activity.onProvideReferrer(); 2580 if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) { 2581 structure = new AssistStructure(r.activity); 2582 Intent activityIntent = r.activity.getIntent(); 2583 if (activityIntent != null && (r.window == null || 2584 (r.window.getAttributes().flags 2585 & WindowManager.LayoutParams.FLAG_SECURE) == 0)) { 2586 Intent intent = new Intent(activityIntent); 2587 intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION 2588 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)); 2589 intent.removeUnsafeExtras(); 2590 content.setDefaultIntent(intent); 2591 } else { 2592 content.setDefaultIntent(new Intent()); 2593 } 2594 r.activity.onProvideAssistContent(content); 2595 } 2596 } 2597 if (structure == null) { 2598 structure = new AssistStructure(); 2599 } 2600 IActivityManager mgr = ActivityManagerNative.getDefault(); 2601 try { 2602 mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer); 2603 } catch (RemoteException e) { 2604 } 2605 } 2606 2607 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 2608 ActivityClientRecord r = mActivities.get(token); 2609 if (r != null) { 2610 r.activity.onTranslucentConversionComplete(drawComplete); 2611 } 2612 } 2613 2614 public void onNewActivityOptions(IBinder token, ActivityOptions options) { 2615 ActivityClientRecord r = mActivities.get(token); 2616 if (r != null) { 2617 r.activity.onNewActivityOptions(options); 2618 } 2619 } 2620 2621 public void handleCancelVisibleBehind(IBinder token) { 2622 ActivityClientRecord r = mActivities.get(token); 2623 if (r != null) { 2624 mSomeActivitiesChanged = true; 2625 final Activity activity = r.activity; 2626 if (activity.mVisibleBehind) { 2627 activity.mCalled = false; 2628 activity.onVisibleBehindCanceled(); 2629 // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed. 2630 if (!activity.mCalled) { 2631 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + 2632 " did not call through to super.onVisibleBehindCanceled()"); 2633 } 2634 activity.mVisibleBehind = false; 2635 } 2636 } 2637 try { 2638 ActivityManagerNative.getDefault().backgroundResourcesReleased(token); 2639 } catch (RemoteException e) { 2640 } 2641 } 2642 2643 public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) { 2644 ActivityClientRecord r = mActivities.get(token); 2645 if (r != null) { 2646 r.activity.onBackgroundVisibleBehindChanged(visible); 2647 } 2648 } 2649 2650 public void handleInstallProvider(ProviderInfo info) { 2651 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2652 try { 2653 installContentProviders(mInitialApplication, Lists.newArrayList(info)); 2654 } finally { 2655 StrictMode.setThreadPolicy(oldPolicy); 2656 } 2657 } 2658 2659 private void handleEnterAnimationComplete(IBinder token) { 2660 ActivityClientRecord r = mActivities.get(token); 2661 if (r != null) { 2662 r.activity.dispatchEnterAnimationComplete(); 2663 } 2664 } 2665 2666 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 2667 2668 /** 2669 * Return the Intent that's currently being handled by a 2670 * BroadcastReceiver on this thread, or null if none. 2671 * @hide 2672 */ 2673 public static Intent getIntentBeingBroadcast() { 2674 return sCurrentBroadcastIntent.get(); 2675 } 2676 2677 private void handleReceiver(ReceiverData data) { 2678 // If we are getting ready to gc after going to the background, well 2679 // we are back active so skip it. 2680 unscheduleGcIdler(); 2681 2682 String component = data.intent.getComponent().getClassName(); 2683 2684 LoadedApk packageInfo = getPackageInfoNoCheck( 2685 data.info.applicationInfo, data.compatInfo); 2686 2687 IActivityManager mgr = ActivityManagerNative.getDefault(); 2688 2689 BroadcastReceiver receiver; 2690 try { 2691 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2692 data.intent.setExtrasClassLoader(cl); 2693 data.intent.prepareToEnterProcess(); 2694 data.setExtrasClassLoader(cl); 2695 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance(); 2696 } catch (Exception e) { 2697 if (DEBUG_BROADCAST) Slog.i(TAG, 2698 "Finishing failed broadcast to " + data.intent.getComponent()); 2699 data.sendFinished(mgr); 2700 throw new RuntimeException( 2701 "Unable to instantiate receiver " + component 2702 + ": " + e.toString(), e); 2703 } 2704 2705 try { 2706 Application app = packageInfo.makeApplication(false, mInstrumentation); 2707 2708 if (localLOGV) Slog.v( 2709 TAG, "Performing receive of " + data.intent 2710 + ": app=" + app 2711 + ", appName=" + app.getPackageName() 2712 + ", pkg=" + packageInfo.getPackageName() 2713 + ", comp=" + data.intent.getComponent().toShortString() 2714 + ", dir=" + packageInfo.getAppDir()); 2715 2716 ContextImpl context = (ContextImpl)app.getBaseContext(); 2717 sCurrentBroadcastIntent.set(data.intent); 2718 receiver.setPendingResult(data); 2719 receiver.onReceive(context.getReceiverRestrictedContext(), 2720 data.intent); 2721 } catch (Exception e) { 2722 if (DEBUG_BROADCAST) Slog.i(TAG, 2723 "Finishing failed broadcast to " + data.intent.getComponent()); 2724 data.sendFinished(mgr); 2725 if (!mInstrumentation.onException(receiver, e)) { 2726 throw new RuntimeException( 2727 "Unable to start receiver " + component 2728 + ": " + e.toString(), e); 2729 } 2730 } finally { 2731 sCurrentBroadcastIntent.set(null); 2732 } 2733 2734 if (receiver.getPendingResult() != null) { 2735 data.finish(); 2736 } 2737 } 2738 2739 // Instantiate a BackupAgent and tell it that it's alive 2740 private void handleCreateBackupAgent(CreateBackupAgentData data) { 2741 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 2742 2743 // Sanity check the requested target package's uid against ours 2744 try { 2745 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 2746 data.appInfo.packageName, 0, UserHandle.myUserId()); 2747 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 2748 Slog.w(TAG, "Asked to instantiate non-matching package " 2749 + data.appInfo.packageName); 2750 return; 2751 } 2752 } catch (RemoteException e) { 2753 Slog.e(TAG, "Can't reach package manager", e); 2754 return; 2755 } 2756 2757 // no longer idle; we have backup work to do 2758 unscheduleGcIdler(); 2759 2760 // instantiate the BackupAgent class named in the manifest 2761 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2762 String packageName = packageInfo.mPackageName; 2763 if (packageName == null) { 2764 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 2765 return; 2766 } 2767 2768 String classname = data.appInfo.backupAgentName; 2769 // full backup operation but no app-supplied agent? use the default implementation 2770 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL 2771 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) { 2772 classname = "android.app.backup.FullBackupAgent"; 2773 } 2774 2775 try { 2776 IBinder binder = null; 2777 BackupAgent agent = mBackupAgents.get(packageName); 2778 if (agent != null) { 2779 // reusing the existing instance 2780 if (DEBUG_BACKUP) { 2781 Slog.v(TAG, "Reusing existing agent instance"); 2782 } 2783 binder = agent.onBind(); 2784 } else { 2785 try { 2786 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 2787 2788 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2789 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 2790 2791 // set up the agent's context 2792 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 2793 context.setOuterContext(agent); 2794 agent.attach(context); 2795 2796 agent.onCreate(); 2797 binder = agent.onBind(); 2798 mBackupAgents.put(packageName, agent); 2799 } catch (Exception e) { 2800 // If this is during restore, fail silently; otherwise go 2801 // ahead and let the user see the crash. 2802 Slog.e(TAG, "Agent threw during creation: " + e); 2803 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE 2804 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) { 2805 throw e; 2806 } 2807 // falling through with 'binder' still null 2808 } 2809 } 2810 2811 // tell the OS that we're live now 2812 try { 2813 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder); 2814 } catch (RemoteException e) { 2815 // nothing to do. 2816 } 2817 } catch (Exception e) { 2818 throw new RuntimeException("Unable to create BackupAgent " 2819 + classname + ": " + e.toString(), e); 2820 } 2821 } 2822 2823 // Tear down a BackupAgent 2824 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 2825 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 2826 2827 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2828 String packageName = packageInfo.mPackageName; 2829 BackupAgent agent = mBackupAgents.get(packageName); 2830 if (agent != null) { 2831 try { 2832 agent.onDestroy(); 2833 } catch (Exception e) { 2834 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 2835 e.printStackTrace(); 2836 } 2837 mBackupAgents.remove(packageName); 2838 } else { 2839 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 2840 } 2841 } 2842 2843 private void handleCreateService(CreateServiceData data) { 2844 // If we are getting ready to gc after going to the background, well 2845 // we are back active so skip it. 2846 unscheduleGcIdler(); 2847 2848 LoadedApk packageInfo = getPackageInfoNoCheck( 2849 data.info.applicationInfo, data.compatInfo); 2850 Service service = null; 2851 try { 2852 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2853 service = (Service) cl.loadClass(data.info.name).newInstance(); 2854 } catch (Exception e) { 2855 if (!mInstrumentation.onException(service, e)) { 2856 throw new RuntimeException( 2857 "Unable to instantiate service " + data.info.name 2858 + ": " + e.toString(), e); 2859 } 2860 } 2861 2862 try { 2863 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 2864 2865 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 2866 context.setOuterContext(service); 2867 2868 Application app = packageInfo.makeApplication(false, mInstrumentation); 2869 service.attach(context, this, data.info.name, data.token, app, 2870 ActivityManagerNative.getDefault()); 2871 service.onCreate(); 2872 mServices.put(data.token, service); 2873 try { 2874 ActivityManagerNative.getDefault().serviceDoneExecuting( 2875 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 2876 } catch (RemoteException e) { 2877 // nothing to do. 2878 } 2879 } catch (Exception e) { 2880 if (!mInstrumentation.onException(service, e)) { 2881 throw new RuntimeException( 2882 "Unable to create service " + data.info.name 2883 + ": " + e.toString(), e); 2884 } 2885 } 2886 } 2887 2888 private void handleBindService(BindServiceData data) { 2889 Service s = mServices.get(data.token); 2890 if (DEBUG_SERVICE) 2891 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 2892 if (s != null) { 2893 try { 2894 data.intent.setExtrasClassLoader(s.getClassLoader()); 2895 data.intent.prepareToEnterProcess(); 2896 try { 2897 if (!data.rebind) { 2898 IBinder binder = s.onBind(data.intent); 2899 ActivityManagerNative.getDefault().publishService( 2900 data.token, data.intent, binder); 2901 } else { 2902 s.onRebind(data.intent); 2903 ActivityManagerNative.getDefault().serviceDoneExecuting( 2904 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 2905 } 2906 ensureJitEnabled(); 2907 } catch (RemoteException ex) { 2908 } 2909 } catch (Exception e) { 2910 if (!mInstrumentation.onException(s, e)) { 2911 throw new RuntimeException( 2912 "Unable to bind to service " + s 2913 + " with " + data.intent + ": " + e.toString(), e); 2914 } 2915 } 2916 } 2917 } 2918 2919 private void handleUnbindService(BindServiceData data) { 2920 Service s = mServices.get(data.token); 2921 if (s != null) { 2922 try { 2923 data.intent.setExtrasClassLoader(s.getClassLoader()); 2924 data.intent.prepareToEnterProcess(); 2925 boolean doRebind = s.onUnbind(data.intent); 2926 try { 2927 if (doRebind) { 2928 ActivityManagerNative.getDefault().unbindFinished( 2929 data.token, data.intent, doRebind); 2930 } else { 2931 ActivityManagerNative.getDefault().serviceDoneExecuting( 2932 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 2933 } 2934 } catch (RemoteException ex) { 2935 } 2936 } catch (Exception e) { 2937 if (!mInstrumentation.onException(s, e)) { 2938 throw new RuntimeException( 2939 "Unable to unbind to service " + s 2940 + " with " + data.intent + ": " + e.toString(), e); 2941 } 2942 } 2943 } 2944 } 2945 2946 private void handleDumpService(DumpComponentInfo info) { 2947 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2948 try { 2949 Service s = mServices.get(info.token); 2950 if (s != null) { 2951 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2952 info.fd.getFileDescriptor())); 2953 s.dump(info.fd.getFileDescriptor(), pw, info.args); 2954 pw.flush(); 2955 } 2956 } finally { 2957 IoUtils.closeQuietly(info.fd); 2958 StrictMode.setThreadPolicy(oldPolicy); 2959 } 2960 } 2961 2962 private void handleDumpActivity(DumpComponentInfo info) { 2963 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2964 try { 2965 ActivityClientRecord r = mActivities.get(info.token); 2966 if (r != null && r.activity != null) { 2967 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2968 info.fd.getFileDescriptor())); 2969 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 2970 pw.flush(); 2971 } 2972 } finally { 2973 IoUtils.closeQuietly(info.fd); 2974 StrictMode.setThreadPolicy(oldPolicy); 2975 } 2976 } 2977 2978 private void handleDumpProvider(DumpComponentInfo info) { 2979 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2980 try { 2981 ProviderClientRecord r = mLocalProviders.get(info.token); 2982 if (r != null && r.mLocalProvider != null) { 2983 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2984 info.fd.getFileDescriptor())); 2985 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 2986 pw.flush(); 2987 } 2988 } finally { 2989 IoUtils.closeQuietly(info.fd); 2990 StrictMode.setThreadPolicy(oldPolicy); 2991 } 2992 } 2993 2994 private void handleServiceArgs(ServiceArgsData data) { 2995 Service s = mServices.get(data.token); 2996 if (s != null) { 2997 try { 2998 if (data.args != null) { 2999 data.args.setExtrasClassLoader(s.getClassLoader()); 3000 data.args.prepareToEnterProcess(); 3001 } 3002 int res; 3003 if (!data.taskRemoved) { 3004 res = s.onStartCommand(data.args, data.flags, data.startId); 3005 } else { 3006 s.onTaskRemoved(data.args); 3007 res = Service.START_TASK_REMOVED_COMPLETE; 3008 } 3009 3010 QueuedWork.waitToFinish(); 3011 3012 try { 3013 ActivityManagerNative.getDefault().serviceDoneExecuting( 3014 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); 3015 } catch (RemoteException e) { 3016 // nothing to do. 3017 } 3018 ensureJitEnabled(); 3019 } catch (Exception e) { 3020 if (!mInstrumentation.onException(s, e)) { 3021 throw new RuntimeException( 3022 "Unable to start service " + s 3023 + " with " + data.args + ": " + e.toString(), e); 3024 } 3025 } 3026 } 3027 } 3028 3029 private void handleStopService(IBinder token) { 3030 Service s = mServices.remove(token); 3031 if (s != null) { 3032 try { 3033 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 3034 s.onDestroy(); 3035 Context context = s.getBaseContext(); 3036 if (context instanceof ContextImpl) { 3037 final String who = s.getClassName(); 3038 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 3039 } 3040 3041 QueuedWork.waitToFinish(); 3042 3043 try { 3044 ActivityManagerNative.getDefault().serviceDoneExecuting( 3045 token, SERVICE_DONE_EXECUTING_STOP, 0, 0); 3046 } catch (RemoteException e) { 3047 // nothing to do. 3048 Slog.i(TAG, "handleStopService: unable to execute serviceDoneExecuting for " 3049 + token, e); 3050 } 3051 } catch (Exception e) { 3052 if (!mInstrumentation.onException(s, e)) { 3053 throw new RuntimeException( 3054 "Unable to stop service " + s 3055 + ": " + e.toString(), e); 3056 } 3057 Slog.i(TAG, "handleStopService: exception for " + token, e); 3058 } 3059 } else { 3060 Slog.i(TAG, "handleStopService: token=" + token + " not found."); 3061 } 3062 //Slog.i(TAG, "Running services: " + mServices); 3063 } 3064 3065 public final ActivityClientRecord performResumeActivity(IBinder token, 3066 boolean clearHide) { 3067 ActivityClientRecord r = mActivities.get(token); 3068 if (localLOGV) Slog.v(TAG, "Performing resume of " + r 3069 + " finished=" + r.activity.mFinished); 3070 if (r != null && !r.activity.mFinished) { 3071 if (clearHide) { 3072 r.hideForNow = false; 3073 r.activity.mStartedActivity = false; 3074 } 3075 try { 3076 r.activity.mFragments.noteStateNotSaved(); 3077 if (r.pendingIntents != null) { 3078 deliverNewIntents(r, r.pendingIntents); 3079 r.pendingIntents = null; 3080 } 3081 if (r.pendingResults != null) { 3082 deliverResults(r, r.pendingResults); 3083 r.pendingResults = null; 3084 } 3085 r.activity.performResume(); 3086 3087 EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, 3088 UserHandle.myUserId(), r.activity.getComponentName().getClassName()); 3089 3090 r.paused = false; 3091 r.stopped = false; 3092 r.state = null; 3093 r.persistentState = null; 3094 } catch (Exception e) { 3095 if (!mInstrumentation.onException(r.activity, e)) { 3096 throw new RuntimeException( 3097 "Unable to resume activity " 3098 + r.intent.getComponent().toShortString() 3099 + ": " + e.toString(), e); 3100 } 3101 } 3102 } 3103 return r; 3104 } 3105 3106 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) { 3107 if (r.mPendingRemoveWindow != null) { 3108 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow); 3109 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken(); 3110 if (wtoken != null) { 3111 WindowManagerGlobal.getInstance().closeAll(wtoken, 3112 r.activity.getClass().getName(), "Activity"); 3113 } 3114 } 3115 r.mPendingRemoveWindow = null; 3116 r.mPendingRemoveWindowManager = null; 3117 } 3118 3119 final void handleResumeActivity(IBinder token, 3120 boolean clearHide, boolean isForward, boolean reallyResume) { 3121 // If we are getting ready to gc after going to the background, well 3122 // we are back active so skip it. 3123 unscheduleGcIdler(); 3124 mSomeActivitiesChanged = true; 3125 3126 // TODO Push resumeArgs into the activity for consideration 3127 ActivityClientRecord r = performResumeActivity(token, clearHide); 3128 3129 if (r != null) { 3130 final Activity a = r.activity; 3131 3132 if (localLOGV) Slog.v( 3133 TAG, "Resume " + r + " started activity: " + 3134 a.mStartedActivity + ", hideForNow: " + r.hideForNow 3135 + ", finished: " + a.mFinished); 3136 3137 final int forwardBit = isForward ? 3138 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 3139 3140 // If the window hasn't yet been added to the window manager, 3141 // and this guy didn't finish itself or start another activity, 3142 // then go ahead and add the window. 3143 boolean willBeVisible = !a.mStartedActivity; 3144 if (!willBeVisible) { 3145 try { 3146 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( 3147 a.getActivityToken()); 3148 } catch (RemoteException e) { 3149 } 3150 } 3151 if (r.window == null && !a.mFinished && willBeVisible) { 3152 r.window = r.activity.getWindow(); 3153 View decor = r.window.getDecorView(); 3154 decor.setVisibility(View.INVISIBLE); 3155 ViewManager wm = a.getWindowManager(); 3156 WindowManager.LayoutParams l = r.window.getAttributes(); 3157 a.mDecor = decor; 3158 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 3159 l.softInputMode |= forwardBit; 3160 if (a.mVisibleFromClient) { 3161 a.mWindowAdded = true; 3162 wm.addView(decor, l); 3163 } 3164 3165 // If the window has already been added, but during resume 3166 // we started another activity, then don't yet make the 3167 // window visible. 3168 } else if (!willBeVisible) { 3169 if (localLOGV) Slog.v( 3170 TAG, "Launch " + r + " mStartedActivity set"); 3171 r.hideForNow = true; 3172 } 3173 3174 // Get rid of anything left hanging around. 3175 cleanUpPendingRemoveWindows(r); 3176 3177 // The window is now visible if it has been added, we are not 3178 // simply finishing, and we are not starting another activity. 3179 if (!r.activity.mFinished && willBeVisible 3180 && r.activity.mDecor != null && !r.hideForNow) { 3181 if (r.newConfig != null) { 3182 r.tmpConfig.setTo(r.newConfig); 3183 if (r.overrideConfig != null) { 3184 r.tmpConfig.updateFrom(r.overrideConfig); 3185 } 3186 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 3187 + r.activityInfo.name + " with newConfig " + r.tmpConfig); 3188 performConfigurationChanged(r.activity, r.tmpConfig); 3189 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 3190 r.newConfig = null; 3191 } 3192 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 3193 + isForward); 3194 WindowManager.LayoutParams l = r.window.getAttributes(); 3195 if ((l.softInputMode 3196 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 3197 != forwardBit) { 3198 l.softInputMode = (l.softInputMode 3199 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 3200 | forwardBit; 3201 if (r.activity.mVisibleFromClient) { 3202 ViewManager wm = a.getWindowManager(); 3203 View decor = r.window.getDecorView(); 3204 wm.updateViewLayout(decor, l); 3205 } 3206 } 3207 r.activity.mVisibleFromServer = true; 3208 mNumVisibleActivities++; 3209 if (r.activity.mVisibleFromClient) { 3210 r.activity.makeVisible(); 3211 } 3212 } 3213 3214 if (!r.onlyLocalRequest) { 3215 r.nextIdle = mNewActivities; 3216 mNewActivities = r; 3217 if (localLOGV) Slog.v( 3218 TAG, "Scheduling idle handler for " + r); 3219 Looper.myQueue().addIdleHandler(new Idler()); 3220 } 3221 r.onlyLocalRequest = false; 3222 3223 // Tell the activity manager we have resumed. 3224 if (reallyResume) { 3225 try { 3226 ActivityManagerNative.getDefault().activityResumed(token); 3227 } catch (RemoteException ex) { 3228 } 3229 } 3230 3231 } else { 3232 // If an exception was thrown when trying to resume, then 3233 // just end this activity. 3234 try { 3235 ActivityManagerNative.getDefault() 3236 .finishActivity(token, Activity.RESULT_CANCELED, null, false); 3237 } catch (RemoteException ex) { 3238 } 3239 } 3240 } 3241 3242 private int mThumbnailWidth = -1; 3243 private int mThumbnailHeight = -1; 3244 private Bitmap mAvailThumbnailBitmap = null; 3245 private Canvas mThumbnailCanvas = null; 3246 3247 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 3248 Bitmap thumbnail = mAvailThumbnailBitmap; 3249 try { 3250 if (thumbnail == null) { 3251 int w = mThumbnailWidth; 3252 int h; 3253 if (w < 0) { 3254 Resources res = r.activity.getResources(); 3255 int wId = com.android.internal.R.dimen.thumbnail_width; 3256 int hId = com.android.internal.R.dimen.thumbnail_height; 3257 mThumbnailWidth = w = res.getDimensionPixelSize(wId); 3258 mThumbnailHeight = h = res.getDimensionPixelSize(hId); 3259 } else { 3260 h = mThumbnailHeight; 3261 } 3262 3263 // On platforms where we don't want thumbnails, set dims to (0,0) 3264 if ((w > 0) && (h > 0)) { 3265 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 3266 w, h, THUMBNAIL_FORMAT); 3267 thumbnail.eraseColor(0); 3268 } 3269 } 3270 3271 if (thumbnail != null) { 3272 Canvas cv = mThumbnailCanvas; 3273 if (cv == null) { 3274 mThumbnailCanvas = cv = new Canvas(); 3275 } 3276 3277 cv.setBitmap(thumbnail); 3278 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 3279 mAvailThumbnailBitmap = thumbnail; 3280 thumbnail = null; 3281 } 3282 cv.setBitmap(null); 3283 } 3284 3285 } catch (Exception e) { 3286 if (!mInstrumentation.onException(r.activity, e)) { 3287 throw new RuntimeException( 3288 "Unable to create thumbnail of " 3289 + r.intent.getComponent().toShortString() 3290 + ": " + e.toString(), e); 3291 } 3292 thumbnail = null; 3293 } 3294 3295 return thumbnail; 3296 } 3297 3298 private void handlePauseActivity(IBinder token, boolean finished, 3299 boolean userLeaving, int configChanges, boolean dontReport) { 3300 ActivityClientRecord r = mActivities.get(token); 3301 if (r != null) { 3302 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3303 if (userLeaving) { 3304 performUserLeavingActivity(r); 3305 } 3306 3307 r.activity.mConfigChangeFlags |= configChanges; 3308 performPauseActivity(token, finished, r.isPreHoneycomb()); 3309 3310 // Make sure any pending writes are now committed. 3311 if (r.isPreHoneycomb()) { 3312 QueuedWork.waitToFinish(); 3313 } 3314 3315 // Tell the activity manager we have paused. 3316 if (!dontReport) { 3317 try { 3318 ActivityManagerNative.getDefault().activityPaused(token); 3319 } catch (RemoteException ex) { 3320 } 3321 } 3322 mSomeActivitiesChanged = true; 3323 } 3324 } 3325 3326 final void performUserLeavingActivity(ActivityClientRecord r) { 3327 mInstrumentation.callActivityOnUserLeaving(r.activity); 3328 } 3329 3330 final Bundle performPauseActivity(IBinder token, boolean finished, 3331 boolean saveState) { 3332 ActivityClientRecord r = mActivities.get(token); 3333 return r != null ? performPauseActivity(r, finished, saveState) : null; 3334 } 3335 3336 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3337 boolean saveState) { 3338 if (r.paused) { 3339 if (r.activity.mFinished) { 3340 // If we are finishing, we won't call onResume() in certain cases. 3341 // So here we likewise don't want to call onPause() if the activity 3342 // isn't resumed. 3343 return null; 3344 } 3345 RuntimeException e = new RuntimeException( 3346 "Performing pause of activity that is not resumed: " 3347 + r.intent.getComponent().toShortString()); 3348 Slog.e(TAG, e.getMessage(), e); 3349 } 3350 if (finished) { 3351 r.activity.mFinished = true; 3352 } 3353 try { 3354 // Next have the activity save its current state and managed dialogs... 3355 if (!r.activity.mFinished && saveState) { 3356 callCallActivityOnSaveInstanceState(r); 3357 } 3358 // Now we are idle. 3359 r.activity.mCalled = false; 3360 mInstrumentation.callActivityOnPause(r.activity); 3361 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 3362 r.activity.getComponentName().getClassName()); 3363 if (!r.activity.mCalled) { 3364 throw new SuperNotCalledException( 3365 "Activity " + r.intent.getComponent().toShortString() + 3366 " did not call through to super.onPause()"); 3367 } 3368 3369 } catch (SuperNotCalledException e) { 3370 throw e; 3371 3372 } catch (Exception e) { 3373 if (!mInstrumentation.onException(r.activity, e)) { 3374 throw new RuntimeException( 3375 "Unable to pause activity " 3376 + r.intent.getComponent().toShortString() 3377 + ": " + e.toString(), e); 3378 } 3379 } 3380 r.paused = true; 3381 3382 // Notify any outstanding on paused listeners 3383 ArrayList<OnActivityPausedListener> listeners; 3384 synchronized (mOnPauseListeners) { 3385 listeners = mOnPauseListeners.remove(r.activity); 3386 } 3387 int size = (listeners != null ? listeners.size() : 0); 3388 for (int i = 0; i < size; i++) { 3389 listeners.get(i).onPaused(r.activity); 3390 } 3391 3392 return !r.activity.mFinished && saveState ? r.state : null; 3393 } 3394 3395 final void performStopActivity(IBinder token, boolean saveState) { 3396 ActivityClientRecord r = mActivities.get(token); 3397 performStopActivityInner(r, null, false, saveState); 3398 } 3399 3400 private static class StopInfo implements Runnable { 3401 ActivityClientRecord activity; 3402 Bundle state; 3403 PersistableBundle persistentState; 3404 CharSequence description; 3405 3406 @Override public void run() { 3407 // Tell activity manager we have been stopped. 3408 try { 3409 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3410 ActivityManagerNative.getDefault().activityStopped( 3411 activity.token, state, persistentState, description); 3412 } catch (RemoteException ex) { 3413 } 3414 } 3415 } 3416 3417 private static final class ProviderRefCount { 3418 public final IActivityManager.ContentProviderHolder holder; 3419 public final ProviderClientRecord client; 3420 public int stableCount; 3421 public int unstableCount; 3422 3423 // When this is set, the stable and unstable ref counts are 0 and 3424 // we have a pending operation scheduled to remove the ref count 3425 // from the activity manager. On the activity manager we are still 3426 // holding an unstable ref, though it is not reflected in the counts 3427 // here. 3428 public boolean removePending; 3429 3430 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3431 ProviderClientRecord inClient, int sCount, int uCount) { 3432 holder = inHolder; 3433 client = inClient; 3434 stableCount = sCount; 3435 unstableCount = uCount; 3436 } 3437 } 3438 3439 /** 3440 * Core implementation of stopping an activity. Note this is a little 3441 * tricky because the server's meaning of stop is slightly different 3442 * than our client -- for the server, stop means to save state and give 3443 * it the result when it is done, but the window may still be visible. 3444 * For the client, we want to call onStop()/onStart() to indicate when 3445 * the activity's UI visibillity changes. 3446 */ 3447 private void performStopActivityInner(ActivityClientRecord r, 3448 StopInfo info, boolean keepShown, boolean saveState) { 3449 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3450 if (r != null) { 3451 if (!keepShown && r.stopped) { 3452 if (r.activity.mFinished) { 3453 // If we are finishing, we won't call onResume() in certain 3454 // cases. So here we likewise don't want to call onStop() 3455 // if the activity isn't resumed. 3456 return; 3457 } 3458 RuntimeException e = new RuntimeException( 3459 "Performing stop of activity that is not resumed: " 3460 + r.intent.getComponent().toShortString()); 3461 Slog.e(TAG, e.getMessage(), e); 3462 } 3463 3464 if (info != null) { 3465 try { 3466 // First create a thumbnail for the activity... 3467 // For now, don't create the thumbnail here; we are 3468 // doing that by doing a screen snapshot. 3469 info.description = r.activity.onCreateDescription(); 3470 } catch (Exception e) { 3471 if (!mInstrumentation.onException(r.activity, e)) { 3472 throw new RuntimeException( 3473 "Unable to save state of activity " 3474 + r.intent.getComponent().toShortString() 3475 + ": " + e.toString(), e); 3476 } 3477 } 3478 } 3479 3480 // Next have the activity save its current state and managed dialogs... 3481 if (!r.activity.mFinished && saveState) { 3482 if (r.state == null) { 3483 callCallActivityOnSaveInstanceState(r); 3484 } 3485 } 3486 3487 if (!keepShown) { 3488 try { 3489 // Now we are idle. 3490 r.activity.performStop(); 3491 } catch (Exception e) { 3492 if (!mInstrumentation.onException(r.activity, e)) { 3493 throw new RuntimeException( 3494 "Unable to stop activity " 3495 + r.intent.getComponent().toShortString() 3496 + ": " + e.toString(), e); 3497 } 3498 } 3499 r.stopped = true; 3500 } 3501 3502 r.paused = true; 3503 } 3504 } 3505 3506 private void updateVisibility(ActivityClientRecord r, boolean show) { 3507 View v = r.activity.mDecor; 3508 if (v != null) { 3509 if (show) { 3510 if (!r.activity.mVisibleFromServer) { 3511 r.activity.mVisibleFromServer = true; 3512 mNumVisibleActivities++; 3513 if (r.activity.mVisibleFromClient) { 3514 r.activity.makeVisible(); 3515 } 3516 } 3517 if (r.newConfig != null) { 3518 r.tmpConfig.setTo(r.newConfig); 3519 if (r.overrideConfig != null) { 3520 r.tmpConfig.updateFrom(r.overrideConfig); 3521 } 3522 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3523 + r.activityInfo.name + " with new config " + r.tmpConfig); 3524 performConfigurationChanged(r.activity, r.tmpConfig); 3525 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 3526 r.newConfig = null; 3527 } 3528 } else { 3529 if (r.activity.mVisibleFromServer) { 3530 r.activity.mVisibleFromServer = false; 3531 mNumVisibleActivities--; 3532 v.setVisibility(View.INVISIBLE); 3533 } 3534 } 3535 } 3536 } 3537 3538 private void handleStopActivity(IBinder token, boolean show, int configChanges) { 3539 ActivityClientRecord r = mActivities.get(token); 3540 r.activity.mConfigChangeFlags |= configChanges; 3541 3542 StopInfo info = new StopInfo(); 3543 performStopActivityInner(r, info, show, true); 3544 3545 if (localLOGV) Slog.v( 3546 TAG, "Finishing stop of " + r + ": show=" + show 3547 + " win=" + r.window); 3548 3549 updateVisibility(r, show); 3550 3551 // Make sure any pending writes are now committed. 3552 if (!r.isPreHoneycomb()) { 3553 QueuedWork.waitToFinish(); 3554 } 3555 3556 // Schedule the call to tell the activity manager we have 3557 // stopped. We don't do this immediately, because we want to 3558 // have a chance for any other pending work (in particular memory 3559 // trim requests) to complete before you tell the activity 3560 // manager to proceed and allow us to go fully into the background. 3561 info.activity = r; 3562 info.state = r.state; 3563 info.persistentState = r.persistentState; 3564 mH.post(info); 3565 mSomeActivitiesChanged = true; 3566 } 3567 3568 final void performRestartActivity(IBinder token) { 3569 ActivityClientRecord r = mActivities.get(token); 3570 if (r.stopped) { 3571 r.activity.performRestart(); 3572 r.stopped = false; 3573 } 3574 } 3575 3576 private void handleWindowVisibility(IBinder token, boolean show) { 3577 ActivityClientRecord r = mActivities.get(token); 3578 3579 if (r == null) { 3580 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3581 return; 3582 } 3583 3584 if (!show && !r.stopped) { 3585 performStopActivityInner(r, null, show, false); 3586 } else if (show && r.stopped) { 3587 // If we are getting ready to gc after going to the background, well 3588 // we are back active so skip it. 3589 unscheduleGcIdler(); 3590 3591 r.activity.performRestart(); 3592 r.stopped = false; 3593 } 3594 if (r.activity.mDecor != null) { 3595 if (false) Slog.v( 3596 TAG, "Handle window " + r + " visibility: " + show); 3597 updateVisibility(r, show); 3598 } 3599 mSomeActivitiesChanged = true; 3600 } 3601 3602 private void handleSleeping(IBinder token, boolean sleeping) { 3603 ActivityClientRecord r = mActivities.get(token); 3604 3605 if (r == null) { 3606 Log.w(TAG, "handleSleeping: no activity for token " + token); 3607 return; 3608 } 3609 3610 if (sleeping) { 3611 if (!r.stopped && !r.isPreHoneycomb()) { 3612 try { 3613 // Now we are idle. 3614 r.activity.performStop(); 3615 } catch (Exception e) { 3616 if (!mInstrumentation.onException(r.activity, e)) { 3617 throw new RuntimeException( 3618 "Unable to stop activity " 3619 + r.intent.getComponent().toShortString() 3620 + ": " + e.toString(), e); 3621 } 3622 } 3623 r.stopped = true; 3624 } 3625 3626 // Make sure any pending writes are now committed. 3627 if (!r.isPreHoneycomb()) { 3628 QueuedWork.waitToFinish(); 3629 } 3630 3631 // Tell activity manager we slept. 3632 try { 3633 ActivityManagerNative.getDefault().activitySlept(r.token); 3634 } catch (RemoteException ex) { 3635 } 3636 } else { 3637 if (r.stopped && r.activity.mVisibleFromServer) { 3638 r.activity.performRestart(); 3639 r.stopped = false; 3640 } 3641 } 3642 } 3643 3644 private void handleSetCoreSettings(Bundle coreSettings) { 3645 synchronized (mResourcesManager) { 3646 mCoreSettings = coreSettings; 3647 } 3648 onCoreSettingsChange(); 3649 } 3650 3651 private void onCoreSettingsChange() { 3652 boolean debugViewAttributes = 3653 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 3654 if (debugViewAttributes != View.mDebugViewAttributes) { 3655 View.mDebugViewAttributes = debugViewAttributes; 3656 3657 // request all activities to relaunch for the changes to take place 3658 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 3659 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false); 3660 } 3661 } 3662 } 3663 3664 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3665 LoadedApk apk = peekPackageInfo(data.pkg, false); 3666 if (apk != null) { 3667 apk.setCompatibilityInfo(data.info); 3668 } 3669 apk = peekPackageInfo(data.pkg, true); 3670 if (apk != null) { 3671 apk.setCompatibilityInfo(data.info); 3672 } 3673 handleConfigurationChanged(mConfiguration, data.info); 3674 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3675 } 3676 3677 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3678 final int N = results.size(); 3679 for (int i=0; i<N; i++) { 3680 ResultInfo ri = results.get(i); 3681 try { 3682 if (ri.mData != null) { 3683 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3684 ri.mData.prepareToEnterProcess(); 3685 } 3686 if (DEBUG_RESULTS) Slog.v(TAG, 3687 "Delivering result to activity " + r + " : " + ri); 3688 r.activity.dispatchActivityResult(ri.mResultWho, 3689 ri.mRequestCode, ri.mResultCode, ri.mData); 3690 } catch (Exception e) { 3691 if (!mInstrumentation.onException(r.activity, e)) { 3692 throw new RuntimeException( 3693 "Failure delivering result " + ri + " to activity " 3694 + r.intent.getComponent().toShortString() 3695 + ": " + e.toString(), e); 3696 } 3697 } 3698 } 3699 } 3700 3701 private void handleSendResult(ResultData res) { 3702 ActivityClientRecord r = mActivities.get(res.token); 3703 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3704 if (r != null) { 3705 final boolean resumed = !r.paused; 3706 if (!r.activity.mFinished && r.activity.mDecor != null 3707 && r.hideForNow && resumed) { 3708 // We had hidden the activity because it started another 3709 // one... we have gotten a result back and we are not 3710 // paused, so make sure our window is visible. 3711 updateVisibility(r, true); 3712 } 3713 if (resumed) { 3714 try { 3715 // Now we are idle. 3716 r.activity.mCalled = false; 3717 r.activity.mTemporaryPause = true; 3718 mInstrumentation.callActivityOnPause(r.activity); 3719 if (!r.activity.mCalled) { 3720 throw new SuperNotCalledException( 3721 "Activity " + r.intent.getComponent().toShortString() 3722 + " did not call through to super.onPause()"); 3723 } 3724 } catch (SuperNotCalledException e) { 3725 throw e; 3726 } catch (Exception e) { 3727 if (!mInstrumentation.onException(r.activity, e)) { 3728 throw new RuntimeException( 3729 "Unable to pause activity " 3730 + r.intent.getComponent().toShortString() 3731 + ": " + e.toString(), e); 3732 } 3733 } 3734 } 3735 deliverResults(r, res.results); 3736 if (resumed) { 3737 r.activity.performResume(); 3738 r.activity.mTemporaryPause = false; 3739 } 3740 } 3741 } 3742 3743 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 3744 return performDestroyActivity(token, finishing, 0, false); 3745 } 3746 3747 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 3748 int configChanges, boolean getNonConfigInstance) { 3749 ActivityClientRecord r = mActivities.get(token); 3750 Class<? extends Activity> activityClass = null; 3751 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 3752 if (r != null) { 3753 activityClass = r.activity.getClass(); 3754 r.activity.mConfigChangeFlags |= configChanges; 3755 if (finishing) { 3756 r.activity.mFinished = true; 3757 } 3758 if (!r.paused) { 3759 try { 3760 r.activity.mCalled = false; 3761 mInstrumentation.callActivityOnPause(r.activity); 3762 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), 3763 r.activity.getComponentName().getClassName()); 3764 if (!r.activity.mCalled) { 3765 throw new SuperNotCalledException( 3766 "Activity " + safeToComponentShortString(r.intent) 3767 + " did not call through to super.onPause()"); 3768 } 3769 } catch (SuperNotCalledException e) { 3770 throw e; 3771 } catch (Exception e) { 3772 if (!mInstrumentation.onException(r.activity, e)) { 3773 throw new RuntimeException( 3774 "Unable to pause activity " 3775 + safeToComponentShortString(r.intent) 3776 + ": " + e.toString(), e); 3777 } 3778 } 3779 r.paused = true; 3780 } 3781 if (!r.stopped) { 3782 try { 3783 r.activity.performStop(); 3784 } catch (SuperNotCalledException e) { 3785 throw e; 3786 } catch (Exception e) { 3787 if (!mInstrumentation.onException(r.activity, e)) { 3788 throw new RuntimeException( 3789 "Unable to stop activity " 3790 + safeToComponentShortString(r.intent) 3791 + ": " + e.toString(), e); 3792 } 3793 } 3794 r.stopped = true; 3795 } 3796 if (getNonConfigInstance) { 3797 try { 3798 r.lastNonConfigurationInstances 3799 = r.activity.retainNonConfigurationInstances(); 3800 } catch (Exception e) { 3801 if (!mInstrumentation.onException(r.activity, e)) { 3802 throw new RuntimeException( 3803 "Unable to retain activity " 3804 + r.intent.getComponent().toShortString() 3805 + ": " + e.toString(), e); 3806 } 3807 } 3808 } 3809 try { 3810 r.activity.mCalled = false; 3811 mInstrumentation.callActivityOnDestroy(r.activity); 3812 if (!r.activity.mCalled) { 3813 throw new SuperNotCalledException( 3814 "Activity " + safeToComponentShortString(r.intent) + 3815 " did not call through to super.onDestroy()"); 3816 } 3817 if (r.window != null) { 3818 r.window.closeAllPanels(); 3819 } 3820 } catch (SuperNotCalledException e) { 3821 throw e; 3822 } catch (Exception e) { 3823 if (!mInstrumentation.onException(r.activity, e)) { 3824 throw new RuntimeException( 3825 "Unable to destroy activity " + safeToComponentShortString(r.intent) 3826 + ": " + e.toString(), e); 3827 } 3828 } 3829 } 3830 mActivities.remove(token); 3831 StrictMode.decrementExpectedActivityCount(activityClass); 3832 return r; 3833 } 3834 3835 private static String safeToComponentShortString(Intent intent) { 3836 ComponentName component = intent.getComponent(); 3837 return component == null ? "[Unknown]" : component.toShortString(); 3838 } 3839 3840 private void handleDestroyActivity(IBinder token, boolean finishing, 3841 int configChanges, boolean getNonConfigInstance) { 3842 ActivityClientRecord r = performDestroyActivity(token, finishing, 3843 configChanges, getNonConfigInstance); 3844 if (r != null) { 3845 cleanUpPendingRemoveWindows(r); 3846 WindowManager wm = r.activity.getWindowManager(); 3847 View v = r.activity.mDecor; 3848 if (v != null) { 3849 if (r.activity.mVisibleFromServer) { 3850 mNumVisibleActivities--; 3851 } 3852 IBinder wtoken = v.getWindowToken(); 3853 if (r.activity.mWindowAdded) { 3854 if (r.onlyLocalRequest) { 3855 // Hold off on removing this until the new activity's 3856 // window is being added. 3857 r.mPendingRemoveWindow = v; 3858 r.mPendingRemoveWindowManager = wm; 3859 } else { 3860 wm.removeViewImmediate(v); 3861 } 3862 } 3863 if (wtoken != null && r.mPendingRemoveWindow == null) { 3864 WindowManagerGlobal.getInstance().closeAll(wtoken, 3865 r.activity.getClass().getName(), "Activity"); 3866 } 3867 r.activity.mDecor = null; 3868 } 3869 if (r.mPendingRemoveWindow == null) { 3870 // If we are delaying the removal of the activity window, then 3871 // we can't clean up all windows here. Note that we can't do 3872 // so later either, which means any windows that aren't closed 3873 // by the app will leak. Well we try to warning them a lot 3874 // about leaking windows, because that is a bug, so if they are 3875 // using this recreate facility then they get to live with leaks. 3876 WindowManagerGlobal.getInstance().closeAll(token, 3877 r.activity.getClass().getName(), "Activity"); 3878 } 3879 3880 // Mocked out contexts won't be participating in the normal 3881 // process lifecycle, but if we're running with a proper 3882 // ApplicationContext we need to have it tear down things 3883 // cleanly. 3884 Context c = r.activity.getBaseContext(); 3885 if (c instanceof ContextImpl) { 3886 ((ContextImpl) c).scheduleFinalCleanup( 3887 r.activity.getClass().getName(), "Activity"); 3888 } 3889 } 3890 if (finishing) { 3891 try { 3892 ActivityManagerNative.getDefault().activityDestroyed(token); 3893 } catch (RemoteException ex) { 3894 // If the system process has died, it's game over for everyone. 3895 } 3896 } 3897 mSomeActivitiesChanged = true; 3898 } 3899 3900 public final void requestRelaunchActivity(IBinder token, 3901 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 3902 int configChanges, boolean notResumed, Configuration config, 3903 Configuration overrideConfig, boolean fromServer) { 3904 ActivityClientRecord target = null; 3905 3906 synchronized (mResourcesManager) { 3907 for (int i=0; i<mRelaunchingActivities.size(); i++) { 3908 ActivityClientRecord r = mRelaunchingActivities.get(i); 3909 if (r.token == token) { 3910 target = r; 3911 if (pendingResults != null) { 3912 if (r.pendingResults != null) { 3913 r.pendingResults.addAll(pendingResults); 3914 } else { 3915 r.pendingResults = pendingResults; 3916 } 3917 } 3918 if (pendingNewIntents != null) { 3919 if (r.pendingIntents != null) { 3920 r.pendingIntents.addAll(pendingNewIntents); 3921 } else { 3922 r.pendingIntents = pendingNewIntents; 3923 } 3924 } 3925 break; 3926 } 3927 } 3928 3929 if (target == null) { 3930 target = new ActivityClientRecord(); 3931 target.token = token; 3932 target.pendingResults = pendingResults; 3933 target.pendingIntents = pendingNewIntents; 3934 if (!fromServer) { 3935 ActivityClientRecord existing = mActivities.get(token); 3936 if (existing != null) { 3937 target.startsNotResumed = existing.paused; 3938 target.overrideConfig = existing.overrideConfig; 3939 } 3940 target.onlyLocalRequest = true; 3941 } 3942 mRelaunchingActivities.add(target); 3943 sendMessage(H.RELAUNCH_ACTIVITY, target); 3944 } 3945 3946 if (fromServer) { 3947 target.startsNotResumed = notResumed; 3948 target.onlyLocalRequest = false; 3949 } 3950 if (config != null) { 3951 target.createdConfig = config; 3952 } 3953 if (overrideConfig != null) { 3954 target.overrideConfig = overrideConfig; 3955 } 3956 target.pendingConfigChanges |= configChanges; 3957 } 3958 } 3959 3960 private void handleRelaunchActivity(ActivityClientRecord tmp) { 3961 // If we are getting ready to gc after going to the background, well 3962 // we are back active so skip it. 3963 unscheduleGcIdler(); 3964 mSomeActivitiesChanged = true; 3965 3966 Configuration changedConfig = null; 3967 int configChanges = 0; 3968 3969 // First: make sure we have the most recent configuration and most 3970 // recent version of the activity, or skip it if some previous call 3971 // had taken a more recent version. 3972 synchronized (mResourcesManager) { 3973 int N = mRelaunchingActivities.size(); 3974 IBinder token = tmp.token; 3975 tmp = null; 3976 for (int i=0; i<N; i++) { 3977 ActivityClientRecord r = mRelaunchingActivities.get(i); 3978 if (r.token == token) { 3979 tmp = r; 3980 configChanges |= tmp.pendingConfigChanges; 3981 mRelaunchingActivities.remove(i); 3982 i--; 3983 N--; 3984 } 3985 } 3986 3987 if (tmp == null) { 3988 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 3989 return; 3990 } 3991 3992 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3993 + tmp.token + " with configChanges=0x" 3994 + Integer.toHexString(configChanges)); 3995 3996 if (mPendingConfiguration != null) { 3997 changedConfig = mPendingConfiguration; 3998 mPendingConfiguration = null; 3999 } 4000 } 4001 4002 if (tmp.createdConfig != null) { 4003 // If the activity manager is passing us its current config, 4004 // assume that is really what we want regardless of what we 4005 // may have pending. 4006 if (mConfiguration == null 4007 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 4008 && mConfiguration.diff(tmp.createdConfig) != 0)) { 4009 if (changedConfig == null 4010 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 4011 changedConfig = tmp.createdConfig; 4012 } 4013 } 4014 } 4015 4016 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 4017 + tmp.token + ": changedConfig=" + changedConfig); 4018 4019 // If there was a pending configuration change, execute it first. 4020 if (changedConfig != null) { 4021 mCurDefaultDisplayDpi = changedConfig.densityDpi; 4022 updateDefaultDensity(); 4023 handleConfigurationChanged(changedConfig, null); 4024 } 4025 4026 ActivityClientRecord r = mActivities.get(tmp.token); 4027 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 4028 if (r == null) { 4029 return; 4030 } 4031 4032 r.activity.mConfigChangeFlags |= configChanges; 4033 r.onlyLocalRequest = tmp.onlyLocalRequest; 4034 Intent currentIntent = r.activity.mIntent; 4035 4036 r.activity.mChangingConfigurations = true; 4037 4038 // Need to ensure state is saved. 4039 if (!r.paused) { 4040 performPauseActivity(r.token, false, r.isPreHoneycomb()); 4041 } 4042 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 4043 callCallActivityOnSaveInstanceState(r); 4044 } 4045 4046 handleDestroyActivity(r.token, false, configChanges, true); 4047 4048 r.activity = null; 4049 r.window = null; 4050 r.hideForNow = false; 4051 r.nextIdle = null; 4052 // Merge any pending results and pending intents; don't just replace them 4053 if (tmp.pendingResults != null) { 4054 if (r.pendingResults == null) { 4055 r.pendingResults = tmp.pendingResults; 4056 } else { 4057 r.pendingResults.addAll(tmp.pendingResults); 4058 } 4059 } 4060 if (tmp.pendingIntents != null) { 4061 if (r.pendingIntents == null) { 4062 r.pendingIntents = tmp.pendingIntents; 4063 } else { 4064 r.pendingIntents.addAll(tmp.pendingIntents); 4065 } 4066 } 4067 r.startsNotResumed = tmp.startsNotResumed; 4068 r.overrideConfig = tmp.overrideConfig; 4069 4070 handleLaunchActivity(r, currentIntent); 4071 } 4072 4073 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) { 4074 r.state = new Bundle(); 4075 r.state.setAllowFds(false); 4076 if (r.isPersistable()) { 4077 r.persistentState = new PersistableBundle(); 4078 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 4079 r.persistentState); 4080 } else { 4081 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 4082 } 4083 } 4084 4085 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 4086 boolean allActivities, Configuration newConfig) { 4087 ArrayList<ComponentCallbacks2> callbacks 4088 = new ArrayList<ComponentCallbacks2>(); 4089 4090 synchronized (mResourcesManager) { 4091 final int NAPP = mAllApplications.size(); 4092 for (int i=0; i<NAPP; i++) { 4093 callbacks.add(mAllApplications.get(i)); 4094 } 4095 final int NACT = mActivities.size(); 4096 for (int i=0; i<NACT; i++) { 4097 ActivityClientRecord ar = mActivities.valueAt(i); 4098 Activity a = ar.activity; 4099 if (a != null) { 4100 Configuration thisConfig = applyConfigCompatMainThread( 4101 mCurDefaultDisplayDpi, newConfig, 4102 ar.packageInfo.getCompatibilityInfo()); 4103 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 4104 // If the activity is currently resumed, its configuration 4105 // needs to change right now. 4106 callbacks.add(a); 4107 } else if (thisConfig != null) { 4108 // Otherwise, we will tell it about the change 4109 // the next time it is resumed or shown. Note that 4110 // the activity manager may, before then, decide the 4111 // activity needs to be destroyed to handle its new 4112 // configuration. 4113 if (DEBUG_CONFIGURATION) { 4114 Slog.v(TAG, "Setting activity " 4115 + ar.activityInfo.name + " newConfig=" + thisConfig); 4116 } 4117 ar.newConfig = thisConfig; 4118 } 4119 } 4120 } 4121 final int NSVC = mServices.size(); 4122 for (int i=0; i<NSVC; i++) { 4123 callbacks.add(mServices.valueAt(i)); 4124 } 4125 } 4126 synchronized (mProviderMap) { 4127 final int NPRV = mLocalProviders.size(); 4128 for (int i=0; i<NPRV; i++) { 4129 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 4130 } 4131 } 4132 4133 return callbacks; 4134 } 4135 4136 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { 4137 // Only for Activity objects, check that they actually call up to their 4138 // superclass implementation. ComponentCallbacks2 is an interface, so 4139 // we check the runtime type and act accordingly. 4140 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 4141 if (activity != null) { 4142 activity.mCalled = false; 4143 } 4144 4145 boolean shouldChangeConfig = false; 4146 if ((activity == null) || (activity.mCurrentConfig == null)) { 4147 shouldChangeConfig = true; 4148 } else { 4149 4150 // If the new config is the same as the config this Activity 4151 // is already running with then don't bother calling 4152 // onConfigurationChanged 4153 int diff = activity.mCurrentConfig.diff(config); 4154 if (diff != 0) { 4155 // If this activity doesn't handle any of the config changes 4156 // then don't bother calling onConfigurationChanged as we're 4157 // going to destroy it. 4158 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) { 4159 shouldChangeConfig = true; 4160 } 4161 } 4162 } 4163 4164 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 4165 + ": shouldChangeConfig=" + shouldChangeConfig); 4166 if (shouldChangeConfig) { 4167 cb.onConfigurationChanged(config); 4168 4169 if (activity != null) { 4170 if (!activity.mCalled) { 4171 throw new SuperNotCalledException( 4172 "Activity " + activity.getLocalClassName() + 4173 " did not call through to super.onConfigurationChanged()"); 4174 } 4175 activity.mConfigChangeFlags = 0; 4176 activity.mCurrentConfig = new Configuration(config); 4177 } 4178 } 4179 } 4180 4181 public final void applyConfigurationToResources(Configuration config) { 4182 synchronized (mResourcesManager) { 4183 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 4184 } 4185 } 4186 4187 final Configuration applyCompatConfiguration(int displayDensity) { 4188 Configuration config = mConfiguration; 4189 if (mCompatConfiguration == null) { 4190 mCompatConfiguration = new Configuration(); 4191 } 4192 mCompatConfiguration.setTo(mConfiguration); 4193 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { 4194 config = mCompatConfiguration; 4195 } 4196 return config; 4197 } 4198 4199 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 4200 4201 int configDiff = 0; 4202 4203 synchronized (mResourcesManager) { 4204 if (mPendingConfiguration != null) { 4205 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 4206 config = mPendingConfiguration; 4207 mCurDefaultDisplayDpi = config.densityDpi; 4208 updateDefaultDensity(); 4209 } 4210 mPendingConfiguration = null; 4211 } 4212 4213 if (config == null) { 4214 return; 4215 } 4216 4217 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 4218 + config); 4219 4220 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 4221 4222 if (mConfiguration == null) { 4223 mConfiguration = new Configuration(); 4224 } 4225 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 4226 return; 4227 } 4228 4229 configDiff = mConfiguration.updateFrom(config); 4230 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 4231 4232 final Theme systemTheme = getSystemContext().getTheme(); 4233 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) { 4234 systemTheme.rebase(); 4235 } 4236 } 4237 4238 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 4239 4240 freeTextLayoutCachesIfNeeded(configDiff); 4241 4242 if (callbacks != null) { 4243 final int N = callbacks.size(); 4244 for (int i=0; i<N; i++) { 4245 performConfigurationChanged(callbacks.get(i), config); 4246 } 4247 } 4248 } 4249 4250 static void freeTextLayoutCachesIfNeeded(int configDiff) { 4251 if (configDiff != 0) { 4252 // Ask text layout engine to free its caches if there is a locale change 4253 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 4254 if (hasLocaleConfigChange) { 4255 Canvas.freeTextLayoutCaches(); 4256 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 4257 } 4258 } 4259 } 4260 4261 final void handleActivityConfigurationChanged(ActivityConfigChangeData data) { 4262 ActivityClientRecord r = mActivities.get(data.activityToken); 4263 if (r == null || r.activity == null) { 4264 return; 4265 } 4266 4267 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4268 + r.activityInfo.name); 4269 4270 r.tmpConfig.setTo(mCompatConfiguration); 4271 if (data.overrideConfig != null) { 4272 r.overrideConfig = data.overrideConfig; 4273 r.tmpConfig.updateFrom(data.overrideConfig); 4274 } 4275 performConfigurationChanged(r.activity, r.tmpConfig); 4276 4277 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 4278 4279 mSomeActivitiesChanged = true; 4280 } 4281 4282 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 4283 if (start) { 4284 try { 4285 switch (profileType) { 4286 default: 4287 mProfiler.setProfiler(profilerInfo); 4288 mProfiler.startProfiling(); 4289 break; 4290 } 4291 } catch (RuntimeException e) { 4292 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile 4293 + " -- can the process access this path?"); 4294 } finally { 4295 try { 4296 profilerInfo.profileFd.close(); 4297 } catch (IOException e) { 4298 Slog.w(TAG, "Failure closing profile fd", e); 4299 } 4300 } 4301 } else { 4302 switch (profileType) { 4303 default: 4304 mProfiler.stopProfiling(); 4305 break; 4306 } 4307 } 4308 } 4309 4310 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4311 if (managed) { 4312 try { 4313 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4314 } catch (IOException e) { 4315 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4316 + " -- can the process access this path?"); 4317 } finally { 4318 try { 4319 dhd.fd.close(); 4320 } catch (IOException e) { 4321 Slog.w(TAG, "Failure closing profile fd", e); 4322 } 4323 } 4324 } else { 4325 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4326 } 4327 try { 4328 ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path); 4329 } catch (RemoteException e) { 4330 } 4331 } 4332 4333 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4334 boolean hasPkgInfo = false; 4335 if (packages != null) { 4336 synchronized (mResourcesManager) { 4337 for (int i=packages.length-1; i>=0; i--) { 4338 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4339 if (!hasPkgInfo) { 4340 WeakReference<LoadedApk> ref; 4341 ref = mPackages.get(packages[i]); 4342 if (ref != null && ref.get() != null) { 4343 hasPkgInfo = true; 4344 } else { 4345 ref = mResourcePackages.get(packages[i]); 4346 if (ref != null && ref.get() != null) { 4347 hasPkgInfo = true; 4348 } 4349 } 4350 } 4351 mPackages.remove(packages[i]); 4352 mResourcePackages.remove(packages[i]); 4353 } 4354 } 4355 } 4356 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4357 hasPkgInfo); 4358 } 4359 4360 final void handleLowMemory() { 4361 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4362 4363 final int N = callbacks.size(); 4364 for (int i=0; i<N; i++) { 4365 callbacks.get(i).onLowMemory(); 4366 } 4367 4368 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4369 if (Process.myUid() != Process.SYSTEM_UID) { 4370 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4371 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4372 } 4373 4374 // Ask graphics to free up as much as possible (font/image caches) 4375 Canvas.freeCaches(); 4376 4377 // Ask text layout engine to free also as much as possible 4378 Canvas.freeTextLayoutCaches(); 4379 4380 BinderInternal.forceGc("mem"); 4381 } 4382 4383 final void handleTrimMemory(int level) { 4384 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4385 4386 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4387 4388 final int N = callbacks.size(); 4389 for (int i = 0; i < N; i++) { 4390 callbacks.get(i).onTrimMemory(level); 4391 } 4392 4393 WindowManagerGlobal.getInstance().trimMemory(level); 4394 } 4395 4396 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4397 if (Process.isIsolated()) { 4398 // Isolated processes aren't going to do UI. 4399 return; 4400 } 4401 try { 4402 int uid = Process.myUid(); 4403 String[] packages = getPackageManager().getPackagesForUid(uid); 4404 4405 // If there are several packages in this application we won't 4406 // initialize the graphics disk caches 4407 if (packages != null && packages.length == 1) { 4408 HardwareRenderer.setupDiskCache(cacheDir); 4409 RenderScriptCacheDir.setupDiskCache(cacheDir); 4410 } 4411 } catch (RemoteException e) { 4412 // Ignore 4413 } 4414 } 4415 4416 private void updateDefaultDensity() { 4417 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED 4418 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE 4419 && !mDensityCompatMode) { 4420 Slog.i(TAG, "Switching default density from " 4421 + DisplayMetrics.DENSITY_DEVICE + " to " 4422 + mCurDefaultDisplayDpi); 4423 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; 4424 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4425 } 4426 } 4427 4428 private void handleBindApplication(AppBindData data) { 4429 mBoundApplication = data; 4430 mConfiguration = new Configuration(data.config); 4431 mCompatConfiguration = new Configuration(data.config); 4432 4433 mProfiler = new Profiler(); 4434 if (data.initProfilerInfo != null) { 4435 mProfiler.profileFile = data.initProfilerInfo.profileFile; 4436 mProfiler.profileFd = data.initProfilerInfo.profileFd; 4437 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 4438 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 4439 } 4440 4441 // send up app name; do this *before* waiting for debugger 4442 Process.setArgV0(data.processName); 4443 android.ddm.DdmHandleAppName.setAppName(data.processName, 4444 UserHandle.myUserId()); 4445 4446 if (data.persistent) { 4447 // Persistent processes on low-memory devices do not get to 4448 // use hardware accelerated drawing, since this can add too much 4449 // overhead to the process. 4450 if (!ActivityManager.isHighEndGfx()) { 4451 HardwareRenderer.disable(false); 4452 } 4453 } 4454 4455 if (mProfiler.profileFd != null) { 4456 mProfiler.startProfiling(); 4457 } 4458 4459 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4460 // implementation to use the pool executor. Normally, we use the 4461 // serialized executor as the default. This has to happen in the 4462 // main thread so the main looper is set right. 4463 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4464 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4465 } 4466 4467 Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 4468 4469 /* 4470 * Before spawning a new process, reset the time zone to be the system time zone. 4471 * This needs to be done because the system time zone could have changed after the 4472 * the spawning of this process. Without doing this this process would have the incorrect 4473 * system time zone. 4474 */ 4475 TimeZone.setDefault(null); 4476 4477 /* 4478 * Initialize the default locale in this process for the reasons we set the time zone. 4479 */ 4480 Locale.setDefault(data.config.locale); 4481 4482 /* 4483 * Update the system configuration since its preloaded and might not 4484 * reflect configuration changes. The configuration object passed 4485 * in AppBindData can be safely assumed to be up to date 4486 */ 4487 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4488 mCurDefaultDisplayDpi = data.config.densityDpi; 4489 applyCompatConfiguration(mCurDefaultDisplayDpi); 4490 4491 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4492 4493 /** 4494 * Switch this process to density compatibility mode if needed. 4495 */ 4496 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4497 == 0) { 4498 mDensityCompatMode = true; 4499 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4500 } 4501 updateDefaultDensity(); 4502 4503 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 4504 if (!Process.isIsolated()) { 4505 final File cacheDir = appContext.getCacheDir(); 4506 4507 if (cacheDir != null) { 4508 // Provide a usable directory for temporary files 4509 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 4510 } else { 4511 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property due to missing cache directory"); 4512 } 4513 4514 // Use codeCacheDir to store generated/compiled graphics code 4515 final File codeCacheDir = appContext.getCodeCacheDir(); 4516 if (codeCacheDir != null) { 4517 setupGraphicsSupport(data.info, codeCacheDir); 4518 } else { 4519 Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory"); 4520 } 4521 } 4522 4523 4524 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); 4525 DateFormat.set24HourTimePref(is24Hr); 4526 4527 View.mDebugViewAttributes = 4528 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; 4529 4530 /** 4531 * For system applications on userdebug/eng builds, log stack 4532 * traces of disk and network access to dropbox for analysis. 4533 */ 4534 if ((data.appInfo.flags & 4535 (ApplicationInfo.FLAG_SYSTEM | 4536 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4537 StrictMode.conditionallyEnableDebugLogging(); 4538 } 4539 4540 /** 4541 * For apps targetting SDK Honeycomb or later, we don't allow 4542 * network usage on the main event loop / UI thread. 4543 * 4544 * Note to those grepping: this is what ultimately throws 4545 * NetworkOnMainThreadException ... 4546 */ 4547 if (data.appInfo.targetSdkVersion > 9) { 4548 StrictMode.enableDeathOnNetwork(); 4549 } 4550 4551 NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted( 4552 (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0); 4553 4554 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4555 // XXX should have option to change the port. 4556 Debug.changeDebugPort(8100); 4557 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4558 Slog.w(TAG, "Application " + data.info.getPackageName() 4559 + " is waiting for the debugger on port 8100..."); 4560 4561 IActivityManager mgr = ActivityManagerNative.getDefault(); 4562 try { 4563 mgr.showWaitingForDebugger(mAppThread, true); 4564 } catch (RemoteException ex) { 4565 } 4566 4567 Debug.waitForDebugger(); 4568 4569 try { 4570 mgr.showWaitingForDebugger(mAppThread, false); 4571 } catch (RemoteException ex) { 4572 } 4573 4574 } else { 4575 Slog.w(TAG, "Application " + data.info.getPackageName() 4576 + " can be debugged on port 8100..."); 4577 } 4578 } 4579 4580 // Enable OpenGL tracing if required 4581 if (data.enableOpenGlTrace) { 4582 GLUtils.setTracingLevel(1); 4583 } 4584 4585 // Allow application-generated systrace messages if we're debuggable. 4586 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0; 4587 Trace.setAppTracingAllowed(appTracingAllowed); 4588 4589 /** 4590 * Initialize the default http proxy in this process for the reasons we set the time zone. 4591 */ 4592 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 4593 if (b != null) { 4594 // In pre-boot mode (doing initial launch to collect password), not 4595 // all system is up. This includes the connectivity service, so don't 4596 // crash if we can't get it. 4597 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4598 try { 4599 final ProxyInfo proxyInfo = service.getProxyForNetwork(null); 4600 Proxy.setHttpProxySystemProperty(proxyInfo); 4601 } catch (RemoteException e) {} 4602 } 4603 4604 if (data.instrumentationName != null) { 4605 InstrumentationInfo ii = null; 4606 try { 4607 ii = appContext.getPackageManager(). 4608 getInstrumentationInfo(data.instrumentationName, 0); 4609 } catch (PackageManager.NameNotFoundException e) { 4610 } 4611 if (ii == null) { 4612 throw new RuntimeException( 4613 "Unable to find instrumentation info for: " 4614 + data.instrumentationName); 4615 } 4616 4617 mInstrumentationPackageName = ii.packageName; 4618 mInstrumentationAppDir = ii.sourceDir; 4619 mInstrumentationSplitAppDirs = ii.splitSourceDirs; 4620 mInstrumentationLibDir = ii.nativeLibraryDir; 4621 mInstrumentedAppDir = data.info.getAppDir(); 4622 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 4623 mInstrumentedLibDir = data.info.getLibDir(); 4624 4625 ApplicationInfo instrApp = new ApplicationInfo(); 4626 instrApp.packageName = ii.packageName; 4627 instrApp.sourceDir = ii.sourceDir; 4628 instrApp.publicSourceDir = ii.publicSourceDir; 4629 instrApp.splitSourceDirs = ii.splitSourceDirs; 4630 instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs; 4631 instrApp.dataDir = ii.dataDir; 4632 instrApp.nativeLibraryDir = ii.nativeLibraryDir; 4633 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 4634 appContext.getClassLoader(), false, true, false); 4635 ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 4636 4637 try { 4638 java.lang.ClassLoader cl = instrContext.getClassLoader(); 4639 mInstrumentation = (Instrumentation) 4640 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4641 } catch (Exception e) { 4642 throw new RuntimeException( 4643 "Unable to instantiate instrumentation " 4644 + data.instrumentationName + ": " + e.toString(), e); 4645 } 4646 4647 mInstrumentation.init(this, instrContext, appContext, 4648 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, 4649 data.instrumentationUiAutomationConnection); 4650 4651 if (mProfiler.profileFile != null && !ii.handleProfiling 4652 && mProfiler.profileFd == null) { 4653 mProfiler.handlingProfiling = true; 4654 File file = new File(mProfiler.profileFile); 4655 file.getParentFile().mkdirs(); 4656 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 4657 } 4658 4659 } else { 4660 mInstrumentation = new Instrumentation(); 4661 } 4662 4663 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 4664 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 4665 } else { 4666 // Small heap, clamp to the current growth limit and let the heap release 4667 // pages after the growth limit to the non growth limit capacity. b/18387825 4668 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); 4669 } 4670 4671 // Allow disk access during application and provider setup. This could 4672 // block processing ordered broadcasts, but later processing would 4673 // probably end up doing the same disk access. 4674 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 4675 try { 4676 // If the app is being launched for full backup or restore, bring it up in 4677 // a restricted environment with the base application class. 4678 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 4679 mInitialApplication = app; 4680 4681 // don't bring up providers in restricted mode; they may depend on the 4682 // app's custom Application class 4683 if (!data.restrictedBackupMode) { 4684 List<ProviderInfo> providers = data.providers; 4685 if (providers != null) { 4686 installContentProviders(app, providers); 4687 // For process that contains content providers, we want to 4688 // ensure that the JIT is enabled "at some point". 4689 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 4690 } 4691 } 4692 4693 // Do this after providers, since instrumentation tests generally start their 4694 // test thread at this point, and we don't want that racing. 4695 try { 4696 mInstrumentation.onCreate(data.instrumentationArgs); 4697 } 4698 catch (Exception e) { 4699 throw new RuntimeException( 4700 "Exception thrown in onCreate() of " 4701 + data.instrumentationName + ": " + e.toString(), e); 4702 } 4703 4704 try { 4705 mInstrumentation.callApplicationOnCreate(app); 4706 } catch (Exception e) { 4707 if (!mInstrumentation.onException(app, e)) { 4708 throw new RuntimeException( 4709 "Unable to create application " + app.getClass().getName() 4710 + ": " + e.toString(), e); 4711 } 4712 } 4713 } finally { 4714 StrictMode.setThreadPolicy(savedPolicy); 4715 } 4716 } 4717 4718 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 4719 IActivityManager am = ActivityManagerNative.getDefault(); 4720 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 4721 && mProfiler.profileFd == null) { 4722 Debug.stopMethodTracing(); 4723 } 4724 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 4725 // + ", app thr: " + mAppThread); 4726 try { 4727 am.finishInstrumentation(mAppThread, resultCode, results); 4728 } catch (RemoteException ex) { 4729 } 4730 } 4731 4732 private void installContentProviders( 4733 Context context, List<ProviderInfo> providers) { 4734 final ArrayList<IActivityManager.ContentProviderHolder> results = 4735 new ArrayList<IActivityManager.ContentProviderHolder>(); 4736 4737 for (ProviderInfo cpi : providers) { 4738 if (DEBUG_PROVIDER) { 4739 StringBuilder buf = new StringBuilder(128); 4740 buf.append("Pub "); 4741 buf.append(cpi.authority); 4742 buf.append(": "); 4743 buf.append(cpi.name); 4744 Log.i(TAG, buf.toString()); 4745 } 4746 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 4747 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 4748 if (cph != null) { 4749 cph.noReleaseNeeded = true; 4750 results.add(cph); 4751 } 4752 } 4753 4754 try { 4755 ActivityManagerNative.getDefault().publishContentProviders( 4756 getApplicationThread(), results); 4757 } catch (RemoteException ex) { 4758 } 4759 } 4760 4761 public final IContentProvider acquireProvider( 4762 Context c, String auth, int userId, boolean stable) { 4763 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 4764 if (provider != null) { 4765 return provider; 4766 } 4767 4768 // There is a possible race here. Another thread may try to acquire 4769 // the same provider at the same time. When this happens, we want to ensure 4770 // that the first one wins. 4771 // Note that we cannot hold the lock while acquiring and installing the 4772 // provider since it might take a long time to run and it could also potentially 4773 // be re-entrant in the case where the provider is in the same process. 4774 IActivityManager.ContentProviderHolder holder = null; 4775 try { 4776 holder = ActivityManagerNative.getDefault().getContentProvider( 4777 getApplicationThread(), auth, userId, stable); 4778 } catch (RemoteException ex) { 4779 } 4780 if (holder == null) { 4781 Slog.e(TAG, "Failed to find provider info for " + auth); 4782 return null; 4783 } 4784 4785 // Install provider will increment the reference count for us, and break 4786 // any ties in the race. 4787 holder = installProvider(c, holder, holder.info, 4788 true /*noisy*/, holder.noReleaseNeeded, stable); 4789 return holder.provider; 4790 } 4791 4792 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 4793 if (stable) { 4794 prc.stableCount += 1; 4795 if (prc.stableCount == 1) { 4796 // We are acquiring a new stable reference on the provider. 4797 int unstableDelta; 4798 if (prc.removePending) { 4799 // We have a pending remove operation, which is holding the 4800 // last unstable reference. At this point we are converting 4801 // that unstable reference to our new stable reference. 4802 unstableDelta = -1; 4803 // Cancel the removal of the provider. 4804 if (DEBUG_PROVIDER) { 4805 Slog.v(TAG, "incProviderRef: stable " 4806 + "snatched provider from the jaws of death"); 4807 } 4808 prc.removePending = false; 4809 // There is a race! It fails to remove the message, which 4810 // will be handled in completeRemoveProvider(). 4811 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4812 } else { 4813 unstableDelta = 0; 4814 } 4815 try { 4816 if (DEBUG_PROVIDER) { 4817 Slog.v(TAG, "incProviderRef Now stable - " 4818 + prc.holder.info.name + ": unstableDelta=" 4819 + unstableDelta); 4820 } 4821 ActivityManagerNative.getDefault().refContentProvider( 4822 prc.holder.connection, 1, unstableDelta); 4823 } catch (RemoteException e) { 4824 //do nothing content provider object is dead any way 4825 } 4826 } 4827 } else { 4828 prc.unstableCount += 1; 4829 if (prc.unstableCount == 1) { 4830 // We are acquiring a new unstable reference on the provider. 4831 if (prc.removePending) { 4832 // Oh look, we actually have a remove pending for the 4833 // provider, which is still holding the last unstable 4834 // reference. We just need to cancel that to take new 4835 // ownership of the reference. 4836 if (DEBUG_PROVIDER) { 4837 Slog.v(TAG, "incProviderRef: unstable " 4838 + "snatched provider from the jaws of death"); 4839 } 4840 prc.removePending = false; 4841 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4842 } else { 4843 // First unstable ref, increment our count in the 4844 // activity manager. 4845 try { 4846 if (DEBUG_PROVIDER) { 4847 Slog.v(TAG, "incProviderRef: Now unstable - " 4848 + prc.holder.info.name); 4849 } 4850 ActivityManagerNative.getDefault().refContentProvider( 4851 prc.holder.connection, 0, 1); 4852 } catch (RemoteException e) { 4853 //do nothing content provider object is dead any way 4854 } 4855 } 4856 } 4857 } 4858 } 4859 4860 public final IContentProvider acquireExistingProvider( 4861 Context c, String auth, int userId, boolean stable) { 4862 synchronized (mProviderMap) { 4863 final ProviderKey key = new ProviderKey(auth, userId); 4864 final ProviderClientRecord pr = mProviderMap.get(key); 4865 if (pr == null) { 4866 return null; 4867 } 4868 4869 IContentProvider provider = pr.mProvider; 4870 IBinder jBinder = provider.asBinder(); 4871 if (!jBinder.isBinderAlive()) { 4872 // The hosting process of the provider has died; we can't 4873 // use this one. 4874 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 4875 + ": existing object's process dead"); 4876 handleUnstableProviderDiedLocked(jBinder, true); 4877 return null; 4878 } 4879 4880 // Only increment the ref count if we have one. If we don't then the 4881 // provider is not reference counted and never needs to be released. 4882 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4883 if (prc != null) { 4884 incProviderRefLocked(prc, stable); 4885 } 4886 return provider; 4887 } 4888 } 4889 4890 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 4891 if (provider == null) { 4892 return false; 4893 } 4894 4895 IBinder jBinder = provider.asBinder(); 4896 synchronized (mProviderMap) { 4897 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4898 if (prc == null) { 4899 // The provider has no ref count, no release is needed. 4900 return false; 4901 } 4902 4903 boolean lastRef = false; 4904 if (stable) { 4905 if (prc.stableCount == 0) { 4906 if (DEBUG_PROVIDER) Slog.v(TAG, 4907 "releaseProvider: stable ref count already 0, how?"); 4908 return false; 4909 } 4910 prc.stableCount -= 1; 4911 if (prc.stableCount == 0) { 4912 // What we do at this point depends on whether there are 4913 // any unstable refs left: if there are, we just tell the 4914 // activity manager to decrement its stable count; if there 4915 // aren't, we need to enqueue this provider to be removed, 4916 // and convert to holding a single unstable ref while 4917 // doing so. 4918 lastRef = prc.unstableCount == 0; 4919 try { 4920 if (DEBUG_PROVIDER) { 4921 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 4922 + lastRef + " - " + prc.holder.info.name); 4923 } 4924 ActivityManagerNative.getDefault().refContentProvider( 4925 prc.holder.connection, -1, lastRef ? 1 : 0); 4926 } catch (RemoteException e) { 4927 //do nothing content provider object is dead any way 4928 } 4929 } 4930 } else { 4931 if (prc.unstableCount == 0) { 4932 if (DEBUG_PROVIDER) Slog.v(TAG, 4933 "releaseProvider: unstable ref count already 0, how?"); 4934 return false; 4935 } 4936 prc.unstableCount -= 1; 4937 if (prc.unstableCount == 0) { 4938 // If this is the last reference, we need to enqueue 4939 // this provider to be removed instead of telling the 4940 // activity manager to remove it at this point. 4941 lastRef = prc.stableCount == 0; 4942 if (!lastRef) { 4943 try { 4944 if (DEBUG_PROVIDER) { 4945 Slog.v(TAG, "releaseProvider: No longer unstable - " 4946 + prc.holder.info.name); 4947 } 4948 ActivityManagerNative.getDefault().refContentProvider( 4949 prc.holder.connection, 0, -1); 4950 } catch (RemoteException e) { 4951 //do nothing content provider object is dead any way 4952 } 4953 } 4954 } 4955 } 4956 4957 if (lastRef) { 4958 if (!prc.removePending) { 4959 // Schedule the actual remove asynchronously, since we don't know the context 4960 // this will be called in. 4961 // TODO: it would be nice to post a delayed message, so 4962 // if we come back and need the same provider quickly 4963 // we will still have it available. 4964 if (DEBUG_PROVIDER) { 4965 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 4966 + prc.holder.info.name); 4967 } 4968 prc.removePending = true; 4969 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 4970 mH.sendMessage(msg); 4971 } else { 4972 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 4973 } 4974 } 4975 return true; 4976 } 4977 } 4978 4979 final void completeRemoveProvider(ProviderRefCount prc) { 4980 synchronized (mProviderMap) { 4981 if (!prc.removePending) { 4982 // There was a race! Some other client managed to acquire 4983 // the provider before the removal was completed. 4984 // Abort the removal. We will do it later. 4985 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 4986 + "provider still in use"); 4987 return; 4988 } 4989 4990 // More complicated race!! Some client managed to acquire the 4991 // provider and release it before the removal was completed. 4992 // Continue the removal, and abort the next remove message. 4993 prc.removePending = false; 4994 4995 final IBinder jBinder = prc.holder.provider.asBinder(); 4996 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 4997 if (existingPrc == prc) { 4998 mProviderRefCountMap.remove(jBinder); 4999 } 5000 5001 for (int i=mProviderMap.size()-1; i>=0; i--) { 5002 ProviderClientRecord pr = mProviderMap.valueAt(i); 5003 IBinder myBinder = pr.mProvider.asBinder(); 5004 if (myBinder == jBinder) { 5005 mProviderMap.removeAt(i); 5006 } 5007 } 5008 } 5009 5010 try { 5011 if (DEBUG_PROVIDER) { 5012 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 5013 + "removeContentProvider(" + prc.holder.info.name + ")"); 5014 } 5015 ActivityManagerNative.getDefault().removeContentProvider( 5016 prc.holder.connection, false); 5017 } catch (RemoteException e) { 5018 //do nothing content provider object is dead any way 5019 } 5020 } 5021 5022 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 5023 synchronized (mProviderMap) { 5024 handleUnstableProviderDiedLocked(provider, fromClient); 5025 } 5026 } 5027 5028 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 5029 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5030 if (prc != null) { 5031 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 5032 + provider + " " + prc.holder.info.name); 5033 mProviderRefCountMap.remove(provider); 5034 for (int i=mProviderMap.size()-1; i>=0; i--) { 5035 ProviderClientRecord pr = mProviderMap.valueAt(i); 5036 if (pr != null && pr.mProvider.asBinder() == provider) { 5037 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 5038 mProviderMap.removeAt(i); 5039 } 5040 } 5041 5042 if (fromClient) { 5043 // We found out about this due to execution in our client 5044 // code. Tell the activity manager about it now, to ensure 5045 // that the next time we go to do anything with the provider 5046 // it knows it is dead (so we don't race with its death 5047 // notification). 5048 try { 5049 ActivityManagerNative.getDefault().unstableProviderDied( 5050 prc.holder.connection); 5051 } catch (RemoteException e) { 5052 //do nothing content provider object is dead any way 5053 } 5054 } 5055 } 5056 } 5057 5058 final void appNotRespondingViaProvider(IBinder provider) { 5059 synchronized (mProviderMap) { 5060 ProviderRefCount prc = mProviderRefCountMap.get(provider); 5061 if (prc != null) { 5062 try { 5063 ActivityManagerNative.getDefault() 5064 .appNotRespondingViaProvider(prc.holder.connection); 5065 } catch (RemoteException e) { 5066 } 5067 } 5068 } 5069 } 5070 5071 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 5072 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 5073 final String auths[] = holder.info.authority.split(";"); 5074 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 5075 5076 final ProviderClientRecord pcr = new ProviderClientRecord( 5077 auths, provider, localProvider, holder); 5078 for (String auth : auths) { 5079 final ProviderKey key = new ProviderKey(auth, userId); 5080 final ProviderClientRecord existing = mProviderMap.get(key); 5081 if (existing != null) { 5082 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 5083 + " already published as " + auth); 5084 } else { 5085 mProviderMap.put(key, pcr); 5086 } 5087 } 5088 return pcr; 5089 } 5090 5091 /** 5092 * Installs the provider. 5093 * 5094 * Providers that are local to the process or that come from the system server 5095 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 5096 * Other remote providers are reference counted. The initial reference count 5097 * for all reference counted providers is one. Providers that are not reference 5098 * counted do not have a reference count (at all). 5099 * 5100 * This method detects when a provider has already been installed. When this happens, 5101 * it increments the reference count of the existing provider (if appropriate) 5102 * and returns the existing provider. This can happen due to concurrent 5103 * attempts to acquire the same provider. 5104 */ 5105 private IActivityManager.ContentProviderHolder installProvider(Context context, 5106 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 5107 boolean noisy, boolean noReleaseNeeded, boolean stable) { 5108 ContentProvider localProvider = null; 5109 IContentProvider provider; 5110 if (holder == null || holder.provider == null) { 5111 if (DEBUG_PROVIDER || noisy) { 5112 Slog.d(TAG, "Loading provider " + info.authority + ": " 5113 + info.name); 5114 } 5115 Context c = null; 5116 ApplicationInfo ai = info.applicationInfo; 5117 if (context.getPackageName().equals(ai.packageName)) { 5118 c = context; 5119 } else if (mInitialApplication != null && 5120 mInitialApplication.getPackageName().equals(ai.packageName)) { 5121 c = mInitialApplication; 5122 } else { 5123 try { 5124 c = context.createPackageContext(ai.packageName, 5125 Context.CONTEXT_INCLUDE_CODE); 5126 } catch (PackageManager.NameNotFoundException e) { 5127 // Ignore 5128 } 5129 } 5130 if (c == null) { 5131 Slog.w(TAG, "Unable to get context for package " + 5132 ai.packageName + 5133 " while loading content provider " + 5134 info.name); 5135 return null; 5136 } 5137 try { 5138 final java.lang.ClassLoader cl = c.getClassLoader(); 5139 localProvider = (ContentProvider)cl. 5140 loadClass(info.name).newInstance(); 5141 provider = localProvider.getIContentProvider(); 5142 if (provider == null) { 5143 Slog.e(TAG, "Failed to instantiate class " + 5144 info.name + " from sourceDir " + 5145 info.applicationInfo.sourceDir); 5146 return null; 5147 } 5148 if (DEBUG_PROVIDER) Slog.v( 5149 TAG, "Instantiating local provider " + info.name); 5150 // XXX Need to create the correct context for this provider. 5151 localProvider.attachInfo(c, info); 5152 } catch (java.lang.Exception e) { 5153 if (!mInstrumentation.onException(null, e)) { 5154 throw new RuntimeException( 5155 "Unable to get provider " + info.name 5156 + ": " + e.toString(), e); 5157 } 5158 return null; 5159 } 5160 } else { 5161 provider = holder.provider; 5162 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 5163 + info.name); 5164 } 5165 5166 IActivityManager.ContentProviderHolder retHolder; 5167 5168 synchronized (mProviderMap) { 5169 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 5170 + " / " + info.name); 5171 IBinder jBinder = provider.asBinder(); 5172 if (localProvider != null) { 5173 ComponentName cname = new ComponentName(info.packageName, info.name); 5174 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 5175 if (pr != null) { 5176 if (DEBUG_PROVIDER) { 5177 Slog.v(TAG, "installProvider: lost the race, " 5178 + "using existing local provider"); 5179 } 5180 provider = pr.mProvider; 5181 } else { 5182 holder = new IActivityManager.ContentProviderHolder(info); 5183 holder.provider = provider; 5184 holder.noReleaseNeeded = true; 5185 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 5186 mLocalProviders.put(jBinder, pr); 5187 mLocalProvidersByName.put(cname, pr); 5188 } 5189 retHolder = pr.mHolder; 5190 } else { 5191 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 5192 if (prc != null) { 5193 if (DEBUG_PROVIDER) { 5194 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 5195 } 5196 // We need to transfer our new reference to the existing 5197 // ref count, releasing the old one... but only if 5198 // release is needed (that is, it is not running in the 5199 // system process). 5200 if (!noReleaseNeeded) { 5201 incProviderRefLocked(prc, stable); 5202 try { 5203 ActivityManagerNative.getDefault().removeContentProvider( 5204 holder.connection, stable); 5205 } catch (RemoteException e) { 5206 //do nothing content provider object is dead any way 5207 } 5208 } 5209 } else { 5210 ProviderClientRecord client = installProviderAuthoritiesLocked( 5211 provider, localProvider, holder); 5212 if (noReleaseNeeded) { 5213 prc = new ProviderRefCount(holder, client, 1000, 1000); 5214 } else { 5215 prc = stable 5216 ? new ProviderRefCount(holder, client, 1, 0) 5217 : new ProviderRefCount(holder, client, 0, 1); 5218 } 5219 mProviderRefCountMap.put(jBinder, prc); 5220 } 5221 retHolder = prc.holder; 5222 } 5223 } 5224 5225 return retHolder; 5226 } 5227 5228 private void attach(boolean system) { 5229 sCurrentActivityThread = this; 5230 mSystemThread = system; 5231 if (!system) { 5232 ViewRootImpl.addFirstDrawHandler(new Runnable() { 5233 @Override 5234 public void run() { 5235 ensureJitEnabled(); 5236 } 5237 }); 5238 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 5239 UserHandle.myUserId()); 5240 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 5241 final IActivityManager mgr = ActivityManagerNative.getDefault(); 5242 try { 5243 mgr.attachApplication(mAppThread); 5244 } catch (RemoteException ex) { 5245 // Ignore 5246 } 5247 // Watch for getting close to heap limit. 5248 BinderInternal.addGcWatcher(new Runnable() { 5249 @Override public void run() { 5250 if (!mSomeActivitiesChanged) { 5251 return; 5252 } 5253 Runtime runtime = Runtime.getRuntime(); 5254 long dalvikMax = runtime.maxMemory(); 5255 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 5256 if (dalvikUsed > ((3*dalvikMax)/4)) { 5257 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 5258 + " total=" + (runtime.totalMemory()/1024) 5259 + " used=" + (dalvikUsed/1024)); 5260 mSomeActivitiesChanged = false; 5261 try { 5262 mgr.releaseSomeActivities(mAppThread); 5263 } catch (RemoteException e) { 5264 } 5265 } 5266 } 5267 }); 5268 } else { 5269 // Don't set application object here -- if the system crashes, 5270 // we can't display an alert, we just want to die die die. 5271 android.ddm.DdmHandleAppName.setAppName("system_process", 5272 UserHandle.myUserId()); 5273 try { 5274 mInstrumentation = new Instrumentation(); 5275 ContextImpl context = ContextImpl.createAppContext( 5276 this, getSystemContext().mPackageInfo); 5277 mInitialApplication = context.mPackageInfo.makeApplication(true, null); 5278 mInitialApplication.onCreate(); 5279 } catch (Exception e) { 5280 throw new RuntimeException( 5281 "Unable to instantiate Application():" + e.toString(), e); 5282 } 5283 } 5284 5285 // add dropbox logging to libcore 5286 DropBox.setReporter(new DropBoxReporter()); 5287 5288 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 5289 @Override 5290 public void onConfigurationChanged(Configuration newConfig) { 5291 synchronized (mResourcesManager) { 5292 // We need to apply this change to the resources 5293 // immediately, because upon returning the view 5294 // hierarchy will be informed about it. 5295 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 5296 // This actually changed the resources! Tell 5297 // everyone about it. 5298 if (mPendingConfiguration == null || 5299 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 5300 mPendingConfiguration = newConfig; 5301 5302 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 5303 } 5304 } 5305 } 5306 } 5307 @Override 5308 public void onLowMemory() { 5309 } 5310 @Override 5311 public void onTrimMemory(int level) { 5312 } 5313 }); 5314 } 5315 5316 public static ActivityThread systemMain() { 5317 // The system process on low-memory devices do not get to use hardware 5318 // accelerated drawing, since this can add too much overhead to the 5319 // process. 5320 if (!ActivityManager.isHighEndGfx()) { 5321 HardwareRenderer.disable(true); 5322 } else { 5323 HardwareRenderer.enableForegroundTrimming(); 5324 } 5325 ActivityThread thread = new ActivityThread(); 5326 thread.attach(true); 5327 return thread; 5328 } 5329 5330 public final void installSystemProviders(List<ProviderInfo> providers) { 5331 if (providers != null) { 5332 installContentProviders(mInitialApplication, providers); 5333 } 5334 } 5335 5336 public int getIntCoreSetting(String key, int defaultValue) { 5337 synchronized (mResourcesManager) { 5338 if (mCoreSettings != null) { 5339 return mCoreSettings.getInt(key, defaultValue); 5340 } 5341 return defaultValue; 5342 } 5343 } 5344 5345 private static class EventLoggingReporter implements EventLogger.Reporter { 5346 @Override 5347 public void report (int code, Object... list) { 5348 EventLog.writeEvent(code, list); 5349 } 5350 } 5351 5352 private class DropBoxReporter implements DropBox.Reporter { 5353 5354 private DropBoxManager dropBox; 5355 5356 public DropBoxReporter() {} 5357 5358 @Override 5359 public void addData(String tag, byte[] data, int flags) { 5360 ensureInitialized(); 5361 dropBox.addData(tag, data, flags); 5362 } 5363 5364 @Override 5365 public void addText(String tag, String data) { 5366 ensureInitialized(); 5367 dropBox.addText(tag, data); 5368 } 5369 5370 private synchronized void ensureInitialized() { 5371 if (dropBox == null) { 5372 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 5373 } 5374 } 5375 } 5376 5377 public static void main(String[] args) { 5378 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 5379 SamplingProfilerIntegration.start(); 5380 5381 // CloseGuard defaults to true and can be quite spammy. We 5382 // disable it here, but selectively enable it later (via 5383 // StrictMode) on debug builds, but using DropBox, not logs. 5384 CloseGuard.setEnabled(false); 5385 5386 Environment.initForCurrentUser(); 5387 5388 // Set the reporter for event logging in libcore 5389 EventLogger.setReporter(new EventLoggingReporter()); 5390 5391 AndroidKeyStoreProvider.install(); 5392 5393 // Make sure TrustedCertificateStore looks in the right place for CA certificates 5394 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 5395 TrustedCertificateStore.setDefaultUserDirectory(configDir); 5396 5397 Process.setArgV0("<pre-initialized>"); 5398 5399 Looper.prepareMainLooper(); 5400 5401 ActivityThread thread = new ActivityThread(); 5402 thread.attach(false); 5403 5404 if (sMainThreadHandler == null) { 5405 sMainThreadHandler = thread.getHandler(); 5406 } 5407 5408 if (false) { 5409 Looper.myLooper().setMessageLogging(new 5410 LogPrinter(Log.DEBUG, "ActivityThread")); 5411 } 5412 5413 // End of event ActivityThreadMain. 5414 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5415 Looper.loop(); 5416 5417 throw new RuntimeException("Main thread loop unexpectedly exited"); 5418 } 5419} 5420