ActivityThread.java revision 7fd239cf0a1ddc0500b51d97e0e6c3539b42639f
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 Configuration config = res.getConfiguration(); 3014 boolean useAlternateRecents = (config.smallestScreenWidthDp < 600); 3015 if (useAlternateRecents) { 3016 int wId = com.android.internal.R.dimen.recents_thumbnail_width; 3017 int hId = com.android.internal.R.dimen.recents_thumbnail_height; 3018 mThumbnailWidth = w = res.getDimensionPixelSize(wId); 3019 mThumbnailHeight = h = res.getDimensionPixelSize(hId); 3020 } else { 3021 mThumbnailHeight = h = 3022 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 3023 mThumbnailWidth = w = 3024 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 3025 } 3026 } else { 3027 h = mThumbnailHeight; 3028 } 3029 3030 // On platforms where we don't want thumbnails, set dims to (0,0) 3031 if ((w > 0) && (h > 0)) { 3032 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 3033 w, h, THUMBNAIL_FORMAT); 3034 thumbnail.eraseColor(0); 3035 } 3036 } 3037 3038 if (thumbnail != null) { 3039 Canvas cv = mThumbnailCanvas; 3040 if (cv == null) { 3041 mThumbnailCanvas = cv = new Canvas(); 3042 } 3043 3044 cv.setBitmap(thumbnail); 3045 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 3046 mAvailThumbnailBitmap = thumbnail; 3047 thumbnail = null; 3048 } 3049 cv.setBitmap(null); 3050 } 3051 3052 } catch (Exception e) { 3053 if (!mInstrumentation.onException(r.activity, e)) { 3054 throw new RuntimeException( 3055 "Unable to create thumbnail of " 3056 + r.intent.getComponent().toShortString() 3057 + ": " + e.toString(), e); 3058 } 3059 thumbnail = null; 3060 } 3061 3062 return thumbnail; 3063 } 3064 3065 private void handlePauseActivity(IBinder token, boolean finished, 3066 boolean userLeaving, int configChanges) { 3067 ActivityClientRecord r = mActivities.get(token); 3068 if (r != null) { 3069 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3070 if (userLeaving) { 3071 performUserLeavingActivity(r); 3072 } 3073 3074 r.activity.mConfigChangeFlags |= configChanges; 3075 performPauseActivity(token, finished, r.isPreHoneycomb()); 3076 3077 // Make sure any pending writes are now committed. 3078 if (r.isPreHoneycomb()) { 3079 QueuedWork.waitToFinish(); 3080 } 3081 3082 // Tell the activity manager we have paused. 3083 try { 3084 ActivityManagerNative.getDefault().activityPaused(token, r.persistentState); 3085 } catch (RemoteException ex) { 3086 } 3087 } 3088 } 3089 3090 final void performUserLeavingActivity(ActivityClientRecord r) { 3091 mInstrumentation.callActivityOnUserLeaving(r.activity); 3092 } 3093 3094 final Bundle performPauseActivity(IBinder token, boolean finished, 3095 boolean saveState) { 3096 ActivityClientRecord r = mActivities.get(token); 3097 return r != null ? performPauseActivity(r, finished, saveState) : null; 3098 } 3099 3100 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3101 boolean saveState) { 3102 if (r.paused) { 3103 if (r.activity.mFinished) { 3104 // If we are finishing, we won't call onResume() in certain cases. 3105 // So here we likewise don't want to call onPause() if the activity 3106 // isn't resumed. 3107 return null; 3108 } 3109 RuntimeException e = new RuntimeException( 3110 "Performing pause of activity that is not resumed: " 3111 + r.intent.getComponent().toShortString()); 3112 Slog.e(TAG, e.getMessage(), e); 3113 } 3114 if (finished) { 3115 r.activity.mFinished = true; 3116 } 3117 try { 3118 // Next have the activity save its current state and managed dialogs... 3119 if (!r.activity.mFinished && saveState) { 3120 callCallActivityOnSaveInstanceState(r); 3121 } 3122 // Now we are idle. 3123 r.activity.mCalled = false; 3124 mInstrumentation.callActivityOnPause(r.activity); 3125 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3126 r.activity.getComponentName().getClassName()); 3127 if (!r.activity.mCalled) { 3128 throw new SuperNotCalledException( 3129 "Activity " + r.intent.getComponent().toShortString() + 3130 " did not call through to super.onPause()"); 3131 } 3132 3133 } catch (SuperNotCalledException e) { 3134 throw e; 3135 3136 } catch (Exception e) { 3137 if (!mInstrumentation.onException(r.activity, e)) { 3138 throw new RuntimeException( 3139 "Unable to pause activity " 3140 + r.intent.getComponent().toShortString() 3141 + ": " + e.toString(), e); 3142 } 3143 } 3144 r.paused = true; 3145 3146 // Notify any outstanding on paused listeners 3147 ArrayList<OnActivityPausedListener> listeners; 3148 synchronized (mOnPauseListeners) { 3149 listeners = mOnPauseListeners.remove(r.activity); 3150 } 3151 int size = (listeners != null ? listeners.size() : 0); 3152 for (int i = 0; i < size; i++) { 3153 listeners.get(i).onPaused(r.activity); 3154 } 3155 3156 return !r.activity.mFinished && saveState ? r.state : null; 3157 } 3158 3159 final void performStopActivity(IBinder token, boolean saveState) { 3160 ActivityClientRecord r = mActivities.get(token); 3161 performStopActivityInner(r, null, false, saveState); 3162 } 3163 3164 private static class StopInfo implements Runnable { 3165 ActivityClientRecord activity; 3166 Bundle state; 3167 PersistableBundle persistentState; 3168 CharSequence description; 3169 3170 @Override public void run() { 3171 // Tell activity manager we have been stopped. 3172 try { 3173 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3174 ActivityManagerNative.getDefault().activityStopped( 3175 activity.token, state, persistentState, description); 3176 } catch (RemoteException ex) { 3177 } 3178 } 3179 } 3180 3181 private static final class ProviderRefCount { 3182 public final IActivityManager.ContentProviderHolder holder; 3183 public final ProviderClientRecord client; 3184 public int stableCount; 3185 public int unstableCount; 3186 3187 // When this is set, the stable and unstable ref counts are 0 and 3188 // we have a pending operation scheduled to remove the ref count 3189 // from the activity manager. On the activity manager we are still 3190 // holding an unstable ref, though it is not reflected in the counts 3191 // here. 3192 public boolean removePending; 3193 3194 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3195 ProviderClientRecord inClient, int sCount, int uCount) { 3196 holder = inHolder; 3197 client = inClient; 3198 stableCount = sCount; 3199 unstableCount = uCount; 3200 } 3201 } 3202 3203 /** 3204 * Core implementation of stopping an activity. Note this is a little 3205 * tricky because the server's meaning of stop is slightly different 3206 * than our client -- for the server, stop means to save state and give 3207 * it the result when it is done, but the window may still be visible. 3208 * For the client, we want to call onStop()/onStart() to indicate when 3209 * the activity's UI visibillity changes. 3210 */ 3211 private void performStopActivityInner(ActivityClientRecord r, 3212 StopInfo info, boolean keepShown, boolean saveState) { 3213 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3214 if (r != null) { 3215 if (!keepShown && r.stopped) { 3216 if (r.activity.mFinished) { 3217 // If we are finishing, we won't call onResume() in certain 3218 // cases. So here we likewise don't want to call onStop() 3219 // if the activity isn't resumed. 3220 return; 3221 } 3222 RuntimeException e = new RuntimeException( 3223 "Performing stop of activity that is not resumed: " 3224 + r.intent.getComponent().toShortString()); 3225 Slog.e(TAG, e.getMessage(), e); 3226 } 3227 3228 if (info != null) { 3229 try { 3230 // First create a thumbnail for the activity... 3231 // For now, don't create the thumbnail here; we are 3232 // doing that by doing a screen snapshot. 3233 info.description = r.activity.onCreateDescription(); 3234 } catch (Exception e) { 3235 if (!mInstrumentation.onException(r.activity, e)) { 3236 throw new RuntimeException( 3237 "Unable to save state of activity " 3238 + r.intent.getComponent().toShortString() 3239 + ": " + e.toString(), e); 3240 } 3241 } 3242 } 3243 3244 // Next have the activity save its current state and managed dialogs... 3245 if (!r.activity.mFinished && saveState) { 3246 if (r.state == null) { 3247 callCallActivityOnSaveInstanceState(r); 3248 } 3249 } 3250 3251 if (!keepShown) { 3252 try { 3253 // Now we are idle. 3254 r.activity.performStop(); 3255 } catch (Exception e) { 3256 if (!mInstrumentation.onException(r.activity, e)) { 3257 throw new RuntimeException( 3258 "Unable to stop activity " 3259 + r.intent.getComponent().toShortString() 3260 + ": " + e.toString(), e); 3261 } 3262 } 3263 r.stopped = true; 3264 } 3265 3266 r.paused = true; 3267 } 3268 } 3269 3270 private void updateVisibility(ActivityClientRecord r, boolean show) { 3271 View v = r.activity.mDecor; 3272 if (v != null) { 3273 if (show) { 3274 if (!r.activity.mVisibleFromServer) { 3275 r.activity.mVisibleFromServer = true; 3276 mNumVisibleActivities++; 3277 if (r.activity.mVisibleFromClient) { 3278 r.activity.makeVisible(); 3279 } 3280 } 3281 if (r.newConfig != null) { 3282 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3283 + r.activityInfo.name + " with new config " + r.newConfig); 3284 performConfigurationChanged(r.activity, r.newConfig); 3285 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 3286 r.newConfig = null; 3287 } 3288 } else { 3289 if (r.activity.mVisibleFromServer) { 3290 r.activity.mVisibleFromServer = false; 3291 mNumVisibleActivities--; 3292 v.setVisibility(View.INVISIBLE); 3293 } 3294 } 3295 } 3296 } 3297 3298 private void handleStopActivity(IBinder token, boolean show, int configChanges) { 3299 ActivityClientRecord r = mActivities.get(token); 3300 r.activity.mConfigChangeFlags |= configChanges; 3301 3302 StopInfo info = new StopInfo(); 3303 performStopActivityInner(r, info, show, true); 3304 3305 if (localLOGV) Slog.v( 3306 TAG, "Finishing stop of " + r + ": show=" + show 3307 + " win=" + r.window); 3308 3309 updateVisibility(r, show); 3310 3311 // Make sure any pending writes are now committed. 3312 if (!r.isPreHoneycomb()) { 3313 QueuedWork.waitToFinish(); 3314 } 3315 3316 // Schedule the call to tell the activity manager we have 3317 // stopped. We don't do this immediately, because we want to 3318 // have a chance for any other pending work (in particular memory 3319 // trim requests) to complete before you tell the activity 3320 // manager to proceed and allow us to go fully into the background. 3321 info.activity = r; 3322 info.state = r.state; 3323 info.persistentState = r.persistentState; 3324 mH.post(info); 3325 } 3326 3327 final void performRestartActivity(IBinder token) { 3328 ActivityClientRecord r = mActivities.get(token); 3329 if (r.stopped) { 3330 r.activity.performRestart(); 3331 r.stopped = false; 3332 } 3333 } 3334 3335 private void handleWindowVisibility(IBinder token, boolean show) { 3336 ActivityClientRecord r = mActivities.get(token); 3337 3338 if (r == null) { 3339 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3340 return; 3341 } 3342 3343 if (!show && !r.stopped) { 3344 performStopActivityInner(r, null, show, false); 3345 } else if (show && r.stopped) { 3346 // If we are getting ready to gc after going to the background, well 3347 // we are back active so skip it. 3348 unscheduleGcIdler(); 3349 3350 r.activity.performRestart(); 3351 r.stopped = false; 3352 } 3353 if (r.activity.mDecor != null) { 3354 if (false) Slog.v( 3355 TAG, "Handle window " + r + " visibility: " + show); 3356 updateVisibility(r, show); 3357 } 3358 } 3359 3360 private void handleSleeping(IBinder token, boolean sleeping) { 3361 ActivityClientRecord r = mActivities.get(token); 3362 3363 if (r == null) { 3364 Log.w(TAG, "handleSleeping: no activity for token " + token); 3365 return; 3366 } 3367 3368 if (sleeping) { 3369 if (!r.stopped && !r.isPreHoneycomb()) { 3370 try { 3371 // Now we are idle. 3372 r.activity.performStop(); 3373 } catch (Exception e) { 3374 if (!mInstrumentation.onException(r.activity, e)) { 3375 throw new RuntimeException( 3376 "Unable to stop activity " 3377 + r.intent.getComponent().toShortString() 3378 + ": " + e.toString(), e); 3379 } 3380 } 3381 r.stopped = true; 3382 } 3383 3384 // Make sure any pending writes are now committed. 3385 if (!r.isPreHoneycomb()) { 3386 QueuedWork.waitToFinish(); 3387 } 3388 3389 // Tell activity manager we slept. 3390 try { 3391 ActivityManagerNative.getDefault().activitySlept(r.token); 3392 } catch (RemoteException ex) { 3393 } 3394 } else { 3395 if (r.stopped && r.activity.mVisibleFromServer) { 3396 r.activity.performRestart(); 3397 r.stopped = false; 3398 } 3399 } 3400 } 3401 3402 private void handleSetCoreSettings(Bundle coreSettings) { 3403 synchronized (mResourcesManager) { 3404 mCoreSettings = coreSettings; 3405 } 3406 } 3407 3408 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3409 LoadedApk apk = peekPackageInfo(data.pkg, false); 3410 if (apk != null) { 3411 apk.setCompatibilityInfo(data.info); 3412 } 3413 apk = peekPackageInfo(data.pkg, true); 3414 if (apk != null) { 3415 apk.setCompatibilityInfo(data.info); 3416 } 3417 handleConfigurationChanged(mConfiguration, data.info); 3418 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3419 } 3420 3421 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3422 final int N = results.size(); 3423 for (int i=0; i<N; i++) { 3424 ResultInfo ri = results.get(i); 3425 try { 3426 if (ri.mData != null) { 3427 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3428 } 3429 if (DEBUG_RESULTS) Slog.v(TAG, 3430 "Delivering result to activity " + r + " : " + ri); 3431 r.activity.dispatchActivityResult(ri.mResultWho, 3432 ri.mRequestCode, ri.mResultCode, ri.mData); 3433 } catch (Exception e) { 3434 if (!mInstrumentation.onException(r.activity, e)) { 3435 throw new RuntimeException( 3436 "Failure delivering result " + ri + " to activity " 3437 + r.intent.getComponent().toShortString() 3438 + ": " + e.toString(), e); 3439 } 3440 } 3441 } 3442 } 3443 3444 private void handleSendResult(ResultData res) { 3445 ActivityClientRecord r = mActivities.get(res.token); 3446 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3447 if (r != null) { 3448 final boolean resumed = !r.paused; 3449 if (!r.activity.mFinished && r.activity.mDecor != null 3450 && r.hideForNow && resumed) { 3451 // We had hidden the activity because it started another 3452 // one... we have gotten a result back and we are not 3453 // paused, so make sure our window is visible. 3454 updateVisibility(r, true); 3455 } 3456 if (resumed) { 3457 try { 3458 // Now we are idle. 3459 r.activity.mCalled = false; 3460 r.activity.mTemporaryPause = true; 3461 mInstrumentation.callActivityOnPause(r.activity); 3462 if (!r.activity.mCalled) { 3463 throw new SuperNotCalledException( 3464 "Activity " + r.intent.getComponent().toShortString() 3465 + " did not call through to super.onPause()"); 3466 } 3467 } catch (SuperNotCalledException e) { 3468 throw e; 3469 } catch (Exception e) { 3470 if (!mInstrumentation.onException(r.activity, e)) { 3471 throw new RuntimeException( 3472 "Unable to pause activity " 3473 + r.intent.getComponent().toShortString() 3474 + ": " + e.toString(), e); 3475 } 3476 } 3477 } 3478 deliverResults(r, res.results); 3479 if (resumed) { 3480 r.activity.performResume(); 3481 r.activity.mTemporaryPause = false; 3482 } 3483 } 3484 } 3485 3486 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 3487 return performDestroyActivity(token, finishing, 0, false); 3488 } 3489 3490 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 3491 int configChanges, boolean getNonConfigInstance) { 3492 ActivityClientRecord r = mActivities.get(token); 3493 Class<? extends Activity> activityClass = null; 3494 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 3495 if (r != null) { 3496 activityClass = r.activity.getClass(); 3497 r.activity.mConfigChangeFlags |= configChanges; 3498 if (finishing) { 3499 r.activity.mFinished = true; 3500 } 3501 if (!r.paused) { 3502 try { 3503 r.activity.mCalled = false; 3504 mInstrumentation.callActivityOnPause(r.activity); 3505 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3506 r.activity.getComponentName().getClassName()); 3507 if (!r.activity.mCalled) { 3508 throw new SuperNotCalledException( 3509 "Activity " + safeToComponentShortString(r.intent) 3510 + " did not call through to super.onPause()"); 3511 } 3512 } catch (SuperNotCalledException e) { 3513 throw e; 3514 } catch (Exception e) { 3515 if (!mInstrumentation.onException(r.activity, e)) { 3516 throw new RuntimeException( 3517 "Unable to pause activity " 3518 + safeToComponentShortString(r.intent) 3519 + ": " + e.toString(), e); 3520 } 3521 } 3522 r.paused = true; 3523 } 3524 if (!r.stopped) { 3525 try { 3526 r.activity.performStop(); 3527 } catch (SuperNotCalledException e) { 3528 throw e; 3529 } catch (Exception e) { 3530 if (!mInstrumentation.onException(r.activity, e)) { 3531 throw new RuntimeException( 3532 "Unable to stop activity " 3533 + safeToComponentShortString(r.intent) 3534 + ": " + e.toString(), e); 3535 } 3536 } 3537 r.stopped = true; 3538 } 3539 if (getNonConfigInstance) { 3540 try { 3541 r.lastNonConfigurationInstances 3542 = r.activity.retainNonConfigurationInstances(); 3543 } catch (Exception e) { 3544 if (!mInstrumentation.onException(r.activity, e)) { 3545 throw new RuntimeException( 3546 "Unable to retain activity " 3547 + r.intent.getComponent().toShortString() 3548 + ": " + e.toString(), e); 3549 } 3550 } 3551 } 3552 try { 3553 r.activity.mCalled = false; 3554 mInstrumentation.callActivityOnDestroy(r.activity); 3555 if (!r.activity.mCalled) { 3556 throw new SuperNotCalledException( 3557 "Activity " + safeToComponentShortString(r.intent) + 3558 " did not call through to super.onDestroy()"); 3559 } 3560 if (r.window != null) { 3561 r.window.closeAllPanels(); 3562 } 3563 } catch (SuperNotCalledException e) { 3564 throw e; 3565 } catch (Exception e) { 3566 if (!mInstrumentation.onException(r.activity, e)) { 3567 throw new RuntimeException( 3568 "Unable to destroy activity " + safeToComponentShortString(r.intent) 3569 + ": " + e.toString(), e); 3570 } 3571 } 3572 } 3573 mActivities.remove(token); 3574 StrictMode.decrementExpectedActivityCount(activityClass); 3575 return r; 3576 } 3577 3578 private static String safeToComponentShortString(Intent intent) { 3579 ComponentName component = intent.getComponent(); 3580 return component == null ? "[Unknown]" : component.toShortString(); 3581 } 3582 3583 private void handleDestroyActivity(IBinder token, boolean finishing, 3584 int configChanges, boolean getNonConfigInstance) { 3585 ActivityClientRecord r = performDestroyActivity(token, finishing, 3586 configChanges, getNonConfigInstance); 3587 if (r != null) { 3588 cleanUpPendingRemoveWindows(r); 3589 WindowManager wm = r.activity.getWindowManager(); 3590 View v = r.activity.mDecor; 3591 if (v != null) { 3592 if (r.activity.mVisibleFromServer) { 3593 mNumVisibleActivities--; 3594 } 3595 IBinder wtoken = v.getWindowToken(); 3596 if (r.activity.mWindowAdded) { 3597 if (r.onlyLocalRequest) { 3598 // Hold off on removing this until the new activity's 3599 // window is being added. 3600 r.mPendingRemoveWindow = v; 3601 r.mPendingRemoveWindowManager = wm; 3602 } else { 3603 wm.removeViewImmediate(v); 3604 } 3605 } 3606 if (wtoken != null && r.mPendingRemoveWindow == null) { 3607 WindowManagerGlobal.getInstance().closeAll(wtoken, 3608 r.activity.getClass().getName(), "Activity"); 3609 } 3610 r.activity.mDecor = null; 3611 } 3612 if (r.mPendingRemoveWindow == null) { 3613 // If we are delaying the removal of the activity window, then 3614 // we can't clean up all windows here. Note that we can't do 3615 // so later either, which means any windows that aren't closed 3616 // by the app will leak. Well we try to warning them a lot 3617 // about leaking windows, because that is a bug, so if they are 3618 // using this recreate facility then they get to live with leaks. 3619 WindowManagerGlobal.getInstance().closeAll(token, 3620 r.activity.getClass().getName(), "Activity"); 3621 } 3622 3623 // Mocked out contexts won't be participating in the normal 3624 // process lifecycle, but if we're running with a proper 3625 // ApplicationContext we need to have it tear down things 3626 // cleanly. 3627 Context c = r.activity.getBaseContext(); 3628 if (c instanceof ContextImpl) { 3629 ((ContextImpl) c).scheduleFinalCleanup( 3630 r.activity.getClass().getName(), "Activity"); 3631 } 3632 } 3633 if (finishing) { 3634 try { 3635 ActivityManagerNative.getDefault().activityDestroyed(token); 3636 } catch (RemoteException ex) { 3637 // If the system process has died, it's game over for everyone. 3638 } 3639 } 3640 } 3641 3642 public final void requestRelaunchActivity(IBinder token, 3643 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 3644 int configChanges, boolean notResumed, Configuration config, 3645 boolean fromServer) { 3646 ActivityClientRecord target = null; 3647 3648 synchronized (mResourcesManager) { 3649 for (int i=0; i<mRelaunchingActivities.size(); i++) { 3650 ActivityClientRecord r = mRelaunchingActivities.get(i); 3651 if (r.token == token) { 3652 target = r; 3653 if (pendingResults != null) { 3654 if (r.pendingResults != null) { 3655 r.pendingResults.addAll(pendingResults); 3656 } else { 3657 r.pendingResults = pendingResults; 3658 } 3659 } 3660 if (pendingNewIntents != null) { 3661 if (r.pendingIntents != null) { 3662 r.pendingIntents.addAll(pendingNewIntents); 3663 } else { 3664 r.pendingIntents = pendingNewIntents; 3665 } 3666 } 3667 break; 3668 } 3669 } 3670 3671 if (target == null) { 3672 target = new ActivityClientRecord(); 3673 target.token = token; 3674 target.pendingResults = pendingResults; 3675 target.pendingIntents = pendingNewIntents; 3676 if (!fromServer) { 3677 ActivityClientRecord existing = mActivities.get(token); 3678 if (existing != null) { 3679 target.startsNotResumed = existing.paused; 3680 } 3681 target.onlyLocalRequest = true; 3682 } 3683 mRelaunchingActivities.add(target); 3684 sendMessage(H.RELAUNCH_ACTIVITY, target); 3685 } 3686 3687 if (fromServer) { 3688 target.startsNotResumed = notResumed; 3689 target.onlyLocalRequest = false; 3690 } 3691 if (config != null) { 3692 target.createdConfig = config; 3693 } 3694 target.pendingConfigChanges |= configChanges; 3695 } 3696 } 3697 3698 private void handleRelaunchActivity(ActivityClientRecord tmp) { 3699 // If we are getting ready to gc after going to the background, well 3700 // we are back active so skip it. 3701 unscheduleGcIdler(); 3702 3703 Configuration changedConfig = null; 3704 int configChanges = 0; 3705 3706 // First: make sure we have the most recent configuration and most 3707 // recent version of the activity, or skip it if some previous call 3708 // had taken a more recent version. 3709 synchronized (mResourcesManager) { 3710 int N = mRelaunchingActivities.size(); 3711 IBinder token = tmp.token; 3712 tmp = null; 3713 for (int i=0; i<N; i++) { 3714 ActivityClientRecord r = mRelaunchingActivities.get(i); 3715 if (r.token == token) { 3716 tmp = r; 3717 configChanges |= tmp.pendingConfigChanges; 3718 mRelaunchingActivities.remove(i); 3719 i--; 3720 N--; 3721 } 3722 } 3723 3724 if (tmp == null) { 3725 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 3726 return; 3727 } 3728 3729 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3730 + tmp.token + " with configChanges=0x" 3731 + Integer.toHexString(configChanges)); 3732 3733 if (mPendingConfiguration != null) { 3734 changedConfig = mPendingConfiguration; 3735 mPendingConfiguration = null; 3736 } 3737 } 3738 3739 if (tmp.createdConfig != null) { 3740 // If the activity manager is passing us its current config, 3741 // assume that is really what we want regardless of what we 3742 // may have pending. 3743 if (mConfiguration == null 3744 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 3745 && mConfiguration.diff(tmp.createdConfig) != 0)) { 3746 if (changedConfig == null 3747 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 3748 changedConfig = tmp.createdConfig; 3749 } 3750 } 3751 } 3752 3753 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3754 + tmp.token + ": changedConfig=" + changedConfig); 3755 3756 // If there was a pending configuration change, execute it first. 3757 if (changedConfig != null) { 3758 mCurDefaultDisplayDpi = changedConfig.densityDpi; 3759 updateDefaultDensity(); 3760 handleConfigurationChanged(changedConfig, null); 3761 } 3762 3763 ActivityClientRecord r = mActivities.get(tmp.token); 3764 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 3765 if (r == null) { 3766 return; 3767 } 3768 3769 r.activity.mConfigChangeFlags |= configChanges; 3770 r.onlyLocalRequest = tmp.onlyLocalRequest; 3771 Intent currentIntent = r.activity.mIntent; 3772 3773 r.activity.mChangingConfigurations = true; 3774 3775 // Need to ensure state is saved. 3776 if (!r.paused) { 3777 performPauseActivity(r.token, false, r.isPreHoneycomb()); 3778 } 3779 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 3780 callCallActivityOnSaveInstanceState(r); 3781 } 3782 3783 handleDestroyActivity(r.token, false, configChanges, true); 3784 3785 r.activity = null; 3786 r.window = null; 3787 r.hideForNow = false; 3788 r.nextIdle = null; 3789 // Merge any pending results and pending intents; don't just replace them 3790 if (tmp.pendingResults != null) { 3791 if (r.pendingResults == null) { 3792 r.pendingResults = tmp.pendingResults; 3793 } else { 3794 r.pendingResults.addAll(tmp.pendingResults); 3795 } 3796 } 3797 if (tmp.pendingIntents != null) { 3798 if (r.pendingIntents == null) { 3799 r.pendingIntents = tmp.pendingIntents; 3800 } else { 3801 r.pendingIntents.addAll(tmp.pendingIntents); 3802 } 3803 } 3804 r.startsNotResumed = tmp.startsNotResumed; 3805 3806 handleLaunchActivity(r, currentIntent); 3807 } 3808 3809 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) { 3810 r.state = new Bundle(); 3811 r.state.setAllowFds(false); 3812 if (r.isPersistable()) { 3813 r.persistentState = new PersistableBundle(); 3814 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 3815 r.persistentState); 3816 } else { 3817 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 3818 } 3819 } 3820 3821 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 3822 boolean allActivities, Configuration newConfig) { 3823 ArrayList<ComponentCallbacks2> callbacks 3824 = new ArrayList<ComponentCallbacks2>(); 3825 3826 synchronized (mResourcesManager) { 3827 final int NAPP = mAllApplications.size(); 3828 for (int i=0; i<NAPP; i++) { 3829 callbacks.add(mAllApplications.get(i)); 3830 } 3831 final int NACT = mActivities.size(); 3832 for (int i=0; i<NACT; i++) { 3833 ActivityClientRecord ar = mActivities.valueAt(i); 3834 Activity a = ar.activity; 3835 if (a != null) { 3836 Configuration thisConfig = applyConfigCompatMainThread( 3837 mCurDefaultDisplayDpi, newConfig, 3838 ar.packageInfo.getCompatibilityInfo()); 3839 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 3840 // If the activity is currently resumed, its configuration 3841 // needs to change right now. 3842 callbacks.add(a); 3843 } else if (thisConfig != null) { 3844 // Otherwise, we will tell it about the change 3845 // the next time it is resumed or shown. Note that 3846 // the activity manager may, before then, decide the 3847 // activity needs to be destroyed to handle its new 3848 // configuration. 3849 if (DEBUG_CONFIGURATION) { 3850 Slog.v(TAG, "Setting activity " 3851 + ar.activityInfo.name + " newConfig=" + thisConfig); 3852 } 3853 ar.newConfig = thisConfig; 3854 } 3855 } 3856 } 3857 final int NSVC = mServices.size(); 3858 for (int i=0; i<NSVC; i++) { 3859 callbacks.add(mServices.valueAt(i)); 3860 } 3861 } 3862 synchronized (mProviderMap) { 3863 final int NPRV = mLocalProviders.size(); 3864 for (int i=0; i<NPRV; i++) { 3865 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 3866 } 3867 } 3868 3869 return callbacks; 3870 } 3871 3872 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { 3873 // Only for Activity objects, check that they actually call up to their 3874 // superclass implementation. ComponentCallbacks2 is an interface, so 3875 // we check the runtime type and act accordingly. 3876 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 3877 if (activity != null) { 3878 activity.mCalled = false; 3879 } 3880 3881 boolean shouldChangeConfig = false; 3882 if ((activity == null) || (activity.mCurrentConfig == null)) { 3883 shouldChangeConfig = true; 3884 } else { 3885 3886 // If the new config is the same as the config this Activity 3887 // is already running with then don't bother calling 3888 // onConfigurationChanged 3889 int diff = activity.mCurrentConfig.diff(config); 3890 if (diff != 0) { 3891 // If this activity doesn't handle any of the config changes 3892 // then don't bother calling onConfigurationChanged as we're 3893 // going to destroy it. 3894 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) { 3895 shouldChangeConfig = true; 3896 } 3897 } 3898 } 3899 3900 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 3901 + ": shouldChangeConfig=" + shouldChangeConfig); 3902 if (shouldChangeConfig) { 3903 cb.onConfigurationChanged(config); 3904 3905 if (activity != null) { 3906 if (!activity.mCalled) { 3907 throw new SuperNotCalledException( 3908 "Activity " + activity.getLocalClassName() + 3909 " did not call through to super.onConfigurationChanged()"); 3910 } 3911 activity.mConfigChangeFlags = 0; 3912 activity.mCurrentConfig = new Configuration(config); 3913 } 3914 } 3915 } 3916 3917 public final void applyConfigurationToResources(Configuration config) { 3918 synchronized (mResourcesManager) { 3919 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 3920 } 3921 } 3922 3923 final Configuration applyCompatConfiguration(int displayDensity) { 3924 Configuration config = mConfiguration; 3925 if (mCompatConfiguration == null) { 3926 mCompatConfiguration = new Configuration(); 3927 } 3928 mCompatConfiguration.setTo(mConfiguration); 3929 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { 3930 config = mCompatConfiguration; 3931 } 3932 return config; 3933 } 3934 3935 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 3936 3937 int configDiff = 0; 3938 3939 synchronized (mResourcesManager) { 3940 if (mPendingConfiguration != null) { 3941 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 3942 config = mPendingConfiguration; 3943 mCurDefaultDisplayDpi = config.densityDpi; 3944 updateDefaultDensity(); 3945 } 3946 mPendingConfiguration = null; 3947 } 3948 3949 if (config == null) { 3950 return; 3951 } 3952 3953 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 3954 + config); 3955 3956 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 3957 3958 if (mConfiguration == null) { 3959 mConfiguration = new Configuration(); 3960 } 3961 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 3962 return; 3963 } 3964 configDiff = mConfiguration.diff(config); 3965 mConfiguration.updateFrom(config); 3966 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 3967 } 3968 3969 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 3970 3971 // Cleanup hardware accelerated stuff 3972 // TODO: Do we actually want to do this in response to all config changes? 3973 WindowManagerGlobal.getInstance().trimLocalMemory(); 3974 3975 freeTextLayoutCachesIfNeeded(configDiff); 3976 3977 if (callbacks != null) { 3978 final int N = callbacks.size(); 3979 for (int i=0; i<N; i++) { 3980 performConfigurationChanged(callbacks.get(i), config); 3981 } 3982 } 3983 } 3984 3985 static void freeTextLayoutCachesIfNeeded(int configDiff) { 3986 if (configDiff != 0) { 3987 // Ask text layout engine to free its caches if there is a locale change 3988 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 3989 if (hasLocaleConfigChange) { 3990 Canvas.freeTextLayoutCaches(); 3991 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 3992 } 3993 } 3994 } 3995 3996 final void handleActivityConfigurationChanged(IBinder token) { 3997 ActivityClientRecord r = mActivities.get(token); 3998 if (r == null || r.activity == null) { 3999 return; 4000 } 4001 4002 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4003 + r.activityInfo.name); 4004 4005 performConfigurationChanged(r.activity, mCompatConfiguration); 4006 4007 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 4008 } 4009 4010 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { 4011 if (start) { 4012 try { 4013 switch (profileType) { 4014 default: 4015 mProfiler.setProfiler(pcd.path, pcd.fd); 4016 mProfiler.autoStopProfiler = false; 4017 mProfiler.startProfiling(); 4018 break; 4019 } 4020 } catch (RuntimeException e) { 4021 Slog.w(TAG, "Profiling failed on path " + pcd.path 4022 + " -- can the process access this path?"); 4023 } finally { 4024 try { 4025 pcd.fd.close(); 4026 } catch (IOException e) { 4027 Slog.w(TAG, "Failure closing profile fd", e); 4028 } 4029 } 4030 } else { 4031 switch (profileType) { 4032 default: 4033 mProfiler.stopProfiling(); 4034 break; 4035 } 4036 } 4037 } 4038 4039 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4040 if (managed) { 4041 try { 4042 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4043 } catch (IOException e) { 4044 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4045 + " -- can the process access this path?"); 4046 } finally { 4047 try { 4048 dhd.fd.close(); 4049 } catch (IOException e) { 4050 Slog.w(TAG, "Failure closing profile fd", e); 4051 } 4052 } 4053 } else { 4054 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4055 } 4056 } 4057 4058 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4059 boolean hasPkgInfo = false; 4060 if (packages != null) { 4061 for (int i=packages.length-1; i>=0; i--) { 4062 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4063 if (!hasPkgInfo) { 4064 WeakReference<LoadedApk> ref; 4065 ref = mPackages.get(packages[i]); 4066 if (ref != null && ref.get() != null) { 4067 hasPkgInfo = true; 4068 } else { 4069 ref = mResourcePackages.get(packages[i]); 4070 if (ref != null && ref.get() != null) { 4071 hasPkgInfo = true; 4072 } 4073 } 4074 } 4075 mPackages.remove(packages[i]); 4076 mResourcePackages.remove(packages[i]); 4077 } 4078 } 4079 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4080 hasPkgInfo); 4081 } 4082 4083 final void handleLowMemory() { 4084 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4085 4086 final int N = callbacks.size(); 4087 for (int i=0; i<N; i++) { 4088 callbacks.get(i).onLowMemory(); 4089 } 4090 4091 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4092 if (Process.myUid() != Process.SYSTEM_UID) { 4093 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4094 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4095 } 4096 4097 // Ask graphics to free up as much as possible (font/image caches) 4098 Canvas.freeCaches(); 4099 4100 // Ask text layout engine to free also as much as possible 4101 Canvas.freeTextLayoutCaches(); 4102 4103 BinderInternal.forceGc("mem"); 4104 } 4105 4106 final void handleTrimMemory(int level) { 4107 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4108 4109 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance(); 4110 windowManager.startTrimMemory(level); 4111 4112 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4113 4114 final int N = callbacks.size(); 4115 for (int i = 0; i < N; i++) { 4116 callbacks.get(i).onTrimMemory(level); 4117 } 4118 4119 windowManager.endTrimMemory(); 4120 } 4121 4122 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4123 if (Process.isIsolated()) { 4124 // Isolated processes aren't going to do UI. 4125 return; 4126 } 4127 try { 4128 int uid = Process.myUid(); 4129 String[] packages = getPackageManager().getPackagesForUid(uid); 4130 4131 // If there are several packages in this application we won't 4132 // initialize the graphics disk caches 4133 if (packages != null && packages.length == 1) { 4134 HardwareRenderer.setupDiskCache(cacheDir); 4135 RenderScript.setupDiskCache(cacheDir); 4136 } 4137 } catch (RemoteException e) { 4138 // Ignore 4139 } 4140 } 4141 4142 private void updateDefaultDensity() { 4143 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED 4144 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE 4145 && !mDensityCompatMode) { 4146 Slog.i(TAG, "Switching default density from " 4147 + DisplayMetrics.DENSITY_DEVICE + " to " 4148 + mCurDefaultDisplayDpi); 4149 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; 4150 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4151 } 4152 } 4153 4154 private void handleBindApplication(AppBindData data) { 4155 mBoundApplication = data; 4156 mConfiguration = new Configuration(data.config); 4157 mCompatConfiguration = new Configuration(data.config); 4158 4159 mProfiler = new Profiler(); 4160 mProfiler.profileFile = data.initProfileFile; 4161 mProfiler.profileFd = data.initProfileFd; 4162 mProfiler.autoStopProfiler = data.initAutoStopProfiler; 4163 4164 // send up app name; do this *before* waiting for debugger 4165 Process.setArgV0(data.processName); 4166 android.ddm.DdmHandleAppName.setAppName(data.processName, 4167 UserHandle.myUserId()); 4168 4169 if (data.persistent) { 4170 // Persistent processes on low-memory devices do not get to 4171 // use hardware accelerated drawing, since this can add too much 4172 // overhead to the process. 4173 if (!ActivityManager.isHighEndGfx()) { 4174 HardwareRenderer.disable(false); 4175 } 4176 } 4177 4178 if (mProfiler.profileFd != null) { 4179 mProfiler.startProfiling(); 4180 } 4181 4182 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4183 // implementation to use the pool executor. Normally, we use the 4184 // serialized executor as the default. This has to happen in the 4185 // main thread so the main looper is set right. 4186 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4187 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4188 } 4189 4190 /* 4191 * Before spawning a new process, reset the time zone to be the system time zone. 4192 * This needs to be done because the system time zone could have changed after the 4193 * the spawning of this process. Without doing this this process would have the incorrect 4194 * system time zone. 4195 */ 4196 TimeZone.setDefault(null); 4197 4198 /* 4199 * Initialize the default locale in this process for the reasons we set the time zone. 4200 */ 4201 Locale.setDefault(data.config.locale); 4202 4203 /* 4204 * Update the system configuration since its preloaded and might not 4205 * reflect configuration changes. The configuration object passed 4206 * in AppBindData can be safely assumed to be up to date 4207 */ 4208 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4209 mCurDefaultDisplayDpi = data.config.densityDpi; 4210 applyCompatConfiguration(mCurDefaultDisplayDpi); 4211 4212 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4213 4214 /** 4215 * Switch this process to density compatibility mode if needed. 4216 */ 4217 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4218 == 0) { 4219 mDensityCompatMode = true; 4220 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4221 } 4222 updateDefaultDensity(); 4223 4224 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 4225 if (!Process.isIsolated()) { 4226 final File cacheDir = appContext.getCacheDir(); 4227 4228 if (cacheDir != null) { 4229 // Provide a usable directory for temporary files 4230 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 4231 4232 setupGraphicsSupport(data.info, cacheDir); 4233 } else { 4234 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory"); 4235 } 4236 } 4237 4238 4239 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); 4240 DateFormat.set24HourTimePref(is24Hr); 4241 4242 /** 4243 * For system applications on userdebug/eng builds, log stack 4244 * traces of disk and network access to dropbox for analysis. 4245 */ 4246 if ((data.appInfo.flags & 4247 (ApplicationInfo.FLAG_SYSTEM | 4248 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4249 StrictMode.conditionallyEnableDebugLogging(); 4250 } 4251 4252 /** 4253 * For apps targetting SDK Honeycomb or later, we don't allow 4254 * network usage on the main event loop / UI thread. 4255 * 4256 * Note to those grepping: this is what ultimately throws 4257 * NetworkOnMainThreadException ... 4258 */ 4259 if (data.appInfo.targetSdkVersion > 9) { 4260 StrictMode.enableDeathOnNetwork(); 4261 } 4262 4263 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4264 // XXX should have option to change the port. 4265 Debug.changeDebugPort(8100); 4266 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4267 Slog.w(TAG, "Application " + data.info.getPackageName() 4268 + " is waiting for the debugger on port 8100..."); 4269 4270 IActivityManager mgr = ActivityManagerNative.getDefault(); 4271 try { 4272 mgr.showWaitingForDebugger(mAppThread, true); 4273 } catch (RemoteException ex) { 4274 } 4275 4276 Debug.waitForDebugger(); 4277 4278 try { 4279 mgr.showWaitingForDebugger(mAppThread, false); 4280 } catch (RemoteException ex) { 4281 } 4282 4283 } else { 4284 Slog.w(TAG, "Application " + data.info.getPackageName() 4285 + " can be debugged on port 8100..."); 4286 } 4287 } 4288 4289 // Enable OpenGL tracing if required 4290 if (data.enableOpenGlTrace) { 4291 GLUtils.setTracingLevel(1); 4292 } 4293 4294 // Allow application-generated systrace messages if we're debuggable. 4295 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0; 4296 Trace.setAppTracingAllowed(appTracingAllowed); 4297 4298 /** 4299 * Initialize the default http proxy in this process for the reasons we set the time zone. 4300 */ 4301 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 4302 if (b != null) { 4303 // In pre-boot mode (doing initial launch to collect password), not 4304 // all system is up. This includes the connectivity service, so don't 4305 // crash if we can't get it. 4306 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4307 try { 4308 ProxyInfo proxyInfo = service.getProxy(); 4309 Proxy.setHttpProxySystemProperty(proxyInfo); 4310 } catch (RemoteException e) {} 4311 } 4312 4313 if (data.instrumentationName != null) { 4314 InstrumentationInfo ii = null; 4315 try { 4316 ii = appContext.getPackageManager(). 4317 getInstrumentationInfo(data.instrumentationName, 0); 4318 } catch (PackageManager.NameNotFoundException e) { 4319 } 4320 if (ii == null) { 4321 throw new RuntimeException( 4322 "Unable to find instrumentation info for: " 4323 + data.instrumentationName); 4324 } 4325 4326 mInstrumentationAppDir = ii.sourceDir; 4327 mInstrumentationAppLibraryDir = ii.nativeLibraryDir; 4328 mInstrumentationAppPackage = ii.packageName; 4329 mInstrumentedAppDir = data.info.getAppDir(); 4330 mInstrumentedAppLibraryDir = data.info.getLibDir(); 4331 4332 ApplicationInfo instrApp = new ApplicationInfo(); 4333 instrApp.packageName = ii.packageName; 4334 instrApp.sourceDir = ii.sourceDir; 4335 instrApp.publicSourceDir = ii.publicSourceDir; 4336 instrApp.dataDir = ii.dataDir; 4337 instrApp.nativeLibraryDir = ii.nativeLibraryDir; 4338 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 4339 appContext.getClassLoader(), false, true); 4340 ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 4341 4342 try { 4343 java.lang.ClassLoader cl = instrContext.getClassLoader(); 4344 mInstrumentation = (Instrumentation) 4345 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4346 } catch (Exception e) { 4347 throw new RuntimeException( 4348 "Unable to instantiate instrumentation " 4349 + data.instrumentationName + ": " + e.toString(), e); 4350 } 4351 4352 mInstrumentation.init(this, instrContext, appContext, 4353 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, 4354 data.instrumentationUiAutomationConnection); 4355 4356 if (mProfiler.profileFile != null && !ii.handleProfiling 4357 && mProfiler.profileFd == null) { 4358 mProfiler.handlingProfiling = true; 4359 File file = new File(mProfiler.profileFile); 4360 file.getParentFile().mkdirs(); 4361 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 4362 } 4363 4364 } else { 4365 mInstrumentation = new Instrumentation(); 4366 } 4367 4368 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 4369 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 4370 } 4371 4372 // Allow disk access during application and provider setup. This could 4373 // block processing ordered broadcasts, but later processing would 4374 // probably end up doing the same disk access. 4375 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 4376 try { 4377 // If the app is being launched for full backup or restore, bring it up in 4378 // a restricted environment with the base application class. 4379 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 4380 mInitialApplication = app; 4381 4382 // don't bring up providers in restricted mode; they may depend on the 4383 // app's custom Application class 4384 if (!data.restrictedBackupMode) { 4385 List<ProviderInfo> providers = data.providers; 4386 if (providers != null) { 4387 installContentProviders(app, providers); 4388 // For process that contains content providers, we want to 4389 // ensure that the JIT is enabled "at some point". 4390 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 4391 } 4392 } 4393 4394 // Do this after providers, since instrumentation tests generally start their 4395 // test thread at this point, and we don't want that racing. 4396 try { 4397 mInstrumentation.onCreate(data.instrumentationArgs); 4398 } 4399 catch (Exception e) { 4400 throw new RuntimeException( 4401 "Exception thrown in onCreate() of " 4402 + data.instrumentationName + ": " + e.toString(), e); 4403 } 4404 4405 try { 4406 mInstrumentation.callApplicationOnCreate(app); 4407 } catch (Exception e) { 4408 if (!mInstrumentation.onException(app, e)) { 4409 throw new RuntimeException( 4410 "Unable to create application " + app.getClass().getName() 4411 + ": " + e.toString(), e); 4412 } 4413 } 4414 } finally { 4415 StrictMode.setThreadPolicy(savedPolicy); 4416 } 4417 } 4418 4419 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 4420 IActivityManager am = ActivityManagerNative.getDefault(); 4421 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 4422 && mProfiler.profileFd == null) { 4423 Debug.stopMethodTracing(); 4424 } 4425 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 4426 // + ", app thr: " + mAppThread); 4427 try { 4428 am.finishInstrumentation(mAppThread, resultCode, results); 4429 } catch (RemoteException ex) { 4430 } 4431 } 4432 4433 private void installContentProviders( 4434 Context context, List<ProviderInfo> providers) { 4435 final ArrayList<IActivityManager.ContentProviderHolder> results = 4436 new ArrayList<IActivityManager.ContentProviderHolder>(); 4437 4438 for (ProviderInfo cpi : providers) { 4439 if (DEBUG_PROVIDER) { 4440 StringBuilder buf = new StringBuilder(128); 4441 buf.append("Pub "); 4442 buf.append(cpi.authority); 4443 buf.append(": "); 4444 buf.append(cpi.name); 4445 Log.i(TAG, buf.toString()); 4446 } 4447 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 4448 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 4449 if (cph != null) { 4450 cph.noReleaseNeeded = true; 4451 results.add(cph); 4452 } 4453 } 4454 4455 try { 4456 ActivityManagerNative.getDefault().publishContentProviders( 4457 getApplicationThread(), results); 4458 } catch (RemoteException ex) { 4459 } 4460 } 4461 4462 public final IContentProvider acquireProvider( 4463 Context c, String auth, int userId, boolean stable) { 4464 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 4465 if (provider != null) { 4466 return provider; 4467 } 4468 4469 // There is a possible race here. Another thread may try to acquire 4470 // the same provider at the same time. When this happens, we want to ensure 4471 // that the first one wins. 4472 // Note that we cannot hold the lock while acquiring and installing the 4473 // provider since it might take a long time to run and it could also potentially 4474 // be re-entrant in the case where the provider is in the same process. 4475 IActivityManager.ContentProviderHolder holder = null; 4476 try { 4477 holder = ActivityManagerNative.getDefault().getContentProvider( 4478 getApplicationThread(), auth, userId, stable); 4479 } catch (RemoteException ex) { 4480 } 4481 if (holder == null) { 4482 Slog.e(TAG, "Failed to find provider info for " + auth); 4483 return null; 4484 } 4485 4486 // Install provider will increment the reference count for us, and break 4487 // any ties in the race. 4488 holder = installProvider(c, holder, holder.info, 4489 true /*noisy*/, holder.noReleaseNeeded, stable); 4490 return holder.provider; 4491 } 4492 4493 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 4494 if (stable) { 4495 prc.stableCount += 1; 4496 if (prc.stableCount == 1) { 4497 // We are acquiring a new stable reference on the provider. 4498 int unstableDelta; 4499 if (prc.removePending) { 4500 // We have a pending remove operation, which is holding the 4501 // last unstable reference. At this point we are converting 4502 // that unstable reference to our new stable reference. 4503 unstableDelta = -1; 4504 // Cancel the removal of the provider. 4505 if (DEBUG_PROVIDER) { 4506 Slog.v(TAG, "incProviderRef: stable " 4507 + "snatched provider from the jaws of death"); 4508 } 4509 prc.removePending = false; 4510 // There is a race! It fails to remove the message, which 4511 // will be handled in completeRemoveProvider(). 4512 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4513 } else { 4514 unstableDelta = 0; 4515 } 4516 try { 4517 if (DEBUG_PROVIDER) { 4518 Slog.v(TAG, "incProviderRef Now stable - " 4519 + prc.holder.info.name + ": unstableDelta=" 4520 + unstableDelta); 4521 } 4522 ActivityManagerNative.getDefault().refContentProvider( 4523 prc.holder.connection, 1, unstableDelta); 4524 } catch (RemoteException e) { 4525 //do nothing content provider object is dead any way 4526 } 4527 } 4528 } else { 4529 prc.unstableCount += 1; 4530 if (prc.unstableCount == 1) { 4531 // We are acquiring a new unstable reference on the provider. 4532 if (prc.removePending) { 4533 // Oh look, we actually have a remove pending for the 4534 // provider, which is still holding the last unstable 4535 // reference. We just need to cancel that to take new 4536 // ownership of the reference. 4537 if (DEBUG_PROVIDER) { 4538 Slog.v(TAG, "incProviderRef: unstable " 4539 + "snatched provider from the jaws of death"); 4540 } 4541 prc.removePending = false; 4542 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4543 } else { 4544 // First unstable ref, increment our count in the 4545 // activity manager. 4546 try { 4547 if (DEBUG_PROVIDER) { 4548 Slog.v(TAG, "incProviderRef: Now unstable - " 4549 + prc.holder.info.name); 4550 } 4551 ActivityManagerNative.getDefault().refContentProvider( 4552 prc.holder.connection, 0, 1); 4553 } catch (RemoteException e) { 4554 //do nothing content provider object is dead any way 4555 } 4556 } 4557 } 4558 } 4559 } 4560 4561 public final IContentProvider acquireExistingProvider( 4562 Context c, String auth, int userId, boolean stable) { 4563 synchronized (mProviderMap) { 4564 final ProviderKey key = new ProviderKey(auth, userId); 4565 final ProviderClientRecord pr = mProviderMap.get(key); 4566 if (pr == null) { 4567 return null; 4568 } 4569 4570 IContentProvider provider = pr.mProvider; 4571 IBinder jBinder = provider.asBinder(); 4572 if (!jBinder.isBinderAlive()) { 4573 // The hosting process of the provider has died; we can't 4574 // use this one. 4575 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 4576 + ": existing object's process dead"); 4577 handleUnstableProviderDiedLocked(jBinder, true); 4578 return null; 4579 } 4580 4581 // Only increment the ref count if we have one. If we don't then the 4582 // provider is not reference counted and never needs to be released. 4583 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4584 if (prc != null) { 4585 incProviderRefLocked(prc, stable); 4586 } 4587 return provider; 4588 } 4589 } 4590 4591 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 4592 if (provider == null) { 4593 return false; 4594 } 4595 4596 IBinder jBinder = provider.asBinder(); 4597 synchronized (mProviderMap) { 4598 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4599 if (prc == null) { 4600 // The provider has no ref count, no release is needed. 4601 return false; 4602 } 4603 4604 boolean lastRef = false; 4605 if (stable) { 4606 if (prc.stableCount == 0) { 4607 if (DEBUG_PROVIDER) Slog.v(TAG, 4608 "releaseProvider: stable ref count already 0, how?"); 4609 return false; 4610 } 4611 prc.stableCount -= 1; 4612 if (prc.stableCount == 0) { 4613 // What we do at this point depends on whether there are 4614 // any unstable refs left: if there are, we just tell the 4615 // activity manager to decrement its stable count; if there 4616 // aren't, we need to enqueue this provider to be removed, 4617 // and convert to holding a single unstable ref while 4618 // doing so. 4619 lastRef = prc.unstableCount == 0; 4620 try { 4621 if (DEBUG_PROVIDER) { 4622 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 4623 + lastRef + " - " + prc.holder.info.name); 4624 } 4625 ActivityManagerNative.getDefault().refContentProvider( 4626 prc.holder.connection, -1, lastRef ? 1 : 0); 4627 } catch (RemoteException e) { 4628 //do nothing content provider object is dead any way 4629 } 4630 } 4631 } else { 4632 if (prc.unstableCount == 0) { 4633 if (DEBUG_PROVIDER) Slog.v(TAG, 4634 "releaseProvider: unstable ref count already 0, how?"); 4635 return false; 4636 } 4637 prc.unstableCount -= 1; 4638 if (prc.unstableCount == 0) { 4639 // If this is the last reference, we need to enqueue 4640 // this provider to be removed instead of telling the 4641 // activity manager to remove it at this point. 4642 lastRef = prc.stableCount == 0; 4643 if (!lastRef) { 4644 try { 4645 if (DEBUG_PROVIDER) { 4646 Slog.v(TAG, "releaseProvider: No longer unstable - " 4647 + prc.holder.info.name); 4648 } 4649 ActivityManagerNative.getDefault().refContentProvider( 4650 prc.holder.connection, 0, -1); 4651 } catch (RemoteException e) { 4652 //do nothing content provider object is dead any way 4653 } 4654 } 4655 } 4656 } 4657 4658 if (lastRef) { 4659 if (!prc.removePending) { 4660 // Schedule the actual remove asynchronously, since we don't know the context 4661 // this will be called in. 4662 // TODO: it would be nice to post a delayed message, so 4663 // if we come back and need the same provider quickly 4664 // we will still have it available. 4665 if (DEBUG_PROVIDER) { 4666 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 4667 + prc.holder.info.name); 4668 } 4669 prc.removePending = true; 4670 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 4671 mH.sendMessage(msg); 4672 } else { 4673 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 4674 } 4675 } 4676 return true; 4677 } 4678 } 4679 4680 final void completeRemoveProvider(ProviderRefCount prc) { 4681 synchronized (mProviderMap) { 4682 if (!prc.removePending) { 4683 // There was a race! Some other client managed to acquire 4684 // the provider before the removal was completed. 4685 // Abort the removal. We will do it later. 4686 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 4687 + "provider still in use"); 4688 return; 4689 } 4690 4691 // More complicated race!! Some client managed to acquire the 4692 // provider and release it before the removal was completed. 4693 // Continue the removal, and abort the next remove message. 4694 prc.removePending = false; 4695 4696 final IBinder jBinder = prc.holder.provider.asBinder(); 4697 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 4698 if (existingPrc == prc) { 4699 mProviderRefCountMap.remove(jBinder); 4700 } 4701 4702 for (int i=mProviderMap.size()-1; i>=0; i--) { 4703 ProviderClientRecord pr = mProviderMap.valueAt(i); 4704 IBinder myBinder = pr.mProvider.asBinder(); 4705 if (myBinder == jBinder) { 4706 mProviderMap.removeAt(i); 4707 } 4708 } 4709 } 4710 4711 try { 4712 if (DEBUG_PROVIDER) { 4713 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 4714 + "removeContentProvider(" + prc.holder.info.name + ")"); 4715 } 4716 ActivityManagerNative.getDefault().removeContentProvider( 4717 prc.holder.connection, false); 4718 } catch (RemoteException e) { 4719 //do nothing content provider object is dead any way 4720 } 4721 } 4722 4723 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 4724 synchronized (mProviderMap) { 4725 handleUnstableProviderDiedLocked(provider, fromClient); 4726 } 4727 } 4728 4729 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 4730 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4731 if (prc != null) { 4732 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 4733 + provider + " " + prc.holder.info.name); 4734 mProviderRefCountMap.remove(provider); 4735 for (int i=mProviderMap.size()-1; i>=0; i--) { 4736 ProviderClientRecord pr = mProviderMap.valueAt(i); 4737 if (pr != null && pr.mProvider.asBinder() == provider) { 4738 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 4739 mProviderMap.removeAt(i); 4740 } 4741 } 4742 4743 if (fromClient) { 4744 // We found out about this due to execution in our client 4745 // code. Tell the activity manager about it now, to ensure 4746 // that the next time we go to do anything with the provider 4747 // it knows it is dead (so we don't race with its death 4748 // notification). 4749 try { 4750 ActivityManagerNative.getDefault().unstableProviderDied( 4751 prc.holder.connection); 4752 } catch (RemoteException e) { 4753 //do nothing content provider object is dead any way 4754 } 4755 } 4756 } 4757 } 4758 4759 final void appNotRespondingViaProvider(IBinder provider) { 4760 synchronized (mProviderMap) { 4761 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4762 if (prc != null) { 4763 try { 4764 ActivityManagerNative.getDefault() 4765 .appNotRespondingViaProvider(prc.holder.connection); 4766 } catch (RemoteException e) { 4767 } 4768 } 4769 } 4770 } 4771 4772 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 4773 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 4774 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority); 4775 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 4776 4777 final ProviderClientRecord pcr = new ProviderClientRecord( 4778 auths, provider, localProvider, holder); 4779 for (String auth : auths) { 4780 final ProviderKey key = new ProviderKey(auth, userId); 4781 final ProviderClientRecord existing = mProviderMap.get(key); 4782 if (existing != null) { 4783 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 4784 + " already published as " + auth); 4785 } else { 4786 mProviderMap.put(key, pcr); 4787 } 4788 } 4789 return pcr; 4790 } 4791 4792 /** 4793 * Installs the provider. 4794 * 4795 * Providers that are local to the process or that come from the system server 4796 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 4797 * Other remote providers are reference counted. The initial reference count 4798 * for all reference counted providers is one. Providers that are not reference 4799 * counted do not have a reference count (at all). 4800 * 4801 * This method detects when a provider has already been installed. When this happens, 4802 * it increments the reference count of the existing provider (if appropriate) 4803 * and returns the existing provider. This can happen due to concurrent 4804 * attempts to acquire the same provider. 4805 */ 4806 private IActivityManager.ContentProviderHolder installProvider(Context context, 4807 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 4808 boolean noisy, boolean noReleaseNeeded, boolean stable) { 4809 ContentProvider localProvider = null; 4810 IContentProvider provider; 4811 if (holder == null || holder.provider == null) { 4812 if (DEBUG_PROVIDER || noisy) { 4813 Slog.d(TAG, "Loading provider " + info.authority + ": " 4814 + info.name); 4815 } 4816 Context c = null; 4817 ApplicationInfo ai = info.applicationInfo; 4818 if (context.getPackageName().equals(ai.packageName)) { 4819 c = context; 4820 } else if (mInitialApplication != null && 4821 mInitialApplication.getPackageName().equals(ai.packageName)) { 4822 c = mInitialApplication; 4823 } else { 4824 try { 4825 c = context.createPackageContext(ai.packageName, 4826 Context.CONTEXT_INCLUDE_CODE); 4827 } catch (PackageManager.NameNotFoundException e) { 4828 // Ignore 4829 } 4830 } 4831 if (c == null) { 4832 Slog.w(TAG, "Unable to get context for package " + 4833 ai.packageName + 4834 " while loading content provider " + 4835 info.name); 4836 return null; 4837 } 4838 try { 4839 final java.lang.ClassLoader cl = c.getClassLoader(); 4840 localProvider = (ContentProvider)cl. 4841 loadClass(info.name).newInstance(); 4842 provider = localProvider.getIContentProvider(); 4843 if (provider == null) { 4844 Slog.e(TAG, "Failed to instantiate class " + 4845 info.name + " from sourceDir " + 4846 info.applicationInfo.sourceDir); 4847 return null; 4848 } 4849 if (DEBUG_PROVIDER) Slog.v( 4850 TAG, "Instantiating local provider " + info.name); 4851 // XXX Need to create the correct context for this provider. 4852 localProvider.attachInfo(c, info); 4853 } catch (java.lang.Exception e) { 4854 if (!mInstrumentation.onException(null, e)) { 4855 throw new RuntimeException( 4856 "Unable to get provider " + info.name 4857 + ": " + e.toString(), e); 4858 } 4859 return null; 4860 } 4861 } else { 4862 provider = holder.provider; 4863 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 4864 + info.name); 4865 } 4866 4867 IActivityManager.ContentProviderHolder retHolder; 4868 4869 synchronized (mProviderMap) { 4870 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 4871 + " / " + info.name); 4872 IBinder jBinder = provider.asBinder(); 4873 if (localProvider != null) { 4874 ComponentName cname = new ComponentName(info.packageName, info.name); 4875 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 4876 if (pr != null) { 4877 if (DEBUG_PROVIDER) { 4878 Slog.v(TAG, "installProvider: lost the race, " 4879 + "using existing local provider"); 4880 } 4881 provider = pr.mProvider; 4882 } else { 4883 holder = new IActivityManager.ContentProviderHolder(info); 4884 holder.provider = provider; 4885 holder.noReleaseNeeded = true; 4886 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 4887 mLocalProviders.put(jBinder, pr); 4888 mLocalProvidersByName.put(cname, pr); 4889 } 4890 retHolder = pr.mHolder; 4891 } else { 4892 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4893 if (prc != null) { 4894 if (DEBUG_PROVIDER) { 4895 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 4896 } 4897 // We need to transfer our new reference to the existing 4898 // ref count, releasing the old one... but only if 4899 // release is needed (that is, it is not running in the 4900 // system process). 4901 if (!noReleaseNeeded) { 4902 incProviderRefLocked(prc, stable); 4903 try { 4904 ActivityManagerNative.getDefault().removeContentProvider( 4905 holder.connection, stable); 4906 } catch (RemoteException e) { 4907 //do nothing content provider object is dead any way 4908 } 4909 } 4910 } else { 4911 ProviderClientRecord client = installProviderAuthoritiesLocked( 4912 provider, localProvider, holder); 4913 if (noReleaseNeeded) { 4914 prc = new ProviderRefCount(holder, client, 1000, 1000); 4915 } else { 4916 prc = stable 4917 ? new ProviderRefCount(holder, client, 1, 0) 4918 : new ProviderRefCount(holder, client, 0, 1); 4919 } 4920 mProviderRefCountMap.put(jBinder, prc); 4921 } 4922 retHolder = prc.holder; 4923 } 4924 } 4925 4926 return retHolder; 4927 } 4928 4929 private void attach(boolean system) { 4930 sCurrentActivityThread = this; 4931 mSystemThread = system; 4932 if (!system) { 4933 ViewRootImpl.addFirstDrawHandler(new Runnable() { 4934 @Override 4935 public void run() { 4936 ensureJitEnabled(); 4937 } 4938 }); 4939 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 4940 UserHandle.myUserId()); 4941 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 4942 IActivityManager mgr = ActivityManagerNative.getDefault(); 4943 try { 4944 mgr.attachApplication(mAppThread); 4945 } catch (RemoteException ex) { 4946 // Ignore 4947 } 4948 } else { 4949 // Don't set application object here -- if the system crashes, 4950 // we can't display an alert, we just want to die die die. 4951 android.ddm.DdmHandleAppName.setAppName("system_process", 4952 UserHandle.myUserId()); 4953 try { 4954 mInstrumentation = new Instrumentation(); 4955 ContextImpl context = ContextImpl.createAppContext( 4956 this, getSystemContext().mPackageInfo); 4957 Application app = Instrumentation.newApplication(Application.class, context); 4958 mAllApplications.add(app); 4959 mInitialApplication = app; 4960 app.onCreate(); 4961 } catch (Exception e) { 4962 throw new RuntimeException( 4963 "Unable to instantiate Application():" + e.toString(), e); 4964 } 4965 } 4966 4967 // add dropbox logging to libcore 4968 DropBox.setReporter(new DropBoxReporter()); 4969 4970 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 4971 @Override 4972 public void onConfigurationChanged(Configuration newConfig) { 4973 synchronized (mResourcesManager) { 4974 // We need to apply this change to the resources 4975 // immediately, because upon returning the view 4976 // hierarchy will be informed about it. 4977 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 4978 // This actually changed the resources! Tell 4979 // everyone about it. 4980 if (mPendingConfiguration == null || 4981 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 4982 mPendingConfiguration = newConfig; 4983 4984 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 4985 } 4986 } 4987 } 4988 } 4989 @Override 4990 public void onLowMemory() { 4991 } 4992 @Override 4993 public void onTrimMemory(int level) { 4994 } 4995 }); 4996 } 4997 4998 public static ActivityThread systemMain() { 4999 HardwareRenderer.disable(true); 5000 ActivityThread thread = new ActivityThread(); 5001 thread.attach(true); 5002 return thread; 5003 } 5004 5005 public final void installSystemProviders(List<ProviderInfo> providers) { 5006 if (providers != null) { 5007 installContentProviders(mInitialApplication, providers); 5008 } 5009 } 5010 5011 public int getIntCoreSetting(String key, int defaultValue) { 5012 synchronized (mResourcesManager) { 5013 if (mCoreSettings != null) { 5014 return mCoreSettings.getInt(key, defaultValue); 5015 } 5016 return defaultValue; 5017 } 5018 } 5019 5020 private static class EventLoggingReporter implements EventLogger.Reporter { 5021 @Override 5022 public void report (int code, Object... list) { 5023 EventLog.writeEvent(code, list); 5024 } 5025 } 5026 5027 private class DropBoxReporter implements DropBox.Reporter { 5028 5029 private DropBoxManager dropBox; 5030 5031 public DropBoxReporter() { 5032 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 5033 } 5034 5035 @Override 5036 public void addData(String tag, byte[] data, int flags) { 5037 dropBox.addData(tag, data, flags); 5038 } 5039 5040 @Override 5041 public void addText(String tag, String data) { 5042 dropBox.addText(tag, data); 5043 } 5044 } 5045 5046 public static void main(String[] args) { 5047 SamplingProfilerIntegration.start(); 5048 5049 // CloseGuard defaults to true and can be quite spammy. We 5050 // disable it here, but selectively enable it later (via 5051 // StrictMode) on debug builds, but using DropBox, not logs. 5052 CloseGuard.setEnabled(false); 5053 5054 Environment.initForCurrentUser(); 5055 5056 // Set the reporter for event logging in libcore 5057 EventLogger.setReporter(new EventLoggingReporter()); 5058 5059 Security.addProvider(new AndroidKeyStoreProvider()); 5060 5061 Process.setArgV0("<pre-initialized>"); 5062 5063 Looper.prepareMainLooper(); 5064 5065 ActivityThread thread = new ActivityThread(); 5066 thread.attach(false); 5067 5068 if (sMainThreadHandler == null) { 5069 sMainThreadHandler = thread.getHandler(); 5070 } 5071 5072 AsyncTask.init(); 5073 5074 if (false) { 5075 Looper.myLooper().setMessageLogging(new 5076 LogPrinter(Log.DEBUG, "ActivityThread")); 5077 } 5078 5079 Looper.loop(); 5080 5081 throw new RuntimeException("Main thread loop unexpectedly exited"); 5082 } 5083} 5084