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