ActivityThread.java revision bd503a4e3a1c897695f0edcf6e4aaac3a7e962c5
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, 1545 int displayId, Configuration overrideConfiguration, 1546 LoadedApk pkgInfo) { 1547 return mResourcesManager.getTopLevelResources(resDir, displayId, overrideConfiguration, 1548 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 Context baseContext = appContext; 2223 2224 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 2225 try { 2226 IActivityContainer container = 2227 ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token); 2228 final int displayId = 2229 container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId(); 2230 if (displayId > Display.DEFAULT_DISPLAY) { 2231 Display display = dm.getRealDisplay(displayId, r.token); 2232 baseContext = appContext.createDisplayContext(display); 2233 } 2234 } catch (RemoteException e) { 2235 } 2236 2237 // For debugging purposes, if the activity's package name contains the value of 2238 // the "debug.use-second-display" system property as a substring, then show 2239 // its content on a secondary display if there is one. 2240 String pkgName = SystemProperties.get("debug.second-display.pkg"); 2241 if (pkgName != null && !pkgName.isEmpty() 2242 && r.packageInfo.mPackageName.contains(pkgName)) { 2243 for (int displayId : dm.getDisplayIds()) { 2244 if (displayId != Display.DEFAULT_DISPLAY) { 2245 Display display = dm.getRealDisplay(displayId, r.token); 2246 baseContext = appContext.createDisplayContext(display); 2247 break; 2248 } 2249 } 2250 } 2251 return baseContext; 2252 } 2253 2254 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2255 // If we are getting ready to gc after going to the background, well 2256 // we are back active so skip it. 2257 unscheduleGcIdler(); 2258 2259 if (r.profileFd != null) { 2260 mProfiler.setProfiler(r.profileFile, r.profileFd); 2261 mProfiler.startProfiling(); 2262 mProfiler.autoStopProfiler = r.autoStopProfiler; 2263 } 2264 2265 // Make sure we are running with the most recent config. 2266 handleConfigurationChanged(null, null); 2267 2268 if (localLOGV) Slog.v( 2269 TAG, "Handling launch of " + r); 2270 Activity a = performLaunchActivity(r, customIntent); 2271 2272 if (a != null) { 2273 r.createdConfig = new Configuration(mConfiguration); 2274 Bundle oldState = r.state; 2275 handleResumeActivity(r.token, false, r.isForward, 2276 !r.activity.mFinished && !r.startsNotResumed); 2277 2278 if (!r.activity.mFinished && r.startsNotResumed) { 2279 // The activity manager actually wants this one to start out 2280 // paused, because it needs to be visible but isn't in the 2281 // foreground. We accomplish this by going through the 2282 // normal startup (because activities expect to go through 2283 // onResume() the first time they run, before their window 2284 // is displayed), and then pausing it. However, in this case 2285 // we do -not- need to do the full pause cycle (of freezing 2286 // and such) because the activity manager assumes it can just 2287 // retain the current state it has. 2288 try { 2289 r.activity.mCalled = false; 2290 mInstrumentation.callActivityOnPause(r.activity); 2291 // We need to keep around the original state, in case 2292 // we need to be created again. But we only do this 2293 // for pre-Honeycomb apps, which always save their state 2294 // when pausing, so we can not have them save their state 2295 // when restarting from a paused state. For HC and later, 2296 // we want to (and can) let the state be saved as the normal 2297 // part of stopping the activity. 2298 if (r.isPreHoneycomb()) { 2299 r.state = oldState; 2300 } 2301 if (!r.activity.mCalled) { 2302 throw new SuperNotCalledException( 2303 "Activity " + r.intent.getComponent().toShortString() + 2304 " did not call through to super.onPause()"); 2305 } 2306 2307 } catch (SuperNotCalledException e) { 2308 throw e; 2309 2310 } catch (Exception e) { 2311 if (!mInstrumentation.onException(r.activity, e)) { 2312 throw new RuntimeException( 2313 "Unable to pause activity " 2314 + r.intent.getComponent().toShortString() 2315 + ": " + e.toString(), e); 2316 } 2317 } 2318 r.paused = true; 2319 } 2320 } else { 2321 // If there was an error, for any reason, tell the activity 2322 // manager to stop us. 2323 try { 2324 ActivityManagerNative.getDefault() 2325 .finishActivity(r.token, Activity.RESULT_CANCELED, null); 2326 } catch (RemoteException ex) { 2327 // Ignore 2328 } 2329 } 2330 } 2331 2332 private void deliverNewIntents(ActivityClientRecord r, 2333 List<Intent> intents) { 2334 final int N = intents.size(); 2335 for (int i=0; i<N; i++) { 2336 Intent intent = intents.get(i); 2337 intent.setExtrasClassLoader(r.activity.getClassLoader()); 2338 r.activity.mFragments.noteStateNotSaved(); 2339 mInstrumentation.callActivityOnNewIntent(r.activity, intent); 2340 } 2341 } 2342 2343 public final void performNewIntents(IBinder token, 2344 List<Intent> intents) { 2345 ActivityClientRecord r = mActivities.get(token); 2346 if (r != null) { 2347 final boolean resumed = !r.paused; 2348 if (resumed) { 2349 r.activity.mTemporaryPause = true; 2350 mInstrumentation.callActivityOnPause(r.activity); 2351 } 2352 deliverNewIntents(r, intents); 2353 if (resumed) { 2354 r.activity.performResume(); 2355 r.activity.mTemporaryPause = false; 2356 } 2357 } 2358 } 2359 2360 private void handleNewIntent(NewIntentData data) { 2361 performNewIntents(data.token, data.intents); 2362 } 2363 2364 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { 2365 Bundle data = new Bundle(); 2366 ActivityClientRecord r = mActivities.get(cmd.activityToken); 2367 if (r != null) { 2368 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 2369 r.activity.onProvideAssistData(data); 2370 } 2371 if (data.isEmpty()) { 2372 data = null; 2373 } 2374 IActivityManager mgr = ActivityManagerNative.getDefault(); 2375 try { 2376 mgr.reportAssistContextExtras(cmd.requestToken, data); 2377 } catch (RemoteException e) { 2378 } 2379 } 2380 2381 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 2382 ActivityClientRecord r = mActivities.get(token); 2383 if (r != null) { 2384 r.activity.onTranslucentConversionComplete(drawComplete); 2385 } 2386 } 2387 2388 public void handleInstallProvider(ProviderInfo info) { 2389 installContentProviders(mInitialApplication, Lists.newArrayList(info)); 2390 } 2391 2392 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 2393 2394 /** 2395 * Return the Intent that's currently being handled by a 2396 * BroadcastReceiver on this thread, or null if none. 2397 * @hide 2398 */ 2399 public static Intent getIntentBeingBroadcast() { 2400 return sCurrentBroadcastIntent.get(); 2401 } 2402 2403 private void handleReceiver(ReceiverData data) { 2404 // If we are getting ready to gc after going to the background, well 2405 // we are back active so skip it. 2406 unscheduleGcIdler(); 2407 2408 String component = data.intent.getComponent().getClassName(); 2409 2410 LoadedApk packageInfo = getPackageInfoNoCheck( 2411 data.info.applicationInfo, data.compatInfo); 2412 2413 IActivityManager mgr = ActivityManagerNative.getDefault(); 2414 2415 BroadcastReceiver receiver; 2416 try { 2417 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2418 data.intent.setExtrasClassLoader(cl); 2419 data.setExtrasClassLoader(cl); 2420 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance(); 2421 } catch (Exception e) { 2422 if (DEBUG_BROADCAST) Slog.i(TAG, 2423 "Finishing failed broadcast to " + data.intent.getComponent()); 2424 data.sendFinished(mgr); 2425 throw new RuntimeException( 2426 "Unable to instantiate receiver " + component 2427 + ": " + e.toString(), e); 2428 } 2429 2430 try { 2431 Application app = packageInfo.makeApplication(false, mInstrumentation); 2432 2433 if (localLOGV) Slog.v( 2434 TAG, "Performing receive of " + data.intent 2435 + ": app=" + app 2436 + ", appName=" + app.getPackageName() 2437 + ", pkg=" + packageInfo.getPackageName() 2438 + ", comp=" + data.intent.getComponent().toShortString() 2439 + ", dir=" + packageInfo.getAppDir()); 2440 2441 ContextImpl context = (ContextImpl)app.getBaseContext(); 2442 sCurrentBroadcastIntent.set(data.intent); 2443 receiver.setPendingResult(data); 2444 receiver.onReceive(context.getReceiverRestrictedContext(), 2445 data.intent); 2446 } catch (Exception e) { 2447 if (DEBUG_BROADCAST) Slog.i(TAG, 2448 "Finishing failed broadcast to " + data.intent.getComponent()); 2449 data.sendFinished(mgr); 2450 if (!mInstrumentation.onException(receiver, e)) { 2451 throw new RuntimeException( 2452 "Unable to start receiver " + component 2453 + ": " + e.toString(), e); 2454 } 2455 } finally { 2456 sCurrentBroadcastIntent.set(null); 2457 } 2458 2459 if (receiver.getPendingResult() != null) { 2460 data.finish(); 2461 } 2462 } 2463 2464 // Instantiate a BackupAgent and tell it that it's alive 2465 private void handleCreateBackupAgent(CreateBackupAgentData data) { 2466 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 2467 2468 // Sanity check the requested target package's uid against ours 2469 try { 2470 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 2471 data.appInfo.packageName, 0, UserHandle.myUserId()); 2472 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 2473 Slog.w(TAG, "Asked to instantiate non-matching package " 2474 + data.appInfo.packageName); 2475 return; 2476 } 2477 } catch (RemoteException e) { 2478 Slog.e(TAG, "Can't reach package manager", e); 2479 return; 2480 } 2481 2482 // no longer idle; we have backup work to do 2483 unscheduleGcIdler(); 2484 2485 // instantiate the BackupAgent class named in the manifest 2486 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2487 String packageName = packageInfo.mPackageName; 2488 if (packageName == null) { 2489 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 2490 return; 2491 } 2492 2493 if (mBackupAgents.get(packageName) != null) { 2494 Slog.d(TAG, "BackupAgent " + " for " + packageName 2495 + " already exists"); 2496 return; 2497 } 2498 2499 BackupAgent agent = null; 2500 String classname = data.appInfo.backupAgentName; 2501 2502 // full backup operation but no app-supplied agent? use the default implementation 2503 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL 2504 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) { 2505 classname = "android.app.backup.FullBackupAgent"; 2506 } 2507 2508 try { 2509 IBinder binder = null; 2510 try { 2511 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 2512 2513 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2514 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 2515 2516 // set up the agent's context 2517 ContextImpl context = new ContextImpl(); 2518 context.init(packageInfo, null, this); 2519 context.setOuterContext(agent); 2520 agent.attach(context); 2521 2522 agent.onCreate(); 2523 binder = agent.onBind(); 2524 mBackupAgents.put(packageName, agent); 2525 } catch (Exception e) { 2526 // If this is during restore, fail silently; otherwise go 2527 // ahead and let the user see the crash. 2528 Slog.e(TAG, "Agent threw during creation: " + e); 2529 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE 2530 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) { 2531 throw e; 2532 } 2533 // falling through with 'binder' still null 2534 } 2535 2536 // tell the OS that we're live now 2537 try { 2538 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder); 2539 } catch (RemoteException e) { 2540 // nothing to do. 2541 } 2542 } catch (Exception e) { 2543 throw new RuntimeException("Unable to create BackupAgent " 2544 + classname + ": " + e.toString(), e); 2545 } 2546 } 2547 2548 // Tear down a BackupAgent 2549 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 2550 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 2551 2552 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2553 String packageName = packageInfo.mPackageName; 2554 BackupAgent agent = mBackupAgents.get(packageName); 2555 if (agent != null) { 2556 try { 2557 agent.onDestroy(); 2558 } catch (Exception e) { 2559 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 2560 e.printStackTrace(); 2561 } 2562 mBackupAgents.remove(packageName); 2563 } else { 2564 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 2565 } 2566 } 2567 2568 private void handleCreateService(CreateServiceData data) { 2569 // If we are getting ready to gc after going to the background, well 2570 // we are back active so skip it. 2571 unscheduleGcIdler(); 2572 2573 LoadedApk packageInfo = getPackageInfoNoCheck( 2574 data.info.applicationInfo, data.compatInfo); 2575 Service service = null; 2576 try { 2577 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2578 service = (Service) cl.loadClass(data.info.name).newInstance(); 2579 } catch (Exception e) { 2580 if (!mInstrumentation.onException(service, e)) { 2581 throw new RuntimeException( 2582 "Unable to instantiate service " + data.info.name 2583 + ": " + e.toString(), e); 2584 } 2585 } 2586 2587 try { 2588 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 2589 2590 ContextImpl context = new ContextImpl(); 2591 context.init(packageInfo, null, this); 2592 2593 Application app = packageInfo.makeApplication(false, mInstrumentation); 2594 context.setOuterContext(service); 2595 service.attach(context, this, data.info.name, data.token, app, 2596 ActivityManagerNative.getDefault()); 2597 service.onCreate(); 2598 mServices.put(data.token, service); 2599 try { 2600 ActivityManagerNative.getDefault().serviceDoneExecuting( 2601 data.token, 0, 0, 0); 2602 } catch (RemoteException e) { 2603 // nothing to do. 2604 } 2605 } catch (Exception e) { 2606 if (!mInstrumentation.onException(service, e)) { 2607 throw new RuntimeException( 2608 "Unable to create service " + data.info.name 2609 + ": " + e.toString(), e); 2610 } 2611 } 2612 } 2613 2614 private void handleBindService(BindServiceData data) { 2615 Service s = mServices.get(data.token); 2616 if (DEBUG_SERVICE) 2617 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 2618 if (s != null) { 2619 try { 2620 data.intent.setExtrasClassLoader(s.getClassLoader()); 2621 try { 2622 if (!data.rebind) { 2623 IBinder binder = s.onBind(data.intent); 2624 ActivityManagerNative.getDefault().publishService( 2625 data.token, data.intent, binder); 2626 } else { 2627 s.onRebind(data.intent); 2628 ActivityManagerNative.getDefault().serviceDoneExecuting( 2629 data.token, 0, 0, 0); 2630 } 2631 ensureJitEnabled(); 2632 } catch (RemoteException ex) { 2633 } 2634 } catch (Exception e) { 2635 if (!mInstrumentation.onException(s, e)) { 2636 throw new RuntimeException( 2637 "Unable to bind to service " + s 2638 + " with " + data.intent + ": " + e.toString(), e); 2639 } 2640 } 2641 } 2642 } 2643 2644 private void handleUnbindService(BindServiceData data) { 2645 Service s = mServices.get(data.token); 2646 if (s != null) { 2647 try { 2648 data.intent.setExtrasClassLoader(s.getClassLoader()); 2649 boolean doRebind = s.onUnbind(data.intent); 2650 try { 2651 if (doRebind) { 2652 ActivityManagerNative.getDefault().unbindFinished( 2653 data.token, data.intent, doRebind); 2654 } else { 2655 ActivityManagerNative.getDefault().serviceDoneExecuting( 2656 data.token, 0, 0, 0); 2657 } 2658 } catch (RemoteException ex) { 2659 } 2660 } catch (Exception e) { 2661 if (!mInstrumentation.onException(s, e)) { 2662 throw new RuntimeException( 2663 "Unable to unbind to service " + s 2664 + " with " + data.intent + ": " + e.toString(), e); 2665 } 2666 } 2667 } 2668 } 2669 2670 private void handleDumpService(DumpComponentInfo info) { 2671 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2672 try { 2673 Service s = mServices.get(info.token); 2674 if (s != null) { 2675 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2676 info.fd.getFileDescriptor())); 2677 s.dump(info.fd.getFileDescriptor(), pw, info.args); 2678 pw.flush(); 2679 } 2680 } finally { 2681 IoUtils.closeQuietly(info.fd); 2682 StrictMode.setThreadPolicy(oldPolicy); 2683 } 2684 } 2685 2686 private void handleDumpActivity(DumpComponentInfo info) { 2687 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2688 try { 2689 ActivityClientRecord r = mActivities.get(info.token); 2690 if (r != null && r.activity != null) { 2691 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2692 info.fd.getFileDescriptor())); 2693 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 2694 pw.flush(); 2695 } 2696 } finally { 2697 IoUtils.closeQuietly(info.fd); 2698 StrictMode.setThreadPolicy(oldPolicy); 2699 } 2700 } 2701 2702 private void handleDumpProvider(DumpComponentInfo info) { 2703 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2704 try { 2705 ProviderClientRecord r = mLocalProviders.get(info.token); 2706 if (r != null && r.mLocalProvider != null) { 2707 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 2708 info.fd.getFileDescriptor())); 2709 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 2710 pw.flush(); 2711 } 2712 } finally { 2713 IoUtils.closeQuietly(info.fd); 2714 StrictMode.setThreadPolicy(oldPolicy); 2715 } 2716 } 2717 2718 private void handleServiceArgs(ServiceArgsData data) { 2719 Service s = mServices.get(data.token); 2720 if (s != null) { 2721 try { 2722 if (data.args != null) { 2723 data.args.setExtrasClassLoader(s.getClassLoader()); 2724 } 2725 int res; 2726 if (!data.taskRemoved) { 2727 res = s.onStartCommand(data.args, data.flags, data.startId); 2728 } else { 2729 s.onTaskRemoved(data.args); 2730 res = Service.START_TASK_REMOVED_COMPLETE; 2731 } 2732 2733 QueuedWork.waitToFinish(); 2734 2735 try { 2736 ActivityManagerNative.getDefault().serviceDoneExecuting( 2737 data.token, 1, data.startId, res); 2738 } catch (RemoteException e) { 2739 // nothing to do. 2740 } 2741 ensureJitEnabled(); 2742 } catch (Exception e) { 2743 if (!mInstrumentation.onException(s, e)) { 2744 throw new RuntimeException( 2745 "Unable to start service " + s 2746 + " with " + data.args + ": " + e.toString(), e); 2747 } 2748 } 2749 } 2750 } 2751 2752 private void handleStopService(IBinder token) { 2753 Service s = mServices.remove(token); 2754 if (s != null) { 2755 try { 2756 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 2757 s.onDestroy(); 2758 Context context = s.getBaseContext(); 2759 if (context instanceof ContextImpl) { 2760 final String who = s.getClassName(); 2761 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 2762 } 2763 2764 QueuedWork.waitToFinish(); 2765 2766 try { 2767 ActivityManagerNative.getDefault().serviceDoneExecuting( 2768 token, 0, 0, 0); 2769 } catch (RemoteException e) { 2770 // nothing to do. 2771 } 2772 } catch (Exception e) { 2773 if (!mInstrumentation.onException(s, e)) { 2774 throw new RuntimeException( 2775 "Unable to stop service " + s 2776 + ": " + e.toString(), e); 2777 } 2778 } 2779 } 2780 //Slog.i(TAG, "Running services: " + mServices); 2781 } 2782 2783 public final ActivityClientRecord performResumeActivity(IBinder token, 2784 boolean clearHide) { 2785 ActivityClientRecord r = mActivities.get(token); 2786 if (localLOGV) Slog.v(TAG, "Performing resume of " + r 2787 + " finished=" + r.activity.mFinished); 2788 if (r != null && !r.activity.mFinished) { 2789 if (clearHide) { 2790 r.hideForNow = false; 2791 r.activity.mStartedActivity = false; 2792 } 2793 try { 2794 r.activity.mFragments.noteStateNotSaved(); 2795 if (r.pendingIntents != null) { 2796 deliverNewIntents(r, r.pendingIntents); 2797 r.pendingIntents = null; 2798 } 2799 if (r.pendingResults != null) { 2800 deliverResults(r, r.pendingResults); 2801 r.pendingResults = null; 2802 } 2803 r.activity.performResume(); 2804 2805 EventLog.writeEvent(LOG_ON_RESUME_CALLED, 2806 UserHandle.myUserId(), r.activity.getComponentName().getClassName()); 2807 2808 r.paused = false; 2809 r.stopped = false; 2810 r.state = null; 2811 } catch (Exception e) { 2812 if (!mInstrumentation.onException(r.activity, e)) { 2813 throw new RuntimeException( 2814 "Unable to resume activity " 2815 + r.intent.getComponent().toShortString() 2816 + ": " + e.toString(), e); 2817 } 2818 } 2819 } 2820 return r; 2821 } 2822 2823 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) { 2824 if (r.mPendingRemoveWindow != null) { 2825 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow); 2826 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken(); 2827 if (wtoken != null) { 2828 WindowManagerGlobal.getInstance().closeAll(wtoken, 2829 r.activity.getClass().getName(), "Activity"); 2830 } 2831 } 2832 r.mPendingRemoveWindow = null; 2833 r.mPendingRemoveWindowManager = null; 2834 } 2835 2836 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, 2837 boolean reallyResume) { 2838 // If we are getting ready to gc after going to the background, well 2839 // we are back active so skip it. 2840 unscheduleGcIdler(); 2841 2842 ActivityClientRecord r = performResumeActivity(token, clearHide); 2843 2844 if (r != null) { 2845 final Activity a = r.activity; 2846 2847 if (localLOGV) Slog.v( 2848 TAG, "Resume " + r + " started activity: " + 2849 a.mStartedActivity + ", hideForNow: " + r.hideForNow 2850 + ", finished: " + a.mFinished); 2851 2852 final int forwardBit = isForward ? 2853 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 2854 2855 // If the window hasn't yet been added to the window manager, 2856 // and this guy didn't finish itself or start another activity, 2857 // then go ahead and add the window. 2858 boolean willBeVisible = !a.mStartedActivity; 2859 if (!willBeVisible) { 2860 try { 2861 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( 2862 a.getActivityToken()); 2863 } catch (RemoteException e) { 2864 } 2865 } 2866 if (r.window == null && !a.mFinished && willBeVisible) { 2867 r.window = r.activity.getWindow(); 2868 View decor = r.window.getDecorView(); 2869 decor.setVisibility(View.INVISIBLE); 2870 ViewManager wm = a.getWindowManager(); 2871 WindowManager.LayoutParams l = r.window.getAttributes(); 2872 a.mDecor = decor; 2873 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 2874 l.softInputMode |= forwardBit; 2875 if (a.mVisibleFromClient) { 2876 a.mWindowAdded = true; 2877 wm.addView(decor, l); 2878 } 2879 2880 // If the window has already been added, but during resume 2881 // we started another activity, then don't yet make the 2882 // window visible. 2883 } else if (!willBeVisible) { 2884 if (localLOGV) Slog.v( 2885 TAG, "Launch " + r + " mStartedActivity set"); 2886 r.hideForNow = true; 2887 } 2888 2889 // Get rid of anything left hanging around. 2890 cleanUpPendingRemoveWindows(r); 2891 2892 // The window is now visible if it has been added, we are not 2893 // simply finishing, and we are not starting another activity. 2894 if (!r.activity.mFinished && willBeVisible 2895 && r.activity.mDecor != null && !r.hideForNow) { 2896 if (r.newConfig != null) { 2897 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 2898 + r.activityInfo.name + " with newConfig " + r.newConfig); 2899 performConfigurationChanged(r.activity, r.newConfig); 2900 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 2901 r.newConfig = null; 2902 } 2903 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 2904 + isForward); 2905 WindowManager.LayoutParams l = r.window.getAttributes(); 2906 if ((l.softInputMode 2907 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 2908 != forwardBit) { 2909 l.softInputMode = (l.softInputMode 2910 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 2911 | forwardBit; 2912 if (r.activity.mVisibleFromClient) { 2913 ViewManager wm = a.getWindowManager(); 2914 View decor = r.window.getDecorView(); 2915 wm.updateViewLayout(decor, l); 2916 } 2917 } 2918 r.activity.mVisibleFromServer = true; 2919 mNumVisibleActivities++; 2920 if (r.activity.mVisibleFromClient) { 2921 r.activity.makeVisible(); 2922 } 2923 } 2924 2925 if (!r.onlyLocalRequest) { 2926 r.nextIdle = mNewActivities; 2927 mNewActivities = r; 2928 if (localLOGV) Slog.v( 2929 TAG, "Scheduling idle handler for " + r); 2930 Looper.myQueue().addIdleHandler(new Idler()); 2931 } 2932 r.onlyLocalRequest = false; 2933 2934 // Tell the activity manager we have resumed. 2935 if (reallyResume) { 2936 try { 2937 ActivityManagerNative.getDefault().activityResumed(token); 2938 } catch (RemoteException ex) { 2939 } 2940 } 2941 2942 } else { 2943 // If an exception was thrown when trying to resume, then 2944 // just end this activity. 2945 try { 2946 ActivityManagerNative.getDefault() 2947 .finishActivity(token, Activity.RESULT_CANCELED, null); 2948 } catch (RemoteException ex) { 2949 } 2950 } 2951 } 2952 2953 private int mThumbnailWidth = -1; 2954 private int mThumbnailHeight = -1; 2955 private Bitmap mAvailThumbnailBitmap = null; 2956 private Canvas mThumbnailCanvas = null; 2957 2958 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 2959 Bitmap thumbnail = mAvailThumbnailBitmap; 2960 try { 2961 if (thumbnail == null) { 2962 int w = mThumbnailWidth; 2963 int h; 2964 if (w < 0) { 2965 Resources res = r.activity.getResources(); 2966 mThumbnailHeight = h = 2967 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2968 2969 mThumbnailWidth = w = 2970 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2971 } else { 2972 h = mThumbnailHeight; 2973 } 2974 2975 // On platforms where we don't want thumbnails, set dims to (0,0) 2976 if ((w > 0) && (h > 0)) { 2977 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 2978 w, h, THUMBNAIL_FORMAT); 2979 thumbnail.eraseColor(0); 2980 } 2981 } 2982 2983 if (thumbnail != null) { 2984 Canvas cv = mThumbnailCanvas; 2985 if (cv == null) { 2986 mThumbnailCanvas = cv = new Canvas(); 2987 } 2988 2989 cv.setBitmap(thumbnail); 2990 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 2991 mAvailThumbnailBitmap = thumbnail; 2992 thumbnail = null; 2993 } 2994 cv.setBitmap(null); 2995 } 2996 2997 } catch (Exception e) { 2998 if (!mInstrumentation.onException(r.activity, e)) { 2999 throw new RuntimeException( 3000 "Unable to create thumbnail of " 3001 + r.intent.getComponent().toShortString() 3002 + ": " + e.toString(), e); 3003 } 3004 thumbnail = null; 3005 } 3006 3007 return thumbnail; 3008 } 3009 3010 private void handlePauseActivity(IBinder token, boolean finished, 3011 boolean userLeaving, int configChanges) { 3012 ActivityClientRecord r = mActivities.get(token); 3013 if (r != null) { 3014 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3015 if (userLeaving) { 3016 performUserLeavingActivity(r); 3017 } 3018 3019 r.activity.mConfigChangeFlags |= configChanges; 3020 performPauseActivity(token, finished, r.isPreHoneycomb()); 3021 3022 // Make sure any pending writes are now committed. 3023 if (r.isPreHoneycomb()) { 3024 QueuedWork.waitToFinish(); 3025 } 3026 3027 // Tell the activity manager we have paused. 3028 try { 3029 ActivityManagerNative.getDefault().activityPaused(token); 3030 } catch (RemoteException ex) { 3031 } 3032 } 3033 } 3034 3035 final void performUserLeavingActivity(ActivityClientRecord r) { 3036 mInstrumentation.callActivityOnUserLeaving(r.activity); 3037 } 3038 3039 final Bundle performPauseActivity(IBinder token, boolean finished, 3040 boolean saveState) { 3041 ActivityClientRecord r = mActivities.get(token); 3042 return r != null ? performPauseActivity(r, finished, saveState) : null; 3043 } 3044 3045 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3046 boolean saveState) { 3047 if (r.paused) { 3048 if (r.activity.mFinished) { 3049 // If we are finishing, we won't call onResume() in certain cases. 3050 // So here we likewise don't want to call onPause() if the activity 3051 // isn't resumed. 3052 return null; 3053 } 3054 RuntimeException e = new RuntimeException( 3055 "Performing pause of activity that is not resumed: " 3056 + r.intent.getComponent().toShortString()); 3057 Slog.e(TAG, e.getMessage(), e); 3058 } 3059 Bundle state = null; 3060 if (finished) { 3061 r.activity.mFinished = true; 3062 } 3063 try { 3064 // Next have the activity save its current state and managed dialogs... 3065 if (!r.activity.mFinished && saveState) { 3066 state = new Bundle(); 3067 state.setAllowFds(false); 3068 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 3069 r.state = state; 3070 } 3071 // Now we are idle. 3072 r.activity.mCalled = false; 3073 mInstrumentation.callActivityOnPause(r.activity); 3074 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3075 r.activity.getComponentName().getClassName()); 3076 if (!r.activity.mCalled) { 3077 throw new SuperNotCalledException( 3078 "Activity " + r.intent.getComponent().toShortString() + 3079 " did not call through to super.onPause()"); 3080 } 3081 3082 } catch (SuperNotCalledException e) { 3083 throw e; 3084 3085 } catch (Exception e) { 3086 if (!mInstrumentation.onException(r.activity, e)) { 3087 throw new RuntimeException( 3088 "Unable to pause activity " 3089 + r.intent.getComponent().toShortString() 3090 + ": " + e.toString(), e); 3091 } 3092 } 3093 r.paused = true; 3094 3095 // Notify any outstanding on paused listeners 3096 ArrayList<OnActivityPausedListener> listeners; 3097 synchronized (mOnPauseListeners) { 3098 listeners = mOnPauseListeners.remove(r.activity); 3099 } 3100 int size = (listeners != null ? listeners.size() : 0); 3101 for (int i = 0; i < size; i++) { 3102 listeners.get(i).onPaused(r.activity); 3103 } 3104 3105 return state; 3106 } 3107 3108 final void performStopActivity(IBinder token, boolean saveState) { 3109 ActivityClientRecord r = mActivities.get(token); 3110 performStopActivityInner(r, null, false, saveState); 3111 } 3112 3113 private static class StopInfo implements Runnable { 3114 ActivityClientRecord activity; 3115 Bundle state; 3116 Bitmap thumbnail; 3117 CharSequence description; 3118 3119 @Override public void run() { 3120 // Tell activity manager we have been stopped. 3121 try { 3122 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3123 ActivityManagerNative.getDefault().activityStopped( 3124 activity.token, state, thumbnail, description); 3125 } catch (RemoteException ex) { 3126 } 3127 } 3128 } 3129 3130 private static final class ProviderRefCount { 3131 public final IActivityManager.ContentProviderHolder holder; 3132 public final ProviderClientRecord client; 3133 public int stableCount; 3134 public int unstableCount; 3135 3136 // When this is set, the stable and unstable ref counts are 0 and 3137 // we have a pending operation scheduled to remove the ref count 3138 // from the activity manager. On the activity manager we are still 3139 // holding an unstable ref, though it is not reflected in the counts 3140 // here. 3141 public boolean removePending; 3142 3143 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3144 ProviderClientRecord inClient, int sCount, int uCount) { 3145 holder = inHolder; 3146 client = inClient; 3147 stableCount = sCount; 3148 unstableCount = uCount; 3149 } 3150 } 3151 3152 /** 3153 * Core implementation of stopping an activity. Note this is a little 3154 * tricky because the server's meaning of stop is slightly different 3155 * than our client -- for the server, stop means to save state and give 3156 * it the result when it is done, but the window may still be visible. 3157 * For the client, we want to call onStop()/onStart() to indicate when 3158 * the activity's UI visibillity changes. 3159 */ 3160 private void performStopActivityInner(ActivityClientRecord r, 3161 StopInfo info, boolean keepShown, boolean saveState) { 3162 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3163 Bundle state = null; 3164 if (r != null) { 3165 if (!keepShown && r.stopped) { 3166 if (r.activity.mFinished) { 3167 // If we are finishing, we won't call onResume() in certain 3168 // cases. So here we likewise don't want to call onStop() 3169 // if the activity isn't resumed. 3170 return; 3171 } 3172 RuntimeException e = new RuntimeException( 3173 "Performing stop of activity that is not resumed: " 3174 + r.intent.getComponent().toShortString()); 3175 Slog.e(TAG, e.getMessage(), e); 3176 } 3177 3178 if (info != null) { 3179 try { 3180 // First create a thumbnail for the activity... 3181 // For now, don't create the thumbnail here; we are 3182 // doing that by doing a screen snapshot. 3183 info.thumbnail = null; //createThumbnailBitmap(r); 3184 info.description = r.activity.onCreateDescription(); 3185 } catch (Exception e) { 3186 if (!mInstrumentation.onException(r.activity, e)) { 3187 throw new RuntimeException( 3188 "Unable to save state of activity " 3189 + r.intent.getComponent().toShortString() 3190 + ": " + e.toString(), e); 3191 } 3192 } 3193 } 3194 3195 // Next have the activity save its current state and managed dialogs... 3196 if (!r.activity.mFinished && saveState) { 3197 if (r.state == null) { 3198 state = new Bundle(); 3199 state.setAllowFds(false); 3200 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 3201 r.state = state; 3202 } else { 3203 state = r.state; 3204 } 3205 } 3206 3207 if (!keepShown) { 3208 try { 3209 // Now we are idle. 3210 r.activity.performStop(); 3211 } catch (Exception e) { 3212 if (!mInstrumentation.onException(r.activity, e)) { 3213 throw new RuntimeException( 3214 "Unable to stop activity " 3215 + r.intent.getComponent().toShortString() 3216 + ": " + e.toString(), e); 3217 } 3218 } 3219 r.stopped = true; 3220 } 3221 3222 r.paused = true; 3223 } 3224 } 3225 3226 private void updateVisibility(ActivityClientRecord r, boolean show) { 3227 View v = r.activity.mDecor; 3228 if (v != null) { 3229 if (show) { 3230 if (!r.activity.mVisibleFromServer) { 3231 r.activity.mVisibleFromServer = true; 3232 mNumVisibleActivities++; 3233 if (r.activity.mVisibleFromClient) { 3234 r.activity.makeVisible(); 3235 } 3236 } 3237 if (r.newConfig != null) { 3238 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3239 + r.activityInfo.name + " with new config " + r.newConfig); 3240 performConfigurationChanged(r.activity, r.newConfig); 3241 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 3242 r.newConfig = null; 3243 } 3244 } else { 3245 if (r.activity.mVisibleFromServer) { 3246 r.activity.mVisibleFromServer = false; 3247 mNumVisibleActivities--; 3248 v.setVisibility(View.INVISIBLE); 3249 } 3250 } 3251 } 3252 } 3253 3254 private void handleStopActivity(IBinder token, boolean show, int configChanges) { 3255 ActivityClientRecord r = mActivities.get(token); 3256 r.activity.mConfigChangeFlags |= configChanges; 3257 3258 StopInfo info = new StopInfo(); 3259 performStopActivityInner(r, info, show, true); 3260 3261 if (localLOGV) Slog.v( 3262 TAG, "Finishing stop of " + r + ": show=" + show 3263 + " win=" + r.window); 3264 3265 updateVisibility(r, show); 3266 3267 // Make sure any pending writes are now committed. 3268 if (!r.isPreHoneycomb()) { 3269 QueuedWork.waitToFinish(); 3270 } 3271 3272 // Schedule the call to tell the activity manager we have 3273 // stopped. We don't do this immediately, because we want to 3274 // have a chance for any other pending work (in particular memory 3275 // trim requests) to complete before you tell the activity 3276 // manager to proceed and allow us to go fully into the background. 3277 info.activity = r; 3278 info.state = r.state; 3279 mH.post(info); 3280 } 3281 3282 final void performRestartActivity(IBinder token) { 3283 ActivityClientRecord r = mActivities.get(token); 3284 if (r.stopped) { 3285 r.activity.performRestart(); 3286 r.stopped = false; 3287 } 3288 } 3289 3290 private void handleWindowVisibility(IBinder token, boolean show) { 3291 ActivityClientRecord r = mActivities.get(token); 3292 3293 if (r == null) { 3294 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3295 return; 3296 } 3297 3298 if (!show && !r.stopped) { 3299 performStopActivityInner(r, null, show, false); 3300 } else if (show && r.stopped) { 3301 // If we are getting ready to gc after going to the background, well 3302 // we are back active so skip it. 3303 unscheduleGcIdler(); 3304 3305 r.activity.performRestart(); 3306 r.stopped = false; 3307 } 3308 if (r.activity.mDecor != null) { 3309 if (false) Slog.v( 3310 TAG, "Handle window " + r + " visibility: " + show); 3311 updateVisibility(r, show); 3312 } 3313 } 3314 3315 private void handleSleeping(IBinder token, boolean sleeping) { 3316 ActivityClientRecord r = mActivities.get(token); 3317 3318 if (r == null) { 3319 Log.w(TAG, "handleSleeping: no activity for token " + token); 3320 return; 3321 } 3322 3323 if (sleeping) { 3324 if (!r.stopped && !r.isPreHoneycomb()) { 3325 try { 3326 // Now we are idle. 3327 r.activity.performStop(); 3328 } catch (Exception e) { 3329 if (!mInstrumentation.onException(r.activity, e)) { 3330 throw new RuntimeException( 3331 "Unable to stop activity " 3332 + r.intent.getComponent().toShortString() 3333 + ": " + e.toString(), e); 3334 } 3335 } 3336 r.stopped = true; 3337 } 3338 3339 // Make sure any pending writes are now committed. 3340 if (!r.isPreHoneycomb()) { 3341 QueuedWork.waitToFinish(); 3342 } 3343 3344 // Tell activity manager we slept. 3345 try { 3346 ActivityManagerNative.getDefault().activitySlept(r.token); 3347 } catch (RemoteException ex) { 3348 } 3349 } else { 3350 if (r.stopped && r.activity.mVisibleFromServer) { 3351 r.activity.performRestart(); 3352 r.stopped = false; 3353 } 3354 } 3355 } 3356 3357 private void handleSetCoreSettings(Bundle coreSettings) { 3358 synchronized (mResourcesManager) { 3359 mCoreSettings = coreSettings; 3360 } 3361 } 3362 3363 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3364 LoadedApk apk = peekPackageInfo(data.pkg, false); 3365 if (apk != null) { 3366 apk.setCompatibilityInfo(data.info); 3367 } 3368 apk = peekPackageInfo(data.pkg, true); 3369 if (apk != null) { 3370 apk.setCompatibilityInfo(data.info); 3371 } 3372 handleConfigurationChanged(mConfiguration, data.info); 3373 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3374 } 3375 3376 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3377 final int N = results.size(); 3378 for (int i=0; i<N; i++) { 3379 ResultInfo ri = results.get(i); 3380 try { 3381 if (ri.mData != null) { 3382 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3383 } 3384 if (DEBUG_RESULTS) Slog.v(TAG, 3385 "Delivering result to activity " + r + " : " + ri); 3386 r.activity.dispatchActivityResult(ri.mResultWho, 3387 ri.mRequestCode, ri.mResultCode, ri.mData); 3388 } catch (Exception e) { 3389 if (!mInstrumentation.onException(r.activity, e)) { 3390 throw new RuntimeException( 3391 "Failure delivering result " + ri + " to activity " 3392 + r.intent.getComponent().toShortString() 3393 + ": " + e.toString(), e); 3394 } 3395 } 3396 } 3397 } 3398 3399 private void handleSendResult(ResultData res) { 3400 ActivityClientRecord r = mActivities.get(res.token); 3401 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3402 if (r != null) { 3403 final boolean resumed = !r.paused; 3404 if (!r.activity.mFinished && r.activity.mDecor != null 3405 && r.hideForNow && resumed) { 3406 // We had hidden the activity because it started another 3407 // one... we have gotten a result back and we are not 3408 // paused, so make sure our window is visible. 3409 updateVisibility(r, true); 3410 } 3411 if (resumed) { 3412 try { 3413 // Now we are idle. 3414 r.activity.mCalled = false; 3415 r.activity.mTemporaryPause = true; 3416 mInstrumentation.callActivityOnPause(r.activity); 3417 if (!r.activity.mCalled) { 3418 throw new SuperNotCalledException( 3419 "Activity " + r.intent.getComponent().toShortString() 3420 + " did not call through to super.onPause()"); 3421 } 3422 } catch (SuperNotCalledException e) { 3423 throw e; 3424 } catch (Exception e) { 3425 if (!mInstrumentation.onException(r.activity, e)) { 3426 throw new RuntimeException( 3427 "Unable to pause activity " 3428 + r.intent.getComponent().toShortString() 3429 + ": " + e.toString(), e); 3430 } 3431 } 3432 } 3433 deliverResults(r, res.results); 3434 if (resumed) { 3435 r.activity.performResume(); 3436 r.activity.mTemporaryPause = false; 3437 } 3438 } 3439 } 3440 3441 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 3442 return performDestroyActivity(token, finishing, 0, false); 3443 } 3444 3445 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 3446 int configChanges, boolean getNonConfigInstance) { 3447 ActivityClientRecord r = mActivities.get(token); 3448 Class<? extends Activity> activityClass = null; 3449 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 3450 if (r != null) { 3451 activityClass = r.activity.getClass(); 3452 r.activity.mConfigChangeFlags |= configChanges; 3453 if (finishing) { 3454 r.activity.mFinished = true; 3455 } 3456 if (!r.paused) { 3457 try { 3458 r.activity.mCalled = false; 3459 mInstrumentation.callActivityOnPause(r.activity); 3460 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3461 r.activity.getComponentName().getClassName()); 3462 if (!r.activity.mCalled) { 3463 throw new SuperNotCalledException( 3464 "Activity " + safeToComponentShortString(r.intent) 3465 + " did not call through to super.onPause()"); 3466 } 3467 } catch (SuperNotCalledException e) { 3468 throw e; 3469 } catch (Exception e) { 3470 if (!mInstrumentation.onException(r.activity, e)) { 3471 throw new RuntimeException( 3472 "Unable to pause activity " 3473 + safeToComponentShortString(r.intent) 3474 + ": " + e.toString(), e); 3475 } 3476 } 3477 r.paused = true; 3478 } 3479 if (!r.stopped) { 3480 try { 3481 r.activity.performStop(); 3482 } catch (SuperNotCalledException e) { 3483 throw e; 3484 } catch (Exception e) { 3485 if (!mInstrumentation.onException(r.activity, e)) { 3486 throw new RuntimeException( 3487 "Unable to stop activity " 3488 + safeToComponentShortString(r.intent) 3489 + ": " + e.toString(), e); 3490 } 3491 } 3492 r.stopped = true; 3493 } 3494 if (getNonConfigInstance) { 3495 try { 3496 r.lastNonConfigurationInstances 3497 = r.activity.retainNonConfigurationInstances(); 3498 } catch (Exception e) { 3499 if (!mInstrumentation.onException(r.activity, e)) { 3500 throw new RuntimeException( 3501 "Unable to retain activity " 3502 + r.intent.getComponent().toShortString() 3503 + ": " + e.toString(), e); 3504 } 3505 } 3506 } 3507 try { 3508 r.activity.mCalled = false; 3509 mInstrumentation.callActivityOnDestroy(r.activity); 3510 if (!r.activity.mCalled) { 3511 throw new SuperNotCalledException( 3512 "Activity " + safeToComponentShortString(r.intent) + 3513 " did not call through to super.onDestroy()"); 3514 } 3515 if (r.window != null) { 3516 r.window.closeAllPanels(); 3517 } 3518 } catch (SuperNotCalledException e) { 3519 throw e; 3520 } catch (Exception e) { 3521 if (!mInstrumentation.onException(r.activity, e)) { 3522 throw new RuntimeException( 3523 "Unable to destroy activity " + safeToComponentShortString(r.intent) 3524 + ": " + e.toString(), e); 3525 } 3526 } 3527 } 3528 mActivities.remove(token); 3529 StrictMode.decrementExpectedActivityCount(activityClass); 3530 return r; 3531 } 3532 3533 private static String safeToComponentShortString(Intent intent) { 3534 ComponentName component = intent.getComponent(); 3535 return component == null ? "[Unknown]" : component.toShortString(); 3536 } 3537 3538 private void handleDestroyActivity(IBinder token, boolean finishing, 3539 int configChanges, boolean getNonConfigInstance) { 3540 ActivityClientRecord r = performDestroyActivity(token, finishing, 3541 configChanges, getNonConfigInstance); 3542 if (r != null) { 3543 cleanUpPendingRemoveWindows(r); 3544 WindowManager wm = r.activity.getWindowManager(); 3545 View v = r.activity.mDecor; 3546 if (v != null) { 3547 if (r.activity.mVisibleFromServer) { 3548 mNumVisibleActivities--; 3549 } 3550 IBinder wtoken = v.getWindowToken(); 3551 if (r.activity.mWindowAdded) { 3552 if (r.onlyLocalRequest) { 3553 // Hold off on removing this until the new activity's 3554 // window is being added. 3555 r.mPendingRemoveWindow = v; 3556 r.mPendingRemoveWindowManager = wm; 3557 } else { 3558 wm.removeViewImmediate(v); 3559 } 3560 } 3561 if (wtoken != null && r.mPendingRemoveWindow == null) { 3562 WindowManagerGlobal.getInstance().closeAll(wtoken, 3563 r.activity.getClass().getName(), "Activity"); 3564 } 3565 r.activity.mDecor = null; 3566 } 3567 if (r.mPendingRemoveWindow == null) { 3568 // If we are delaying the removal of the activity window, then 3569 // we can't clean up all windows here. Note that we can't do 3570 // so later either, which means any windows that aren't closed 3571 // by the app will leak. Well we try to warning them a lot 3572 // about leaking windows, because that is a bug, so if they are 3573 // using this recreate facility then they get to live with leaks. 3574 WindowManagerGlobal.getInstance().closeAll(token, 3575 r.activity.getClass().getName(), "Activity"); 3576 } 3577 3578 // Mocked out contexts won't be participating in the normal 3579 // process lifecycle, but if we're running with a proper 3580 // ApplicationContext we need to have it tear down things 3581 // cleanly. 3582 Context c = r.activity.getBaseContext(); 3583 if (c instanceof ContextImpl) { 3584 ((ContextImpl) c).scheduleFinalCleanup( 3585 r.activity.getClass().getName(), "Activity"); 3586 } 3587 } 3588 if (finishing) { 3589 try { 3590 ActivityManagerNative.getDefault().activityDestroyed(token); 3591 } catch (RemoteException ex) { 3592 // If the system process has died, it's game over for everyone. 3593 } 3594 } 3595 } 3596 3597 public final void requestRelaunchActivity(IBinder token, 3598 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 3599 int configChanges, boolean notResumed, Configuration config, 3600 boolean fromServer) { 3601 ActivityClientRecord target = null; 3602 3603 synchronized (mResourcesManager) { 3604 for (int i=0; i<mRelaunchingActivities.size(); i++) { 3605 ActivityClientRecord r = mRelaunchingActivities.get(i); 3606 if (r.token == token) { 3607 target = r; 3608 if (pendingResults != null) { 3609 if (r.pendingResults != null) { 3610 r.pendingResults.addAll(pendingResults); 3611 } else { 3612 r.pendingResults = pendingResults; 3613 } 3614 } 3615 if (pendingNewIntents != null) { 3616 if (r.pendingIntents != null) { 3617 r.pendingIntents.addAll(pendingNewIntents); 3618 } else { 3619 r.pendingIntents = pendingNewIntents; 3620 } 3621 } 3622 break; 3623 } 3624 } 3625 3626 if (target == null) { 3627 target = new ActivityClientRecord(); 3628 target.token = token; 3629 target.pendingResults = pendingResults; 3630 target.pendingIntents = pendingNewIntents; 3631 if (!fromServer) { 3632 ActivityClientRecord existing = mActivities.get(token); 3633 if (existing != null) { 3634 target.startsNotResumed = existing.paused; 3635 } 3636 target.onlyLocalRequest = true; 3637 } 3638 mRelaunchingActivities.add(target); 3639 sendMessage(H.RELAUNCH_ACTIVITY, target); 3640 } 3641 3642 if (fromServer) { 3643 target.startsNotResumed = notResumed; 3644 target.onlyLocalRequest = false; 3645 } 3646 if (config != null) { 3647 target.createdConfig = config; 3648 } 3649 target.pendingConfigChanges |= configChanges; 3650 } 3651 } 3652 3653 private void handleRelaunchActivity(ActivityClientRecord tmp) { 3654 // If we are getting ready to gc after going to the background, well 3655 // we are back active so skip it. 3656 unscheduleGcIdler(); 3657 3658 Configuration changedConfig = null; 3659 int configChanges = 0; 3660 3661 // First: make sure we have the most recent configuration and most 3662 // recent version of the activity, or skip it if some previous call 3663 // had taken a more recent version. 3664 synchronized (mResourcesManager) { 3665 int N = mRelaunchingActivities.size(); 3666 IBinder token = tmp.token; 3667 tmp = null; 3668 for (int i=0; i<N; i++) { 3669 ActivityClientRecord r = mRelaunchingActivities.get(i); 3670 if (r.token == token) { 3671 tmp = r; 3672 configChanges |= tmp.pendingConfigChanges; 3673 mRelaunchingActivities.remove(i); 3674 i--; 3675 N--; 3676 } 3677 } 3678 3679 if (tmp == null) { 3680 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 3681 return; 3682 } 3683 3684 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3685 + tmp.token + " with configChanges=0x" 3686 + Integer.toHexString(configChanges)); 3687 3688 if (mPendingConfiguration != null) { 3689 changedConfig = mPendingConfiguration; 3690 mPendingConfiguration = null; 3691 } 3692 } 3693 3694 if (tmp.createdConfig != null) { 3695 // If the activity manager is passing us its current config, 3696 // assume that is really what we want regardless of what we 3697 // may have pending. 3698 if (mConfiguration == null 3699 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 3700 && mConfiguration.diff(tmp.createdConfig) != 0)) { 3701 if (changedConfig == null 3702 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 3703 changedConfig = tmp.createdConfig; 3704 } 3705 } 3706 } 3707 3708 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3709 + tmp.token + ": changedConfig=" + changedConfig); 3710 3711 // If there was a pending configuration change, execute it first. 3712 if (changedConfig != null) { 3713 mCurDefaultDisplayDpi = changedConfig.densityDpi; 3714 updateDefaultDensity(); 3715 handleConfigurationChanged(changedConfig, null); 3716 } 3717 3718 ActivityClientRecord r = mActivities.get(tmp.token); 3719 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 3720 if (r == null) { 3721 return; 3722 } 3723 3724 r.activity.mConfigChangeFlags |= configChanges; 3725 r.onlyLocalRequest = tmp.onlyLocalRequest; 3726 Intent currentIntent = r.activity.mIntent; 3727 3728 r.activity.mChangingConfigurations = true; 3729 3730 // Need to ensure state is saved. 3731 if (!r.paused) { 3732 performPauseActivity(r.token, false, r.isPreHoneycomb()); 3733 } 3734 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 3735 r.state = new Bundle(); 3736 r.state.setAllowFds(false); 3737 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 3738 } 3739 3740 handleDestroyActivity(r.token, false, configChanges, true); 3741 3742 r.activity = null; 3743 r.window = null; 3744 r.hideForNow = false; 3745 r.nextIdle = null; 3746 // Merge any pending results and pending intents; don't just replace them 3747 if (tmp.pendingResults != null) { 3748 if (r.pendingResults == null) { 3749 r.pendingResults = tmp.pendingResults; 3750 } else { 3751 r.pendingResults.addAll(tmp.pendingResults); 3752 } 3753 } 3754 if (tmp.pendingIntents != null) { 3755 if (r.pendingIntents == null) { 3756 r.pendingIntents = tmp.pendingIntents; 3757 } else { 3758 r.pendingIntents.addAll(tmp.pendingIntents); 3759 } 3760 } 3761 r.startsNotResumed = tmp.startsNotResumed; 3762 3763 handleLaunchActivity(r, currentIntent); 3764 } 3765 3766 private void handleRequestThumbnail(IBinder token) { 3767 ActivityClientRecord r = mActivities.get(token); 3768 Bitmap thumbnail = createThumbnailBitmap(r); 3769 CharSequence description = null; 3770 try { 3771 description = r.activity.onCreateDescription(); 3772 } catch (Exception e) { 3773 if (!mInstrumentation.onException(r.activity, e)) { 3774 throw new RuntimeException( 3775 "Unable to create description of activity " 3776 + r.intent.getComponent().toShortString() 3777 + ": " + e.toString(), e); 3778 } 3779 } 3780 //System.out.println("Reporting top thumbnail " + thumbnail); 3781 try { 3782 ActivityManagerNative.getDefault().reportThumbnail( 3783 token, thumbnail, description); 3784 } catch (RemoteException ex) { 3785 } 3786 } 3787 3788 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 3789 boolean allActivities, Configuration newConfig) { 3790 ArrayList<ComponentCallbacks2> callbacks 3791 = new ArrayList<ComponentCallbacks2>(); 3792 3793 synchronized (mResourcesManager) { 3794 final int NAPP = mAllApplications.size(); 3795 for (int i=0; i<NAPP; i++) { 3796 callbacks.add(mAllApplications.get(i)); 3797 } 3798 final int NACT = mActivities.size(); 3799 for (int i=0; i<NACT; i++) { 3800 ActivityClientRecord ar = mActivities.valueAt(i); 3801 Activity a = ar.activity; 3802 if (a != null) { 3803 Configuration thisConfig = applyConfigCompatMainThread( 3804 mCurDefaultDisplayDpi, newConfig, 3805 ar.packageInfo.getCompatibilityInfo()); 3806 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 3807 // If the activity is currently resumed, its configuration 3808 // needs to change right now. 3809 callbacks.add(a); 3810 } else if (thisConfig != null) { 3811 // Otherwise, we will tell it about the change 3812 // the next time it is resumed or shown. Note that 3813 // the activity manager may, before then, decide the 3814 // activity needs to be destroyed to handle its new 3815 // configuration. 3816 if (DEBUG_CONFIGURATION) { 3817 Slog.v(TAG, "Setting activity " 3818 + ar.activityInfo.name + " newConfig=" + thisConfig); 3819 } 3820 ar.newConfig = thisConfig; 3821 } 3822 } 3823 } 3824 final int NSVC = mServices.size(); 3825 for (int i=0; i<NSVC; i++) { 3826 callbacks.add(mServices.valueAt(i)); 3827 } 3828 } 3829 synchronized (mProviderMap) { 3830 final int NPRV = mLocalProviders.size(); 3831 for (int i=0; i<NPRV; i++) { 3832 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 3833 } 3834 } 3835 3836 return callbacks; 3837 } 3838 3839 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { 3840 // Only for Activity objects, check that they actually call up to their 3841 // superclass implementation. ComponentCallbacks2 is an interface, so 3842 // we check the runtime type and act accordingly. 3843 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 3844 if (activity != null) { 3845 activity.mCalled = false; 3846 } 3847 3848 boolean shouldChangeConfig = false; 3849 if ((activity == null) || (activity.mCurrentConfig == null)) { 3850 shouldChangeConfig = true; 3851 } else { 3852 3853 // If the new config is the same as the config this Activity 3854 // is already running with then don't bother calling 3855 // onConfigurationChanged 3856 int diff = activity.mCurrentConfig.diff(config); 3857 if (diff != 0) { 3858 // If this activity doesn't handle any of the config changes 3859 // then don't bother calling onConfigurationChanged as we're 3860 // going to destroy it. 3861 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) { 3862 shouldChangeConfig = true; 3863 } 3864 } 3865 } 3866 3867 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 3868 + ": shouldChangeConfig=" + shouldChangeConfig); 3869 if (shouldChangeConfig) { 3870 cb.onConfigurationChanged(config); 3871 3872 if (activity != null) { 3873 if (!activity.mCalled) { 3874 throw new SuperNotCalledException( 3875 "Activity " + activity.getLocalClassName() + 3876 " did not call through to super.onConfigurationChanged()"); 3877 } 3878 activity.mConfigChangeFlags = 0; 3879 activity.mCurrentConfig = new Configuration(config); 3880 } 3881 } 3882 } 3883 3884 public final void applyConfigurationToResources(Configuration config) { 3885 synchronized (mResourcesManager) { 3886 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 3887 } 3888 } 3889 3890 final Configuration applyCompatConfiguration(int displayDensity) { 3891 Configuration config = mConfiguration; 3892 if (mCompatConfiguration == null) { 3893 mCompatConfiguration = new Configuration(); 3894 } 3895 mCompatConfiguration.setTo(mConfiguration); 3896 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { 3897 config = mCompatConfiguration; 3898 } 3899 return config; 3900 } 3901 3902 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 3903 3904 int configDiff = 0; 3905 3906 synchronized (mResourcesManager) { 3907 if (mPendingConfiguration != null) { 3908 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 3909 config = mPendingConfiguration; 3910 mCurDefaultDisplayDpi = config.densityDpi; 3911 updateDefaultDensity(); 3912 } 3913 mPendingConfiguration = null; 3914 } 3915 3916 if (config == null) { 3917 return; 3918 } 3919 3920 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 3921 + config); 3922 3923 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 3924 3925 if (mConfiguration == null) { 3926 mConfiguration = new Configuration(); 3927 } 3928 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 3929 return; 3930 } 3931 configDiff = mConfiguration.diff(config); 3932 mConfiguration.updateFrom(config); 3933 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 3934 } 3935 3936 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 3937 3938 // Cleanup hardware accelerated stuff 3939 WindowManagerGlobal.getInstance().trimLocalMemory(); 3940 3941 freeTextLayoutCachesIfNeeded(configDiff); 3942 3943 if (callbacks != null) { 3944 final int N = callbacks.size(); 3945 for (int i=0; i<N; i++) { 3946 performConfigurationChanged(callbacks.get(i), config); 3947 } 3948 } 3949 } 3950 3951 static void freeTextLayoutCachesIfNeeded(int configDiff) { 3952 if (configDiff != 0) { 3953 // Ask text layout engine to free its caches if there is a locale change 3954 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 3955 if (hasLocaleConfigChange) { 3956 Canvas.freeTextLayoutCaches(); 3957 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 3958 } 3959 } 3960 } 3961 3962 final void handleActivityConfigurationChanged(IBinder token) { 3963 ActivityClientRecord r = mActivities.get(token); 3964 if (r == null || r.activity == null) { 3965 return; 3966 } 3967 3968 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 3969 + r.activityInfo.name); 3970 3971 performConfigurationChanged(r.activity, mCompatConfiguration); 3972 3973 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 3974 } 3975 3976 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { 3977 if (start) { 3978 try { 3979 switch (profileType) { 3980 default: 3981 mProfiler.setProfiler(pcd.path, pcd.fd); 3982 mProfiler.autoStopProfiler = false; 3983 mProfiler.startProfiling(); 3984 break; 3985 } 3986 } catch (RuntimeException e) { 3987 Slog.w(TAG, "Profiling failed on path " + pcd.path 3988 + " -- can the process access this path?"); 3989 } finally { 3990 try { 3991 pcd.fd.close(); 3992 } catch (IOException e) { 3993 Slog.w(TAG, "Failure closing profile fd", e); 3994 } 3995 } 3996 } else { 3997 switch (profileType) { 3998 default: 3999 mProfiler.stopProfiling(); 4000 break; 4001 } 4002 } 4003 } 4004 4005 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4006 if (managed) { 4007 try { 4008 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4009 } catch (IOException e) { 4010 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4011 + " -- can the process access this path?"); 4012 } finally { 4013 try { 4014 dhd.fd.close(); 4015 } catch (IOException e) { 4016 Slog.w(TAG, "Failure closing profile fd", e); 4017 } 4018 } 4019 } else { 4020 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4021 } 4022 } 4023 4024 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4025 boolean hasPkgInfo = false; 4026 if (packages != null) { 4027 for (int i=packages.length-1; i>=0; i--) { 4028 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4029 if (!hasPkgInfo) { 4030 WeakReference<LoadedApk> ref; 4031 ref = mPackages.get(packages[i]); 4032 if (ref != null && ref.get() != null) { 4033 hasPkgInfo = true; 4034 } else { 4035 ref = mResourcePackages.get(packages[i]); 4036 if (ref != null && ref.get() != null) { 4037 hasPkgInfo = true; 4038 } 4039 } 4040 } 4041 mPackages.remove(packages[i]); 4042 mResourcePackages.remove(packages[i]); 4043 } 4044 } 4045 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4046 hasPkgInfo); 4047 } 4048 4049 final void handleLowMemory() { 4050 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4051 4052 final int N = callbacks.size(); 4053 for (int i=0; i<N; i++) { 4054 callbacks.get(i).onLowMemory(); 4055 } 4056 4057 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4058 if (Process.myUid() != Process.SYSTEM_UID) { 4059 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4060 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4061 } 4062 4063 // Ask graphics to free up as much as possible (font/image caches) 4064 Canvas.freeCaches(); 4065 4066 // Ask text layout engine to free also as much as possible 4067 Canvas.freeTextLayoutCaches(); 4068 4069 BinderInternal.forceGc("mem"); 4070 } 4071 4072 final void handleTrimMemory(int level) { 4073 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4074 4075 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance(); 4076 windowManager.startTrimMemory(level); 4077 4078 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4079 4080 final int N = callbacks.size(); 4081 for (int i = 0; i < N; i++) { 4082 callbacks.get(i).onTrimMemory(level); 4083 } 4084 4085 windowManager.endTrimMemory(); 4086 } 4087 4088 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4089 if (Process.isIsolated()) { 4090 // Isolated processes aren't going to do UI. 4091 return; 4092 } 4093 try { 4094 int uid = Process.myUid(); 4095 String[] packages = getPackageManager().getPackagesForUid(uid); 4096 4097 // If there are several packages in this application we won't 4098 // initialize the graphics disk caches 4099 if (packages != null && packages.length == 1) { 4100 HardwareRenderer.setupDiskCache(cacheDir); 4101 RenderScript.setupDiskCache(cacheDir); 4102 } 4103 } catch (RemoteException e) { 4104 // Ignore 4105 } 4106 } 4107 4108 private void updateDefaultDensity() { 4109 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED 4110 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE 4111 && !mDensityCompatMode) { 4112 Slog.i(TAG, "Switching default density from " 4113 + DisplayMetrics.DENSITY_DEVICE + " to " 4114 + mCurDefaultDisplayDpi); 4115 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; 4116 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4117 } 4118 } 4119 4120 private void handleBindApplication(AppBindData data) { 4121 mBoundApplication = data; 4122 mConfiguration = new Configuration(data.config); 4123 mCompatConfiguration = new Configuration(data.config); 4124 4125 mProfiler = new Profiler(); 4126 mProfiler.profileFile = data.initProfileFile; 4127 mProfiler.profileFd = data.initProfileFd; 4128 mProfiler.autoStopProfiler = data.initAutoStopProfiler; 4129 4130 // send up app name; do this *before* waiting for debugger 4131 Process.setArgV0(data.processName); 4132 android.ddm.DdmHandleAppName.setAppName(data.processName, 4133 UserHandle.myUserId()); 4134 4135 if (data.persistent) { 4136 // Persistent processes on low-memory devices do not get to 4137 // use hardware accelerated drawing, since this can add too much 4138 // overhead to the process. 4139 if (!ActivityManager.isHighEndGfx()) { 4140 HardwareRenderer.disable(false); 4141 } 4142 } 4143 4144 if (mProfiler.profileFd != null) { 4145 mProfiler.startProfiling(); 4146 } 4147 4148 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4149 // implementation to use the pool executor. Normally, we use the 4150 // serialized executor as the default. This has to happen in the 4151 // main thread so the main looper is set right. 4152 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4153 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4154 } 4155 4156 /* 4157 * Before spawning a new process, reset the time zone to be the system time zone. 4158 * This needs to be done because the system time zone could have changed after the 4159 * the spawning of this process. Without doing this this process would have the incorrect 4160 * system time zone. 4161 */ 4162 TimeZone.setDefault(null); 4163 4164 /* 4165 * Initialize the default locale in this process for the reasons we set the time zone. 4166 */ 4167 Locale.setDefault(data.config.locale); 4168 4169 /* 4170 * Update the system configuration since its preloaded and might not 4171 * reflect configuration changes. The configuration object passed 4172 * in AppBindData can be safely assumed to be up to date 4173 */ 4174 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4175 mCurDefaultDisplayDpi = data.config.densityDpi; 4176 applyCompatConfiguration(mCurDefaultDisplayDpi); 4177 4178 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4179 4180 /** 4181 * Switch this process to density compatibility mode if needed. 4182 */ 4183 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4184 == 0) { 4185 mDensityCompatMode = true; 4186 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4187 } 4188 updateDefaultDensity(); 4189 4190 final ContextImpl appContext = new ContextImpl(); 4191 appContext.init(data.info, null, this); 4192 if (!Process.isIsolated()) { 4193 final File cacheDir = appContext.getCacheDir(); 4194 4195 if (cacheDir != null) { 4196 // Provide a usable directory for temporary files 4197 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 4198 4199 setupGraphicsSupport(data.info, cacheDir); 4200 } else { 4201 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory"); 4202 } 4203 } 4204 /** 4205 * For system applications on userdebug/eng builds, log stack 4206 * traces of disk and network access to dropbox for analysis. 4207 */ 4208 if ((data.appInfo.flags & 4209 (ApplicationInfo.FLAG_SYSTEM | 4210 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4211 StrictMode.conditionallyEnableDebugLogging(); 4212 } 4213 4214 /** 4215 * For apps targetting SDK Honeycomb or later, we don't allow 4216 * network usage on the main event loop / UI thread. 4217 * 4218 * Note to those grepping: this is what ultimately throws 4219 * NetworkOnMainThreadException ... 4220 */ 4221 if (data.appInfo.targetSdkVersion > 9) { 4222 StrictMode.enableDeathOnNetwork(); 4223 } 4224 4225 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4226 // XXX should have option to change the port. 4227 Debug.changeDebugPort(8100); 4228 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4229 Slog.w(TAG, "Application " + data.info.getPackageName() 4230 + " is waiting for the debugger on port 8100..."); 4231 4232 IActivityManager mgr = ActivityManagerNative.getDefault(); 4233 try { 4234 mgr.showWaitingForDebugger(mAppThread, true); 4235 } catch (RemoteException ex) { 4236 } 4237 4238 Debug.waitForDebugger(); 4239 4240 try { 4241 mgr.showWaitingForDebugger(mAppThread, false); 4242 } catch (RemoteException ex) { 4243 } 4244 4245 } else { 4246 Slog.w(TAG, "Application " + data.info.getPackageName() 4247 + " can be debugged on port 8100..."); 4248 } 4249 } 4250 4251 // Enable OpenGL tracing if required 4252 if (data.enableOpenGlTrace) { 4253 GLUtils.setTracingLevel(1); 4254 } 4255 4256 // Allow application-generated systrace messages if we're debuggable. 4257 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0; 4258 Trace.setAppTracingAllowed(appTracingAllowed); 4259 4260 /** 4261 * Initialize the default http proxy in this process for the reasons we set the time zone. 4262 */ 4263 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 4264 if (b != null) { 4265 // In pre-boot mode (doing initial launch to collect password), not 4266 // all system is up. This includes the connectivity service, so don't 4267 // crash if we can't get it. 4268 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4269 try { 4270 ProxyProperties proxyProperties = service.getProxy(); 4271 Proxy.setHttpProxySystemProperty(proxyProperties); 4272 } catch (RemoteException e) {} 4273 } 4274 4275 if (data.instrumentationName != null) { 4276 InstrumentationInfo ii = null; 4277 try { 4278 ii = appContext.getPackageManager(). 4279 getInstrumentationInfo(data.instrumentationName, 0); 4280 } catch (PackageManager.NameNotFoundException e) { 4281 } 4282 if (ii == null) { 4283 throw new RuntimeException( 4284 "Unable to find instrumentation info for: " 4285 + data.instrumentationName); 4286 } 4287 4288 mInstrumentationAppDir = ii.sourceDir; 4289 mInstrumentationAppLibraryDir = ii.nativeLibraryDir; 4290 mInstrumentationAppPackage = ii.packageName; 4291 mInstrumentedAppDir = data.info.getAppDir(); 4292 mInstrumentedAppLibraryDir = data.info.getLibDir(); 4293 4294 ApplicationInfo instrApp = new ApplicationInfo(); 4295 instrApp.packageName = ii.packageName; 4296 instrApp.sourceDir = ii.sourceDir; 4297 instrApp.publicSourceDir = ii.publicSourceDir; 4298 instrApp.dataDir = ii.dataDir; 4299 instrApp.nativeLibraryDir = ii.nativeLibraryDir; 4300 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 4301 appContext.getClassLoader(), false, true); 4302 ContextImpl instrContext = new ContextImpl(); 4303 instrContext.init(pi, null, this); 4304 4305 try { 4306 java.lang.ClassLoader cl = instrContext.getClassLoader(); 4307 mInstrumentation = (Instrumentation) 4308 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4309 } catch (Exception e) { 4310 throw new RuntimeException( 4311 "Unable to instantiate instrumentation " 4312 + data.instrumentationName + ": " + e.toString(), e); 4313 } 4314 4315 mInstrumentation.init(this, instrContext, appContext, 4316 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, 4317 data.instrumentationUiAutomationConnection); 4318 4319 if (mProfiler.profileFile != null && !ii.handleProfiling 4320 && mProfiler.profileFd == null) { 4321 mProfiler.handlingProfiling = true; 4322 File file = new File(mProfiler.profileFile); 4323 file.getParentFile().mkdirs(); 4324 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 4325 } 4326 4327 } else { 4328 mInstrumentation = new Instrumentation(); 4329 } 4330 4331 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 4332 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 4333 } 4334 4335 // Allow disk access during application and provider setup. This could 4336 // block processing ordered broadcasts, but later processing would 4337 // probably end up doing the same disk access. 4338 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 4339 try { 4340 // If the app is being launched for full backup or restore, bring it up in 4341 // a restricted environment with the base application class. 4342 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 4343 mInitialApplication = app; 4344 4345 // don't bring up providers in restricted mode; they may depend on the 4346 // app's custom Application class 4347 if (!data.restrictedBackupMode) { 4348 List<ProviderInfo> providers = data.providers; 4349 if (providers != null) { 4350 installContentProviders(app, providers); 4351 // For process that contains content providers, we want to 4352 // ensure that the JIT is enabled "at some point". 4353 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 4354 } 4355 } 4356 4357 // Do this after providers, since instrumentation tests generally start their 4358 // test thread at this point, and we don't want that racing. 4359 try { 4360 mInstrumentation.onCreate(data.instrumentationArgs); 4361 } 4362 catch (Exception e) { 4363 throw new RuntimeException( 4364 "Exception thrown in onCreate() of " 4365 + data.instrumentationName + ": " + e.toString(), e); 4366 } 4367 4368 try { 4369 mInstrumentation.callApplicationOnCreate(app); 4370 } catch (Exception e) { 4371 if (!mInstrumentation.onException(app, e)) { 4372 throw new RuntimeException( 4373 "Unable to create application " + app.getClass().getName() 4374 + ": " + e.toString(), e); 4375 } 4376 } 4377 } finally { 4378 StrictMode.setThreadPolicy(savedPolicy); 4379 } 4380 } 4381 4382 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 4383 IActivityManager am = ActivityManagerNative.getDefault(); 4384 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 4385 && mProfiler.profileFd == null) { 4386 Debug.stopMethodTracing(); 4387 } 4388 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 4389 // + ", app thr: " + mAppThread); 4390 try { 4391 am.finishInstrumentation(mAppThread, resultCode, results); 4392 } catch (RemoteException ex) { 4393 } 4394 } 4395 4396 private void installContentProviders( 4397 Context context, List<ProviderInfo> providers) { 4398 final ArrayList<IActivityManager.ContentProviderHolder> results = 4399 new ArrayList<IActivityManager.ContentProviderHolder>(); 4400 4401 for (ProviderInfo cpi : providers) { 4402 if (DEBUG_PROVIDER) { 4403 StringBuilder buf = new StringBuilder(128); 4404 buf.append("Pub "); 4405 buf.append(cpi.authority); 4406 buf.append(": "); 4407 buf.append(cpi.name); 4408 Log.i(TAG, buf.toString()); 4409 } 4410 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 4411 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 4412 if (cph != null) { 4413 cph.noReleaseNeeded = true; 4414 results.add(cph); 4415 } 4416 } 4417 4418 try { 4419 ActivityManagerNative.getDefault().publishContentProviders( 4420 getApplicationThread(), results); 4421 } catch (RemoteException ex) { 4422 } 4423 } 4424 4425 public final IContentProvider acquireProvider( 4426 Context c, String auth, int userId, boolean stable) { 4427 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 4428 if (provider != null) { 4429 return provider; 4430 } 4431 4432 // There is a possible race here. Another thread may try to acquire 4433 // the same provider at the same time. When this happens, we want to ensure 4434 // that the first one wins. 4435 // Note that we cannot hold the lock while acquiring and installing the 4436 // provider since it might take a long time to run and it could also potentially 4437 // be re-entrant in the case where the provider is in the same process. 4438 IActivityManager.ContentProviderHolder holder = null; 4439 try { 4440 holder = ActivityManagerNative.getDefault().getContentProvider( 4441 getApplicationThread(), auth, userId, stable); 4442 } catch (RemoteException ex) { 4443 } 4444 if (holder == null) { 4445 Slog.e(TAG, "Failed to find provider info for " + auth); 4446 return null; 4447 } 4448 4449 // Install provider will increment the reference count for us, and break 4450 // any ties in the race. 4451 holder = installProvider(c, holder, holder.info, 4452 true /*noisy*/, holder.noReleaseNeeded, stable); 4453 return holder.provider; 4454 } 4455 4456 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 4457 if (stable) { 4458 prc.stableCount += 1; 4459 if (prc.stableCount == 1) { 4460 // We are acquiring a new stable reference on the provider. 4461 int unstableDelta; 4462 if (prc.removePending) { 4463 // We have a pending remove operation, which is holding the 4464 // last unstable reference. At this point we are converting 4465 // that unstable reference to our new stable reference. 4466 unstableDelta = -1; 4467 // Cancel the removal of the provider. 4468 if (DEBUG_PROVIDER) { 4469 Slog.v(TAG, "incProviderRef: stable " 4470 + "snatched provider from the jaws of death"); 4471 } 4472 prc.removePending = false; 4473 // There is a race! It fails to remove the message, which 4474 // will be handled in completeRemoveProvider(). 4475 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4476 } else { 4477 unstableDelta = 0; 4478 } 4479 try { 4480 if (DEBUG_PROVIDER) { 4481 Slog.v(TAG, "incProviderRef Now stable - " 4482 + prc.holder.info.name + ": unstableDelta=" 4483 + unstableDelta); 4484 } 4485 ActivityManagerNative.getDefault().refContentProvider( 4486 prc.holder.connection, 1, unstableDelta); 4487 } catch (RemoteException e) { 4488 //do nothing content provider object is dead any way 4489 } 4490 } 4491 } else { 4492 prc.unstableCount += 1; 4493 if (prc.unstableCount == 1) { 4494 // We are acquiring a new unstable reference on the provider. 4495 if (prc.removePending) { 4496 // Oh look, we actually have a remove pending for the 4497 // provider, which is still holding the last unstable 4498 // reference. We just need to cancel that to take new 4499 // ownership of the reference. 4500 if (DEBUG_PROVIDER) { 4501 Slog.v(TAG, "incProviderRef: unstable " 4502 + "snatched provider from the jaws of death"); 4503 } 4504 prc.removePending = false; 4505 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4506 } else { 4507 // First unstable ref, increment our count in the 4508 // activity manager. 4509 try { 4510 if (DEBUG_PROVIDER) { 4511 Slog.v(TAG, "incProviderRef: Now unstable - " 4512 + prc.holder.info.name); 4513 } 4514 ActivityManagerNative.getDefault().refContentProvider( 4515 prc.holder.connection, 0, 1); 4516 } catch (RemoteException e) { 4517 //do nothing content provider object is dead any way 4518 } 4519 } 4520 } 4521 } 4522 } 4523 4524 public final IContentProvider acquireExistingProvider( 4525 Context c, String auth, int userId, boolean stable) { 4526 synchronized (mProviderMap) { 4527 final ProviderKey key = new ProviderKey(auth, userId); 4528 final ProviderClientRecord pr = mProviderMap.get(key); 4529 if (pr == null) { 4530 return null; 4531 } 4532 4533 IContentProvider provider = pr.mProvider; 4534 IBinder jBinder = provider.asBinder(); 4535 if (!jBinder.isBinderAlive()) { 4536 // The hosting process of the provider has died; we can't 4537 // use this one. 4538 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 4539 + ": existing object's process dead"); 4540 handleUnstableProviderDiedLocked(jBinder, true); 4541 return null; 4542 } 4543 4544 // Only increment the ref count if we have one. If we don't then the 4545 // provider is not reference counted and never needs to be released. 4546 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4547 if (prc != null) { 4548 incProviderRefLocked(prc, stable); 4549 } 4550 return provider; 4551 } 4552 } 4553 4554 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 4555 if (provider == null) { 4556 return false; 4557 } 4558 4559 IBinder jBinder = provider.asBinder(); 4560 synchronized (mProviderMap) { 4561 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4562 if (prc == null) { 4563 // The provider has no ref count, no release is needed. 4564 return false; 4565 } 4566 4567 boolean lastRef = false; 4568 if (stable) { 4569 if (prc.stableCount == 0) { 4570 if (DEBUG_PROVIDER) Slog.v(TAG, 4571 "releaseProvider: stable ref count already 0, how?"); 4572 return false; 4573 } 4574 prc.stableCount -= 1; 4575 if (prc.stableCount == 0) { 4576 // What we do at this point depends on whether there are 4577 // any unstable refs left: if there are, we just tell the 4578 // activity manager to decrement its stable count; if there 4579 // aren't, we need to enqueue this provider to be removed, 4580 // and convert to holding a single unstable ref while 4581 // doing so. 4582 lastRef = prc.unstableCount == 0; 4583 try { 4584 if (DEBUG_PROVIDER) { 4585 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 4586 + lastRef + " - " + prc.holder.info.name); 4587 } 4588 ActivityManagerNative.getDefault().refContentProvider( 4589 prc.holder.connection, -1, lastRef ? 1 : 0); 4590 } catch (RemoteException e) { 4591 //do nothing content provider object is dead any way 4592 } 4593 } 4594 } else { 4595 if (prc.unstableCount == 0) { 4596 if (DEBUG_PROVIDER) Slog.v(TAG, 4597 "releaseProvider: unstable ref count already 0, how?"); 4598 return false; 4599 } 4600 prc.unstableCount -= 1; 4601 if (prc.unstableCount == 0) { 4602 // If this is the last reference, we need to enqueue 4603 // this provider to be removed instead of telling the 4604 // activity manager to remove it at this point. 4605 lastRef = prc.stableCount == 0; 4606 if (!lastRef) { 4607 try { 4608 if (DEBUG_PROVIDER) { 4609 Slog.v(TAG, "releaseProvider: No longer unstable - " 4610 + prc.holder.info.name); 4611 } 4612 ActivityManagerNative.getDefault().refContentProvider( 4613 prc.holder.connection, 0, -1); 4614 } catch (RemoteException e) { 4615 //do nothing content provider object is dead any way 4616 } 4617 } 4618 } 4619 } 4620 4621 if (lastRef) { 4622 if (!prc.removePending) { 4623 // Schedule the actual remove asynchronously, since we don't know the context 4624 // this will be called in. 4625 // TODO: it would be nice to post a delayed message, so 4626 // if we come back and need the same provider quickly 4627 // we will still have it available. 4628 if (DEBUG_PROVIDER) { 4629 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 4630 + prc.holder.info.name); 4631 } 4632 prc.removePending = true; 4633 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 4634 mH.sendMessage(msg); 4635 } else { 4636 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 4637 } 4638 } 4639 return true; 4640 } 4641 } 4642 4643 final void completeRemoveProvider(ProviderRefCount prc) { 4644 synchronized (mProviderMap) { 4645 if (!prc.removePending) { 4646 // There was a race! Some other client managed to acquire 4647 // the provider before the removal was completed. 4648 // Abort the removal. We will do it later. 4649 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 4650 + "provider still in use"); 4651 return; 4652 } 4653 4654 // More complicated race!! Some client managed to acquire the 4655 // provider and release it before the removal was completed. 4656 // Continue the removal, and abort the next remove message. 4657 prc.removePending = false; 4658 4659 final IBinder jBinder = prc.holder.provider.asBinder(); 4660 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 4661 if (existingPrc == prc) { 4662 mProviderRefCountMap.remove(jBinder); 4663 } 4664 4665 for (int i=mProviderMap.size()-1; i>=0; i--) { 4666 ProviderClientRecord pr = mProviderMap.valueAt(i); 4667 IBinder myBinder = pr.mProvider.asBinder(); 4668 if (myBinder == jBinder) { 4669 mProviderMap.removeAt(i); 4670 } 4671 } 4672 } 4673 4674 try { 4675 if (DEBUG_PROVIDER) { 4676 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 4677 + "removeContentProvider(" + prc.holder.info.name + ")"); 4678 } 4679 ActivityManagerNative.getDefault().removeContentProvider( 4680 prc.holder.connection, false); 4681 } catch (RemoteException e) { 4682 //do nothing content provider object is dead any way 4683 } 4684 } 4685 4686 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 4687 synchronized (mProviderMap) { 4688 handleUnstableProviderDiedLocked(provider, fromClient); 4689 } 4690 } 4691 4692 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 4693 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4694 if (prc != null) { 4695 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 4696 + provider + " " + prc.holder.info.name); 4697 mProviderRefCountMap.remove(provider); 4698 for (int i=mProviderMap.size()-1; i>=0; i--) { 4699 ProviderClientRecord pr = mProviderMap.valueAt(i); 4700 if (pr != null && pr.mProvider.asBinder() == provider) { 4701 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 4702 mProviderMap.removeAt(i); 4703 } 4704 } 4705 4706 if (fromClient) { 4707 // We found out about this due to execution in our client 4708 // code. Tell the activity manager about it now, to ensure 4709 // that the next time we go to do anything with the provider 4710 // it knows it is dead (so we don't race with its death 4711 // notification). 4712 try { 4713 ActivityManagerNative.getDefault().unstableProviderDied( 4714 prc.holder.connection); 4715 } catch (RemoteException e) { 4716 //do nothing content provider object is dead any way 4717 } 4718 } 4719 } 4720 } 4721 4722 final void appNotRespondingViaProvider(IBinder provider) { 4723 synchronized (mProviderMap) { 4724 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4725 if (prc != null) { 4726 try { 4727 ActivityManagerNative.getDefault() 4728 .appNotRespondingViaProvider(prc.holder.connection); 4729 } catch (RemoteException e) { 4730 } 4731 } 4732 } 4733 } 4734 4735 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 4736 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 4737 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority); 4738 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 4739 4740 final ProviderClientRecord pcr = new ProviderClientRecord( 4741 auths, provider, localProvider, holder); 4742 for (String auth : auths) { 4743 final ProviderKey key = new ProviderKey(auth, userId); 4744 final ProviderClientRecord existing = mProviderMap.get(key); 4745 if (existing != null) { 4746 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 4747 + " already published as " + auth); 4748 } else { 4749 mProviderMap.put(key, pcr); 4750 } 4751 } 4752 return pcr; 4753 } 4754 4755 /** 4756 * Installs the provider. 4757 * 4758 * Providers that are local to the process or that come from the system server 4759 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 4760 * Other remote providers are reference counted. The initial reference count 4761 * for all reference counted providers is one. Providers that are not reference 4762 * counted do not have a reference count (at all). 4763 * 4764 * This method detects when a provider has already been installed. When this happens, 4765 * it increments the reference count of the existing provider (if appropriate) 4766 * and returns the existing provider. This can happen due to concurrent 4767 * attempts to acquire the same provider. 4768 */ 4769 private IActivityManager.ContentProviderHolder installProvider(Context context, 4770 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 4771 boolean noisy, boolean noReleaseNeeded, boolean stable) { 4772 ContentProvider localProvider = null; 4773 IContentProvider provider; 4774 if (holder == null || holder.provider == null) { 4775 if (DEBUG_PROVIDER || noisy) { 4776 Slog.d(TAG, "Loading provider " + info.authority + ": " 4777 + info.name); 4778 } 4779 Context c = null; 4780 ApplicationInfo ai = info.applicationInfo; 4781 if (context.getPackageName().equals(ai.packageName)) { 4782 c = context; 4783 } else if (mInitialApplication != null && 4784 mInitialApplication.getPackageName().equals(ai.packageName)) { 4785 c = mInitialApplication; 4786 } else { 4787 try { 4788 c = context.createPackageContext(ai.packageName, 4789 Context.CONTEXT_INCLUDE_CODE); 4790 } catch (PackageManager.NameNotFoundException e) { 4791 // Ignore 4792 } 4793 } 4794 if (c == null) { 4795 Slog.w(TAG, "Unable to get context for package " + 4796 ai.packageName + 4797 " while loading content provider " + 4798 info.name); 4799 return null; 4800 } 4801 try { 4802 final java.lang.ClassLoader cl = c.getClassLoader(); 4803 localProvider = (ContentProvider)cl. 4804 loadClass(info.name).newInstance(); 4805 provider = localProvider.getIContentProvider(); 4806 if (provider == null) { 4807 Slog.e(TAG, "Failed to instantiate class " + 4808 info.name + " from sourceDir " + 4809 info.applicationInfo.sourceDir); 4810 return null; 4811 } 4812 if (DEBUG_PROVIDER) Slog.v( 4813 TAG, "Instantiating local provider " + info.name); 4814 // XXX Need to create the correct context for this provider. 4815 localProvider.attachInfo(c, info); 4816 } catch (java.lang.Exception e) { 4817 if (!mInstrumentation.onException(null, e)) { 4818 throw new RuntimeException( 4819 "Unable to get provider " + info.name 4820 + ": " + e.toString(), e); 4821 } 4822 return null; 4823 } 4824 } else { 4825 provider = holder.provider; 4826 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 4827 + info.name); 4828 } 4829 4830 IActivityManager.ContentProviderHolder retHolder; 4831 4832 synchronized (mProviderMap) { 4833 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 4834 + " / " + info.name); 4835 IBinder jBinder = provider.asBinder(); 4836 if (localProvider != null) { 4837 ComponentName cname = new ComponentName(info.packageName, info.name); 4838 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 4839 if (pr != null) { 4840 if (DEBUG_PROVIDER) { 4841 Slog.v(TAG, "installProvider: lost the race, " 4842 + "using existing local provider"); 4843 } 4844 provider = pr.mProvider; 4845 } else { 4846 holder = new IActivityManager.ContentProviderHolder(info); 4847 holder.provider = provider; 4848 holder.noReleaseNeeded = true; 4849 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 4850 mLocalProviders.put(jBinder, pr); 4851 mLocalProvidersByName.put(cname, pr); 4852 } 4853 retHolder = pr.mHolder; 4854 } else { 4855 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4856 if (prc != null) { 4857 if (DEBUG_PROVIDER) { 4858 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 4859 } 4860 // We need to transfer our new reference to the existing 4861 // ref count, releasing the old one... but only if 4862 // release is needed (that is, it is not running in the 4863 // system process). 4864 if (!noReleaseNeeded) { 4865 incProviderRefLocked(prc, stable); 4866 try { 4867 ActivityManagerNative.getDefault().removeContentProvider( 4868 holder.connection, stable); 4869 } catch (RemoteException e) { 4870 //do nothing content provider object is dead any way 4871 } 4872 } 4873 } else { 4874 ProviderClientRecord client = installProviderAuthoritiesLocked( 4875 provider, localProvider, holder); 4876 if (noReleaseNeeded) { 4877 prc = new ProviderRefCount(holder, client, 1000, 1000); 4878 } else { 4879 prc = stable 4880 ? new ProviderRefCount(holder, client, 1, 0) 4881 : new ProviderRefCount(holder, client, 0, 1); 4882 } 4883 mProviderRefCountMap.put(jBinder, prc); 4884 } 4885 retHolder = prc.holder; 4886 } 4887 } 4888 4889 return retHolder; 4890 } 4891 4892 private void attach(boolean system) { 4893 sCurrentActivityThread = this; 4894 mSystemThread = system; 4895 if (!system) { 4896 ViewRootImpl.addFirstDrawHandler(new Runnable() { 4897 @Override 4898 public void run() { 4899 ensureJitEnabled(); 4900 } 4901 }); 4902 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 4903 UserHandle.myUserId()); 4904 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 4905 IActivityManager mgr = ActivityManagerNative.getDefault(); 4906 try { 4907 mgr.attachApplication(mAppThread); 4908 } catch (RemoteException ex) { 4909 // Ignore 4910 } 4911 } else { 4912 // Don't set application object here -- if the system crashes, 4913 // we can't display an alert, we just want to die die die. 4914 android.ddm.DdmHandleAppName.setAppName("system_process", 4915 UserHandle.myUserId()); 4916 try { 4917 mInstrumentation = new Instrumentation(); 4918 ContextImpl context = new ContextImpl(); 4919 context.init(getSystemContext().mPackageInfo, null, this); 4920 Application app = Instrumentation.newApplication(Application.class, context); 4921 mAllApplications.add(app); 4922 mInitialApplication = app; 4923 app.onCreate(); 4924 } catch (Exception e) { 4925 throw new RuntimeException( 4926 "Unable to instantiate Application():" + e.toString(), e); 4927 } 4928 } 4929 4930 // add dropbox logging to libcore 4931 DropBox.setReporter(new DropBoxReporter()); 4932 4933 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 4934 @Override 4935 public void onConfigurationChanged(Configuration newConfig) { 4936 synchronized (mResourcesManager) { 4937 // We need to apply this change to the resources 4938 // immediately, because upon returning the view 4939 // hierarchy will be informed about it. 4940 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 4941 // This actually changed the resources! Tell 4942 // everyone about it. 4943 if (mPendingConfiguration == null || 4944 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 4945 mPendingConfiguration = newConfig; 4946 4947 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 4948 } 4949 } 4950 } 4951 } 4952 @Override 4953 public void onLowMemory() { 4954 } 4955 @Override 4956 public void onTrimMemory(int level) { 4957 } 4958 }); 4959 } 4960 4961 public static ActivityThread systemMain() { 4962 HardwareRenderer.disable(true); 4963 ActivityThread thread = new ActivityThread(); 4964 thread.attach(true); 4965 return thread; 4966 } 4967 4968 public final void installSystemProviders(List<ProviderInfo> providers) { 4969 if (providers != null) { 4970 installContentProviders(mInitialApplication, providers); 4971 } 4972 } 4973 4974 public int getIntCoreSetting(String key, int defaultValue) { 4975 synchronized (mResourcesManager) { 4976 if (mCoreSettings != null) { 4977 return mCoreSettings.getInt(key, defaultValue); 4978 } 4979 return defaultValue; 4980 } 4981 } 4982 4983 private static class EventLoggingReporter implements EventLogger.Reporter { 4984 @Override 4985 public void report (int code, Object... list) { 4986 EventLog.writeEvent(code, list); 4987 } 4988 } 4989 4990 private class DropBoxReporter implements DropBox.Reporter { 4991 4992 private DropBoxManager dropBox; 4993 4994 public DropBoxReporter() { 4995 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 4996 } 4997 4998 @Override 4999 public void addData(String tag, byte[] data, int flags) { 5000 dropBox.addData(tag, data, flags); 5001 } 5002 5003 @Override 5004 public void addText(String tag, String data) { 5005 dropBox.addText(tag, data); 5006 } 5007 } 5008 5009 public static void main(String[] args) { 5010 SamplingProfilerIntegration.start(); 5011 5012 // CloseGuard defaults to true and can be quite spammy. We 5013 // disable it here, but selectively enable it later (via 5014 // StrictMode) on debug builds, but using DropBox, not logs. 5015 CloseGuard.setEnabled(false); 5016 5017 Environment.initForCurrentUser(); 5018 5019 // Set the reporter for event logging in libcore 5020 EventLogger.setReporter(new EventLoggingReporter()); 5021 5022 Security.addProvider(new AndroidKeyStoreProvider()); 5023 5024 Process.setArgV0("<pre-initialized>"); 5025 5026 Looper.prepareMainLooper(); 5027 5028 ActivityThread thread = new ActivityThread(); 5029 thread.attach(false); 5030 5031 if (sMainThreadHandler == null) { 5032 sMainThreadHandler = thread.getHandler(); 5033 } 5034 5035 AsyncTask.init(); 5036 5037 if (false) { 5038 Looper.myLooper().setMessageLogging(new 5039 LogPrinter(Log.DEBUG, "ActivityThread")); 5040 } 5041 5042 Looper.loop(); 5043 5044 throw new RuntimeException("Main thread loop unexpectedly exited"); 5045 } 5046} 5047