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