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