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