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