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