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