ActivityThread.java revision 7a0437b89a2982cd2ec1afb6fbe619d6842015e8
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 if (r.pendingIntents != null) { 2703 deliverNewIntents(r, r.pendingIntents); 2704 r.pendingIntents = null; 2705 } 2706 if (r.pendingResults != null) { 2707 deliverResults(r, r.pendingResults); 2708 r.pendingResults = null; 2709 } 2710 r.activity.performResume(); 2711 2712 EventLog.writeEvent(LOG_ON_RESUME_CALLED, 2713 UserHandle.myUserId(), r.activity.getComponentName().getClassName()); 2714 2715 r.paused = false; 2716 r.stopped = false; 2717 r.state = null; 2718 } catch (Exception e) { 2719 if (!mInstrumentation.onException(r.activity, e)) { 2720 throw new RuntimeException( 2721 "Unable to resume activity " 2722 + r.intent.getComponent().toShortString() 2723 + ": " + e.toString(), e); 2724 } 2725 } 2726 } 2727 return r; 2728 } 2729 2730 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) { 2731 if (r.mPendingRemoveWindow != null) { 2732 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow); 2733 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken(); 2734 if (wtoken != null) { 2735 WindowManagerGlobal.getInstance().closeAll(wtoken, 2736 r.activity.getClass().getName(), "Activity"); 2737 } 2738 } 2739 r.mPendingRemoveWindow = null; 2740 r.mPendingRemoveWindowManager = null; 2741 } 2742 2743 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, 2744 boolean reallyResume) { 2745 // If we are getting ready to gc after going to the background, well 2746 // we are back active so skip it. 2747 unscheduleGcIdler(); 2748 2749 ActivityClientRecord r = performResumeActivity(token, clearHide); 2750 2751 if (r != null) { 2752 final Activity a = r.activity; 2753 2754 if (localLOGV) Slog.v( 2755 TAG, "Resume " + r + " started activity: " + 2756 a.mStartedActivity + ", hideForNow: " + r.hideForNow 2757 + ", finished: " + a.mFinished); 2758 2759 final int forwardBit = isForward ? 2760 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 2761 2762 // If the window hasn't yet been added to the window manager, 2763 // and this guy didn't finish itself or start another activity, 2764 // then go ahead and add the window. 2765 boolean willBeVisible = !a.mStartedActivity; 2766 if (!willBeVisible) { 2767 try { 2768 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( 2769 a.getActivityToken()); 2770 } catch (RemoteException e) { 2771 } 2772 } 2773 if (r.window == null && !a.mFinished && willBeVisible) { 2774 r.window = r.activity.getWindow(); 2775 View decor = r.window.getDecorView(); 2776 decor.setVisibility(View.INVISIBLE); 2777 ViewManager wm = a.getWindowManager(); 2778 WindowManager.LayoutParams l = r.window.getAttributes(); 2779 a.mDecor = decor; 2780 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 2781 l.softInputMode |= forwardBit; 2782 if (a.mVisibleFromClient) { 2783 a.mWindowAdded = true; 2784 wm.addView(decor, l); 2785 } 2786 2787 // If the window has already been added, but during resume 2788 // we started another activity, then don't yet make the 2789 // window visible. 2790 } else if (!willBeVisible) { 2791 if (localLOGV) Slog.v( 2792 TAG, "Launch " + r + " mStartedActivity set"); 2793 r.hideForNow = true; 2794 } 2795 2796 // Get rid of anything left hanging around. 2797 cleanUpPendingRemoveWindows(r); 2798 2799 // The window is now visible if it has been added, we are not 2800 // simply finishing, and we are not starting another activity. 2801 if (!r.activity.mFinished && willBeVisible 2802 && r.activity.mDecor != null && !r.hideForNow) { 2803 if (r.newConfig != null) { 2804 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 2805 + r.activityInfo.name + " with newConfig " + r.newConfig); 2806 performConfigurationChanged(r.activity, r.newConfig); 2807 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 2808 r.newConfig = null; 2809 } 2810 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 2811 + isForward); 2812 WindowManager.LayoutParams l = r.window.getAttributes(); 2813 if ((l.softInputMode 2814 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 2815 != forwardBit) { 2816 l.softInputMode = (l.softInputMode 2817 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 2818 | forwardBit; 2819 if (r.activity.mVisibleFromClient) { 2820 ViewManager wm = a.getWindowManager(); 2821 View decor = r.window.getDecorView(); 2822 wm.updateViewLayout(decor, l); 2823 } 2824 } 2825 r.activity.mVisibleFromServer = true; 2826 mNumVisibleActivities++; 2827 if (r.activity.mVisibleFromClient) { 2828 r.activity.makeVisible(); 2829 } 2830 } 2831 2832 if (!r.onlyLocalRequest) { 2833 r.nextIdle = mNewActivities; 2834 mNewActivities = r; 2835 if (localLOGV) Slog.v( 2836 TAG, "Scheduling idle handler for " + r); 2837 Looper.myQueue().addIdleHandler(new Idler()); 2838 } 2839 r.onlyLocalRequest = false; 2840 2841 // Tell the activity manager we have resumed. 2842 if (reallyResume) { 2843 try { 2844 ActivityManagerNative.getDefault().activityResumed(token); 2845 } catch (RemoteException ex) { 2846 } 2847 } 2848 2849 } else { 2850 // If an exception was thrown when trying to resume, then 2851 // just end this activity. 2852 try { 2853 ActivityManagerNative.getDefault() 2854 .finishActivity(token, Activity.RESULT_CANCELED, null); 2855 } catch (RemoteException ex) { 2856 } 2857 } 2858 } 2859 2860 private int mThumbnailWidth = -1; 2861 private int mThumbnailHeight = -1; 2862 private Bitmap mAvailThumbnailBitmap = null; 2863 private Canvas mThumbnailCanvas = null; 2864 2865 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 2866 Bitmap thumbnail = mAvailThumbnailBitmap; 2867 try { 2868 if (thumbnail == null) { 2869 int w = mThumbnailWidth; 2870 int h; 2871 if (w < 0) { 2872 Resources res = r.activity.getResources(); 2873 mThumbnailHeight = h = 2874 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2875 2876 mThumbnailWidth = w = 2877 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2878 } else { 2879 h = mThumbnailHeight; 2880 } 2881 2882 // On platforms where we don't want thumbnails, set dims to (0,0) 2883 if ((w > 0) && (h > 0)) { 2884 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 2885 w, h, THUMBNAIL_FORMAT); 2886 thumbnail.eraseColor(0); 2887 } 2888 } 2889 2890 if (thumbnail != null) { 2891 Canvas cv = mThumbnailCanvas; 2892 if (cv == null) { 2893 mThumbnailCanvas = cv = new Canvas(); 2894 } 2895 2896 cv.setBitmap(thumbnail); 2897 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 2898 mAvailThumbnailBitmap = thumbnail; 2899 thumbnail = null; 2900 } 2901 cv.setBitmap(null); 2902 } 2903 2904 } catch (Exception e) { 2905 if (!mInstrumentation.onException(r.activity, e)) { 2906 throw new RuntimeException( 2907 "Unable to create thumbnail of " 2908 + r.intent.getComponent().toShortString() 2909 + ": " + e.toString(), e); 2910 } 2911 thumbnail = null; 2912 } 2913 2914 return thumbnail; 2915 } 2916 2917 private void handlePauseActivity(IBinder token, boolean finished, 2918 boolean userLeaving, int configChanges) { 2919 ActivityClientRecord r = mActivities.get(token); 2920 if (r != null) { 2921 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 2922 if (userLeaving) { 2923 performUserLeavingActivity(r); 2924 } 2925 2926 r.activity.mConfigChangeFlags |= configChanges; 2927 performPauseActivity(token, finished, r.isPreHoneycomb()); 2928 2929 // Make sure any pending writes are now committed. 2930 if (r.isPreHoneycomb()) { 2931 QueuedWork.waitToFinish(); 2932 } 2933 2934 // Tell the activity manager we have paused. 2935 try { 2936 ActivityManagerNative.getDefault().activityPaused(token); 2937 } catch (RemoteException ex) { 2938 } 2939 } 2940 } 2941 2942 final void performUserLeavingActivity(ActivityClientRecord r) { 2943 mInstrumentation.callActivityOnUserLeaving(r.activity); 2944 } 2945 2946 final Bundle performPauseActivity(IBinder token, boolean finished, 2947 boolean saveState) { 2948 ActivityClientRecord r = mActivities.get(token); 2949 return r != null ? performPauseActivity(r, finished, saveState) : null; 2950 } 2951 2952 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 2953 boolean saveState) { 2954 if (r.paused) { 2955 if (r.activity.mFinished) { 2956 // If we are finishing, we won't call onResume() in certain cases. 2957 // So here we likewise don't want to call onPause() if the activity 2958 // isn't resumed. 2959 return null; 2960 } 2961 RuntimeException e = new RuntimeException( 2962 "Performing pause of activity that is not resumed: " 2963 + r.intent.getComponent().toShortString()); 2964 Slog.e(TAG, e.getMessage(), e); 2965 } 2966 Bundle state = null; 2967 if (finished) { 2968 r.activity.mFinished = true; 2969 } 2970 try { 2971 // Next have the activity save its current state and managed dialogs... 2972 if (!r.activity.mFinished && saveState) { 2973 state = new Bundle(); 2974 state.setAllowFds(false); 2975 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 2976 r.state = state; 2977 } 2978 // Now we are idle. 2979 r.activity.mCalled = false; 2980 mInstrumentation.callActivityOnPause(r.activity); 2981 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 2982 r.activity.getComponentName().getClassName()); 2983 if (!r.activity.mCalled) { 2984 throw new SuperNotCalledException( 2985 "Activity " + r.intent.getComponent().toShortString() + 2986 " did not call through to super.onPause()"); 2987 } 2988 2989 } catch (SuperNotCalledException e) { 2990 throw e; 2991 2992 } catch (Exception e) { 2993 if (!mInstrumentation.onException(r.activity, e)) { 2994 throw new RuntimeException( 2995 "Unable to pause activity " 2996 + r.intent.getComponent().toShortString() 2997 + ": " + e.toString(), e); 2998 } 2999 } 3000 r.paused = true; 3001 3002 // Notify any outstanding on paused listeners 3003 ArrayList<OnActivityPausedListener> listeners; 3004 synchronized (mOnPauseListeners) { 3005 listeners = mOnPauseListeners.remove(r.activity); 3006 } 3007 int size = (listeners != null ? listeners.size() : 0); 3008 for (int i = 0; i < size; i++) { 3009 listeners.get(i).onPaused(r.activity); 3010 } 3011 3012 return state; 3013 } 3014 3015 final void performStopActivity(IBinder token, boolean saveState) { 3016 ActivityClientRecord r = mActivities.get(token); 3017 performStopActivityInner(r, null, false, saveState); 3018 } 3019 3020 private static class StopInfo implements Runnable { 3021 ActivityClientRecord activity; 3022 Bundle state; 3023 Bitmap thumbnail; 3024 CharSequence description; 3025 3026 @Override public void run() { 3027 // Tell activity manager we have been stopped. 3028 try { 3029 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3030 ActivityManagerNative.getDefault().activityStopped( 3031 activity.token, state, thumbnail, description); 3032 } catch (RemoteException ex) { 3033 } 3034 } 3035 } 3036 3037 private static final class ProviderRefCount { 3038 public final IActivityManager.ContentProviderHolder holder; 3039 public final ProviderClientRecord client; 3040 public int stableCount; 3041 public int unstableCount; 3042 3043 // When this is set, the stable and unstable ref counts are 0 and 3044 // we have a pending operation scheduled to remove the ref count 3045 // from the activity manager. On the activity manager we are still 3046 // holding an unstable ref, though it is not reflected in the counts 3047 // here. 3048 public boolean removePending; 3049 3050 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3051 ProviderClientRecord inClient, int sCount, int uCount) { 3052 holder = inHolder; 3053 client = inClient; 3054 stableCount = sCount; 3055 unstableCount = uCount; 3056 } 3057 } 3058 3059 /** 3060 * Core implementation of stopping an activity. Note this is a little 3061 * tricky because the server's meaning of stop is slightly different 3062 * than our client -- for the server, stop means to save state and give 3063 * it the result when it is done, but the window may still be visible. 3064 * For the client, we want to call onStop()/onStart() to indicate when 3065 * the activity's UI visibillity changes. 3066 */ 3067 private void performStopActivityInner(ActivityClientRecord r, 3068 StopInfo info, boolean keepShown, boolean saveState) { 3069 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3070 Bundle state = null; 3071 if (r != null) { 3072 if (!keepShown && r.stopped) { 3073 if (r.activity.mFinished) { 3074 // If we are finishing, we won't call onResume() in certain 3075 // cases. So here we likewise don't want to call onStop() 3076 // if the activity isn't resumed. 3077 return; 3078 } 3079 RuntimeException e = new RuntimeException( 3080 "Performing stop of activity that is not resumed: " 3081 + r.intent.getComponent().toShortString()); 3082 Slog.e(TAG, e.getMessage(), e); 3083 } 3084 3085 if (info != null) { 3086 try { 3087 // First create a thumbnail for the activity... 3088 // For now, don't create the thumbnail here; we are 3089 // doing that by doing a screen snapshot. 3090 info.thumbnail = null; //createThumbnailBitmap(r); 3091 info.description = r.activity.onCreateDescription(); 3092 } catch (Exception e) { 3093 if (!mInstrumentation.onException(r.activity, e)) { 3094 throw new RuntimeException( 3095 "Unable to save state of activity " 3096 + r.intent.getComponent().toShortString() 3097 + ": " + e.toString(), e); 3098 } 3099 } 3100 } 3101 3102 // Next have the activity save its current state and managed dialogs... 3103 if (!r.activity.mFinished && saveState) { 3104 if (r.state == null) { 3105 state = new Bundle(); 3106 state.setAllowFds(false); 3107 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 3108 r.state = state; 3109 } else { 3110 state = r.state; 3111 } 3112 } 3113 3114 if (!keepShown) { 3115 try { 3116 // Now we are idle. 3117 r.activity.performStop(); 3118 } catch (Exception e) { 3119 if (!mInstrumentation.onException(r.activity, e)) { 3120 throw new RuntimeException( 3121 "Unable to stop activity " 3122 + r.intent.getComponent().toShortString() 3123 + ": " + e.toString(), e); 3124 } 3125 } 3126 r.stopped = true; 3127 } 3128 3129 r.paused = true; 3130 } 3131 } 3132 3133 private void updateVisibility(ActivityClientRecord r, boolean show) { 3134 View v = r.activity.mDecor; 3135 if (v != null) { 3136 if (show) { 3137 if (!r.activity.mVisibleFromServer) { 3138 r.activity.mVisibleFromServer = true; 3139 mNumVisibleActivities++; 3140 if (r.activity.mVisibleFromClient) { 3141 r.activity.makeVisible(); 3142 } 3143 } 3144 if (r.newConfig != null) { 3145 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3146 + r.activityInfo.name + " with new config " + r.newConfig); 3147 performConfigurationChanged(r.activity, r.newConfig); 3148 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 3149 r.newConfig = null; 3150 } 3151 } else { 3152 if (r.activity.mVisibleFromServer) { 3153 r.activity.mVisibleFromServer = false; 3154 mNumVisibleActivities--; 3155 v.setVisibility(View.INVISIBLE); 3156 } 3157 } 3158 } 3159 } 3160 3161 private void handleStopActivity(IBinder token, boolean show, int configChanges) { 3162 ActivityClientRecord r = mActivities.get(token); 3163 r.activity.mConfigChangeFlags |= configChanges; 3164 3165 StopInfo info = new StopInfo(); 3166 performStopActivityInner(r, info, show, true); 3167 3168 if (localLOGV) Slog.v( 3169 TAG, "Finishing stop of " + r + ": show=" + show 3170 + " win=" + r.window); 3171 3172 updateVisibility(r, show); 3173 3174 // Make sure any pending writes are now committed. 3175 if (!r.isPreHoneycomb()) { 3176 QueuedWork.waitToFinish(); 3177 } 3178 3179 // Schedule the call to tell the activity manager we have 3180 // stopped. We don't do this immediately, because we want to 3181 // have a chance for any other pending work (in particular memory 3182 // trim requests) to complete before you tell the activity 3183 // manager to proceed and allow us to go fully into the background. 3184 info.activity = r; 3185 info.state = r.state; 3186 mH.post(info); 3187 } 3188 3189 final void performRestartActivity(IBinder token) { 3190 ActivityClientRecord r = mActivities.get(token); 3191 if (r.stopped) { 3192 r.activity.performRestart(); 3193 r.stopped = false; 3194 } 3195 } 3196 3197 private void handleWindowVisibility(IBinder token, boolean show) { 3198 ActivityClientRecord r = mActivities.get(token); 3199 3200 if (r == null) { 3201 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3202 return; 3203 } 3204 3205 if (!show && !r.stopped) { 3206 performStopActivityInner(r, null, show, false); 3207 } else if (show && r.stopped) { 3208 // If we are getting ready to gc after going to the background, well 3209 // we are back active so skip it. 3210 unscheduleGcIdler(); 3211 3212 r.activity.performRestart(); 3213 r.stopped = false; 3214 } 3215 if (r.activity.mDecor != null) { 3216 if (false) Slog.v( 3217 TAG, "Handle window " + r + " visibility: " + show); 3218 updateVisibility(r, show); 3219 } 3220 } 3221 3222 private void handleSleeping(IBinder token, boolean sleeping) { 3223 ActivityClientRecord r = mActivities.get(token); 3224 3225 if (r == null) { 3226 Log.w(TAG, "handleSleeping: no activity for token " + token); 3227 return; 3228 } 3229 3230 if (sleeping) { 3231 if (!r.stopped && !r.isPreHoneycomb()) { 3232 try { 3233 // Now we are idle. 3234 r.activity.performStop(); 3235 } catch (Exception e) { 3236 if (!mInstrumentation.onException(r.activity, e)) { 3237 throw new RuntimeException( 3238 "Unable to stop activity " 3239 + r.intent.getComponent().toShortString() 3240 + ": " + e.toString(), e); 3241 } 3242 } 3243 r.stopped = true; 3244 } 3245 3246 // Make sure any pending writes are now committed. 3247 if (!r.isPreHoneycomb()) { 3248 QueuedWork.waitToFinish(); 3249 } 3250 3251 // Tell activity manager we slept. 3252 try { 3253 ActivityManagerNative.getDefault().activitySlept(r.token); 3254 } catch (RemoteException ex) { 3255 } 3256 } else { 3257 if (r.stopped && r.activity.mVisibleFromServer) { 3258 r.activity.performRestart(); 3259 r.stopped = false; 3260 } 3261 } 3262 } 3263 3264 private void handleSetCoreSettings(Bundle coreSettings) { 3265 synchronized (mPackages) { 3266 mCoreSettings = coreSettings; 3267 } 3268 } 3269 3270 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3271 LoadedApk apk = peekPackageInfo(data.pkg, false); 3272 if (apk != null) { 3273 apk.mCompatibilityInfo.set(data.info); 3274 } 3275 apk = peekPackageInfo(data.pkg, true); 3276 if (apk != null) { 3277 apk.mCompatibilityInfo.set(data.info); 3278 } 3279 handleConfigurationChanged(mConfiguration, data.info); 3280 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3281 } 3282 3283 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3284 final int N = results.size(); 3285 for (int i=0; i<N; i++) { 3286 ResultInfo ri = results.get(i); 3287 try { 3288 if (ri.mData != null) { 3289 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3290 } 3291 if (DEBUG_RESULTS) Slog.v(TAG, 3292 "Delivering result to activity " + r + " : " + ri); 3293 r.activity.dispatchActivityResult(ri.mResultWho, 3294 ri.mRequestCode, ri.mResultCode, ri.mData); 3295 } catch (Exception e) { 3296 if (!mInstrumentation.onException(r.activity, e)) { 3297 throw new RuntimeException( 3298 "Failure delivering result " + ri + " to activity " 3299 + r.intent.getComponent().toShortString() 3300 + ": " + e.toString(), e); 3301 } 3302 } 3303 } 3304 } 3305 3306 private void handleSendResult(ResultData res) { 3307 ActivityClientRecord r = mActivities.get(res.token); 3308 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3309 if (r != null) { 3310 final boolean resumed = !r.paused; 3311 if (!r.activity.mFinished && r.activity.mDecor != null 3312 && r.hideForNow && resumed) { 3313 // We had hidden the activity because it started another 3314 // one... we have gotten a result back and we are not 3315 // paused, so make sure our window is visible. 3316 updateVisibility(r, true); 3317 } 3318 if (resumed) { 3319 try { 3320 // Now we are idle. 3321 r.activity.mCalled = false; 3322 r.activity.mTemporaryPause = true; 3323 mInstrumentation.callActivityOnPause(r.activity); 3324 if (!r.activity.mCalled) { 3325 throw new SuperNotCalledException( 3326 "Activity " + r.intent.getComponent().toShortString() 3327 + " did not call through to super.onPause()"); 3328 } 3329 } catch (SuperNotCalledException e) { 3330 throw e; 3331 } catch (Exception e) { 3332 if (!mInstrumentation.onException(r.activity, e)) { 3333 throw new RuntimeException( 3334 "Unable to pause activity " 3335 + r.intent.getComponent().toShortString() 3336 + ": " + e.toString(), e); 3337 } 3338 } 3339 } 3340 deliverResults(r, res.results); 3341 if (resumed) { 3342 r.activity.performResume(); 3343 r.activity.mTemporaryPause = false; 3344 } 3345 } 3346 } 3347 3348 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 3349 return performDestroyActivity(token, finishing, 0, false); 3350 } 3351 3352 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 3353 int configChanges, boolean getNonConfigInstance) { 3354 ActivityClientRecord r = mActivities.get(token); 3355 Class activityClass = null; 3356 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 3357 if (r != null) { 3358 activityClass = r.activity.getClass(); 3359 r.activity.mConfigChangeFlags |= configChanges; 3360 if (finishing) { 3361 r.activity.mFinished = true; 3362 } 3363 if (!r.paused) { 3364 try { 3365 r.activity.mCalled = false; 3366 mInstrumentation.callActivityOnPause(r.activity); 3367 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3368 r.activity.getComponentName().getClassName()); 3369 if (!r.activity.mCalled) { 3370 throw new SuperNotCalledException( 3371 "Activity " + safeToComponentShortString(r.intent) 3372 + " did not call through to super.onPause()"); 3373 } 3374 } catch (SuperNotCalledException e) { 3375 throw e; 3376 } catch (Exception e) { 3377 if (!mInstrumentation.onException(r.activity, e)) { 3378 throw new RuntimeException( 3379 "Unable to pause activity " 3380 + safeToComponentShortString(r.intent) 3381 + ": " + e.toString(), e); 3382 } 3383 } 3384 r.paused = true; 3385 } 3386 if (!r.stopped) { 3387 try { 3388 r.activity.performStop(); 3389 } catch (SuperNotCalledException e) { 3390 throw e; 3391 } catch (Exception e) { 3392 if (!mInstrumentation.onException(r.activity, e)) { 3393 throw new RuntimeException( 3394 "Unable to stop activity " 3395 + safeToComponentShortString(r.intent) 3396 + ": " + e.toString(), e); 3397 } 3398 } 3399 r.stopped = true; 3400 } 3401 if (getNonConfigInstance) { 3402 try { 3403 r.lastNonConfigurationInstances 3404 = r.activity.retainNonConfigurationInstances(); 3405 } catch (Exception e) { 3406 if (!mInstrumentation.onException(r.activity, e)) { 3407 throw new RuntimeException( 3408 "Unable to retain activity " 3409 + r.intent.getComponent().toShortString() 3410 + ": " + e.toString(), e); 3411 } 3412 } 3413 } 3414 try { 3415 r.activity.mCalled = false; 3416 mInstrumentation.callActivityOnDestroy(r.activity); 3417 if (!r.activity.mCalled) { 3418 throw new SuperNotCalledException( 3419 "Activity " + safeToComponentShortString(r.intent) + 3420 " did not call through to super.onDestroy()"); 3421 } 3422 if (r.window != null) { 3423 r.window.closeAllPanels(); 3424 } 3425 } catch (SuperNotCalledException e) { 3426 throw e; 3427 } catch (Exception e) { 3428 if (!mInstrumentation.onException(r.activity, e)) { 3429 throw new RuntimeException( 3430 "Unable to destroy activity " + safeToComponentShortString(r.intent) 3431 + ": " + e.toString(), e); 3432 } 3433 } 3434 } 3435 mActivities.remove(token); 3436 StrictMode.decrementExpectedActivityCount(activityClass); 3437 return r; 3438 } 3439 3440 private static String safeToComponentShortString(Intent intent) { 3441 ComponentName component = intent.getComponent(); 3442 return component == null ? "[Unknown]" : component.toShortString(); 3443 } 3444 3445 private void handleDestroyActivity(IBinder token, boolean finishing, 3446 int configChanges, boolean getNonConfigInstance) { 3447 ActivityClientRecord r = performDestroyActivity(token, finishing, 3448 configChanges, getNonConfigInstance); 3449 if (r != null) { 3450 cleanUpPendingRemoveWindows(r); 3451 WindowManager wm = r.activity.getWindowManager(); 3452 View v = r.activity.mDecor; 3453 if (v != null) { 3454 if (r.activity.mVisibleFromServer) { 3455 mNumVisibleActivities--; 3456 } 3457 IBinder wtoken = v.getWindowToken(); 3458 if (r.activity.mWindowAdded) { 3459 if (r.onlyLocalRequest) { 3460 // Hold off on removing this until the new activity's 3461 // window is being added. 3462 r.mPendingRemoveWindow = v; 3463 r.mPendingRemoveWindowManager = wm; 3464 } else { 3465 wm.removeViewImmediate(v); 3466 } 3467 } 3468 if (wtoken != null && r.mPendingRemoveWindow == null) { 3469 WindowManagerGlobal.getInstance().closeAll(wtoken, 3470 r.activity.getClass().getName(), "Activity"); 3471 } 3472 r.activity.mDecor = null; 3473 } 3474 if (r.mPendingRemoveWindow == null) { 3475 // If we are delaying the removal of the activity window, then 3476 // we can't clean up all windows here. Note that we can't do 3477 // so later either, which means any windows that aren't closed 3478 // by the app will leak. Well we try to warning them a lot 3479 // about leaking windows, because that is a bug, so if they are 3480 // using this recreate facility then they get to live with leaks. 3481 WindowManagerGlobal.getInstance().closeAll(token, 3482 r.activity.getClass().getName(), "Activity"); 3483 } 3484 3485 // Mocked out contexts won't be participating in the normal 3486 // process lifecycle, but if we're running with a proper 3487 // ApplicationContext we need to have it tear down things 3488 // cleanly. 3489 Context c = r.activity.getBaseContext(); 3490 if (c instanceof ContextImpl) { 3491 ((ContextImpl) c).scheduleFinalCleanup( 3492 r.activity.getClass().getName(), "Activity"); 3493 } 3494 } 3495 if (finishing) { 3496 try { 3497 ActivityManagerNative.getDefault().activityDestroyed(token); 3498 } catch (RemoteException ex) { 3499 // If the system process has died, it's game over for everyone. 3500 } 3501 } 3502 } 3503 3504 public final void requestRelaunchActivity(IBinder token, 3505 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 3506 int configChanges, boolean notResumed, Configuration config, 3507 boolean fromServer) { 3508 ActivityClientRecord target = null; 3509 3510 synchronized (mPackages) { 3511 for (int i=0; i<mRelaunchingActivities.size(); i++) { 3512 ActivityClientRecord r = mRelaunchingActivities.get(i); 3513 if (r.token == token) { 3514 target = r; 3515 if (pendingResults != null) { 3516 if (r.pendingResults != null) { 3517 r.pendingResults.addAll(pendingResults); 3518 } else { 3519 r.pendingResults = pendingResults; 3520 } 3521 } 3522 if (pendingNewIntents != null) { 3523 if (r.pendingIntents != null) { 3524 r.pendingIntents.addAll(pendingNewIntents); 3525 } else { 3526 r.pendingIntents = pendingNewIntents; 3527 } 3528 } 3529 break; 3530 } 3531 } 3532 3533 if (target == null) { 3534 target = new ActivityClientRecord(); 3535 target.token = token; 3536 target.pendingResults = pendingResults; 3537 target.pendingIntents = pendingNewIntents; 3538 if (!fromServer) { 3539 ActivityClientRecord existing = mActivities.get(token); 3540 if (existing != null) { 3541 target.startsNotResumed = existing.paused; 3542 } 3543 target.onlyLocalRequest = true; 3544 } 3545 mRelaunchingActivities.add(target); 3546 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target); 3547 } 3548 3549 if (fromServer) { 3550 target.startsNotResumed = notResumed; 3551 target.onlyLocalRequest = false; 3552 } 3553 if (config != null) { 3554 target.createdConfig = config; 3555 } 3556 target.pendingConfigChanges |= configChanges; 3557 } 3558 } 3559 3560 private void handleRelaunchActivity(ActivityClientRecord tmp) { 3561 // If we are getting ready to gc after going to the background, well 3562 // we are back active so skip it. 3563 unscheduleGcIdler(); 3564 3565 Configuration changedConfig = null; 3566 int configChanges = 0; 3567 3568 // First: make sure we have the most recent configuration and most 3569 // recent version of the activity, or skip it if some previous call 3570 // had taken a more recent version. 3571 synchronized (mPackages) { 3572 int N = mRelaunchingActivities.size(); 3573 IBinder token = tmp.token; 3574 tmp = null; 3575 for (int i=0; i<N; i++) { 3576 ActivityClientRecord r = mRelaunchingActivities.get(i); 3577 if (r.token == token) { 3578 tmp = r; 3579 configChanges |= tmp.pendingConfigChanges; 3580 mRelaunchingActivities.remove(i); 3581 i--; 3582 N--; 3583 } 3584 } 3585 3586 if (tmp == null) { 3587 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 3588 return; 3589 } 3590 3591 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3592 + tmp.token + " with configChanges=0x" 3593 + Integer.toHexString(configChanges)); 3594 3595 if (mPendingConfiguration != null) { 3596 changedConfig = mPendingConfiguration; 3597 mPendingConfiguration = null; 3598 } 3599 } 3600 3601 if (tmp.createdConfig != null) { 3602 // If the activity manager is passing us its current config, 3603 // assume that is really what we want regardless of what we 3604 // may have pending. 3605 if (mConfiguration == null 3606 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 3607 && mConfiguration.diff(tmp.createdConfig) != 0)) { 3608 if (changedConfig == null 3609 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 3610 changedConfig = tmp.createdConfig; 3611 } 3612 } 3613 } 3614 3615 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3616 + tmp.token + ": changedConfig=" + changedConfig); 3617 3618 // If there was a pending configuration change, execute it first. 3619 if (changedConfig != null) { 3620 mCurDefaultDisplayDpi = changedConfig.densityDpi; 3621 updateDefaultDensity(); 3622 handleConfigurationChanged(changedConfig, null); 3623 } 3624 3625 ActivityClientRecord r = mActivities.get(tmp.token); 3626 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 3627 if (r == null) { 3628 return; 3629 } 3630 3631 r.activity.mConfigChangeFlags |= configChanges; 3632 r.onlyLocalRequest = tmp.onlyLocalRequest; 3633 Intent currentIntent = r.activity.mIntent; 3634 3635 r.activity.mChangingConfigurations = true; 3636 3637 // Need to ensure state is saved. 3638 if (!r.paused) { 3639 performPauseActivity(r.token, false, r.isPreHoneycomb()); 3640 } 3641 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 3642 r.state = new Bundle(); 3643 r.state.setAllowFds(false); 3644 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 3645 } 3646 3647 handleDestroyActivity(r.token, false, configChanges, true); 3648 3649 r.activity = null; 3650 r.window = null; 3651 r.hideForNow = false; 3652 r.nextIdle = null; 3653 // Merge any pending results and pending intents; don't just replace them 3654 if (tmp.pendingResults != null) { 3655 if (r.pendingResults == null) { 3656 r.pendingResults = tmp.pendingResults; 3657 } else { 3658 r.pendingResults.addAll(tmp.pendingResults); 3659 } 3660 } 3661 if (tmp.pendingIntents != null) { 3662 if (r.pendingIntents == null) { 3663 r.pendingIntents = tmp.pendingIntents; 3664 } else { 3665 r.pendingIntents.addAll(tmp.pendingIntents); 3666 } 3667 } 3668 r.startsNotResumed = tmp.startsNotResumed; 3669 3670 handleLaunchActivity(r, currentIntent); 3671 } 3672 3673 private void handleRequestThumbnail(IBinder token) { 3674 ActivityClientRecord r = mActivities.get(token); 3675 Bitmap thumbnail = createThumbnailBitmap(r); 3676 CharSequence description = null; 3677 try { 3678 description = r.activity.onCreateDescription(); 3679 } catch (Exception e) { 3680 if (!mInstrumentation.onException(r.activity, e)) { 3681 throw new RuntimeException( 3682 "Unable to create description of activity " 3683 + r.intent.getComponent().toShortString() 3684 + ": " + e.toString(), e); 3685 } 3686 } 3687 //System.out.println("Reporting top thumbnail " + thumbnail); 3688 try { 3689 ActivityManagerNative.getDefault().reportThumbnail( 3690 token, thumbnail, description); 3691 } catch (RemoteException ex) { 3692 } 3693 } 3694 3695 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 3696 boolean allActivities, Configuration newConfig) { 3697 ArrayList<ComponentCallbacks2> callbacks 3698 = new ArrayList<ComponentCallbacks2>(); 3699 3700 synchronized (mPackages) { 3701 final int N = mAllApplications.size(); 3702 for (int i=0; i<N; i++) { 3703 callbacks.add(mAllApplications.get(i)); 3704 } 3705 if (mActivities.size() > 0) { 3706 for (ActivityClientRecord ar : mActivities.values()) { 3707 Activity a = ar.activity; 3708 if (a != null) { 3709 Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi, 3710 newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded()); 3711 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 3712 // If the activity is currently resumed, its configuration 3713 // needs to change right now. 3714 callbacks.add(a); 3715 } else if (thisConfig != null) { 3716 // Otherwise, we will tell it about the change 3717 // the next time it is resumed or shown. Note that 3718 // the activity manager may, before then, decide the 3719 // activity needs to be destroyed to handle its new 3720 // configuration. 3721 if (DEBUG_CONFIGURATION) { 3722 Slog.v(TAG, "Setting activity " 3723 + ar.activityInfo.name + " newConfig=" + thisConfig); 3724 } 3725 ar.newConfig = thisConfig; 3726 } 3727 } 3728 } 3729 } 3730 if (mServices.size() > 0) { 3731 for (Service service : mServices.values()) { 3732 callbacks.add(service); 3733 } 3734 } 3735 } 3736 synchronized (mProviderMap) { 3737 if (mLocalProviders.size() > 0) { 3738 for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) { 3739 callbacks.add(providerClientRecord.mLocalProvider); 3740 } 3741 } 3742 } 3743 3744 return callbacks; 3745 } 3746 3747 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { 3748 // Only for Activity objects, check that they actually call up to their 3749 // superclass implementation. ComponentCallbacks2 is an interface, so 3750 // we check the runtime type and act accordingly. 3751 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 3752 if (activity != null) { 3753 activity.mCalled = false; 3754 } 3755 3756 boolean shouldChangeConfig = false; 3757 if ((activity == null) || (activity.mCurrentConfig == null)) { 3758 shouldChangeConfig = true; 3759 } else { 3760 3761 // If the new config is the same as the config this Activity 3762 // is already running with then don't bother calling 3763 // onConfigurationChanged 3764 int diff = activity.mCurrentConfig.diff(config); 3765 if (diff != 0) { 3766 // If this activity doesn't handle any of the config changes 3767 // then don't bother calling onConfigurationChanged as we're 3768 // going to destroy it. 3769 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) { 3770 shouldChangeConfig = true; 3771 } 3772 } 3773 } 3774 3775 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 3776 + ": shouldChangeConfig=" + shouldChangeConfig); 3777 if (shouldChangeConfig) { 3778 cb.onConfigurationChanged(config); 3779 3780 if (activity != null) { 3781 if (!activity.mCalled) { 3782 throw new SuperNotCalledException( 3783 "Activity " + activity.getLocalClassName() + 3784 " did not call through to super.onConfigurationChanged()"); 3785 } 3786 activity.mConfigChangeFlags = 0; 3787 activity.mCurrentConfig = new Configuration(config); 3788 } 3789 } 3790 } 3791 3792 public final void applyConfigurationToResources(Configuration config) { 3793 synchronized (mPackages) { 3794 applyConfigurationToResourcesLocked(config, null); 3795 } 3796 } 3797 3798 final boolean applyConfigurationToResourcesLocked(Configuration config, 3799 CompatibilityInfo compat) { 3800 if (mResConfiguration == null) { 3801 mResConfiguration = new Configuration(); 3802 } 3803 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) { 3804 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq=" 3805 + mResConfiguration.seq + ", newSeq=" + config.seq); 3806 return false; 3807 } 3808 int changes = mResConfiguration.updateFrom(config); 3809 flushDisplayMetricsLocked(); 3810 DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked( 3811 Display.DEFAULT_DISPLAY, null); 3812 3813 if (compat != null && (mResCompatibilityInfo == null || 3814 !mResCompatibilityInfo.equals(compat))) { 3815 mResCompatibilityInfo = compat; 3816 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT 3817 | ActivityInfo.CONFIG_SCREEN_SIZE 3818 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; 3819 } 3820 3821 // set it for java, this also affects newly created Resources 3822 if (config.locale != null) { 3823 Locale.setDefault(config.locale); 3824 } 3825 3826 Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat); 3827 3828 ApplicationPackageManager.configurationChanged(); 3829 //Slog.i(TAG, "Configuration changed in " + currentPackageName()); 3830 3831 Configuration tmpConfig = null; 3832 3833 Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it = 3834 mActiveResources.entrySet().iterator(); 3835 while (it.hasNext()) { 3836 Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next(); 3837 Resources r = entry.getValue().get(); 3838 if (r != null) { 3839 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources " 3840 + r + " config to: " + config); 3841 int displayId = entry.getKey().mDisplayId; 3842 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); 3843 DisplayMetrics dm = defaultDisplayMetrics; 3844 Configuration overrideConfig = entry.getKey().mOverrideConfiguration; 3845 if (!isDefaultDisplay || overrideConfig != null) { 3846 if (tmpConfig == null) { 3847 tmpConfig = new Configuration(); 3848 } 3849 tmpConfig.setTo(config); 3850 if (!isDefaultDisplay) { 3851 dm = getDisplayMetricsLocked(displayId, null); 3852 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig); 3853 } 3854 if (overrideConfig != null) { 3855 tmpConfig.updateFrom(overrideConfig); 3856 } 3857 r.updateConfiguration(tmpConfig, dm, compat); 3858 } else { 3859 r.updateConfiguration(config, dm, compat); 3860 } 3861 //Slog.i(TAG, "Updated app resources " + v.getKey() 3862 // + " " + r + ": " + r.getConfiguration()); 3863 } else { 3864 //Slog.i(TAG, "Removing old resources " + v.getKey()); 3865 it.remove(); 3866 } 3867 } 3868 3869 return changes != 0; 3870 } 3871 3872 final void applyNonDefaultDisplayMetricsToConfigurationLocked( 3873 DisplayMetrics dm, Configuration config) { 3874 config.screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE 3875 | Configuration.SCREENLAYOUT_LONG_NO; 3876 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH; 3877 config.orientation = (dm.widthPixels >= dm.heightPixels) ? 3878 Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT; 3879 config.densityDpi = dm.densityDpi; 3880 config.screenWidthDp = (int)(dm.widthPixels / dm.density); 3881 config.screenHeightDp = (int)(dm.heightPixels / dm.density); 3882 config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate 3883 config.compatScreenWidthDp = config.screenWidthDp; 3884 config.compatScreenHeightDp = config.screenHeightDp; 3885 config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp; 3886 } 3887 3888 final Configuration applyCompatConfiguration(int displayDensity) { 3889 Configuration config = mConfiguration; 3890 if (mCompatConfiguration == null) { 3891 mCompatConfiguration = new Configuration(); 3892 } 3893 mCompatConfiguration.setTo(mConfiguration); 3894 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) { 3895 mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration); 3896 config = mCompatConfiguration; 3897 } 3898 return config; 3899 } 3900 3901 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 3902 3903 int configDiff = 0; 3904 3905 synchronized (mPackages) { 3906 if (mPendingConfiguration != null) { 3907 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 3908 config = mPendingConfiguration; 3909 mCurDefaultDisplayDpi = config.densityDpi; 3910 updateDefaultDensity(); 3911 } 3912 mPendingConfiguration = null; 3913 } 3914 3915 if (config == null) { 3916 return; 3917 } 3918 3919 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 3920 + config); 3921 3922 applyConfigurationToResourcesLocked(config, compat); 3923 3924 if (mConfiguration == null) { 3925 mConfiguration = new Configuration(); 3926 } 3927 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 3928 return; 3929 } 3930 configDiff = mConfiguration.diff(config); 3931 mConfiguration.updateFrom(config); 3932 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 3933 } 3934 3935 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 3936 3937 // Cleanup hardware accelerated stuff 3938 WindowManagerGlobal.getInstance().trimLocalMemory(); 3939 3940 freeTextLayoutCachesIfNeeded(configDiff); 3941 3942 if (callbacks != null) { 3943 final int N = callbacks.size(); 3944 for (int i=0; i<N; i++) { 3945 performConfigurationChanged(callbacks.get(i), config); 3946 } 3947 } 3948 } 3949 3950 final void freeTextLayoutCachesIfNeeded(int configDiff) { 3951 if (configDiff != 0) { 3952 // Ask text layout engine to free its caches if there is a locale change 3953 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 3954 if (hasLocaleConfigChange) { 3955 Canvas.freeTextLayoutCaches(); 3956 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 3957 } 3958 } 3959 } 3960 3961 final void handleActivityConfigurationChanged(IBinder token) { 3962 ActivityClientRecord r = mActivities.get(token); 3963 if (r == null || r.activity == null) { 3964 return; 3965 } 3966 3967 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 3968 + r.activityInfo.name); 3969 3970 performConfigurationChanged(r.activity, mCompatConfiguration); 3971 3972 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 3973 } 3974 3975 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { 3976 if (start) { 3977 try { 3978 switch (profileType) { 3979 default: 3980 mProfiler.setProfiler(pcd.path, pcd.fd); 3981 mProfiler.autoStopProfiler = false; 3982 mProfiler.startProfiling(); 3983 break; 3984 } 3985 } catch (RuntimeException e) { 3986 Slog.w(TAG, "Profiling failed on path " + pcd.path 3987 + " -- can the process access this path?"); 3988 } finally { 3989 try { 3990 pcd.fd.close(); 3991 } catch (IOException e) { 3992 Slog.w(TAG, "Failure closing profile fd", e); 3993 } 3994 } 3995 } else { 3996 switch (profileType) { 3997 default: 3998 mProfiler.stopProfiling(); 3999 break; 4000 } 4001 } 4002 } 4003 4004 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4005 if (managed) { 4006 try { 4007 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4008 } catch (IOException e) { 4009 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4010 + " -- can the process access this path?"); 4011 } finally { 4012 try { 4013 dhd.fd.close(); 4014 } catch (IOException e) { 4015 Slog.w(TAG, "Failure closing profile fd", e); 4016 } 4017 } 4018 } else { 4019 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4020 } 4021 } 4022 4023 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4024 boolean hasPkgInfo = false; 4025 if (packages != null) { 4026 for (int i=packages.length-1; i>=0; i--) { 4027 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4028 if (!hasPkgInfo) { 4029 WeakReference<LoadedApk> ref; 4030 ref = mPackages.get(packages[i]); 4031 if (ref != null && ref.get() != null) { 4032 hasPkgInfo = true; 4033 } else { 4034 ref = mResourcePackages.get(packages[i]); 4035 if (ref != null && ref.get() != null) { 4036 hasPkgInfo = true; 4037 } 4038 } 4039 } 4040 mPackages.remove(packages[i]); 4041 mResourcePackages.remove(packages[i]); 4042 } 4043 } 4044 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4045 hasPkgInfo); 4046 } 4047 4048 final void handleLowMemory() { 4049 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4050 4051 final int N = callbacks.size(); 4052 for (int i=0; i<N; i++) { 4053 callbacks.get(i).onLowMemory(); 4054 } 4055 4056 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4057 if (Process.myUid() != Process.SYSTEM_UID) { 4058 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4059 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4060 } 4061 4062 // Ask graphics to free up as much as possible (font/image caches) 4063 Canvas.freeCaches(); 4064 4065 // Ask text layout engine to free also as much as possible 4066 Canvas.freeTextLayoutCaches(); 4067 4068 BinderInternal.forceGc("mem"); 4069 } 4070 4071 final void handleTrimMemory(int level) { 4072 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4073 4074 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance(); 4075 windowManager.startTrimMemory(level); 4076 4077 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4078 4079 final int N = callbacks.size(); 4080 for (int i = 0; i < N; i++) { 4081 callbacks.get(i).onTrimMemory(level); 4082 } 4083 4084 windowManager.endTrimMemory(); 4085 } 4086 4087 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4088 if (Process.isIsolated()) { 4089 // Isolated processes aren't going to do UI. 4090 return; 4091 } 4092 try { 4093 int uid = Process.myUid(); 4094 String[] packages = getPackageManager().getPackagesForUid(uid); 4095 4096 // If there are several packages in this application we won't 4097 // initialize the graphics disk caches 4098 if (packages != null && packages.length == 1) { 4099 HardwareRenderer.setupDiskCache(cacheDir); 4100 RenderScript.setupDiskCache(cacheDir); 4101 } 4102 } catch (RemoteException e) { 4103 // Ignore 4104 } 4105 } 4106 4107 private void updateDefaultDensity() { 4108 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED 4109 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE 4110 && !mDensityCompatMode) { 4111 Slog.i(TAG, "Switching default density from " 4112 + DisplayMetrics.DENSITY_DEVICE + " to " 4113 + mCurDefaultDisplayDpi); 4114 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; 4115 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4116 } 4117 } 4118 4119 private void handleBindApplication(AppBindData data) { 4120 mBoundApplication = data; 4121 mConfiguration = new Configuration(data.config); 4122 mCompatConfiguration = new Configuration(data.config); 4123 4124 mProfiler = new Profiler(); 4125 mProfiler.profileFile = data.initProfileFile; 4126 mProfiler.profileFd = data.initProfileFd; 4127 mProfiler.autoStopProfiler = data.initAutoStopProfiler; 4128 4129 // send up app name; do this *before* waiting for debugger 4130 Process.setArgV0(data.processName); 4131 android.ddm.DdmHandleAppName.setAppName(data.processName, 4132 UserHandle.myUserId()); 4133 4134 if (data.persistent) { 4135 // Persistent processes on low-memory devices do not get to 4136 // use hardware accelerated drawing, since this can add too much 4137 // overhead to the process. 4138 if (!ActivityManager.isHighEndGfx()) { 4139 HardwareRenderer.disable(false); 4140 } 4141 } 4142 4143 if (mProfiler.profileFd != null) { 4144 mProfiler.startProfiling(); 4145 } 4146 4147 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4148 // implementation to use the pool executor. Normally, we use the 4149 // serialized executor as the default. This has to happen in the 4150 // main thread so the main looper is set right. 4151 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4152 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4153 } 4154 4155 /* 4156 * Before spawning a new process, reset the time zone to be the system time zone. 4157 * This needs to be done because the system time zone could have changed after the 4158 * the spawning of this process. Without doing this this process would have the incorrect 4159 * system time zone. 4160 */ 4161 TimeZone.setDefault(null); 4162 4163 /* 4164 * Initialize the default locale in this process for the reasons we set the time zone. 4165 */ 4166 Locale.setDefault(data.config.locale); 4167 4168 /* 4169 * Update the system configuration since its preloaded and might not 4170 * reflect configuration changes. The configuration object passed 4171 * in AppBindData can be safely assumed to be up to date 4172 */ 4173 applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4174 mCurDefaultDisplayDpi = data.config.densityDpi; 4175 applyCompatConfiguration(mCurDefaultDisplayDpi); 4176 4177 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4178 4179 /** 4180 * Switch this process to density compatibility mode if needed. 4181 */ 4182 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4183 == 0) { 4184 mDensityCompatMode = true; 4185 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4186 } 4187 updateDefaultDensity(); 4188 4189 final ContextImpl appContext = new ContextImpl(); 4190 appContext.init(data.info, null, this); 4191 if (!Process.isIsolated()) { 4192 final File cacheDir = appContext.getCacheDir(); 4193 4194 if (cacheDir != null) { 4195 // Provide a usable directory for temporary files 4196 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 4197 4198 setupGraphicsSupport(data.info, cacheDir); 4199 } else { 4200 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory"); 4201 } 4202 } 4203 /** 4204 * For system applications on userdebug/eng builds, log stack 4205 * traces of disk and network access to dropbox for analysis. 4206 */ 4207 if ((data.appInfo.flags & 4208 (ApplicationInfo.FLAG_SYSTEM | 4209 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4210 StrictMode.conditionallyEnableDebugLogging(); 4211 } 4212 4213 /** 4214 * For apps targetting SDK Honeycomb or later, we don't allow 4215 * network usage on the main event loop / UI thread. 4216 * 4217 * Note to those grepping: this is what ultimately throws 4218 * NetworkOnMainThreadException ... 4219 */ 4220 if (data.appInfo.targetSdkVersion > 9) { 4221 StrictMode.enableDeathOnNetwork(); 4222 } 4223 4224 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4225 // XXX should have option to change the port. 4226 Debug.changeDebugPort(8100); 4227 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4228 Slog.w(TAG, "Application " + data.info.getPackageName() 4229 + " is waiting for the debugger on port 8100..."); 4230 4231 IActivityManager mgr = ActivityManagerNative.getDefault(); 4232 try { 4233 mgr.showWaitingForDebugger(mAppThread, true); 4234 } catch (RemoteException ex) { 4235 } 4236 4237 Debug.waitForDebugger(); 4238 4239 try { 4240 mgr.showWaitingForDebugger(mAppThread, false); 4241 } catch (RemoteException ex) { 4242 } 4243 4244 } else { 4245 Slog.w(TAG, "Application " + data.info.getPackageName() 4246 + " can be debugged on port 8100..."); 4247 } 4248 } 4249 4250 // Enable OpenGL tracing if required 4251 if (data.enableOpenGlTrace) { 4252 GLUtils.enableTracing(); 4253 } 4254 4255 /** 4256 * Initialize the default http proxy in this process for the reasons we set the time zone. 4257 */ 4258 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 4259 if (b != null) { 4260 // In pre-boot mode (doing initial launch to collect password), not 4261 // all system is up. This includes the connectivity service, so don't 4262 // crash if we can't get it. 4263 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4264 try { 4265 ProxyProperties proxyProperties = service.getProxy(); 4266 Proxy.setHttpProxySystemProperty(proxyProperties); 4267 } catch (RemoteException e) {} 4268 } 4269 4270 if (data.instrumentationName != null) { 4271 InstrumentationInfo ii = null; 4272 try { 4273 ii = appContext.getPackageManager(). 4274 getInstrumentationInfo(data.instrumentationName, 0); 4275 } catch (PackageManager.NameNotFoundException e) { 4276 } 4277 if (ii == null) { 4278 throw new RuntimeException( 4279 "Unable to find instrumentation info for: " 4280 + data.instrumentationName); 4281 } 4282 4283 mInstrumentationAppDir = ii.sourceDir; 4284 mInstrumentationAppLibraryDir = ii.nativeLibraryDir; 4285 mInstrumentationAppPackage = ii.packageName; 4286 mInstrumentedAppDir = data.info.getAppDir(); 4287 mInstrumentedAppLibraryDir = data.info.getLibDir(); 4288 4289 ApplicationInfo instrApp = new ApplicationInfo(); 4290 instrApp.packageName = ii.packageName; 4291 instrApp.sourceDir = ii.sourceDir; 4292 instrApp.publicSourceDir = ii.publicSourceDir; 4293 instrApp.dataDir = ii.dataDir; 4294 instrApp.nativeLibraryDir = ii.nativeLibraryDir; 4295 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 4296 appContext.getClassLoader(), false, true); 4297 ContextImpl instrContext = new ContextImpl(); 4298 instrContext.init(pi, null, this); 4299 4300 try { 4301 java.lang.ClassLoader cl = instrContext.getClassLoader(); 4302 mInstrumentation = (Instrumentation) 4303 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4304 } catch (Exception e) { 4305 throw new RuntimeException( 4306 "Unable to instantiate instrumentation " 4307 + data.instrumentationName + ": " + e.toString(), e); 4308 } 4309 4310 mInstrumentation.init(this, instrContext, appContext, 4311 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher); 4312 4313 if (mProfiler.profileFile != null && !ii.handleProfiling 4314 && mProfiler.profileFd == null) { 4315 mProfiler.handlingProfiling = true; 4316 File file = new File(mProfiler.profileFile); 4317 file.getParentFile().mkdirs(); 4318 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 4319 } 4320 4321 } else { 4322 mInstrumentation = new Instrumentation(); 4323 } 4324 4325 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 4326 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 4327 } 4328 4329 // Allow disk access during application and provider setup. This could 4330 // block processing ordered broadcasts, but later processing would 4331 // probably end up doing the same disk access. 4332 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 4333 try { 4334 // If the app is being launched for full backup or restore, bring it up in 4335 // a restricted environment with the base application class. 4336 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 4337 mInitialApplication = app; 4338 4339 // don't bring up providers in restricted mode; they may depend on the 4340 // app's custom Application class 4341 if (!data.restrictedBackupMode) { 4342 List<ProviderInfo> providers = data.providers; 4343 if (providers != null) { 4344 installContentProviders(app, providers); 4345 // For process that contains content providers, we want to 4346 // ensure that the JIT is enabled "at some point". 4347 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 4348 } 4349 } 4350 4351 // Do this after providers, since instrumentation tests generally start their 4352 // test thread at this point, and we don't want that racing. 4353 try { 4354 mInstrumentation.onCreate(data.instrumentationArgs); 4355 } 4356 catch (Exception e) { 4357 throw new RuntimeException( 4358 "Exception thrown in onCreate() of " 4359 + data.instrumentationName + ": " + e.toString(), e); 4360 } 4361 4362 try { 4363 mInstrumentation.callApplicationOnCreate(app); 4364 } catch (Exception e) { 4365 if (!mInstrumentation.onException(app, e)) { 4366 throw new RuntimeException( 4367 "Unable to create application " + app.getClass().getName() 4368 + ": " + e.toString(), e); 4369 } 4370 } 4371 } finally { 4372 StrictMode.setThreadPolicy(savedPolicy); 4373 } 4374 } 4375 4376 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 4377 IActivityManager am = ActivityManagerNative.getDefault(); 4378 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 4379 && mProfiler.profileFd == null) { 4380 Debug.stopMethodTracing(); 4381 } 4382 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 4383 // + ", app thr: " + mAppThread); 4384 try { 4385 am.finishInstrumentation(mAppThread, resultCode, results); 4386 } catch (RemoteException ex) { 4387 } 4388 } 4389 4390 private void installContentProviders( 4391 Context context, List<ProviderInfo> providers) { 4392 final ArrayList<IActivityManager.ContentProviderHolder> results = 4393 new ArrayList<IActivityManager.ContentProviderHolder>(); 4394 4395 for (ProviderInfo cpi : providers) { 4396 StringBuilder buf = new StringBuilder(128); 4397 buf.append("Pub "); 4398 buf.append(cpi.authority); 4399 buf.append(": "); 4400 buf.append(cpi.name); 4401 Log.i(TAG, buf.toString()); 4402 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 4403 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 4404 if (cph != null) { 4405 cph.noReleaseNeeded = true; 4406 results.add(cph); 4407 } 4408 } 4409 4410 try { 4411 ActivityManagerNative.getDefault().publishContentProviders( 4412 getApplicationThread(), results); 4413 } catch (RemoteException ex) { 4414 } 4415 } 4416 4417 public final IContentProvider acquireProvider( 4418 Context c, String auth, int userId, boolean stable) { 4419 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 4420 if (provider != null) { 4421 return provider; 4422 } 4423 4424 // There is a possible race here. Another thread may try to acquire 4425 // the same provider at the same time. When this happens, we want to ensure 4426 // that the first one wins. 4427 // Note that we cannot hold the lock while acquiring and installing the 4428 // provider since it might take a long time to run and it could also potentially 4429 // be re-entrant in the case where the provider is in the same process. 4430 IActivityManager.ContentProviderHolder holder = null; 4431 try { 4432 holder = ActivityManagerNative.getDefault().getContentProvider( 4433 getApplicationThread(), auth, userId, stable); 4434 } catch (RemoteException ex) { 4435 } 4436 if (holder == null) { 4437 Slog.e(TAG, "Failed to find provider info for " + auth); 4438 return null; 4439 } 4440 4441 // Install provider will increment the reference count for us, and break 4442 // any ties in the race. 4443 holder = installProvider(c, holder, holder.info, 4444 true /*noisy*/, holder.noReleaseNeeded, stable); 4445 return holder.provider; 4446 } 4447 4448 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 4449 if (stable) { 4450 prc.stableCount += 1; 4451 if (prc.stableCount == 1) { 4452 // We are acquiring a new stable reference on the provider. 4453 int unstableDelta; 4454 if (prc.removePending) { 4455 // We have a pending remove operation, which is holding the 4456 // last unstable reference. At this point we are converting 4457 // that unstable reference to our new stable reference. 4458 unstableDelta = -1; 4459 // Cancel the removal of the provider. 4460 if (DEBUG_PROVIDER) { 4461 Slog.v(TAG, "incProviderRef: stable " 4462 + "snatched provider from the jaws of death"); 4463 } 4464 prc.removePending = false; 4465 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4466 } else { 4467 unstableDelta = 0; 4468 } 4469 try { 4470 if (DEBUG_PROVIDER) { 4471 Slog.v(TAG, "incProviderRef Now stable - " 4472 + prc.holder.info.name + ": unstableDelta=" 4473 + unstableDelta); 4474 } 4475 ActivityManagerNative.getDefault().refContentProvider( 4476 prc.holder.connection, 1, unstableDelta); 4477 } catch (RemoteException e) { 4478 //do nothing content provider object is dead any way 4479 } 4480 } 4481 } else { 4482 prc.unstableCount += 1; 4483 if (prc.unstableCount == 1) { 4484 // We are acquiring a new unstable reference on the provider. 4485 if (prc.removePending) { 4486 // Oh look, we actually have a remove pending for the 4487 // provider, which is still holding the last unstable 4488 // reference. We just need to cancel that to take new 4489 // ownership of the reference. 4490 if (DEBUG_PROVIDER) { 4491 Slog.v(TAG, "incProviderRef: unstable " 4492 + "snatched provider from the jaws of death"); 4493 } 4494 prc.removePending = false; 4495 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4496 } else { 4497 // First unstable ref, increment our count in the 4498 // activity manager. 4499 try { 4500 if (DEBUG_PROVIDER) { 4501 Slog.v(TAG, "incProviderRef: Now unstable - " 4502 + prc.holder.info.name); 4503 } 4504 ActivityManagerNative.getDefault().refContentProvider( 4505 prc.holder.connection, 0, 1); 4506 } catch (RemoteException e) { 4507 //do nothing content provider object is dead any way 4508 } 4509 } 4510 } 4511 } 4512 } 4513 4514 public final IContentProvider acquireExistingProvider( 4515 Context c, String auth, int userId, boolean stable) { 4516 synchronized (mProviderMap) { 4517 final ProviderKey key = new ProviderKey(auth, userId); 4518 final ProviderClientRecord pr = mProviderMap.get(key); 4519 if (pr == null) { 4520 return null; 4521 } 4522 4523 IContentProvider provider = pr.mProvider; 4524 IBinder jBinder = provider.asBinder(); 4525 4526 // Only increment the ref count if we have one. If we don't then the 4527 // provider is not reference counted and never needs to be released. 4528 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4529 if (prc != null) { 4530 incProviderRefLocked(prc, stable); 4531 } 4532 return provider; 4533 } 4534 } 4535 4536 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 4537 if (provider == null) { 4538 return false; 4539 } 4540 4541 IBinder jBinder = provider.asBinder(); 4542 synchronized (mProviderMap) { 4543 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4544 if (prc == null) { 4545 // The provider has no ref count, no release is needed. 4546 return false; 4547 } 4548 4549 boolean lastRef = false; 4550 if (stable) { 4551 if (prc.stableCount == 0) { 4552 if (DEBUG_PROVIDER) Slog.v(TAG, 4553 "releaseProvider: stable ref count already 0, how?"); 4554 return false; 4555 } 4556 prc.stableCount -= 1; 4557 if (prc.stableCount == 0) { 4558 // What we do at this point depends on whether there are 4559 // any unstable refs left: if there are, we just tell the 4560 // activity manager to decrement its stable count; if there 4561 // aren't, we need to enqueue this provider to be removed, 4562 // and convert to holding a single unstable ref while 4563 // doing so. 4564 lastRef = prc.unstableCount == 0; 4565 try { 4566 if (DEBUG_PROVIDER) { 4567 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 4568 + lastRef + " - " + prc.holder.info.name); 4569 } 4570 ActivityManagerNative.getDefault().refContentProvider( 4571 prc.holder.connection, -1, lastRef ? 1 : 0); 4572 } catch (RemoteException e) { 4573 //do nothing content provider object is dead any way 4574 } 4575 } 4576 } else { 4577 if (prc.unstableCount == 0) { 4578 if (DEBUG_PROVIDER) Slog.v(TAG, 4579 "releaseProvider: unstable ref count already 0, how?"); 4580 return false; 4581 } 4582 prc.unstableCount -= 1; 4583 if (prc.unstableCount == 0) { 4584 // If this is the last reference, we need to enqueue 4585 // this provider to be removed instead of telling the 4586 // activity manager to remove it at this point. 4587 lastRef = prc.stableCount == 0; 4588 if (!lastRef) { 4589 try { 4590 if (DEBUG_PROVIDER) { 4591 Slog.v(TAG, "releaseProvider: No longer unstable - " 4592 + prc.holder.info.name); 4593 } 4594 ActivityManagerNative.getDefault().refContentProvider( 4595 prc.holder.connection, 0, -1); 4596 } catch (RemoteException e) { 4597 //do nothing content provider object is dead any way 4598 } 4599 } 4600 } 4601 } 4602 4603 if (lastRef) { 4604 if (!prc.removePending) { 4605 // Schedule the actual remove asynchronously, since we don't know the context 4606 // this will be called in. 4607 // TODO: it would be nice to post a delayed message, so 4608 // if we come back and need the same provider quickly 4609 // we will still have it available. 4610 if (DEBUG_PROVIDER) { 4611 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 4612 + prc.holder.info.name); 4613 } 4614 prc.removePending = true; 4615 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 4616 mH.sendMessage(msg); 4617 } else { 4618 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 4619 } 4620 } 4621 return true; 4622 } 4623 } 4624 4625 final void completeRemoveProvider(ProviderRefCount prc) { 4626 synchronized (mProviderMap) { 4627 if (!prc.removePending) { 4628 // There was a race! Some other client managed to acquire 4629 // the provider before the removal was completed. 4630 // Abort the removal. We will do it later. 4631 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 4632 + "provider still in use"); 4633 return; 4634 } 4635 4636 final IBinder jBinder = prc.holder.provider.asBinder(); 4637 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 4638 if (existingPrc == prc) { 4639 mProviderRefCountMap.remove(jBinder); 4640 } 4641 4642 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator(); 4643 while (iter.hasNext()) { 4644 ProviderClientRecord pr = iter.next(); 4645 IBinder myBinder = pr.mProvider.asBinder(); 4646 if (myBinder == jBinder) { 4647 iter.remove(); 4648 } 4649 } 4650 } 4651 4652 try { 4653 if (DEBUG_PROVIDER) { 4654 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 4655 + "removeContentProvider(" + prc.holder.info.name + ")"); 4656 } 4657 ActivityManagerNative.getDefault().removeContentProvider( 4658 prc.holder.connection, false); 4659 } catch (RemoteException e) { 4660 //do nothing content provider object is dead any way 4661 } 4662 } 4663 4664 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 4665 synchronized(mProviderMap) { 4666 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4667 if (prc != null) { 4668 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 4669 + provider + " " + prc.holder.info.name); 4670 mProviderRefCountMap.remove(provider); 4671 if (prc.client != null && prc.client.mNames != null) { 4672 for (String name : prc.client.mNames) { 4673 ProviderClientRecord pr = mProviderMap.get(name); 4674 if (pr != null && pr.mProvider.asBinder() == provider) { 4675 Slog.i(TAG, "Removing dead content provider: " + name); 4676 mProviderMap.remove(name); 4677 } 4678 } 4679 } 4680 if (fromClient) { 4681 // We found out about this due to execution in our client 4682 // code. Tell the activity manager about it now, to ensure 4683 // that the next time we go to do anything with the provider 4684 // it knows it is dead (so we don't race with its death 4685 // notification). 4686 try { 4687 ActivityManagerNative.getDefault().unstableProviderDied( 4688 prc.holder.connection); 4689 } catch (RemoteException e) { 4690 //do nothing content provider object is dead any way 4691 } 4692 } 4693 } 4694 } 4695 } 4696 4697 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 4698 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 4699 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority); 4700 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 4701 4702 final ProviderClientRecord pcr = new ProviderClientRecord( 4703 auths, provider, localProvider, holder); 4704 for (String auth : auths) { 4705 final ProviderKey key = new ProviderKey(auth, userId); 4706 final ProviderClientRecord existing = mProviderMap.get(key); 4707 if (existing != null) { 4708 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 4709 + " already published as " + auth); 4710 } else { 4711 mProviderMap.put(key, pcr); 4712 } 4713 } 4714 return pcr; 4715 } 4716 4717 /** 4718 * Installs the provider. 4719 * 4720 * Providers that are local to the process or that come from the system server 4721 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 4722 * Other remote providers are reference counted. The initial reference count 4723 * for all reference counted providers is one. Providers that are not reference 4724 * counted do not have a reference count (at all). 4725 * 4726 * This method detects when a provider has already been installed. When this happens, 4727 * it increments the reference count of the existing provider (if appropriate) 4728 * and returns the existing provider. This can happen due to concurrent 4729 * attempts to acquire the same provider. 4730 */ 4731 private IActivityManager.ContentProviderHolder installProvider(Context context, 4732 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 4733 boolean noisy, boolean noReleaseNeeded, boolean stable) { 4734 ContentProvider localProvider = null; 4735 IContentProvider provider; 4736 if (holder == null || holder.provider == null) { 4737 if (DEBUG_PROVIDER || noisy) { 4738 Slog.d(TAG, "Loading provider " + info.authority + ": " 4739 + info.name); 4740 } 4741 Context c = null; 4742 ApplicationInfo ai = info.applicationInfo; 4743 if (context.getPackageName().equals(ai.packageName)) { 4744 c = context; 4745 } else if (mInitialApplication != null && 4746 mInitialApplication.getPackageName().equals(ai.packageName)) { 4747 c = mInitialApplication; 4748 } else { 4749 try { 4750 c = context.createPackageContext(ai.packageName, 4751 Context.CONTEXT_INCLUDE_CODE); 4752 } catch (PackageManager.NameNotFoundException e) { 4753 // Ignore 4754 } 4755 } 4756 if (c == null) { 4757 Slog.w(TAG, "Unable to get context for package " + 4758 ai.packageName + 4759 " while loading content provider " + 4760 info.name); 4761 return null; 4762 } 4763 try { 4764 final java.lang.ClassLoader cl = c.getClassLoader(); 4765 localProvider = (ContentProvider)cl. 4766 loadClass(info.name).newInstance(); 4767 provider = localProvider.getIContentProvider(); 4768 if (provider == null) { 4769 Slog.e(TAG, "Failed to instantiate class " + 4770 info.name + " from sourceDir " + 4771 info.applicationInfo.sourceDir); 4772 return null; 4773 } 4774 if (DEBUG_PROVIDER) Slog.v( 4775 TAG, "Instantiating local provider " + info.name); 4776 // XXX Need to create the correct context for this provider. 4777 localProvider.attachInfo(c, info); 4778 } catch (java.lang.Exception e) { 4779 if (!mInstrumentation.onException(null, e)) { 4780 throw new RuntimeException( 4781 "Unable to get provider " + info.name 4782 + ": " + e.toString(), e); 4783 } 4784 return null; 4785 } 4786 } else { 4787 provider = holder.provider; 4788 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 4789 + info.name); 4790 } 4791 4792 IActivityManager.ContentProviderHolder retHolder; 4793 4794 synchronized (mProviderMap) { 4795 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 4796 + " / " + info.name); 4797 IBinder jBinder = provider.asBinder(); 4798 if (localProvider != null) { 4799 ComponentName cname = new ComponentName(info.packageName, info.name); 4800 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 4801 if (pr != null) { 4802 if (DEBUG_PROVIDER) { 4803 Slog.v(TAG, "installProvider: lost the race, " 4804 + "using existing local provider"); 4805 } 4806 provider = pr.mProvider; 4807 } else { 4808 holder = new IActivityManager.ContentProviderHolder(info); 4809 holder.provider = provider; 4810 holder.noReleaseNeeded = true; 4811 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 4812 mLocalProviders.put(jBinder, pr); 4813 mLocalProvidersByName.put(cname, pr); 4814 } 4815 retHolder = pr.mHolder; 4816 } else { 4817 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4818 if (prc != null) { 4819 if (DEBUG_PROVIDER) { 4820 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 4821 } 4822 // We need to transfer our new reference to the existing 4823 // ref count, releasing the old one... but only if 4824 // release is needed (that is, it is not running in the 4825 // system process). 4826 if (!noReleaseNeeded) { 4827 incProviderRefLocked(prc, stable); 4828 try { 4829 ActivityManagerNative.getDefault().removeContentProvider( 4830 holder.connection, stable); 4831 } catch (RemoteException e) { 4832 //do nothing content provider object is dead any way 4833 } 4834 } 4835 } else { 4836 ProviderClientRecord client = installProviderAuthoritiesLocked( 4837 provider, localProvider, holder); 4838 if (noReleaseNeeded) { 4839 prc = new ProviderRefCount(holder, client, 1000, 1000); 4840 } else { 4841 prc = stable 4842 ? new ProviderRefCount(holder, client, 1, 0) 4843 : new ProviderRefCount(holder, client, 0, 1); 4844 } 4845 mProviderRefCountMap.put(jBinder, prc); 4846 } 4847 retHolder = prc.holder; 4848 } 4849 } 4850 4851 return retHolder; 4852 } 4853 4854 private void attach(boolean system) { 4855 sThreadLocal.set(this); 4856 mSystemThread = system; 4857 if (!system) { 4858 ViewRootImpl.addFirstDrawHandler(new Runnable() { 4859 public void run() { 4860 ensureJitEnabled(); 4861 } 4862 }); 4863 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 4864 UserHandle.myUserId()); 4865 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 4866 IActivityManager mgr = ActivityManagerNative.getDefault(); 4867 try { 4868 mgr.attachApplication(mAppThread); 4869 } catch (RemoteException ex) { 4870 // Ignore 4871 } 4872 } else { 4873 // Don't set application object here -- if the system crashes, 4874 // we can't display an alert, we just want to die die die. 4875 android.ddm.DdmHandleAppName.setAppName("system_process", 4876 UserHandle.myUserId()); 4877 try { 4878 mInstrumentation = new Instrumentation(); 4879 ContextImpl context = new ContextImpl(); 4880 context.init(getSystemContext().mPackageInfo, null, this); 4881 Application app = Instrumentation.newApplication(Application.class, context); 4882 mAllApplications.add(app); 4883 mInitialApplication = app; 4884 app.onCreate(); 4885 } catch (Exception e) { 4886 throw new RuntimeException( 4887 "Unable to instantiate Application():" + e.toString(), e); 4888 } 4889 } 4890 4891 // add dropbox logging to libcore 4892 DropBox.setReporter(new DropBoxReporter()); 4893 4894 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 4895 public void onConfigurationChanged(Configuration newConfig) { 4896 synchronized (mPackages) { 4897 // We need to apply this change to the resources 4898 // immediately, because upon returning the view 4899 // hierarchy will be informed about it. 4900 if (applyConfigurationToResourcesLocked(newConfig, null)) { 4901 // This actually changed the resources! Tell 4902 // everyone about it. 4903 if (mPendingConfiguration == null || 4904 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 4905 mPendingConfiguration = newConfig; 4906 4907 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig); 4908 } 4909 } 4910 } 4911 } 4912 public void onLowMemory() { 4913 } 4914 public void onTrimMemory(int level) { 4915 } 4916 }); 4917 } 4918 4919 public static ActivityThread systemMain() { 4920 HardwareRenderer.disable(true); 4921 ActivityThread thread = new ActivityThread(); 4922 thread.attach(true); 4923 return thread; 4924 } 4925 4926 public final void installSystemProviders(List<ProviderInfo> providers) { 4927 if (providers != null) { 4928 installContentProviders(mInitialApplication, providers); 4929 } 4930 } 4931 4932 public int getIntCoreSetting(String key, int defaultValue) { 4933 synchronized (mPackages) { 4934 if (mCoreSettings != null) { 4935 return mCoreSettings.getInt(key, defaultValue); 4936 } else { 4937 return defaultValue; 4938 } 4939 } 4940 } 4941 4942 private class DropBoxReporter implements DropBox.Reporter { 4943 4944 private DropBoxManager dropBox; 4945 4946 public DropBoxReporter() { 4947 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 4948 } 4949 4950 @Override 4951 public void addData(String tag, byte[] data, int flags) { 4952 dropBox.addData(tag, data, flags); 4953 } 4954 4955 @Override 4956 public void addText(String tag, String data) { 4957 dropBox.addText(tag, data); 4958 } 4959 } 4960 4961 public static void main(String[] args) { 4962 SamplingProfilerIntegration.start(); 4963 4964 // CloseGuard defaults to true and can be quite spammy. We 4965 // disable it here, but selectively enable it later (via 4966 // StrictMode) on debug builds, but using DropBox, not logs. 4967 CloseGuard.setEnabled(false); 4968 4969 Environment.initForCurrentUser(); 4970 4971 Process.setArgV0("<pre-initialized>"); 4972 4973 Looper.prepareMainLooper(); 4974 4975 ActivityThread thread = new ActivityThread(); 4976 thread.attach(false); 4977 4978 if (sMainThreadHandler == null) { 4979 sMainThreadHandler = thread.getHandler(); 4980 } 4981 4982 AsyncTask.init(); 4983 4984 if (false) { 4985 Looper.myLooper().setMessageLogging(new 4986 LogPrinter(Log.DEBUG, "ActivityThread")); 4987 } 4988 4989 Looper.loop(); 4990 4991 throw new RuntimeException("Main thread loop unexpectedly exited"); 4992 } 4993} 4994