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