ActivityThread.java revision 3480ab45c82681399ac45d54105513baa9c041f6
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) { 1811 synchronized (this) { 1812 getSystemContext().installSystemApplicationInfo(info); 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 } 3498 3499 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3500 LoadedApk apk = peekPackageInfo(data.pkg, false); 3501 if (apk != null) { 3502 apk.setCompatibilityInfo(data.info); 3503 } 3504 apk = peekPackageInfo(data.pkg, true); 3505 if (apk != null) { 3506 apk.setCompatibilityInfo(data.info); 3507 } 3508 handleConfigurationChanged(mConfiguration, data.info); 3509 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3510 } 3511 3512 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3513 final int N = results.size(); 3514 for (int i=0; i<N; i++) { 3515 ResultInfo ri = results.get(i); 3516 try { 3517 if (ri.mData != null) { 3518 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3519 ri.mData.prepareToEnterProcess(); 3520 } 3521 if (DEBUG_RESULTS) Slog.v(TAG, 3522 "Delivering result to activity " + r + " : " + ri); 3523 r.activity.dispatchActivityResult(ri.mResultWho, 3524 ri.mRequestCode, ri.mResultCode, ri.mData); 3525 } catch (Exception e) { 3526 if (!mInstrumentation.onException(r.activity, e)) { 3527 throw new RuntimeException( 3528 "Failure delivering result " + ri + " to activity " 3529 + r.intent.getComponent().toShortString() 3530 + ": " + e.toString(), e); 3531 } 3532 } 3533 } 3534 } 3535 3536 private void handleSendResult(ResultData res) { 3537 ActivityClientRecord r = mActivities.get(res.token); 3538 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3539 if (r != null) { 3540 final boolean resumed = !r.paused; 3541 if (!r.activity.mFinished && r.activity.mDecor != null 3542 && r.hideForNow && resumed) { 3543 // We had hidden the activity because it started another 3544 // one... we have gotten a result back and we are not 3545 // paused, so make sure our window is visible. 3546 updateVisibility(r, true); 3547 } 3548 if (resumed) { 3549 try { 3550 // Now we are idle. 3551 r.activity.mCalled = false; 3552 r.activity.mTemporaryPause = true; 3553 mInstrumentation.callActivityOnPause(r.activity); 3554 if (!r.activity.mCalled) { 3555 throw new SuperNotCalledException( 3556 "Activity " + r.intent.getComponent().toShortString() 3557 + " did not call through to super.onPause()"); 3558 } 3559 } catch (SuperNotCalledException e) { 3560 throw e; 3561 } catch (Exception e) { 3562 if (!mInstrumentation.onException(r.activity, e)) { 3563 throw new RuntimeException( 3564 "Unable to pause activity " 3565 + r.intent.getComponent().toShortString() 3566 + ": " + e.toString(), e); 3567 } 3568 } 3569 } 3570 deliverResults(r, res.results); 3571 if (resumed) { 3572 r.activity.performResume(); 3573 r.activity.mTemporaryPause = false; 3574 } 3575 } 3576 } 3577 3578 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 3579 return performDestroyActivity(token, finishing, 0, false); 3580 } 3581 3582 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 3583 int configChanges, boolean getNonConfigInstance) { 3584 ActivityClientRecord r = mActivities.get(token); 3585 Class<? extends Activity> activityClass = null; 3586 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 3587 if (r != null) { 3588 activityClass = r.activity.getClass(); 3589 r.activity.mConfigChangeFlags |= configChanges; 3590 if (finishing) { 3591 r.activity.mFinished = true; 3592 } 3593 if (!r.paused) { 3594 try { 3595 r.activity.mCalled = false; 3596 mInstrumentation.callActivityOnPause(r.activity); 3597 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3598 r.activity.getComponentName().getClassName()); 3599 if (!r.activity.mCalled) { 3600 throw new SuperNotCalledException( 3601 "Activity " + safeToComponentShortString(r.intent) 3602 + " did not call through to super.onPause()"); 3603 } 3604 } catch (SuperNotCalledException e) { 3605 throw e; 3606 } catch (Exception e) { 3607 if (!mInstrumentation.onException(r.activity, e)) { 3608 throw new RuntimeException( 3609 "Unable to pause activity " 3610 + safeToComponentShortString(r.intent) 3611 + ": " + e.toString(), e); 3612 } 3613 } 3614 r.paused = true; 3615 } 3616 if (!r.stopped) { 3617 try { 3618 r.activity.performStop(); 3619 } catch (SuperNotCalledException e) { 3620 throw e; 3621 } catch (Exception e) { 3622 if (!mInstrumentation.onException(r.activity, e)) { 3623 throw new RuntimeException( 3624 "Unable to stop activity " 3625 + safeToComponentShortString(r.intent) 3626 + ": " + e.toString(), e); 3627 } 3628 } 3629 r.stopped = true; 3630 } 3631 if (getNonConfigInstance) { 3632 try { 3633 r.lastNonConfigurationInstances 3634 = r.activity.retainNonConfigurationInstances(); 3635 } catch (Exception e) { 3636 if (!mInstrumentation.onException(r.activity, e)) { 3637 throw new RuntimeException( 3638 "Unable to retain activity " 3639 + r.intent.getComponent().toShortString() 3640 + ": " + e.toString(), e); 3641 } 3642 } 3643 } 3644 try { 3645 r.activity.mCalled = false; 3646 mInstrumentation.callActivityOnDestroy(r.activity); 3647 if (!r.activity.mCalled) { 3648 throw new SuperNotCalledException( 3649 "Activity " + safeToComponentShortString(r.intent) + 3650 " did not call through to super.onDestroy()"); 3651 } 3652 if (r.window != null) { 3653 r.window.closeAllPanels(); 3654 } 3655 } catch (SuperNotCalledException e) { 3656 throw e; 3657 } catch (Exception e) { 3658 if (!mInstrumentation.onException(r.activity, e)) { 3659 throw new RuntimeException( 3660 "Unable to destroy activity " + safeToComponentShortString(r.intent) 3661 + ": " + e.toString(), e); 3662 } 3663 } 3664 } 3665 mActivities.remove(token); 3666 StrictMode.decrementExpectedActivityCount(activityClass); 3667 return r; 3668 } 3669 3670 private static String safeToComponentShortString(Intent intent) { 3671 ComponentName component = intent.getComponent(); 3672 return component == null ? "[Unknown]" : component.toShortString(); 3673 } 3674 3675 private void handleDestroyActivity(IBinder token, boolean finishing, 3676 int configChanges, boolean getNonConfigInstance) { 3677 ActivityClientRecord r = performDestroyActivity(token, finishing, 3678 configChanges, getNonConfigInstance); 3679 if (r != null) { 3680 cleanUpPendingRemoveWindows(r); 3681 WindowManager wm = r.activity.getWindowManager(); 3682 View v = r.activity.mDecor; 3683 if (v != null) { 3684 if (r.activity.mVisibleFromServer) { 3685 mNumVisibleActivities--; 3686 } 3687 IBinder wtoken = v.getWindowToken(); 3688 if (r.activity.mWindowAdded) { 3689 if (r.onlyLocalRequest) { 3690 // Hold off on removing this until the new activity's 3691 // window is being added. 3692 r.mPendingRemoveWindow = v; 3693 r.mPendingRemoveWindowManager = wm; 3694 } else { 3695 wm.removeViewImmediate(v); 3696 } 3697 } 3698 if (wtoken != null && r.mPendingRemoveWindow == null) { 3699 WindowManagerGlobal.getInstance().closeAll(wtoken, 3700 r.activity.getClass().getName(), "Activity"); 3701 } 3702 r.activity.mDecor = null; 3703 } 3704 if (r.mPendingRemoveWindow == null) { 3705 // If we are delaying the removal of the activity window, then 3706 // we can't clean up all windows here. Note that we can't do 3707 // so later either, which means any windows that aren't closed 3708 // by the app will leak. Well we try to warning them a lot 3709 // about leaking windows, because that is a bug, so if they are 3710 // using this recreate facility then they get to live with leaks. 3711 WindowManagerGlobal.getInstance().closeAll(token, 3712 r.activity.getClass().getName(), "Activity"); 3713 } 3714 3715 // Mocked out contexts won't be participating in the normal 3716 // process lifecycle, but if we're running with a proper 3717 // ApplicationContext we need to have it tear down things 3718 // cleanly. 3719 Context c = r.activity.getBaseContext(); 3720 if (c instanceof ContextImpl) { 3721 ((ContextImpl) c).scheduleFinalCleanup( 3722 r.activity.getClass().getName(), "Activity"); 3723 } 3724 } 3725 if (finishing) { 3726 try { 3727 ActivityManagerNative.getDefault().activityDestroyed(token); 3728 } catch (RemoteException ex) { 3729 // If the system process has died, it's game over for everyone. 3730 } 3731 } 3732 } 3733 3734 public final void requestRelaunchActivity(IBinder token, 3735 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 3736 int configChanges, boolean notResumed, Configuration config, 3737 boolean fromServer) { 3738 ActivityClientRecord target = null; 3739 3740 synchronized (mResourcesManager) { 3741 for (int i=0; i<mRelaunchingActivities.size(); i++) { 3742 ActivityClientRecord r = mRelaunchingActivities.get(i); 3743 if (r.token == token) { 3744 target = r; 3745 if (pendingResults != null) { 3746 if (r.pendingResults != null) { 3747 r.pendingResults.addAll(pendingResults); 3748 } else { 3749 r.pendingResults = pendingResults; 3750 } 3751 } 3752 if (pendingNewIntents != null) { 3753 if (r.pendingIntents != null) { 3754 r.pendingIntents.addAll(pendingNewIntents); 3755 } else { 3756 r.pendingIntents = pendingNewIntents; 3757 } 3758 } 3759 break; 3760 } 3761 } 3762 3763 if (target == null) { 3764 target = new ActivityClientRecord(); 3765 target.token = token; 3766 target.pendingResults = pendingResults; 3767 target.pendingIntents = pendingNewIntents; 3768 if (!fromServer) { 3769 ActivityClientRecord existing = mActivities.get(token); 3770 if (existing != null) { 3771 target.startsNotResumed = existing.paused; 3772 } 3773 target.onlyLocalRequest = true; 3774 } 3775 mRelaunchingActivities.add(target); 3776 sendMessage(H.RELAUNCH_ACTIVITY, target); 3777 } 3778 3779 if (fromServer) { 3780 target.startsNotResumed = notResumed; 3781 target.onlyLocalRequest = false; 3782 } 3783 if (config != null) { 3784 target.createdConfig = config; 3785 } 3786 target.pendingConfigChanges |= configChanges; 3787 } 3788 } 3789 3790 private void handleRelaunchActivity(ActivityClientRecord tmp) { 3791 // If we are getting ready to gc after going to the background, well 3792 // we are back active so skip it. 3793 unscheduleGcIdler(); 3794 3795 Configuration changedConfig = null; 3796 int configChanges = 0; 3797 3798 // First: make sure we have the most recent configuration and most 3799 // recent version of the activity, or skip it if some previous call 3800 // had taken a more recent version. 3801 synchronized (mResourcesManager) { 3802 int N = mRelaunchingActivities.size(); 3803 IBinder token = tmp.token; 3804 tmp = null; 3805 for (int i=0; i<N; i++) { 3806 ActivityClientRecord r = mRelaunchingActivities.get(i); 3807 if (r.token == token) { 3808 tmp = r; 3809 configChanges |= tmp.pendingConfigChanges; 3810 mRelaunchingActivities.remove(i); 3811 i--; 3812 N--; 3813 } 3814 } 3815 3816 if (tmp == null) { 3817 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 3818 return; 3819 } 3820 3821 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3822 + tmp.token + " with configChanges=0x" 3823 + Integer.toHexString(configChanges)); 3824 3825 if (mPendingConfiguration != null) { 3826 changedConfig = mPendingConfiguration; 3827 mPendingConfiguration = null; 3828 } 3829 } 3830 3831 if (tmp.createdConfig != null) { 3832 // If the activity manager is passing us its current config, 3833 // assume that is really what we want regardless of what we 3834 // may have pending. 3835 if (mConfiguration == null 3836 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 3837 && mConfiguration.diff(tmp.createdConfig) != 0)) { 3838 if (changedConfig == null 3839 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 3840 changedConfig = tmp.createdConfig; 3841 } 3842 } 3843 } 3844 3845 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3846 + tmp.token + ": changedConfig=" + changedConfig); 3847 3848 // If there was a pending configuration change, execute it first. 3849 if (changedConfig != null) { 3850 mCurDefaultDisplayDpi = changedConfig.densityDpi; 3851 updateDefaultDensity(); 3852 handleConfigurationChanged(changedConfig, null); 3853 } 3854 3855 ActivityClientRecord r = mActivities.get(tmp.token); 3856 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 3857 if (r == null) { 3858 return; 3859 } 3860 3861 r.activity.mConfigChangeFlags |= configChanges; 3862 r.onlyLocalRequest = tmp.onlyLocalRequest; 3863 Intent currentIntent = r.activity.mIntent; 3864 3865 r.activity.mChangingConfigurations = true; 3866 3867 // Need to ensure state is saved. 3868 if (!r.paused) { 3869 performPauseActivity(r.token, false, r.isPreHoneycomb()); 3870 } 3871 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 3872 callCallActivityOnSaveInstanceState(r); 3873 } 3874 3875 handleDestroyActivity(r.token, false, configChanges, true); 3876 3877 r.activity = null; 3878 r.window = null; 3879 r.hideForNow = false; 3880 r.nextIdle = null; 3881 // Merge any pending results and pending intents; don't just replace them 3882 if (tmp.pendingResults != null) { 3883 if (r.pendingResults == null) { 3884 r.pendingResults = tmp.pendingResults; 3885 } else { 3886 r.pendingResults.addAll(tmp.pendingResults); 3887 } 3888 } 3889 if (tmp.pendingIntents != null) { 3890 if (r.pendingIntents == null) { 3891 r.pendingIntents = tmp.pendingIntents; 3892 } else { 3893 r.pendingIntents.addAll(tmp.pendingIntents); 3894 } 3895 } 3896 r.startsNotResumed = tmp.startsNotResumed; 3897 3898 handleLaunchActivity(r, currentIntent); 3899 } 3900 3901 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) { 3902 r.state = new Bundle(); 3903 r.state.setAllowFds(false); 3904 if (r.isPersistable()) { 3905 r.persistentState = new PersistableBundle(); 3906 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 3907 r.persistentState); 3908 } else { 3909 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 3910 } 3911 } 3912 3913 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 3914 boolean allActivities, Configuration newConfig) { 3915 ArrayList<ComponentCallbacks2> callbacks 3916 = new ArrayList<ComponentCallbacks2>(); 3917 3918 synchronized (mResourcesManager) { 3919 final int NAPP = mAllApplications.size(); 3920 for (int i=0; i<NAPP; i++) { 3921 callbacks.add(mAllApplications.get(i)); 3922 } 3923 final int NACT = mActivities.size(); 3924 for (int i=0; i<NACT; i++) { 3925 ActivityClientRecord ar = mActivities.valueAt(i); 3926 Activity a = ar.activity; 3927 if (a != null) { 3928 Configuration thisConfig = applyConfigCompatMainThread( 3929 mCurDefaultDisplayDpi, newConfig, 3930 ar.packageInfo.getCompatibilityInfo()); 3931 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 3932 // If the activity is currently resumed, its configuration 3933 // needs to change right now. 3934 callbacks.add(a); 3935 } else if (thisConfig != null) { 3936 // Otherwise, we will tell it about the change 3937 // the next time it is resumed or shown. Note that 3938 // the activity manager may, before then, decide the 3939 // activity needs to be destroyed to handle its new 3940 // configuration. 3941 if (DEBUG_CONFIGURATION) { 3942 Slog.v(TAG, "Setting activity " 3943 + ar.activityInfo.name + " newConfig=" + thisConfig); 3944 } 3945 ar.newConfig = thisConfig; 3946 } 3947 } 3948 } 3949 final int NSVC = mServices.size(); 3950 for (int i=0; i<NSVC; i++) { 3951 callbacks.add(mServices.valueAt(i)); 3952 } 3953 } 3954 synchronized (mProviderMap) { 3955 final int NPRV = mLocalProviders.size(); 3956 for (int i=0; i<NPRV; i++) { 3957 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 3958 } 3959 } 3960 3961 return callbacks; 3962 } 3963 3964 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { 3965 // Only for Activity objects, check that they actually call up to their 3966 // superclass implementation. ComponentCallbacks2 is an interface, so 3967 // we check the runtime type and act accordingly. 3968 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 3969 if (activity != null) { 3970 activity.mCalled = false; 3971 } 3972 3973 boolean shouldChangeConfig = false; 3974 if ((activity == null) || (activity.mCurrentConfig == null)) { 3975 shouldChangeConfig = true; 3976 } else { 3977 3978 // If the new config is the same as the config this Activity 3979 // is already running with then don't bother calling 3980 // onConfigurationChanged 3981 int diff = activity.mCurrentConfig.diff(config); 3982 if (diff != 0) { 3983 // If this activity doesn't handle any of the config changes 3984 // then don't bother calling onConfigurationChanged as we're 3985 // going to destroy it. 3986 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) { 3987 shouldChangeConfig = true; 3988 } 3989 } 3990 } 3991 3992 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 3993 + ": shouldChangeConfig=" + shouldChangeConfig); 3994 if (shouldChangeConfig) { 3995 cb.onConfigurationChanged(config); 3996 3997 if (activity != null) { 3998 if (!activity.mCalled) { 3999 throw new SuperNotCalledException( 4000 "Activity " + activity.getLocalClassName() + 4001 " did not call through to super.onConfigurationChanged()"); 4002 } 4003 activity.mConfigChangeFlags = 0; 4004 activity.mCurrentConfig = new Configuration(config); 4005 } 4006 } 4007 } 4008 4009 public final void applyConfigurationToResources(Configuration config) { 4010 synchronized (mResourcesManager) { 4011 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 4012 } 4013 } 4014 4015 final Configuration applyCompatConfiguration(int displayDensity) { 4016 Configuration config = mConfiguration; 4017 if (mCompatConfiguration == null) { 4018 mCompatConfiguration = new Configuration(); 4019 } 4020 mCompatConfiguration.setTo(mConfiguration); 4021 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { 4022 config = mCompatConfiguration; 4023 } 4024 return config; 4025 } 4026 4027 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 4028 4029 int configDiff = 0; 4030 4031 synchronized (mResourcesManager) { 4032 if (mPendingConfiguration != null) { 4033 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 4034 config = mPendingConfiguration; 4035 mCurDefaultDisplayDpi = config.densityDpi; 4036 updateDefaultDensity(); 4037 } 4038 mPendingConfiguration = null; 4039 } 4040 4041 if (config == null) { 4042 return; 4043 } 4044 4045 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 4046 + config); 4047 4048 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 4049 4050 if (mConfiguration == null) { 4051 mConfiguration = new Configuration(); 4052 } 4053 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 4054 return; 4055 } 4056 configDiff = mConfiguration.diff(config); 4057 mConfiguration.updateFrom(config); 4058 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 4059 } 4060 4061 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 4062 4063 freeTextLayoutCachesIfNeeded(configDiff); 4064 4065 if (callbacks != null) { 4066 final int N = callbacks.size(); 4067 for (int i=0; i<N; i++) { 4068 performConfigurationChanged(callbacks.get(i), config); 4069 } 4070 } 4071 } 4072 4073 static void freeTextLayoutCachesIfNeeded(int configDiff) { 4074 if (configDiff != 0) { 4075 // Ask text layout engine to free its caches if there is a locale change 4076 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 4077 if (hasLocaleConfigChange) { 4078 Canvas.freeTextLayoutCaches(); 4079 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 4080 } 4081 } 4082 } 4083 4084 final void handleActivityConfigurationChanged(IBinder token) { 4085 ActivityClientRecord r = mActivities.get(token); 4086 if (r == null || r.activity == null) { 4087 return; 4088 } 4089 4090 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4091 + r.activityInfo.name); 4092 4093 performConfigurationChanged(r.activity, mCompatConfiguration); 4094 4095 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 4096 } 4097 4098 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { 4099 if (start) { 4100 try { 4101 switch (profileType) { 4102 default: 4103 mProfiler.setProfiler(pcd.path, pcd.fd); 4104 mProfiler.autoStopProfiler = false; 4105 mProfiler.startProfiling(); 4106 break; 4107 } 4108 } catch (RuntimeException e) { 4109 Slog.w(TAG, "Profiling failed on path " + pcd.path 4110 + " -- can the process access this path?"); 4111 } finally { 4112 try { 4113 pcd.fd.close(); 4114 } catch (IOException e) { 4115 Slog.w(TAG, "Failure closing profile fd", e); 4116 } 4117 } 4118 } else { 4119 switch (profileType) { 4120 default: 4121 mProfiler.stopProfiling(); 4122 break; 4123 } 4124 } 4125 } 4126 4127 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4128 if (managed) { 4129 try { 4130 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4131 } catch (IOException e) { 4132 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4133 + " -- can the process access this path?"); 4134 } finally { 4135 try { 4136 dhd.fd.close(); 4137 } catch (IOException e) { 4138 Slog.w(TAG, "Failure closing profile fd", e); 4139 } 4140 } 4141 } else { 4142 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4143 } 4144 } 4145 4146 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4147 boolean hasPkgInfo = false; 4148 if (packages != null) { 4149 for (int i=packages.length-1; i>=0; i--) { 4150 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4151 if (!hasPkgInfo) { 4152 WeakReference<LoadedApk> ref; 4153 ref = mPackages.get(packages[i]); 4154 if (ref != null && ref.get() != null) { 4155 hasPkgInfo = true; 4156 } else { 4157 ref = mResourcePackages.get(packages[i]); 4158 if (ref != null && ref.get() != null) { 4159 hasPkgInfo = true; 4160 } 4161 } 4162 } 4163 mPackages.remove(packages[i]); 4164 mResourcePackages.remove(packages[i]); 4165 } 4166 } 4167 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4168 hasPkgInfo); 4169 } 4170 4171 final void handleLowMemory() { 4172 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4173 4174 final int N = callbacks.size(); 4175 for (int i=0; i<N; i++) { 4176 callbacks.get(i).onLowMemory(); 4177 } 4178 4179 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4180 if (Process.myUid() != Process.SYSTEM_UID) { 4181 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4182 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4183 } 4184 4185 // Ask graphics to free up as much as possible (font/image caches) 4186 Canvas.freeCaches(); 4187 4188 // Ask text layout engine to free also as much as possible 4189 Canvas.freeTextLayoutCaches(); 4190 4191 BinderInternal.forceGc("mem"); 4192 } 4193 4194 final void handleTrimMemory(int level) { 4195 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4196 4197 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4198 4199 final int N = callbacks.size(); 4200 for (int i = 0; i < N; i++) { 4201 callbacks.get(i).onTrimMemory(level); 4202 } 4203 4204 WindowManagerGlobal.getInstance().trimMemory(level); 4205 } 4206 4207 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4208 if (Process.isIsolated()) { 4209 // Isolated processes aren't going to do UI. 4210 return; 4211 } 4212 try { 4213 int uid = Process.myUid(); 4214 String[] packages = getPackageManager().getPackagesForUid(uid); 4215 4216 // If there are several packages in this application we won't 4217 // initialize the graphics disk caches 4218 if (packages != null && packages.length == 1) { 4219 HardwareRenderer.setupDiskCache(cacheDir); 4220 RenderScript.setupDiskCache(cacheDir); 4221 } 4222 } catch (RemoteException e) { 4223 // Ignore 4224 } 4225 } 4226 4227 private void updateDefaultDensity() { 4228 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED 4229 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE 4230 && !mDensityCompatMode) { 4231 Slog.i(TAG, "Switching default density from " 4232 + DisplayMetrics.DENSITY_DEVICE + " to " 4233 + mCurDefaultDisplayDpi); 4234 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; 4235 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4236 } 4237 } 4238 4239 private void handleBindApplication(AppBindData data) { 4240 mBoundApplication = data; 4241 mConfiguration = new Configuration(data.config); 4242 mCompatConfiguration = new Configuration(data.config); 4243 4244 mProfiler = new Profiler(); 4245 mProfiler.profileFile = data.initProfileFile; 4246 mProfiler.profileFd = data.initProfileFd; 4247 mProfiler.autoStopProfiler = data.initAutoStopProfiler; 4248 4249 // send up app name; do this *before* waiting for debugger 4250 Process.setArgV0(data.processName); 4251 android.ddm.DdmHandleAppName.setAppName(data.processName, 4252 UserHandle.myUserId()); 4253 4254 if (data.persistent) { 4255 // Persistent processes on low-memory devices do not get to 4256 // use hardware accelerated drawing, since this can add too much 4257 // overhead to the process. 4258 if (!ActivityManager.isHighEndGfx()) { 4259 HardwareRenderer.disable(false); 4260 } 4261 } 4262 4263 if (mProfiler.profileFd != null) { 4264 mProfiler.startProfiling(); 4265 } 4266 4267 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4268 // implementation to use the pool executor. Normally, we use the 4269 // serialized executor as the default. This has to happen in the 4270 // main thread so the main looper is set right. 4271 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4272 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4273 } 4274 4275 /* 4276 * Before spawning a new process, reset the time zone to be the system time zone. 4277 * This needs to be done because the system time zone could have changed after the 4278 * the spawning of this process. Without doing this this process would have the incorrect 4279 * system time zone. 4280 */ 4281 TimeZone.setDefault(null); 4282 4283 /* 4284 * Initialize the default locale in this process for the reasons we set the time zone. 4285 */ 4286 Locale.setDefault(data.config.locale); 4287 4288 /* 4289 * Update the system configuration since its preloaded and might not 4290 * reflect configuration changes. The configuration object passed 4291 * in AppBindData can be safely assumed to be up to date 4292 */ 4293 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4294 mCurDefaultDisplayDpi = data.config.densityDpi; 4295 applyCompatConfiguration(mCurDefaultDisplayDpi); 4296 4297 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4298 4299 /** 4300 * Switch this process to density compatibility mode if needed. 4301 */ 4302 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4303 == 0) { 4304 mDensityCompatMode = true; 4305 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4306 } 4307 updateDefaultDensity(); 4308 4309 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 4310 if (!Process.isIsolated()) { 4311 final File cacheDir = appContext.getCacheDir(); 4312 4313 if (cacheDir != null) { 4314 // Provide a usable directory for temporary files 4315 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 4316 4317 setupGraphicsSupport(data.info, cacheDir); 4318 } else { 4319 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory"); 4320 } 4321 } 4322 4323 4324 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); 4325 DateFormat.set24HourTimePref(is24Hr); 4326 4327 /** 4328 * For system applications on userdebug/eng builds, log stack 4329 * traces of disk and network access to dropbox for analysis. 4330 */ 4331 if ((data.appInfo.flags & 4332 (ApplicationInfo.FLAG_SYSTEM | 4333 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4334 StrictMode.conditionallyEnableDebugLogging(); 4335 } 4336 4337 /** 4338 * For apps targetting SDK Honeycomb or later, we don't allow 4339 * network usage on the main event loop / UI thread. 4340 * 4341 * Note to those grepping: this is what ultimately throws 4342 * NetworkOnMainThreadException ... 4343 */ 4344 if (data.appInfo.targetSdkVersion > 9) { 4345 StrictMode.enableDeathOnNetwork(); 4346 } 4347 4348 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4349 // XXX should have option to change the port. 4350 Debug.changeDebugPort(8100); 4351 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4352 Slog.w(TAG, "Application " + data.info.getPackageName() 4353 + " is waiting for the debugger on port 8100..."); 4354 4355 IActivityManager mgr = ActivityManagerNative.getDefault(); 4356 try { 4357 mgr.showWaitingForDebugger(mAppThread, true); 4358 } catch (RemoteException ex) { 4359 } 4360 4361 Debug.waitForDebugger(); 4362 4363 try { 4364 mgr.showWaitingForDebugger(mAppThread, false); 4365 } catch (RemoteException ex) { 4366 } 4367 4368 } else { 4369 Slog.w(TAG, "Application " + data.info.getPackageName() 4370 + " can be debugged on port 8100..."); 4371 } 4372 } 4373 4374 // Enable OpenGL tracing if required 4375 if (data.enableOpenGlTrace) { 4376 GLUtils.setTracingLevel(1); 4377 } 4378 4379 // Allow application-generated systrace messages if we're debuggable. 4380 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0; 4381 Trace.setAppTracingAllowed(appTracingAllowed); 4382 4383 /** 4384 * Initialize the default http proxy in this process for the reasons we set the time zone. 4385 */ 4386 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 4387 if (b != null) { 4388 // In pre-boot mode (doing initial launch to collect password), not 4389 // all system is up. This includes the connectivity service, so don't 4390 // crash if we can't get it. 4391 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4392 try { 4393 ProxyInfo proxyInfo = service.getProxy(); 4394 Proxy.setHttpProxySystemProperty(proxyInfo); 4395 } catch (RemoteException e) {} 4396 } 4397 4398 if (data.instrumentationName != null) { 4399 InstrumentationInfo ii = null; 4400 try { 4401 ii = appContext.getPackageManager(). 4402 getInstrumentationInfo(data.instrumentationName, 0); 4403 } catch (PackageManager.NameNotFoundException e) { 4404 } 4405 if (ii == null) { 4406 throw new RuntimeException( 4407 "Unable to find instrumentation info for: " 4408 + data.instrumentationName); 4409 } 4410 4411 mInstrumentationPackageName = ii.packageName; 4412 mInstrumentationAppDir = ii.sourceDir; 4413 mInstrumentationSplitAppDirs = ii.splitSourceDirs; 4414 mInstrumentationLibDir = ii.nativeLibraryDir; 4415 mInstrumentedAppDir = data.info.getAppDir(); 4416 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 4417 mInstrumentedLibDir = data.info.getLibDir(); 4418 4419 ApplicationInfo instrApp = new ApplicationInfo(); 4420 instrApp.packageName = ii.packageName; 4421 instrApp.sourceDir = ii.sourceDir; 4422 instrApp.publicSourceDir = ii.publicSourceDir; 4423 instrApp.splitSourceDirs = ii.splitSourceDirs; 4424 instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs; 4425 instrApp.dataDir = ii.dataDir; 4426 instrApp.nativeLibraryDir = ii.nativeLibraryDir; 4427 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 4428 appContext.getClassLoader(), false, true, false); 4429 ContextImpl instrContext = ContextImpl.createAppContext(this, pi); 4430 4431 try { 4432 java.lang.ClassLoader cl = instrContext.getClassLoader(); 4433 mInstrumentation = (Instrumentation) 4434 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4435 } catch (Exception e) { 4436 throw new RuntimeException( 4437 "Unable to instantiate instrumentation " 4438 + data.instrumentationName + ": " + e.toString(), e); 4439 } 4440 4441 mInstrumentation.init(this, instrContext, appContext, 4442 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, 4443 data.instrumentationUiAutomationConnection); 4444 4445 if (mProfiler.profileFile != null && !ii.handleProfiling 4446 && mProfiler.profileFd == null) { 4447 mProfiler.handlingProfiling = true; 4448 File file = new File(mProfiler.profileFile); 4449 file.getParentFile().mkdirs(); 4450 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 4451 } 4452 4453 } else { 4454 mInstrumentation = new Instrumentation(); 4455 } 4456 4457 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 4458 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 4459 } 4460 4461 // Allow disk access during application and provider setup. This could 4462 // block processing ordered broadcasts, but later processing would 4463 // probably end up doing the same disk access. 4464 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 4465 try { 4466 // If the app is being launched for full backup or restore, bring it up in 4467 // a restricted environment with the base application class. 4468 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 4469 mInitialApplication = app; 4470 4471 // don't bring up providers in restricted mode; they may depend on the 4472 // app's custom Application class 4473 if (!data.restrictedBackupMode) { 4474 List<ProviderInfo> providers = data.providers; 4475 if (providers != null) { 4476 installContentProviders(app, providers); 4477 // For process that contains content providers, we want to 4478 // ensure that the JIT is enabled "at some point". 4479 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 4480 } 4481 } 4482 4483 // Do this after providers, since instrumentation tests generally start their 4484 // test thread at this point, and we don't want that racing. 4485 try { 4486 mInstrumentation.onCreate(data.instrumentationArgs); 4487 } 4488 catch (Exception e) { 4489 throw new RuntimeException( 4490 "Exception thrown in onCreate() of " 4491 + data.instrumentationName + ": " + e.toString(), e); 4492 } 4493 4494 try { 4495 mInstrumentation.callApplicationOnCreate(app); 4496 } catch (Exception e) { 4497 if (!mInstrumentation.onException(app, e)) { 4498 throw new RuntimeException( 4499 "Unable to create application " + app.getClass().getName() 4500 + ": " + e.toString(), e); 4501 } 4502 } 4503 } finally { 4504 StrictMode.setThreadPolicy(savedPolicy); 4505 } 4506 } 4507 4508 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 4509 IActivityManager am = ActivityManagerNative.getDefault(); 4510 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 4511 && mProfiler.profileFd == null) { 4512 Debug.stopMethodTracing(); 4513 } 4514 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 4515 // + ", app thr: " + mAppThread); 4516 try { 4517 am.finishInstrumentation(mAppThread, resultCode, results); 4518 } catch (RemoteException ex) { 4519 } 4520 } 4521 4522 private void installContentProviders( 4523 Context context, List<ProviderInfo> providers) { 4524 final ArrayList<IActivityManager.ContentProviderHolder> results = 4525 new ArrayList<IActivityManager.ContentProviderHolder>(); 4526 4527 for (ProviderInfo cpi : providers) { 4528 if (DEBUG_PROVIDER) { 4529 StringBuilder buf = new StringBuilder(128); 4530 buf.append("Pub "); 4531 buf.append(cpi.authority); 4532 buf.append(": "); 4533 buf.append(cpi.name); 4534 Log.i(TAG, buf.toString()); 4535 } 4536 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 4537 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 4538 if (cph != null) { 4539 cph.noReleaseNeeded = true; 4540 results.add(cph); 4541 } 4542 } 4543 4544 try { 4545 ActivityManagerNative.getDefault().publishContentProviders( 4546 getApplicationThread(), results); 4547 } catch (RemoteException ex) { 4548 } 4549 } 4550 4551 public final IContentProvider acquireProvider( 4552 Context c, String auth, int userId, boolean stable) { 4553 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 4554 if (provider != null) { 4555 return provider; 4556 } 4557 4558 // There is a possible race here. Another thread may try to acquire 4559 // the same provider at the same time. When this happens, we want to ensure 4560 // that the first one wins. 4561 // Note that we cannot hold the lock while acquiring and installing the 4562 // provider since it might take a long time to run and it could also potentially 4563 // be re-entrant in the case where the provider is in the same process. 4564 IActivityManager.ContentProviderHolder holder = null; 4565 try { 4566 holder = ActivityManagerNative.getDefault().getContentProvider( 4567 getApplicationThread(), auth, userId, stable); 4568 } catch (RemoteException ex) { 4569 } 4570 if (holder == null) { 4571 Slog.e(TAG, "Failed to find provider info for " + auth); 4572 return null; 4573 } 4574 4575 // Install provider will increment the reference count for us, and break 4576 // any ties in the race. 4577 holder = installProvider(c, holder, holder.info, 4578 true /*noisy*/, holder.noReleaseNeeded, stable); 4579 return holder.provider; 4580 } 4581 4582 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 4583 if (stable) { 4584 prc.stableCount += 1; 4585 if (prc.stableCount == 1) { 4586 // We are acquiring a new stable reference on the provider. 4587 int unstableDelta; 4588 if (prc.removePending) { 4589 // We have a pending remove operation, which is holding the 4590 // last unstable reference. At this point we are converting 4591 // that unstable reference to our new stable reference. 4592 unstableDelta = -1; 4593 // Cancel the removal of the provider. 4594 if (DEBUG_PROVIDER) { 4595 Slog.v(TAG, "incProviderRef: stable " 4596 + "snatched provider from the jaws of death"); 4597 } 4598 prc.removePending = false; 4599 // There is a race! It fails to remove the message, which 4600 // will be handled in completeRemoveProvider(). 4601 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4602 } else { 4603 unstableDelta = 0; 4604 } 4605 try { 4606 if (DEBUG_PROVIDER) { 4607 Slog.v(TAG, "incProviderRef Now stable - " 4608 + prc.holder.info.name + ": unstableDelta=" 4609 + unstableDelta); 4610 } 4611 ActivityManagerNative.getDefault().refContentProvider( 4612 prc.holder.connection, 1, unstableDelta); 4613 } catch (RemoteException e) { 4614 //do nothing content provider object is dead any way 4615 } 4616 } 4617 } else { 4618 prc.unstableCount += 1; 4619 if (prc.unstableCount == 1) { 4620 // We are acquiring a new unstable reference on the provider. 4621 if (prc.removePending) { 4622 // Oh look, we actually have a remove pending for the 4623 // provider, which is still holding the last unstable 4624 // reference. We just need to cancel that to take new 4625 // ownership of the reference. 4626 if (DEBUG_PROVIDER) { 4627 Slog.v(TAG, "incProviderRef: unstable " 4628 + "snatched provider from the jaws of death"); 4629 } 4630 prc.removePending = false; 4631 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4632 } else { 4633 // First unstable ref, increment our count in the 4634 // activity manager. 4635 try { 4636 if (DEBUG_PROVIDER) { 4637 Slog.v(TAG, "incProviderRef: Now unstable - " 4638 + prc.holder.info.name); 4639 } 4640 ActivityManagerNative.getDefault().refContentProvider( 4641 prc.holder.connection, 0, 1); 4642 } catch (RemoteException e) { 4643 //do nothing content provider object is dead any way 4644 } 4645 } 4646 } 4647 } 4648 } 4649 4650 public final IContentProvider acquireExistingProvider( 4651 Context c, String auth, int userId, boolean stable) { 4652 synchronized (mProviderMap) { 4653 final ProviderKey key = new ProviderKey(auth, userId); 4654 final ProviderClientRecord pr = mProviderMap.get(key); 4655 if (pr == null) { 4656 return null; 4657 } 4658 4659 IContentProvider provider = pr.mProvider; 4660 IBinder jBinder = provider.asBinder(); 4661 if (!jBinder.isBinderAlive()) { 4662 // The hosting process of the provider has died; we can't 4663 // use this one. 4664 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 4665 + ": existing object's process dead"); 4666 handleUnstableProviderDiedLocked(jBinder, true); 4667 return null; 4668 } 4669 4670 // Only increment the ref count if we have one. If we don't then the 4671 // provider is not reference counted and never needs to be released. 4672 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4673 if (prc != null) { 4674 incProviderRefLocked(prc, stable); 4675 } 4676 return provider; 4677 } 4678 } 4679 4680 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 4681 if (provider == null) { 4682 return false; 4683 } 4684 4685 IBinder jBinder = provider.asBinder(); 4686 synchronized (mProviderMap) { 4687 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4688 if (prc == null) { 4689 // The provider has no ref count, no release is needed. 4690 return false; 4691 } 4692 4693 boolean lastRef = false; 4694 if (stable) { 4695 if (prc.stableCount == 0) { 4696 if (DEBUG_PROVIDER) Slog.v(TAG, 4697 "releaseProvider: stable ref count already 0, how?"); 4698 return false; 4699 } 4700 prc.stableCount -= 1; 4701 if (prc.stableCount == 0) { 4702 // What we do at this point depends on whether there are 4703 // any unstable refs left: if there are, we just tell the 4704 // activity manager to decrement its stable count; if there 4705 // aren't, we need to enqueue this provider to be removed, 4706 // and convert to holding a single unstable ref while 4707 // doing so. 4708 lastRef = prc.unstableCount == 0; 4709 try { 4710 if (DEBUG_PROVIDER) { 4711 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 4712 + lastRef + " - " + prc.holder.info.name); 4713 } 4714 ActivityManagerNative.getDefault().refContentProvider( 4715 prc.holder.connection, -1, lastRef ? 1 : 0); 4716 } catch (RemoteException e) { 4717 //do nothing content provider object is dead any way 4718 } 4719 } 4720 } else { 4721 if (prc.unstableCount == 0) { 4722 if (DEBUG_PROVIDER) Slog.v(TAG, 4723 "releaseProvider: unstable ref count already 0, how?"); 4724 return false; 4725 } 4726 prc.unstableCount -= 1; 4727 if (prc.unstableCount == 0) { 4728 // If this is the last reference, we need to enqueue 4729 // this provider to be removed instead of telling the 4730 // activity manager to remove it at this point. 4731 lastRef = prc.stableCount == 0; 4732 if (!lastRef) { 4733 try { 4734 if (DEBUG_PROVIDER) { 4735 Slog.v(TAG, "releaseProvider: No longer unstable - " 4736 + prc.holder.info.name); 4737 } 4738 ActivityManagerNative.getDefault().refContentProvider( 4739 prc.holder.connection, 0, -1); 4740 } catch (RemoteException e) { 4741 //do nothing content provider object is dead any way 4742 } 4743 } 4744 } 4745 } 4746 4747 if (lastRef) { 4748 if (!prc.removePending) { 4749 // Schedule the actual remove asynchronously, since we don't know the context 4750 // this will be called in. 4751 // TODO: it would be nice to post a delayed message, so 4752 // if we come back and need the same provider quickly 4753 // we will still have it available. 4754 if (DEBUG_PROVIDER) { 4755 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 4756 + prc.holder.info.name); 4757 } 4758 prc.removePending = true; 4759 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 4760 mH.sendMessage(msg); 4761 } else { 4762 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 4763 } 4764 } 4765 return true; 4766 } 4767 } 4768 4769 final void completeRemoveProvider(ProviderRefCount prc) { 4770 synchronized (mProviderMap) { 4771 if (!prc.removePending) { 4772 // There was a race! Some other client managed to acquire 4773 // the provider before the removal was completed. 4774 // Abort the removal. We will do it later. 4775 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 4776 + "provider still in use"); 4777 return; 4778 } 4779 4780 // More complicated race!! Some client managed to acquire the 4781 // provider and release it before the removal was completed. 4782 // Continue the removal, and abort the next remove message. 4783 prc.removePending = false; 4784 4785 final IBinder jBinder = prc.holder.provider.asBinder(); 4786 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 4787 if (existingPrc == prc) { 4788 mProviderRefCountMap.remove(jBinder); 4789 } 4790 4791 for (int i=mProviderMap.size()-1; i>=0; i--) { 4792 ProviderClientRecord pr = mProviderMap.valueAt(i); 4793 IBinder myBinder = pr.mProvider.asBinder(); 4794 if (myBinder == jBinder) { 4795 mProviderMap.removeAt(i); 4796 } 4797 } 4798 } 4799 4800 try { 4801 if (DEBUG_PROVIDER) { 4802 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 4803 + "removeContentProvider(" + prc.holder.info.name + ")"); 4804 } 4805 ActivityManagerNative.getDefault().removeContentProvider( 4806 prc.holder.connection, false); 4807 } catch (RemoteException e) { 4808 //do nothing content provider object is dead any way 4809 } 4810 } 4811 4812 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 4813 synchronized (mProviderMap) { 4814 handleUnstableProviderDiedLocked(provider, fromClient); 4815 } 4816 } 4817 4818 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 4819 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4820 if (prc != null) { 4821 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 4822 + provider + " " + prc.holder.info.name); 4823 mProviderRefCountMap.remove(provider); 4824 for (int i=mProviderMap.size()-1; i>=0; i--) { 4825 ProviderClientRecord pr = mProviderMap.valueAt(i); 4826 if (pr != null && pr.mProvider.asBinder() == provider) { 4827 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 4828 mProviderMap.removeAt(i); 4829 } 4830 } 4831 4832 if (fromClient) { 4833 // We found out about this due to execution in our client 4834 // code. Tell the activity manager about it now, to ensure 4835 // that the next time we go to do anything with the provider 4836 // it knows it is dead (so we don't race with its death 4837 // notification). 4838 try { 4839 ActivityManagerNative.getDefault().unstableProviderDied( 4840 prc.holder.connection); 4841 } catch (RemoteException e) { 4842 //do nothing content provider object is dead any way 4843 } 4844 } 4845 } 4846 } 4847 4848 final void appNotRespondingViaProvider(IBinder provider) { 4849 synchronized (mProviderMap) { 4850 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4851 if (prc != null) { 4852 try { 4853 ActivityManagerNative.getDefault() 4854 .appNotRespondingViaProvider(prc.holder.connection); 4855 } catch (RemoteException e) { 4856 } 4857 } 4858 } 4859 } 4860 4861 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 4862 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 4863 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority); 4864 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 4865 4866 final ProviderClientRecord pcr = new ProviderClientRecord( 4867 auths, provider, localProvider, holder); 4868 for (String auth : auths) { 4869 final ProviderKey key = new ProviderKey(auth, userId); 4870 final ProviderClientRecord existing = mProviderMap.get(key); 4871 if (existing != null) { 4872 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 4873 + " already published as " + auth); 4874 } else { 4875 mProviderMap.put(key, pcr); 4876 } 4877 } 4878 return pcr; 4879 } 4880 4881 /** 4882 * Installs the provider. 4883 * 4884 * Providers that are local to the process or that come from the system server 4885 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 4886 * Other remote providers are reference counted. The initial reference count 4887 * for all reference counted providers is one. Providers that are not reference 4888 * counted do not have a reference count (at all). 4889 * 4890 * This method detects when a provider has already been installed. When this happens, 4891 * it increments the reference count of the existing provider (if appropriate) 4892 * and returns the existing provider. This can happen due to concurrent 4893 * attempts to acquire the same provider. 4894 */ 4895 private IActivityManager.ContentProviderHolder installProvider(Context context, 4896 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 4897 boolean noisy, boolean noReleaseNeeded, boolean stable) { 4898 ContentProvider localProvider = null; 4899 IContentProvider provider; 4900 if (holder == null || holder.provider == null) { 4901 if (DEBUG_PROVIDER || noisy) { 4902 Slog.d(TAG, "Loading provider " + info.authority + ": " 4903 + info.name); 4904 } 4905 Context c = null; 4906 ApplicationInfo ai = info.applicationInfo; 4907 if (context.getPackageName().equals(ai.packageName)) { 4908 c = context; 4909 } else if (mInitialApplication != null && 4910 mInitialApplication.getPackageName().equals(ai.packageName)) { 4911 c = mInitialApplication; 4912 } else { 4913 try { 4914 c = context.createPackageContext(ai.packageName, 4915 Context.CONTEXT_INCLUDE_CODE); 4916 } catch (PackageManager.NameNotFoundException e) { 4917 // Ignore 4918 } 4919 } 4920 if (c == null) { 4921 Slog.w(TAG, "Unable to get context for package " + 4922 ai.packageName + 4923 " while loading content provider " + 4924 info.name); 4925 return null; 4926 } 4927 try { 4928 final java.lang.ClassLoader cl = c.getClassLoader(); 4929 localProvider = (ContentProvider)cl. 4930 loadClass(info.name).newInstance(); 4931 provider = localProvider.getIContentProvider(); 4932 if (provider == null) { 4933 Slog.e(TAG, "Failed to instantiate class " + 4934 info.name + " from sourceDir " + 4935 info.applicationInfo.sourceDir); 4936 return null; 4937 } 4938 if (DEBUG_PROVIDER) Slog.v( 4939 TAG, "Instantiating local provider " + info.name); 4940 // XXX Need to create the correct context for this provider. 4941 localProvider.attachInfo(c, info); 4942 } catch (java.lang.Exception e) { 4943 if (!mInstrumentation.onException(null, e)) { 4944 throw new RuntimeException( 4945 "Unable to get provider " + info.name 4946 + ": " + e.toString(), e); 4947 } 4948 return null; 4949 } 4950 } else { 4951 provider = holder.provider; 4952 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 4953 + info.name); 4954 } 4955 4956 IActivityManager.ContentProviderHolder retHolder; 4957 4958 synchronized (mProviderMap) { 4959 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 4960 + " / " + info.name); 4961 IBinder jBinder = provider.asBinder(); 4962 if (localProvider != null) { 4963 ComponentName cname = new ComponentName(info.packageName, info.name); 4964 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 4965 if (pr != null) { 4966 if (DEBUG_PROVIDER) { 4967 Slog.v(TAG, "installProvider: lost the race, " 4968 + "using existing local provider"); 4969 } 4970 provider = pr.mProvider; 4971 } else { 4972 holder = new IActivityManager.ContentProviderHolder(info); 4973 holder.provider = provider; 4974 holder.noReleaseNeeded = true; 4975 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 4976 mLocalProviders.put(jBinder, pr); 4977 mLocalProvidersByName.put(cname, pr); 4978 } 4979 retHolder = pr.mHolder; 4980 } else { 4981 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4982 if (prc != null) { 4983 if (DEBUG_PROVIDER) { 4984 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 4985 } 4986 // We need to transfer our new reference to the existing 4987 // ref count, releasing the old one... but only if 4988 // release is needed (that is, it is not running in the 4989 // system process). 4990 if (!noReleaseNeeded) { 4991 incProviderRefLocked(prc, stable); 4992 try { 4993 ActivityManagerNative.getDefault().removeContentProvider( 4994 holder.connection, stable); 4995 } catch (RemoteException e) { 4996 //do nothing content provider object is dead any way 4997 } 4998 } 4999 } else { 5000 ProviderClientRecord client = installProviderAuthoritiesLocked( 5001 provider, localProvider, holder); 5002 if (noReleaseNeeded) { 5003 prc = new ProviderRefCount(holder, client, 1000, 1000); 5004 } else { 5005 prc = stable 5006 ? new ProviderRefCount(holder, client, 1, 0) 5007 : new ProviderRefCount(holder, client, 0, 1); 5008 } 5009 mProviderRefCountMap.put(jBinder, prc); 5010 } 5011 retHolder = prc.holder; 5012 } 5013 } 5014 5015 return retHolder; 5016 } 5017 5018 private void attach(boolean system) { 5019 sCurrentActivityThread = this; 5020 mSystemThread = system; 5021 if (!system) { 5022 ViewRootImpl.addFirstDrawHandler(new Runnable() { 5023 @Override 5024 public void run() { 5025 ensureJitEnabled(); 5026 } 5027 }); 5028 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 5029 UserHandle.myUserId()); 5030 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 5031 IActivityManager mgr = ActivityManagerNative.getDefault(); 5032 try { 5033 mgr.attachApplication(mAppThread); 5034 } catch (RemoteException ex) { 5035 // Ignore 5036 } 5037 } else { 5038 // Don't set application object here -- if the system crashes, 5039 // we can't display an alert, we just want to die die die. 5040 android.ddm.DdmHandleAppName.setAppName("system_process", 5041 UserHandle.myUserId()); 5042 try { 5043 mInstrumentation = new Instrumentation(); 5044 ContextImpl context = ContextImpl.createAppContext( 5045 this, getSystemContext().mPackageInfo); 5046 Application app = Instrumentation.newApplication(Application.class, context); 5047 mAllApplications.add(app); 5048 mInitialApplication = app; 5049 app.onCreate(); 5050 } catch (Exception e) { 5051 throw new RuntimeException( 5052 "Unable to instantiate Application():" + e.toString(), e); 5053 } 5054 } 5055 5056 // add dropbox logging to libcore 5057 DropBox.setReporter(new DropBoxReporter()); 5058 5059 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 5060 @Override 5061 public void onConfigurationChanged(Configuration newConfig) { 5062 synchronized (mResourcesManager) { 5063 // We need to apply this change to the resources 5064 // immediately, because upon returning the view 5065 // hierarchy will be informed about it. 5066 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { 5067 // This actually changed the resources! Tell 5068 // everyone about it. 5069 if (mPendingConfiguration == null || 5070 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 5071 mPendingConfiguration = newConfig; 5072 5073 sendMessage(H.CONFIGURATION_CHANGED, newConfig); 5074 } 5075 } 5076 } 5077 } 5078 @Override 5079 public void onLowMemory() { 5080 } 5081 @Override 5082 public void onTrimMemory(int level) { 5083 } 5084 }); 5085 } 5086 5087 public static ActivityThread systemMain() { 5088 // The system process on low-memory devices do not get to use hardware 5089 // accelerated drawing, since this can add too much overhead to the 5090 // process. 5091 if (!ActivityManager.isHighEndGfx()) { 5092 HardwareRenderer.disable(true); 5093 } 5094 ActivityThread thread = new ActivityThread(); 5095 thread.attach(true); 5096 return thread; 5097 } 5098 5099 public final void installSystemProviders(List<ProviderInfo> providers) { 5100 if (providers != null) { 5101 installContentProviders(mInitialApplication, providers); 5102 } 5103 } 5104 5105 public int getIntCoreSetting(String key, int defaultValue) { 5106 synchronized (mResourcesManager) { 5107 if (mCoreSettings != null) { 5108 return mCoreSettings.getInt(key, defaultValue); 5109 } 5110 return defaultValue; 5111 } 5112 } 5113 5114 private static class EventLoggingReporter implements EventLogger.Reporter { 5115 @Override 5116 public void report (int code, Object... list) { 5117 EventLog.writeEvent(code, list); 5118 } 5119 } 5120 5121 private class DropBoxReporter implements DropBox.Reporter { 5122 5123 private DropBoxManager dropBox; 5124 5125 public DropBoxReporter() { 5126 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 5127 } 5128 5129 @Override 5130 public void addData(String tag, byte[] data, int flags) { 5131 dropBox.addData(tag, data, flags); 5132 } 5133 5134 @Override 5135 public void addText(String tag, String data) { 5136 dropBox.addText(tag, data); 5137 } 5138 } 5139 5140 public static void main(String[] args) { 5141 SamplingProfilerIntegration.start(); 5142 5143 // CloseGuard defaults to true and can be quite spammy. We 5144 // disable it here, but selectively enable it later (via 5145 // StrictMode) on debug builds, but using DropBox, not logs. 5146 CloseGuard.setEnabled(false); 5147 5148 Environment.initForCurrentUser(); 5149 5150 // Set the reporter for event logging in libcore 5151 EventLogger.setReporter(new EventLoggingReporter()); 5152 5153 Security.addProvider(new AndroidKeyStoreProvider()); 5154 5155 // Make sure TrustedCertificateStore looks in the right place for CA certificates 5156 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 5157 TrustedCertificateStore.setDefaultUserDirectory(configDir); 5158 5159 Process.setArgV0("<pre-initialized>"); 5160 5161 Looper.prepareMainLooper(); 5162 5163 ActivityThread thread = new ActivityThread(); 5164 thread.attach(false); 5165 5166 if (sMainThreadHandler == null) { 5167 sMainThreadHandler = thread.getHandler(); 5168 } 5169 5170 AsyncTask.init(); 5171 5172 if (false) { 5173 Looper.myLooper().setMessageLogging(new 5174 LogPrinter(Log.DEBUG, "ActivityThread")); 5175 } 5176 5177 Looper.loop(); 5178 5179 throw new RuntimeException("Main thread loop unexpectedly exited"); 5180 } 5181} 5182