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