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