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