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