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