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