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