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