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