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