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