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