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