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