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