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