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