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