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