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