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