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