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