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