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