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