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