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