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