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