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