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