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