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