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 @Override handleFixedRotationAdjustments(@onNull IBinder token, @Nullable FixedRotationAdjustments fixedRotationAdjustments)3254 public void handleFixedRotationAdjustments(@NonNull IBinder token, 3255 @Nullable FixedRotationAdjustments fixedRotationAdjustments) { 3256 handleFixedRotationAdjustments(token, fixedRotationAdjustments, null /* overrideConfig */); 3257 } 3258 3259 /** 3260 * Applies the rotation adjustments to override display information in resources belong to the 3261 * provided token. If the token is activity token, the adjustments also apply to application 3262 * because the appearance of activity is usually more sensitive to the application resources. 3263 * 3264 * @param token The token to apply the adjustments. 3265 * @param fixedRotationAdjustments The information to override the display adjustments of 3266 * corresponding resources. If it is null, the exiting override 3267 * will be cleared. 3268 * @param overrideConfig The override configuration of activity. It is used to override 3269 * application configuration. If it is non-null, it means the token is 3270 * confirmed as activity token. Especially when launching new activity, 3271 * {@link #mActivities} hasn't put the new token. 3272 */ handleFixedRotationAdjustments(@onNull IBinder token, @Nullable FixedRotationAdjustments fixedRotationAdjustments, @Nullable Configuration overrideConfig)3273 private void handleFixedRotationAdjustments(@NonNull IBinder token, 3274 @Nullable FixedRotationAdjustments fixedRotationAdjustments, 3275 @Nullable Configuration overrideConfig) { 3276 // The element of application configuration override is set only if the application 3277 // adjustments are needed, because activity already has its own override configuration. 3278 final Configuration[] appConfigOverride; 3279 final Consumer<DisplayAdjustments> override; 3280 if (fixedRotationAdjustments != null) { 3281 appConfigOverride = new Configuration[1]; 3282 override = displayAdjustments -> { 3283 displayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments); 3284 if (appConfigOverride[0] != null) { 3285 displayAdjustments.getConfiguration().updateFrom(appConfigOverride[0]); 3286 } 3287 }; 3288 } else { 3289 appConfigOverride = null; 3290 override = null; 3291 } 3292 if (!mResourcesManager.overrideTokenDisplayAdjustments(token, override)) { 3293 // No resources are associated with the token. 3294 return; 3295 } 3296 if (overrideConfig == null) { 3297 final ActivityClientRecord r = mActivities.get(token); 3298 if (r == null) { 3299 // It is not an activity token. Nothing to do for application. 3300 return; 3301 } 3302 overrideConfig = r.overrideConfig; 3303 } 3304 if (appConfigOverride != null) { 3305 appConfigOverride[0] = overrideConfig; 3306 } 3307 3308 // Apply the last override to application resources for compatibility. Because the Resources 3309 // of Display can be from application, e.g. 3310 // applicationContext.getSystemService(DisplayManager.class).getDisplay(displayId) 3311 // and the deprecated usage: 3312 // applicationContext.getSystemService(WindowManager.class).getDefaultDisplay(); 3313 final Consumer<DisplayAdjustments> appOverride; 3314 if (mActiveRotationAdjustments == null) { 3315 mActiveRotationAdjustments = new ArrayList<>(2); 3316 } 3317 if (override != null) { 3318 mActiveRotationAdjustments.add(Pair.create(token, override)); 3319 appOverride = override; 3320 } else { 3321 mActiveRotationAdjustments.removeIf(adjustmentsPair -> adjustmentsPair.first == token); 3322 appOverride = mActiveRotationAdjustments.isEmpty() 3323 ? null 3324 : mActiveRotationAdjustments.get(mActiveRotationAdjustments.size() - 1).second; 3325 } 3326 mInitialApplication.getResources().overrideDisplayAdjustments(appOverride); 3327 } 3328 3329 /** Core implementation of activity launch. */ performLaunchActivity(ActivityClientRecord r, Intent customIntent)3330 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 3331 ActivityInfo aInfo = r.activityInfo; 3332 if (r.packageInfo == null) { 3333 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 3334 Context.CONTEXT_INCLUDE_CODE); 3335 } 3336 3337 ComponentName component = r.intent.getComponent(); 3338 if (component == null) { 3339 component = r.intent.resolveActivity( 3340 mInitialApplication.getPackageManager()); 3341 r.intent.setComponent(component); 3342 } 3343 3344 if (r.activityInfo.targetActivity != null) { 3345 component = new ComponentName(r.activityInfo.packageName, 3346 r.activityInfo.targetActivity); 3347 } 3348 3349 ContextImpl appContext = createBaseContextForActivity(r); 3350 Activity activity = null; 3351 try { 3352 java.lang.ClassLoader cl = appContext.getClassLoader(); 3353 activity = mInstrumentation.newActivity( 3354 cl, component.getClassName(), r.intent); 3355 StrictMode.incrementExpectedActivityCount(activity.getClass()); 3356 r.intent.setExtrasClassLoader(cl); 3357 r.intent.prepareToEnterProcess(); 3358 if (r.state != null) { 3359 r.state.setClassLoader(cl); 3360 } 3361 } catch (Exception e) { 3362 if (!mInstrumentation.onException(activity, e)) { 3363 throw new RuntimeException( 3364 "Unable to instantiate activity " + component 3365 + ": " + e.toString(), e); 3366 } 3367 } 3368 3369 try { 3370 Application app = r.packageInfo.makeApplication(false, mInstrumentation); 3371 3372 if (localLOGV) Slog.v(TAG, "Performing launch of " + r); 3373 if (localLOGV) Slog.v( 3374 TAG, r + ": app=" + app 3375 + ", appName=" + app.getPackageName() 3376 + ", pkg=" + r.packageInfo.getPackageName() 3377 + ", comp=" + r.intent.getComponent().toShortString() 3378 + ", dir=" + r.packageInfo.getAppDir()); 3379 3380 if (activity != null) { 3381 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); 3382 Configuration config = new Configuration(mCompatConfiguration); 3383 if (r.overrideConfig != null) { 3384 config.updateFrom(r.overrideConfig); 3385 } 3386 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " 3387 + r.activityInfo.name + " with config " + config); 3388 Window window = null; 3389 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { 3390 window = r.mPendingRemoveWindow; 3391 r.mPendingRemoveWindow = null; 3392 r.mPendingRemoveWindowManager = null; 3393 } 3394 3395 // Activity resources must be initialized with the same loaders as the 3396 // application context. 3397 appContext.getResources().addLoaders( 3398 app.getResources().getLoaders().toArray(new ResourcesLoader[0])); 3399 3400 appContext.setOuterContext(activity); 3401 activity.attach(appContext, this, getInstrumentation(), r.token, 3402 r.ident, app, r.intent, r.activityInfo, title, r.parent, 3403 r.embeddedID, r.lastNonConfigurationInstances, config, 3404 r.referrer, r.voiceInteractor, window, r.configCallback, 3405 r.assistToken); 3406 3407 if (customIntent != null) { 3408 activity.mIntent = customIntent; 3409 } 3410 r.lastNonConfigurationInstances = null; 3411 checkAndBlockForNetworkAccess(); 3412 activity.mStartedActivity = false; 3413 int theme = r.activityInfo.getThemeResource(); 3414 if (theme != 0) { 3415 activity.setTheme(theme); 3416 } 3417 3418 activity.mCalled = false; 3419 if (r.isPersistable()) { 3420 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 3421 } else { 3422 mInstrumentation.callActivityOnCreate(activity, r.state); 3423 } 3424 if (!activity.mCalled) { 3425 throw new SuperNotCalledException( 3426 "Activity " + r.intent.getComponent().toShortString() + 3427 " did not call through to super.onCreate()"); 3428 } 3429 r.activity = activity; 3430 mLastReportedWindowingMode.put(activity.getActivityToken(), 3431 config.windowConfiguration.getWindowingMode()); 3432 } 3433 r.setState(ON_CREATE); 3434 3435 // updatePendingActivityConfiguration() reads from mActivities to update 3436 // ActivityClientRecord which runs in a different thread. Protect modifications to 3437 // mActivities to avoid race. 3438 synchronized (mResourcesManager) { 3439 mActivities.put(r.token, r); 3440 } 3441 3442 } catch (SuperNotCalledException e) { 3443 throw e; 3444 3445 } catch (Exception e) { 3446 if (!mInstrumentation.onException(activity, e)) { 3447 throw new RuntimeException( 3448 "Unable to start activity " + component 3449 + ": " + e.toString(), e); 3450 } 3451 } 3452 3453 return activity; 3454 } 3455 3456 @Override handleStartActivity(IBinder token, PendingTransactionActions pendingActions)3457 public void handleStartActivity(IBinder token, PendingTransactionActions pendingActions) { 3458 final ActivityClientRecord r = mActivities.get(token); 3459 final Activity activity = r.activity; 3460 if (r.activity == null) { 3461 // TODO(lifecycler): What do we do in this case? 3462 return; 3463 } 3464 if (!r.stopped) { 3465 throw new IllegalStateException("Can't start activity that is not stopped."); 3466 } 3467 if (r.activity.mFinished) { 3468 // TODO(lifecycler): How can this happen? 3469 return; 3470 } 3471 3472 unscheduleGcIdler(); 3473 3474 // Start 3475 activity.performStart("handleStartActivity"); 3476 r.setState(ON_START); 3477 3478 if (pendingActions == null) { 3479 // No more work to do. 3480 return; 3481 } 3482 3483 // Restore instance state 3484 if (pendingActions.shouldRestoreInstanceState()) { 3485 if (r.isPersistable()) { 3486 if (r.state != null || r.persistentState != null) { 3487 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, 3488 r.persistentState); 3489 } 3490 } else if (r.state != null) { 3491 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); 3492 } 3493 } 3494 3495 // Call postOnCreate() 3496 if (pendingActions.shouldCallOnPostCreate()) { 3497 activity.mCalled = false; 3498 if (r.isPersistable()) { 3499 mInstrumentation.callActivityOnPostCreate(activity, r.state, 3500 r.persistentState); 3501 } else { 3502 mInstrumentation.callActivityOnPostCreate(activity, r.state); 3503 } 3504 if (!activity.mCalled) { 3505 throw new SuperNotCalledException( 3506 "Activity " + r.intent.getComponent().toShortString() 3507 + " did not call through to super.onPostCreate()"); 3508 } 3509 } 3510 3511 updateVisibility(r, true /* show */); 3512 mSomeActivitiesChanged = true; 3513 } 3514 3515 /** 3516 * Checks if {@link #mNetworkBlockSeq} is {@link #INVALID_PROC_STATE_SEQ} and if so, returns 3517 * immediately. Otherwise, makes a blocking call to ActivityManagerService to wait for the 3518 * network rules to get updated. 3519 */ checkAndBlockForNetworkAccess()3520 private void checkAndBlockForNetworkAccess() { 3521 synchronized (mNetworkPolicyLock) { 3522 if (mNetworkBlockSeq != INVALID_PROC_STATE_SEQ) { 3523 try { 3524 ActivityManager.getService().waitForNetworkStateUpdate(mNetworkBlockSeq); 3525 mNetworkBlockSeq = INVALID_PROC_STATE_SEQ; 3526 } catch (RemoteException ignored) {} 3527 } 3528 } 3529 } 3530 createBaseContextForActivity(ActivityClientRecord r)3531 private ContextImpl createBaseContextForActivity(ActivityClientRecord r) { 3532 final int displayId; 3533 try { 3534 displayId = ActivityTaskManager.getService().getDisplayId(r.token); 3535 } catch (RemoteException e) { 3536 throw e.rethrowFromSystemServer(); 3537 } 3538 3539 ContextImpl appContext = ContextImpl.createActivityContext( 3540 this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); 3541 3542 // The rotation adjustments must be applied before creating the activity, so the activity 3543 // can get the adjusted display info during creation. 3544 if (r.mPendingFixedRotationAdjustments != null) { 3545 handleFixedRotationAdjustments(r.token, r.mPendingFixedRotationAdjustments, 3546 r.overrideConfig); 3547 r.mPendingFixedRotationAdjustments = null; 3548 } 3549 3550 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 3551 // For debugging purposes, if the activity's package name contains the value of 3552 // the "debug.use-second-display" system property as a substring, then show 3553 // its content on a secondary display if there is one. 3554 String pkgName = SystemProperties.get("debug.second-display.pkg"); 3555 if (pkgName != null && !pkgName.isEmpty() 3556 && r.packageInfo.mPackageName.contains(pkgName)) { 3557 for (int id : dm.getDisplayIds()) { 3558 if (id != Display.DEFAULT_DISPLAY) { 3559 Display display = 3560 dm.getCompatibleDisplay(id, appContext.getResources()); 3561 appContext = (ContextImpl) appContext.createDisplayContext(display); 3562 break; 3563 } 3564 } 3565 } 3566 return appContext; 3567 } 3568 3569 /** 3570 * Extended implementation of activity launch. Used when server requests a launch or relaunch. 3571 */ 3572 @Override handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent)3573 public Activity handleLaunchActivity(ActivityClientRecord r, 3574 PendingTransactionActions pendingActions, Intent customIntent) { 3575 // If we are getting ready to gc after going to the background, well 3576 // we are back active so skip it. 3577 unscheduleGcIdler(); 3578 mSomeActivitiesChanged = true; 3579 3580 if (r.profilerInfo != null) { 3581 mProfiler.setProfiler(r.profilerInfo); 3582 mProfiler.startProfiling(); 3583 } 3584 3585 // Make sure we are running with the most recent config. 3586 handleConfigurationChanged(null, null); 3587 3588 if (localLOGV) Slog.v( 3589 TAG, "Handling launch of " + r); 3590 3591 // Initialize before creating the activity 3592 if (!ThreadedRenderer.sRendererDisabled 3593 && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) { 3594 HardwareRenderer.preload(); 3595 } 3596 WindowManagerGlobal.initialize(); 3597 3598 // Hint the GraphicsEnvironment that an activity is launching on the process. 3599 GraphicsEnvironment.hintActivityLaunch(); 3600 3601 final Activity a = performLaunchActivity(r, customIntent); 3602 3603 if (a != null) { 3604 r.createdConfig = new Configuration(mConfiguration); 3605 reportSizeConfigurations(r); 3606 if (!r.activity.mFinished && pendingActions != null) { 3607 pendingActions.setOldState(r.state); 3608 pendingActions.setRestoreInstanceState(true); 3609 pendingActions.setCallOnPostCreate(true); 3610 } 3611 } else { 3612 // If there was an error, for any reason, tell the activity manager to stop us. 3613 try { 3614 ActivityTaskManager.getService() 3615 .finishActivity(r.token, Activity.RESULT_CANCELED, null, 3616 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3617 } catch (RemoteException ex) { 3618 throw ex.rethrowFromSystemServer(); 3619 } 3620 } 3621 3622 return a; 3623 } 3624 reportSizeConfigurations(ActivityClientRecord r)3625 private void reportSizeConfigurations(ActivityClientRecord r) { 3626 if (mActivitiesToBeDestroyed.containsKey(r.token)) { 3627 // Size configurations of a destroyed activity is meaningless. 3628 return; 3629 } 3630 Configuration[] configurations = r.activity.getResources().getSizeConfigurations(); 3631 if (configurations == null) { 3632 return; 3633 } 3634 SparseIntArray horizontal = new SparseIntArray(); 3635 SparseIntArray vertical = new SparseIntArray(); 3636 SparseIntArray smallest = new SparseIntArray(); 3637 for (int i = configurations.length - 1; i >= 0; i--) { 3638 Configuration config = configurations[i]; 3639 if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { 3640 vertical.put(config.screenHeightDp, 0); 3641 } 3642 if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) { 3643 horizontal.put(config.screenWidthDp, 0); 3644 } 3645 if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { 3646 smallest.put(config.smallestScreenWidthDp, 0); 3647 } 3648 } 3649 try { 3650 ActivityTaskManager.getService().reportSizeConfigurations(r.token, 3651 horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys()); 3652 } catch (RemoteException ex) { 3653 throw ex.rethrowFromSystemServer(); 3654 } 3655 } 3656 deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents)3657 private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) { 3658 final int N = intents.size(); 3659 for (int i=0; i<N; i++) { 3660 ReferrerIntent intent = intents.get(i); 3661 intent.setExtrasClassLoader(r.activity.getClassLoader()); 3662 intent.prepareToEnterProcess(); 3663 r.activity.mFragments.noteStateNotSaved(); 3664 mInstrumentation.callActivityOnNewIntent(r.activity, intent); 3665 } 3666 } 3667 3668 @Override handleNewIntent(IBinder token, List<ReferrerIntent> intents)3669 public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) { 3670 final ActivityClientRecord r = mActivities.get(token); 3671 if (r == null) { 3672 return; 3673 } 3674 3675 checkAndBlockForNetworkAccess(); 3676 deliverNewIntents(r, intents); 3677 } 3678 handleRequestAssistContextExtras(RequestAssistContextExtras cmd)3679 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { 3680 // Filling for autofill has a few differences: 3681 // - it does not need an AssistContent 3682 // - it does not call onProvideAssistData() 3683 // - it needs an IAutoFillCallback 3684 boolean forAutofill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTOFILL; 3685 3686 // TODO: decide if lastSessionId logic applies to autofill sessions 3687 if (mLastSessionId != cmd.sessionId) { 3688 // Clear the existing structures 3689 mLastSessionId = cmd.sessionId; 3690 for (int i = mLastAssistStructures.size() - 1; i >= 0; i--) { 3691 AssistStructure structure = mLastAssistStructures.get(i).get(); 3692 if (structure != null) { 3693 structure.clearSendChannel(); 3694 } 3695 mLastAssistStructures.remove(i); 3696 } 3697 } 3698 3699 Bundle data = new Bundle(); 3700 AssistStructure structure = null; 3701 AssistContent content = forAutofill ? null : new AssistContent(); 3702 final long startTime = SystemClock.uptimeMillis(); 3703 ActivityClientRecord r = mActivities.get(cmd.activityToken); 3704 Uri referrer = null; 3705 if (r != null) { 3706 if (!forAutofill) { 3707 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 3708 r.activity.onProvideAssistData(data); 3709 referrer = r.activity.onProvideReferrer(); 3710 } 3711 if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill) { 3712 structure = new AssistStructure(r.activity, forAutofill, cmd.flags); 3713 Intent activityIntent = r.activity.getIntent(); 3714 boolean notSecure = r.window == null || 3715 (r.window.getAttributes().flags 3716 & WindowManager.LayoutParams.FLAG_SECURE) == 0; 3717 if (activityIntent != null && notSecure) { 3718 if (!forAutofill) { 3719 Intent intent = new Intent(activityIntent); 3720 intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION 3721 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)); 3722 intent.removeUnsafeExtras(); 3723 content.setDefaultIntent(intent); 3724 } 3725 } else { 3726 if (!forAutofill) { 3727 content.setDefaultIntent(new Intent()); 3728 } 3729 } 3730 if (!forAutofill) { 3731 r.activity.onProvideAssistContent(content); 3732 } 3733 } 3734 3735 } 3736 if (structure == null) { 3737 structure = new AssistStructure(); 3738 } 3739 3740 // TODO: decide if lastSessionId logic applies to autofill sessions 3741 3742 structure.setAcquisitionStartTime(startTime); 3743 structure.setAcquisitionEndTime(SystemClock.uptimeMillis()); 3744 3745 mLastAssistStructures.add(new WeakReference<>(structure)); 3746 IActivityTaskManager mgr = ActivityTaskManager.getService(); 3747 try { 3748 mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer); 3749 } catch (RemoteException e) { 3750 throw e.rethrowFromSystemServer(); 3751 } 3752 } 3753 3754 /** Fetches the user actions for the corresponding activity */ handleRequestDirectActions(@onNull IBinder activityToken, @NonNull IVoiceInteractor interactor, @NonNull CancellationSignal cancellationSignal, @NonNull RemoteCallback callback)3755 private void handleRequestDirectActions(@NonNull IBinder activityToken, 3756 @NonNull IVoiceInteractor interactor, @NonNull CancellationSignal cancellationSignal, 3757 @NonNull RemoteCallback callback) { 3758 final ActivityClientRecord r = mActivities.get(activityToken); 3759 if (r == null) { 3760 Log.w(TAG, "requestDirectActions(): no activity for " + activityToken); 3761 callback.sendResult(null); 3762 return; 3763 } 3764 final int lifecycleState = r.getLifecycleState(); 3765 if (lifecycleState < ON_START || lifecycleState >= ON_STOP) { 3766 Log.w(TAG, "requestDirectActions(" + r + "): wrong lifecycle: " + lifecycleState); 3767 callback.sendResult(null); 3768 return; 3769 } 3770 if (r.activity.mVoiceInteractor == null 3771 || r.activity.mVoiceInteractor.mInteractor.asBinder() 3772 != interactor.asBinder()) { 3773 if (r.activity.mVoiceInteractor != null) { 3774 r.activity.mVoiceInteractor.destroy(); 3775 } 3776 r.activity.mVoiceInteractor = new VoiceInteractor(interactor, r.activity, 3777 r.activity, Looper.myLooper()); 3778 } 3779 r.activity.onGetDirectActions(cancellationSignal, (actions) -> { 3780 Objects.requireNonNull(actions); 3781 Preconditions.checkCollectionElementsNotNull(actions, "actions"); 3782 if (!actions.isEmpty()) { 3783 final int actionCount = actions.size(); 3784 for (int i = 0; i < actionCount; i++) { 3785 final DirectAction action = actions.get(i); 3786 action.setSource(r.activity.getTaskId(), r.activity.getAssistToken()); 3787 } 3788 final Bundle result = new Bundle(); 3789 result.putParcelable(DirectAction.KEY_ACTIONS_LIST, 3790 new ParceledListSlice<>(actions)); 3791 callback.sendResult(result); 3792 } else { 3793 callback.sendResult(null); 3794 } 3795 }); 3796 } 3797 3798 /** Performs an actions in the corresponding activity */ handlePerformDirectAction(@onNull IBinder activityToken, @NonNull String actionId, @Nullable Bundle arguments, @NonNull CancellationSignal cancellationSignal, @NonNull RemoteCallback resultCallback)3799 private void handlePerformDirectAction(@NonNull IBinder activityToken, 3800 @NonNull String actionId, @Nullable Bundle arguments, 3801 @NonNull CancellationSignal cancellationSignal, 3802 @NonNull RemoteCallback resultCallback) { 3803 final ActivityClientRecord r = mActivities.get(activityToken); 3804 if (r != null) { 3805 final int lifecycleState = r.getLifecycleState(); 3806 if (lifecycleState < ON_START || lifecycleState >= ON_STOP) { 3807 resultCallback.sendResult(null); 3808 return; 3809 } 3810 final Bundle nonNullArguments = (arguments != null) ? arguments : Bundle.EMPTY; 3811 r.activity.onPerformDirectAction(actionId, nonNullArguments, cancellationSignal, 3812 resultCallback::sendResult); 3813 } else { 3814 resultCallback.sendResult(null); 3815 } 3816 } 3817 handleTranslucentConversionComplete(IBinder token, boolean drawComplete)3818 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { 3819 ActivityClientRecord r = mActivities.get(token); 3820 if (r != null) { 3821 r.activity.onTranslucentConversionComplete(drawComplete); 3822 } 3823 } 3824 onNewActivityOptions(IBinder token, ActivityOptions options)3825 public void onNewActivityOptions(IBinder token, ActivityOptions options) { 3826 ActivityClientRecord r = mActivities.get(token); 3827 if (r != null) { 3828 r.activity.onNewActivityOptions(options); 3829 } 3830 } 3831 handleInstallProvider(ProviderInfo info)3832 public void handleInstallProvider(ProviderInfo info) { 3833 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 3834 try { 3835 installContentProviders(mInitialApplication, Arrays.asList(info)); 3836 } finally { 3837 StrictMode.setThreadPolicy(oldPolicy); 3838 } 3839 } 3840 handleEnterAnimationComplete(IBinder token)3841 private void handleEnterAnimationComplete(IBinder token) { 3842 ActivityClientRecord r = mActivities.get(token); 3843 if (r != null) { 3844 r.activity.dispatchEnterAnimationComplete(); 3845 } 3846 } 3847 handleStartBinderTracking()3848 private void handleStartBinderTracking() { 3849 Binder.enableTracing(); 3850 } 3851 handleStopBinderTrackingAndDump(ParcelFileDescriptor fd)3852 private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) { 3853 try { 3854 Binder.disableTracing(); 3855 Binder.getTransactionTracker().writeTracesToFile(fd); 3856 } finally { 3857 IoUtils.closeQuietly(fd); 3858 Binder.getTransactionTracker().clearTraces(); 3859 } 3860 } 3861 3862 @Override handlePictureInPictureRequested(IBinder token)3863 public void handlePictureInPictureRequested(IBinder token) { 3864 final ActivityClientRecord r = mActivities.get(token); 3865 if (r == null) { 3866 Log.w(TAG, "Activity to request PIP to no longer exists"); 3867 return; 3868 } 3869 3870 final boolean receivedByApp = r.activity.onPictureInPictureRequested(); 3871 if (!receivedByApp) { 3872 // Previous recommendation was for apps to enter picture-in-picture in 3873 // onUserLeavingHint() for cases such as the app being put into the background. For 3874 // backwards compatibility with apps that are not using the newer 3875 // onPictureInPictureRequested() callback, we schedule the life cycle events needed to 3876 // trigger onUserLeavingHint(), then we return the activity to its previous state. 3877 schedulePauseWithUserLeaveHintAndReturnToCurrentState(r); 3878 } 3879 } 3880 3881 /** 3882 * Cycle activity through onPause and onUserLeaveHint so that PIP is entered if supported, then 3883 * return to its previous state. This allows activities that rely on onUserLeaveHint instead of 3884 * onPictureInPictureRequested to enter picture-in-picture. 3885 */ schedulePauseWithUserLeaveHintAndReturnToCurrentState(ActivityClientRecord r)3886 private void schedulePauseWithUserLeaveHintAndReturnToCurrentState(ActivityClientRecord r) { 3887 final int prevState = r.getLifecycleState(); 3888 if (prevState != ON_RESUME && prevState != ON_PAUSE) { 3889 return; 3890 } 3891 3892 switch (prevState) { 3893 case ON_RESUME: 3894 // Schedule a PAUSE then return to RESUME. 3895 schedulePauseWithUserLeavingHint(r); 3896 scheduleResume(r); 3897 break; 3898 case ON_PAUSE: 3899 // Schedule a RESUME then return to PAUSE. 3900 scheduleResume(r); 3901 schedulePauseWithUserLeavingHint(r); 3902 break; 3903 } 3904 } 3905 schedulePauseWithUserLeavingHint(ActivityClientRecord r)3906 private void schedulePauseWithUserLeavingHint(ActivityClientRecord r) { 3907 final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); 3908 transaction.setLifecycleStateRequest(PauseActivityItem.obtain(r.activity.isFinishing(), 3909 /* userLeaving */ true, r.activity.mConfigChangeFlags, /* dontReport */ false)); 3910 executeTransaction(transaction); 3911 } 3912 scheduleResume(ActivityClientRecord r)3913 private void scheduleResume(ActivityClientRecord r) { 3914 final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); 3915 transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false)); 3916 executeTransaction(transaction); 3917 } 3918 handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor)3919 private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) { 3920 final ActivityClientRecord r = mActivities.get(token); 3921 if (r != null) { 3922 r.voiceInteractor = interactor; 3923 r.activity.setVoiceInteractor(interactor); 3924 if (interactor == null) { 3925 r.activity.onLocalVoiceInteractionStopped(); 3926 } else { 3927 r.activity.onLocalVoiceInteractionStarted(); 3928 } 3929 } 3930 } 3931 attemptAttachAgent(String agent, ClassLoader classLoader)3932 private static boolean attemptAttachAgent(String agent, ClassLoader classLoader) { 3933 try { 3934 VMDebug.attachAgent(agent, classLoader); 3935 return true; 3936 } catch (IOException e) { 3937 Slog.e(TAG, "Attaching agent with " + classLoader + " failed: " + agent); 3938 return false; 3939 } 3940 } 3941 handleAttachAgent(String agent, LoadedApk loadedApk)3942 static void handleAttachAgent(String agent, LoadedApk loadedApk) { 3943 ClassLoader classLoader = loadedApk != null ? loadedApk.getClassLoader() : null; 3944 if (attemptAttachAgent(agent, classLoader)) { 3945 return; 3946 } 3947 if (classLoader != null) { 3948 attemptAttachAgent(agent, null); 3949 } 3950 } 3951 handleAttachStartupAgents(String dataDir)3952 static void handleAttachStartupAgents(String dataDir) { 3953 try { 3954 Path code_cache = ContextImpl.getCodeCacheDirBeforeBind(new File(dataDir)).toPath(); 3955 if (!Files.exists(code_cache)) { 3956 return; 3957 } 3958 Path startup_path = code_cache.resolve("startup_agents"); 3959 if (Files.exists(startup_path)) { 3960 for (Path p : Files.newDirectoryStream(startup_path)) { 3961 handleAttachAgent( 3962 p.toAbsolutePath().toString() 3963 + "=" 3964 + dataDir, 3965 null); 3966 } 3967 } 3968 } catch (Exception e) { 3969 // Ignored. 3970 } 3971 } 3972 3973 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 3974 3975 /** 3976 * Return the Intent that's currently being handled by a 3977 * BroadcastReceiver on this thread, or null if none. 3978 * @hide 3979 */ getIntentBeingBroadcast()3980 public static Intent getIntentBeingBroadcast() { 3981 return sCurrentBroadcastIntent.get(); 3982 } 3983 3984 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) handleReceiver(ReceiverData data)3985 private void handleReceiver(ReceiverData data) { 3986 // If we are getting ready to gc after going to the background, well 3987 // we are back active so skip it. 3988 unscheduleGcIdler(); 3989 3990 String component = data.intent.getComponent().getClassName(); 3991 3992 LoadedApk packageInfo = getPackageInfoNoCheck( 3993 data.info.applicationInfo, data.compatInfo); 3994 3995 IActivityManager mgr = ActivityManager.getService(); 3996 3997 Application app; 3998 BroadcastReceiver receiver; 3999 ContextImpl context; 4000 try { 4001 app = packageInfo.makeApplication(false, mInstrumentation); 4002 context = (ContextImpl) app.getBaseContext(); 4003 if (data.info.splitName != null) { 4004 context = (ContextImpl) context.createContextForSplit(data.info.splitName); 4005 } 4006 java.lang.ClassLoader cl = context.getClassLoader(); 4007 data.intent.setExtrasClassLoader(cl); 4008 data.intent.prepareToEnterProcess(); 4009 data.setExtrasClassLoader(cl); 4010 receiver = packageInfo.getAppFactory() 4011 .instantiateReceiver(cl, data.info.name, data.intent); 4012 } catch (Exception e) { 4013 if (DEBUG_BROADCAST) Slog.i(TAG, 4014 "Finishing failed broadcast to " + data.intent.getComponent()); 4015 data.sendFinished(mgr); 4016 throw new RuntimeException( 4017 "Unable to instantiate receiver " + component 4018 + ": " + e.toString(), e); 4019 } 4020 4021 try { 4022 if (localLOGV) Slog.v( 4023 TAG, "Performing receive of " + data.intent 4024 + ": app=" + app 4025 + ", appName=" + app.getPackageName() 4026 + ", pkg=" + packageInfo.getPackageName() 4027 + ", comp=" + data.intent.getComponent().toShortString() 4028 + ", dir=" + packageInfo.getAppDir()); 4029 4030 sCurrentBroadcastIntent.set(data.intent); 4031 receiver.setPendingResult(data); 4032 receiver.onReceive(context.getReceiverRestrictedContext(), 4033 data.intent); 4034 } catch (Exception e) { 4035 if (DEBUG_BROADCAST) Slog.i(TAG, 4036 "Finishing failed broadcast to " + data.intent.getComponent()); 4037 data.sendFinished(mgr); 4038 if (!mInstrumentation.onException(receiver, e)) { 4039 throw new RuntimeException( 4040 "Unable to start receiver " + component 4041 + ": " + e.toString(), e); 4042 } 4043 } finally { 4044 sCurrentBroadcastIntent.set(null); 4045 } 4046 4047 if (receiver.getPendingResult() != null) { 4048 data.finish(); 4049 } 4050 } 4051 4052 // Instantiate a BackupAgent and tell it that it's alive handleCreateBackupAgent(CreateBackupAgentData data)4053 private void handleCreateBackupAgent(CreateBackupAgentData data) { 4054 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 4055 4056 // Sanity check the requested target package's uid against ours 4057 try { 4058 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 4059 data.appInfo.packageName, 0, UserHandle.myUserId()); 4060 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 4061 Slog.w(TAG, "Asked to instantiate non-matching package " 4062 + data.appInfo.packageName); 4063 return; 4064 } 4065 } catch (RemoteException e) { 4066 throw e.rethrowFromSystemServer(); 4067 } 4068 4069 // no longer idle; we have backup work to do 4070 unscheduleGcIdler(); 4071 4072 // instantiate the BackupAgent class named in the manifest 4073 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4074 String packageName = packageInfo.mPackageName; 4075 if (packageName == null) { 4076 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 4077 return; 4078 } 4079 4080 String classname = data.appInfo.backupAgentName; 4081 // full backup operation but no app-supplied agent? use the default implementation 4082 if (classname == null && (data.backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL 4083 || data.backupMode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL)) { 4084 classname = "android.app.backup.FullBackupAgent"; 4085 } 4086 4087 try { 4088 IBinder binder = null; 4089 ArrayMap<String, BackupAgent> backupAgents = getBackupAgentsForUser(data.userId); 4090 BackupAgent agent = backupAgents.get(packageName); 4091 if (agent != null) { 4092 // reusing the existing instance 4093 if (DEBUG_BACKUP) { 4094 Slog.v(TAG, "Reusing existing agent instance"); 4095 } 4096 binder = agent.onBind(); 4097 } else { 4098 try { 4099 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 4100 4101 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 4102 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 4103 4104 // set up the agent's context 4105 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 4106 context.setOuterContext(agent); 4107 agent.attach(context); 4108 4109 agent.onCreate(UserHandle.of(data.userId)); 4110 binder = agent.onBind(); 4111 backupAgents.put(packageName, agent); 4112 } catch (Exception e) { 4113 // If this is during restore, fail silently; otherwise go 4114 // ahead and let the user see the crash. 4115 Slog.e(TAG, "Agent threw during creation: " + e); 4116 if (data.backupMode != ApplicationThreadConstants.BACKUP_MODE_RESTORE 4117 && data.backupMode != 4118 ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL) { 4119 throw e; 4120 } 4121 // falling through with 'binder' still null 4122 } 4123 } 4124 4125 // tell the OS that we're live now 4126 try { 4127 ActivityManager.getService().backupAgentCreated(packageName, binder, data.userId); 4128 } catch (RemoteException e) { 4129 throw e.rethrowFromSystemServer(); 4130 } 4131 } catch (Exception e) { 4132 throw new RuntimeException("Unable to create BackupAgent " 4133 + classname + ": " + e.toString(), e); 4134 } 4135 } 4136 4137 // Tear down a BackupAgent handleDestroyBackupAgent(CreateBackupAgentData data)4138 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 4139 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 4140 4141 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4142 String packageName = packageInfo.mPackageName; 4143 ArrayMap<String, BackupAgent> backupAgents = getBackupAgentsForUser(data.userId); 4144 BackupAgent agent = backupAgents.get(packageName); 4145 if (agent != null) { 4146 try { 4147 agent.onDestroy(); 4148 } catch (Exception e) { 4149 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 4150 e.printStackTrace(); 4151 } 4152 backupAgents.remove(packageName); 4153 } else { 4154 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 4155 } 4156 } 4157 getBackupAgentsForUser(int userId)4158 private ArrayMap<String, BackupAgent> getBackupAgentsForUser(int userId) { 4159 ArrayMap<String, BackupAgent> backupAgents = mBackupAgentsByUser.get(userId); 4160 if (backupAgents == null) { 4161 backupAgents = new ArrayMap<>(); 4162 mBackupAgentsByUser.put(userId, backupAgents); 4163 } 4164 return backupAgents; 4165 } 4166 4167 @UnsupportedAppUsage handleCreateService(CreateServiceData data)4168 private void handleCreateService(CreateServiceData data) { 4169 // If we are getting ready to gc after going to the background, well 4170 // we are back active so skip it. 4171 unscheduleGcIdler(); 4172 4173 LoadedApk packageInfo = getPackageInfoNoCheck( 4174 data.info.applicationInfo, data.compatInfo); 4175 Service service = null; 4176 try { 4177 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 4178 4179 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); 4180 Application app = packageInfo.makeApplication(false, mInstrumentation); 4181 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 4182 service = packageInfo.getAppFactory() 4183 .instantiateService(cl, data.info.name, data.intent); 4184 // Service resources must be initialized with the same loaders as the application 4185 // context. 4186 context.getResources().addLoaders( 4187 app.getResources().getLoaders().toArray(new ResourcesLoader[0])); 4188 4189 context.setOuterContext(service); 4190 service.attach(context, this, data.info.name, data.token, app, 4191 ActivityManager.getService()); 4192 service.onCreate(); 4193 mServices.put(data.token, service); 4194 try { 4195 ActivityManager.getService().serviceDoneExecuting( 4196 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 4197 } catch (RemoteException e) { 4198 throw e.rethrowFromSystemServer(); 4199 } 4200 } catch (Exception e) { 4201 if (!mInstrumentation.onException(service, e)) { 4202 throw new RuntimeException( 4203 "Unable to create service " + data.info.name 4204 + ": " + e.toString(), e); 4205 } 4206 } 4207 } 4208 handleBindService(BindServiceData data)4209 private void handleBindService(BindServiceData data) { 4210 Service s = mServices.get(data.token); 4211 if (DEBUG_SERVICE) 4212 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 4213 if (s != null) { 4214 try { 4215 data.intent.setExtrasClassLoader(s.getClassLoader()); 4216 data.intent.prepareToEnterProcess(); 4217 try { 4218 if (!data.rebind) { 4219 IBinder binder = s.onBind(data.intent); 4220 ActivityManager.getService().publishService( 4221 data.token, data.intent, binder); 4222 } else { 4223 s.onRebind(data.intent); 4224 ActivityManager.getService().serviceDoneExecuting( 4225 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 4226 } 4227 } catch (RemoteException ex) { 4228 throw ex.rethrowFromSystemServer(); 4229 } 4230 } catch (Exception e) { 4231 if (!mInstrumentation.onException(s, e)) { 4232 throw new RuntimeException( 4233 "Unable to bind to service " + s 4234 + " with " + data.intent + ": " + e.toString(), e); 4235 } 4236 } 4237 } 4238 } 4239 handleUnbindService(BindServiceData data)4240 private void handleUnbindService(BindServiceData data) { 4241 Service s = mServices.get(data.token); 4242 if (s != null) { 4243 try { 4244 data.intent.setExtrasClassLoader(s.getClassLoader()); 4245 data.intent.prepareToEnterProcess(); 4246 boolean doRebind = s.onUnbind(data.intent); 4247 try { 4248 if (doRebind) { 4249 ActivityManager.getService().unbindFinished( 4250 data.token, data.intent, doRebind); 4251 } else { 4252 ActivityManager.getService().serviceDoneExecuting( 4253 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 4254 } 4255 } catch (RemoteException ex) { 4256 throw ex.rethrowFromSystemServer(); 4257 } 4258 } catch (Exception e) { 4259 if (!mInstrumentation.onException(s, e)) { 4260 throw new RuntimeException( 4261 "Unable to unbind to service " + s 4262 + " with " + data.intent + ": " + e.toString(), e); 4263 } 4264 } 4265 } 4266 } 4267 handleDumpService(DumpComponentInfo info)4268 private void handleDumpService(DumpComponentInfo info) { 4269 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 4270 try { 4271 Service s = mServices.get(info.token); 4272 if (s != null) { 4273 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 4274 info.fd.getFileDescriptor())); 4275 s.dump(info.fd.getFileDescriptor(), pw, info.args); 4276 pw.flush(); 4277 } 4278 } finally { 4279 IoUtils.closeQuietly(info.fd); 4280 StrictMode.setThreadPolicy(oldPolicy); 4281 } 4282 } 4283 handleDumpActivity(DumpComponentInfo info)4284 private void handleDumpActivity(DumpComponentInfo info) { 4285 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 4286 try { 4287 ActivityClientRecord r = mActivities.get(info.token); 4288 if (r != null && r.activity != null) { 4289 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 4290 info.fd.getFileDescriptor())); 4291 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 4292 pw.flush(); 4293 } 4294 } finally { 4295 IoUtils.closeQuietly(info.fd); 4296 StrictMode.setThreadPolicy(oldPolicy); 4297 } 4298 } 4299 handleDumpProvider(DumpComponentInfo info)4300 private void handleDumpProvider(DumpComponentInfo info) { 4301 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 4302 try { 4303 ProviderClientRecord r = mLocalProviders.get(info.token); 4304 if (r != null && r.mLocalProvider != null) { 4305 PrintWriter pw = new FastPrintWriter(new FileOutputStream( 4306 info.fd.getFileDescriptor())); 4307 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 4308 pw.flush(); 4309 } 4310 } finally { 4311 IoUtils.closeQuietly(info.fd); 4312 StrictMode.setThreadPolicy(oldPolicy); 4313 } 4314 } 4315 handleServiceArgs(ServiceArgsData data)4316 private void handleServiceArgs(ServiceArgsData data) { 4317 Service s = mServices.get(data.token); 4318 if (s != null) { 4319 try { 4320 if (data.args != null) { 4321 data.args.setExtrasClassLoader(s.getClassLoader()); 4322 data.args.prepareToEnterProcess(); 4323 } 4324 int res; 4325 if (!data.taskRemoved) { 4326 res = s.onStartCommand(data.args, data.flags, data.startId); 4327 } else { 4328 s.onTaskRemoved(data.args); 4329 res = Service.START_TASK_REMOVED_COMPLETE; 4330 } 4331 4332 QueuedWork.waitToFinish(); 4333 4334 try { 4335 ActivityManager.getService().serviceDoneExecuting( 4336 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); 4337 } catch (RemoteException e) { 4338 throw e.rethrowFromSystemServer(); 4339 } 4340 } catch (Exception e) { 4341 if (!mInstrumentation.onException(s, e)) { 4342 throw new RuntimeException( 4343 "Unable to start service " + s 4344 + " with " + data.args + ": " + e.toString(), e); 4345 } 4346 } 4347 } 4348 } 4349 handleStopService(IBinder token)4350 private void handleStopService(IBinder token) { 4351 Service s = mServices.remove(token); 4352 if (s != null) { 4353 try { 4354 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 4355 s.onDestroy(); 4356 s.detachAndCleanUp(); 4357 Context context = s.getBaseContext(); 4358 if (context instanceof ContextImpl) { 4359 final String who = s.getClassName(); 4360 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 4361 } 4362 4363 QueuedWork.waitToFinish(); 4364 4365 try { 4366 ActivityManager.getService().serviceDoneExecuting( 4367 token, SERVICE_DONE_EXECUTING_STOP, 0, 0); 4368 } catch (RemoteException e) { 4369 throw e.rethrowFromSystemServer(); 4370 } 4371 } catch (Exception e) { 4372 if (!mInstrumentation.onException(s, e)) { 4373 throw new RuntimeException( 4374 "Unable to stop service " + s 4375 + ": " + e.toString(), e); 4376 } 4377 Slog.i(TAG, "handleStopService: exception for " + token, e); 4378 } 4379 } else { 4380 Slog.i(TAG, "handleStopService: token=" + token + " not found."); 4381 } 4382 //Slog.i(TAG, "Running services: " + mServices); 4383 } 4384 4385 /** 4386 * Resume the activity. 4387 * @param token Target activity token. 4388 * @param finalStateRequest Flag indicating if this is part of final state resolution for a 4389 * transaction. 4390 * @param reason Reason for performing the action. 4391 * 4392 * @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise. 4393 */ 4394 @VisibleForTesting performResumeActivity(IBinder token, boolean finalStateRequest, String reason)4395 public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest, 4396 String reason) { 4397 final ActivityClientRecord r = mActivities.get(token); 4398 if (localLOGV) { 4399 Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished); 4400 } 4401 if (r == null || r.activity.mFinished) { 4402 return null; 4403 } 4404 if (r.getLifecycleState() == ON_RESUME) { 4405 if (!finalStateRequest) { 4406 final RuntimeException e = new IllegalStateException( 4407 "Trying to resume activity which is already resumed"); 4408 Slog.e(TAG, e.getMessage(), e); 4409 Slog.e(TAG, r.getStateString()); 4410 // TODO(lifecycler): A double resume request is possible when an activity 4411 // receives two consequent transactions with relaunch requests and "resumed" 4412 // final state requests and the second relaunch is omitted. We still try to 4413 // handle two resume requests for the final state. For cases other than this 4414 // one, we don't expect it to happen. 4415 } 4416 return null; 4417 } 4418 if (finalStateRequest) { 4419 r.hideForNow = false; 4420 r.activity.mStartedActivity = false; 4421 } 4422 try { 4423 r.activity.onStateNotSaved(); 4424 r.activity.mFragments.noteStateNotSaved(); 4425 checkAndBlockForNetworkAccess(); 4426 if (r.pendingIntents != null) { 4427 deliverNewIntents(r, r.pendingIntents); 4428 r.pendingIntents = null; 4429 } 4430 if (r.pendingResults != null) { 4431 deliverResults(r, r.pendingResults, reason); 4432 r.pendingResults = null; 4433 } 4434 r.activity.performResume(r.startsNotResumed, reason); 4435 4436 r.state = null; 4437 r.persistentState = null; 4438 r.setState(ON_RESUME); 4439 4440 reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming"); 4441 } catch (Exception e) { 4442 if (!mInstrumentation.onException(r.activity, e)) { 4443 throw new RuntimeException("Unable to resume activity " 4444 + r.intent.getComponent().toShortString() + ": " + e.toString(), e); 4445 } 4446 } 4447 return r; 4448 } 4449 cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force)4450 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) { 4451 if (r.mPreserveWindow && !force) { 4452 return; 4453 } 4454 if (r.mPendingRemoveWindow != null) { 4455 r.mPendingRemoveWindowManager.removeViewImmediate( 4456 r.mPendingRemoveWindow.getDecorView()); 4457 IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken(); 4458 if (wtoken != null) { 4459 WindowManagerGlobal.getInstance().closeAll(wtoken, 4460 r.activity.getClass().getName(), "Activity"); 4461 } 4462 } 4463 r.mPendingRemoveWindow = null; 4464 r.mPendingRemoveWindowManager = null; 4465 } 4466 4467 @Override handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason)4468 public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, 4469 String reason) { 4470 // If we are getting ready to gc after going to the background, well 4471 // we are back active so skip it. 4472 unscheduleGcIdler(); 4473 mSomeActivitiesChanged = true; 4474 4475 // TODO Push resumeArgs into the activity for consideration 4476 final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); 4477 if (r == null) { 4478 // We didn't actually resume the activity, so skipping any follow-up actions. 4479 return; 4480 } 4481 if (mActivitiesToBeDestroyed.containsKey(token)) { 4482 // Although the activity is resumed, it is going to be destroyed. So the following 4483 // UI operations are unnecessary and also prevents exception because its token may 4484 // be gone that window manager cannot recognize it. All necessary cleanup actions 4485 // performed below will be done while handling destruction. 4486 return; 4487 } 4488 4489 final Activity a = r.activity; 4490 4491 if (localLOGV) { 4492 Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity 4493 + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished); 4494 } 4495 4496 final int forwardBit = isForward 4497 ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 4498 4499 // If the window hasn't yet been added to the window manager, 4500 // and this guy didn't finish itself or start another activity, 4501 // then go ahead and add the window. 4502 boolean willBeVisible = !a.mStartedActivity; 4503 if (!willBeVisible) { 4504 try { 4505 willBeVisible = ActivityTaskManager.getService().willActivityBeVisible( 4506 a.getActivityToken()); 4507 } catch (RemoteException e) { 4508 throw e.rethrowFromSystemServer(); 4509 } 4510 } 4511 if (r.window == null && !a.mFinished && willBeVisible) { 4512 r.window = r.activity.getWindow(); 4513 View decor = r.window.getDecorView(); 4514 decor.setVisibility(View.INVISIBLE); 4515 ViewManager wm = a.getWindowManager(); 4516 WindowManager.LayoutParams l = r.window.getAttributes(); 4517 a.mDecor = decor; 4518 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 4519 l.softInputMode |= forwardBit; 4520 if (r.mPreserveWindow) { 4521 a.mWindowAdded = true; 4522 r.mPreserveWindow = false; 4523 // Normally the ViewRoot sets up callbacks with the Activity 4524 // in addView->ViewRootImpl#setView. If we are instead reusing 4525 // the decor view we have to notify the view root that the 4526 // callbacks may have changed. 4527 ViewRootImpl impl = decor.getViewRootImpl(); 4528 if (impl != null) { 4529 impl.notifyChildRebuilt(); 4530 } 4531 } 4532 if (a.mVisibleFromClient) { 4533 if (!a.mWindowAdded) { 4534 a.mWindowAdded = true; 4535 wm.addView(decor, l); 4536 } else { 4537 // The activity will get a callback for this {@link LayoutParams} change 4538 // earlier. However, at that time the decor will not be set (this is set 4539 // in this method), so no action will be taken. This call ensures the 4540 // callback occurs with the decor set. 4541 a.onWindowAttributesChanged(l); 4542 } 4543 } 4544 4545 // If the window has already been added, but during resume 4546 // we started another activity, then don't yet make the 4547 // window visible. 4548 } else if (!willBeVisible) { 4549 if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set"); 4550 r.hideForNow = true; 4551 } 4552 4553 // Get rid of anything left hanging around. 4554 cleanUpPendingRemoveWindows(r, false /* force */); 4555 4556 // The window is now visible if it has been added, we are not 4557 // simply finishing, and we are not starting another activity. 4558 if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { 4559 if (r.newConfig != null) { 4560 performConfigurationChangedForActivity(r, r.newConfig); 4561 if (DEBUG_CONFIGURATION) { 4562 Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " 4563 + r.activity.mCurrentConfig); 4564 } 4565 r.newConfig = null; 4566 } 4567 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); 4568 ViewRootImpl impl = r.window.getDecorView().getViewRootImpl(); 4569 WindowManager.LayoutParams l = impl != null 4570 ? impl.mWindowAttributes : r.window.getAttributes(); 4571 if ((l.softInputMode 4572 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 4573 != forwardBit) { 4574 l.softInputMode = (l.softInputMode 4575 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 4576 | forwardBit; 4577 if (r.activity.mVisibleFromClient) { 4578 ViewManager wm = a.getWindowManager(); 4579 View decor = r.window.getDecorView(); 4580 wm.updateViewLayout(decor, l); 4581 } 4582 } 4583 4584 r.activity.mVisibleFromServer = true; 4585 mNumVisibleActivities++; 4586 if (r.activity.mVisibleFromClient) { 4587 r.activity.makeVisible(); 4588 } 4589 } 4590 4591 r.nextIdle = mNewActivities; 4592 mNewActivities = r; 4593 if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r); 4594 Looper.myQueue().addIdleHandler(new Idler()); 4595 } 4596 4597 4598 @Override handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason)4599 public void handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason) { 4600 ActivityClientRecord r = mActivities.get(token); 4601 if (r == null || r.activity == null) { 4602 Slog.w(TAG, "Not found target activity to report position change for token: " + token); 4603 return; 4604 } 4605 4606 if (DEBUG_ORDER) { 4607 Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r); 4608 } 4609 4610 if (r.isTopResumedActivity == onTop) { 4611 throw new IllegalStateException("Activity top position already set to onTop=" + onTop); 4612 } 4613 4614 r.isTopResumedActivity = onTop; 4615 4616 if (r.getLifecycleState() == ON_RESUME) { 4617 reportTopResumedActivityChanged(r, onTop, "topStateChangedWhenResumed"); 4618 } else { 4619 if (DEBUG_ORDER) { 4620 Slog.d(TAG, "Won't deliver top position change in state=" + r.getLifecycleState()); 4621 } 4622 } 4623 } 4624 4625 /** 4626 * Call {@link Activity#onTopResumedActivityChanged(boolean)} if its top resumed state changed 4627 * since the last report. 4628 */ reportTopResumedActivityChanged(ActivityClientRecord r, boolean onTop, String reason)4629 private void reportTopResumedActivityChanged(ActivityClientRecord r, boolean onTop, 4630 String reason) { 4631 if (r.lastReportedTopResumedState != onTop) { 4632 r.lastReportedTopResumedState = onTop; 4633 r.activity.performTopResumedActivityChanged(onTop, reason); 4634 } 4635 } 4636 4637 @Override handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, PendingTransactionActions pendingActions, String reason)4638 public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, 4639 int configChanges, PendingTransactionActions pendingActions, String reason) { 4640 ActivityClientRecord r = mActivities.get(token); 4641 if (r != null) { 4642 if (userLeaving) { 4643 performUserLeavingActivity(r); 4644 } 4645 4646 r.activity.mConfigChangeFlags |= configChanges; 4647 performPauseActivity(r, finished, reason, pendingActions); 4648 4649 // Make sure any pending writes are now committed. 4650 if (r.isPreHoneycomb()) { 4651 QueuedWork.waitToFinish(); 4652 } 4653 mSomeActivitiesChanged = true; 4654 } 4655 } 4656 performUserLeavingActivity(ActivityClientRecord r)4657 final void performUserLeavingActivity(ActivityClientRecord r) { 4658 mInstrumentation.callActivityOnPictureInPictureRequested(r.activity); 4659 mInstrumentation.callActivityOnUserLeaving(r.activity); 4660 } 4661 performPauseActivity(IBinder token, boolean finished, String reason, PendingTransactionActions pendingActions)4662 final Bundle performPauseActivity(IBinder token, boolean finished, String reason, 4663 PendingTransactionActions pendingActions) { 4664 ActivityClientRecord r = mActivities.get(token); 4665 return r != null ? performPauseActivity(r, finished, reason, pendingActions) : null; 4666 } 4667 4668 /** 4669 * Pause the activity. 4670 * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise. 4671 */ performPauseActivity(ActivityClientRecord r, boolean finished, String reason, PendingTransactionActions pendingActions)4672 private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason, 4673 PendingTransactionActions pendingActions) { 4674 if (r.paused) { 4675 if (r.activity.mFinished) { 4676 // If we are finishing, we won't call onResume() in certain cases. 4677 // So here we likewise don't want to call onPause() if the activity 4678 // isn't resumed. 4679 return null; 4680 } 4681 RuntimeException e = new RuntimeException( 4682 "Performing pause of activity that is not resumed: " 4683 + r.intent.getComponent().toShortString()); 4684 Slog.e(TAG, e.getMessage(), e); 4685 } 4686 if (finished) { 4687 r.activity.mFinished = true; 4688 } 4689 4690 // Pre-Honeycomb apps always save their state before pausing 4691 final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb(); 4692 if (shouldSaveState) { 4693 callActivityOnSaveInstanceState(r); 4694 } 4695 4696 performPauseActivityIfNeeded(r, reason); 4697 4698 // Notify any outstanding on paused listeners 4699 ArrayList<OnActivityPausedListener> listeners; 4700 synchronized (mOnPauseListeners) { 4701 listeners = mOnPauseListeners.remove(r.activity); 4702 } 4703 int size = (listeners != null ? listeners.size() : 0); 4704 for (int i = 0; i < size; i++) { 4705 listeners.get(i).onPaused(r.activity); 4706 } 4707 4708 final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null; 4709 if (oldState != null) { 4710 // We need to keep around the original state, in case we need to be created again. 4711 // But we only do this for pre-Honeycomb apps, which always save their state when 4712 // pausing, so we can not have them save their state when restarting from a paused 4713 // state. For HC and later, we want to (and can) let the state be saved as the 4714 // normal part of stopping the activity. 4715 if (r.isPreHoneycomb()) { 4716 r.state = oldState; 4717 } 4718 } 4719 4720 return shouldSaveState ? r.state : null; 4721 } 4722 performPauseActivityIfNeeded(ActivityClientRecord r, String reason)4723 private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) { 4724 if (r.paused) { 4725 // You are already paused silly... 4726 return; 4727 } 4728 4729 // Always reporting top resumed position loss when pausing an activity. If necessary, it 4730 // will be restored in performResumeActivity(). 4731 reportTopResumedActivityChanged(r, false /* onTop */, "pausing"); 4732 4733 try { 4734 r.activity.mCalled = false; 4735 mInstrumentation.callActivityOnPause(r.activity); 4736 if (!r.activity.mCalled) { 4737 throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent) 4738 + " did not call through to super.onPause()"); 4739 } 4740 } catch (SuperNotCalledException e) { 4741 throw e; 4742 } catch (Exception e) { 4743 if (!mInstrumentation.onException(r.activity, e)) { 4744 throw new RuntimeException("Unable to pause activity " 4745 + safeToComponentShortString(r.intent) + ": " + e.toString(), e); 4746 } 4747 } 4748 r.setState(ON_PAUSE); 4749 } 4750 4751 /** Called from {@link LocalActivityManager}. */ 4752 @UnsupportedAppUsage performStopActivity(IBinder token, boolean saveState, String reason)4753 final void performStopActivity(IBinder token, boolean saveState, String reason) { 4754 ActivityClientRecord r = mActivities.get(token); 4755 performStopActivityInner(r, null /* stopInfo */, saveState, false /* finalStateRequest */, 4756 reason); 4757 } 4758 4759 private static final class ProviderRefCount { 4760 public final ContentProviderHolder holder; 4761 public final ProviderClientRecord client; 4762 public int stableCount; 4763 public int unstableCount; 4764 4765 // When this is set, the stable and unstable ref counts are 0 and 4766 // we have a pending operation scheduled to remove the ref count 4767 // from the activity manager. On the activity manager we are still 4768 // holding an unstable ref, though it is not reflected in the counts 4769 // here. 4770 public boolean removePending; 4771 ProviderRefCount(ContentProviderHolder inHolder, ProviderClientRecord inClient, int sCount, int uCount)4772 ProviderRefCount(ContentProviderHolder inHolder, 4773 ProviderClientRecord inClient, int sCount, int uCount) { 4774 holder = inHolder; 4775 client = inClient; 4776 stableCount = sCount; 4777 unstableCount = uCount; 4778 } 4779 } 4780 4781 /** 4782 * Core implementation of stopping an activity. 4783 * @param r Target activity client record. 4784 * @param info Action that will report activity stop to server. 4785 * @param saveState Flag indicating whether the activity state should be saved. 4786 * @param finalStateRequest Flag indicating if this call is handling final lifecycle state 4787 * request for a transaction. 4788 * @param reason Reason for performing this operation. 4789 */ performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean saveState, boolean finalStateRequest, String reason)4790 private void performStopActivityInner(ActivityClientRecord r, StopInfo info, 4791 boolean saveState, boolean finalStateRequest, String reason) { 4792 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 4793 if (r != null) { 4794 if (r.stopped) { 4795 if (r.activity.mFinished) { 4796 // If we are finishing, we won't call onResume() in certain 4797 // cases. So here we likewise don't want to call onStop() 4798 // if the activity isn't resumed. 4799 return; 4800 } 4801 if (!finalStateRequest) { 4802 final RuntimeException e = new RuntimeException( 4803 "Performing stop of activity that is already stopped: " 4804 + r.intent.getComponent().toShortString()); 4805 Slog.e(TAG, e.getMessage(), e); 4806 Slog.e(TAG, r.getStateString()); 4807 } 4808 } 4809 4810 // One must first be paused before stopped... 4811 performPauseActivityIfNeeded(r, reason); 4812 4813 if (info != null) { 4814 try { 4815 // First create a thumbnail for the activity... 4816 // For now, don't create the thumbnail here; we are 4817 // doing that by doing a screen snapshot. 4818 info.setDescription(r.activity.onCreateDescription()); 4819 } catch (Exception e) { 4820 if (!mInstrumentation.onException(r.activity, e)) { 4821 throw new RuntimeException( 4822 "Unable to save state of activity " 4823 + r.intent.getComponent().toShortString() 4824 + ": " + e.toString(), e); 4825 } 4826 } 4827 } 4828 4829 callActivityOnStop(r, saveState, reason); 4830 } 4831 } 4832 4833 /** 4834 * Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates 4835 * the client record's state. 4836 * All calls to stop an activity must be done through this method to make sure that 4837 * {@link Activity#onSaveInstanceState(Bundle)} is also executed in the same call. 4838 */ callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason)4839 private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) { 4840 // Before P onSaveInstanceState was called before onStop, starting with P it's 4841 // called after. Before Honeycomb state was always saved before onPause. 4842 final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null 4843 && !r.isPreHoneycomb(); 4844 final boolean isPreP = r.isPreP(); 4845 if (shouldSaveState && isPreP) { 4846 callActivityOnSaveInstanceState(r); 4847 } 4848 4849 try { 4850 r.activity.performStop(r.mPreserveWindow, reason); 4851 } catch (SuperNotCalledException e) { 4852 throw e; 4853 } catch (Exception e) { 4854 if (!mInstrumentation.onException(r.activity, e)) { 4855 throw new RuntimeException( 4856 "Unable to stop activity " 4857 + r.intent.getComponent().toShortString() 4858 + ": " + e.toString(), e); 4859 } 4860 } 4861 r.setState(ON_STOP); 4862 4863 if (shouldSaveState && !isPreP) { 4864 callActivityOnSaveInstanceState(r); 4865 } 4866 } 4867 updateVisibility(ActivityClientRecord r, boolean show)4868 private void updateVisibility(ActivityClientRecord r, boolean show) { 4869 View v = r.activity.mDecor; 4870 if (v != null) { 4871 if (show) { 4872 if (!r.activity.mVisibleFromServer) { 4873 r.activity.mVisibleFromServer = true; 4874 mNumVisibleActivities++; 4875 if (r.activity.mVisibleFromClient) { 4876 r.activity.makeVisible(); 4877 } 4878 } 4879 if (r.newConfig != null) { 4880 performConfigurationChangedForActivity(r, r.newConfig); 4881 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 4882 + r.activityInfo.name + " with new config " 4883 + r.activity.mCurrentConfig); 4884 r.newConfig = null; 4885 } 4886 } else { 4887 if (r.activity.mVisibleFromServer) { 4888 r.activity.mVisibleFromServer = false; 4889 mNumVisibleActivities--; 4890 v.setVisibility(View.INVISIBLE); 4891 } 4892 } 4893 } 4894 } 4895 4896 @Override handleStopActivity(IBinder token, int configChanges, PendingTransactionActions pendingActions, boolean finalStateRequest, String reason)4897 public void handleStopActivity(IBinder token, int configChanges, 4898 PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) { 4899 final ActivityClientRecord r = mActivities.get(token); 4900 r.activity.mConfigChangeFlags |= configChanges; 4901 4902 final StopInfo stopInfo = new StopInfo(); 4903 performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest, 4904 reason); 4905 4906 if (localLOGV) Slog.v( 4907 TAG, "Finishing stop of " + r + ": win=" + r.window); 4908 4909 updateVisibility(r, false); 4910 4911 // Make sure any pending writes are now committed. 4912 if (!r.isPreHoneycomb()) { 4913 QueuedWork.waitToFinish(); 4914 } 4915 4916 stopInfo.setActivity(r); 4917 stopInfo.setState(r.state); 4918 stopInfo.setPersistentState(r.persistentState); 4919 pendingActions.setStopInfo(stopInfo); 4920 mSomeActivitiesChanged = true; 4921 } 4922 4923 /** 4924 * Schedule the call to tell the activity manager we have stopped. We don't do this 4925 * immediately, because we want to have a chance for any other pending work (in particular 4926 * memory trim requests) to complete before you tell the activity manager to proceed and allow 4927 * us to go fully into the background. 4928 */ 4929 @Override reportStop(PendingTransactionActions pendingActions)4930 public void reportStop(PendingTransactionActions pendingActions) { 4931 mH.post(pendingActions.getStopInfo()); 4932 } 4933 4934 @Override performRestartActivity(IBinder token, boolean start)4935 public void performRestartActivity(IBinder token, boolean start) { 4936 ActivityClientRecord r = mActivities.get(token); 4937 if (r.stopped) { 4938 r.activity.performRestart(start, "performRestartActivity"); 4939 if (start) { 4940 r.setState(ON_START); 4941 } 4942 } 4943 } 4944 handleSetCoreSettings(Bundle coreSettings)4945 private void handleSetCoreSettings(Bundle coreSettings) { 4946 synchronized (mResourcesManager) { 4947 mCoreSettings = coreSettings; 4948 } 4949 onCoreSettingsChange(); 4950 } 4951 onCoreSettingsChange()4952 private void onCoreSettingsChange() { 4953 if (updateDebugViewAttributeState()) { 4954 // request all activities to relaunch for the changes to take place 4955 relaunchAllActivities(false /* preserveWindows */); 4956 } 4957 } 4958 updateDebugViewAttributeState()4959 private boolean updateDebugViewAttributeState() { 4960 boolean previousState = View.sDebugViewAttributes; 4961 4962 View.sDebugViewAttributesApplicationPackage = mCoreSettings.getString( 4963 Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, ""); 4964 String currentPackage = (mBoundApplication != null && mBoundApplication.appInfo != null) 4965 ? mBoundApplication.appInfo.packageName : "<unknown-app>"; 4966 View.sDebugViewAttributes = 4967 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0 4968 || View.sDebugViewAttributesApplicationPackage.equals(currentPackage); 4969 return previousState != View.sDebugViewAttributes; 4970 } 4971 relaunchAllActivities(boolean preserveWindows)4972 private void relaunchAllActivities(boolean preserveWindows) { 4973 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { 4974 final ActivityClientRecord r = entry.getValue(); 4975 if (!r.activity.mFinished) { 4976 if (preserveWindows && r.window != null) { 4977 r.mPreserveWindow = true; 4978 } 4979 scheduleRelaunchActivity(entry.getKey()); 4980 } 4981 } 4982 } 4983 handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data)4984 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 4985 LoadedApk apk = peekPackageInfo(data.pkg, false); 4986 if (apk != null) { 4987 apk.setCompatibilityInfo(data.info); 4988 } 4989 apk = peekPackageInfo(data.pkg, true); 4990 if (apk != null) { 4991 apk.setCompatibilityInfo(data.info); 4992 } 4993 handleConfigurationChanged(mConfiguration, data.info); 4994 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 4995 } 4996 deliverResults(ActivityClientRecord r, List<ResultInfo> results, String reason)4997 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results, String reason) { 4998 final int N = results.size(); 4999 for (int i=0; i<N; i++) { 5000 ResultInfo ri = results.get(i); 5001 try { 5002 if (ri.mData != null) { 5003 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 5004 ri.mData.prepareToEnterProcess(); 5005 } 5006 if (DEBUG_RESULTS) Slog.v(TAG, 5007 "Delivering result to activity " + r + " : " + ri); 5008 r.activity.dispatchActivityResult(ri.mResultWho, 5009 ri.mRequestCode, ri.mResultCode, ri.mData, reason); 5010 } catch (Exception e) { 5011 if (!mInstrumentation.onException(r.activity, e)) { 5012 throw new RuntimeException( 5013 "Failure delivering result " + ri + " to activity " 5014 + r.intent.getComponent().toShortString() 5015 + ": " + e.toString(), e); 5016 } 5017 } 5018 } 5019 } 5020 5021 @Override handleSendResult(IBinder token, List<ResultInfo> results, String reason)5022 public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) { 5023 ActivityClientRecord r = mActivities.get(token); 5024 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 5025 if (r != null) { 5026 final boolean resumed = !r.paused; 5027 if (!r.activity.mFinished && r.activity.mDecor != null 5028 && r.hideForNow && resumed) { 5029 // We had hidden the activity because it started another 5030 // one... we have gotten a result back and we are not 5031 // paused, so make sure our window is visible. 5032 updateVisibility(r, true); 5033 } 5034 if (resumed) { 5035 try { 5036 // Now we are idle. 5037 r.activity.mCalled = false; 5038 mInstrumentation.callActivityOnPause(r.activity); 5039 if (!r.activity.mCalled) { 5040 throw new SuperNotCalledException( 5041 "Activity " + r.intent.getComponent().toShortString() 5042 + " did not call through to super.onPause()"); 5043 } 5044 } catch (SuperNotCalledException e) { 5045 throw e; 5046 } catch (Exception e) { 5047 if (!mInstrumentation.onException(r.activity, e)) { 5048 throw new RuntimeException( 5049 "Unable to pause activity " 5050 + r.intent.getComponent().toShortString() 5051 + ": " + e.toString(), e); 5052 } 5053 } 5054 } 5055 checkAndBlockForNetworkAccess(); 5056 deliverResults(r, results, reason); 5057 if (resumed) { 5058 r.activity.performResume(false, reason); 5059 } 5060 } 5061 } 5062 5063 /** Core implementation of activity destroy call. */ performDestroyActivity(IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance, String reason)5064 ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 5065 int configChanges, boolean getNonConfigInstance, String reason) { 5066 ActivityClientRecord r = mActivities.get(token); 5067 Class<? extends Activity> activityClass = null; 5068 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 5069 if (r != null) { 5070 activityClass = r.activity.getClass(); 5071 r.activity.mConfigChangeFlags |= configChanges; 5072 if (finishing) { 5073 r.activity.mFinished = true; 5074 } 5075 5076 performPauseActivityIfNeeded(r, "destroy"); 5077 5078 if (!r.stopped) { 5079 callActivityOnStop(r, false /* saveState */, "destroy"); 5080 } 5081 if (getNonConfigInstance) { 5082 try { 5083 r.lastNonConfigurationInstances 5084 = r.activity.retainNonConfigurationInstances(); 5085 } catch (Exception e) { 5086 if (!mInstrumentation.onException(r.activity, e)) { 5087 throw new RuntimeException( 5088 "Unable to retain activity " 5089 + r.intent.getComponent().toShortString() 5090 + ": " + e.toString(), e); 5091 } 5092 } 5093 } 5094 try { 5095 r.activity.mCalled = false; 5096 mInstrumentation.callActivityOnDestroy(r.activity); 5097 if (!r.activity.mCalled) { 5098 throw new SuperNotCalledException( 5099 "Activity " + safeToComponentShortString(r.intent) + 5100 " did not call through to super.onDestroy()"); 5101 } 5102 if (r.window != null) { 5103 r.window.closeAllPanels(); 5104 } 5105 } catch (SuperNotCalledException e) { 5106 throw e; 5107 } catch (Exception e) { 5108 if (!mInstrumentation.onException(r.activity, e)) { 5109 throw new RuntimeException( 5110 "Unable to destroy activity " + safeToComponentShortString(r.intent) 5111 + ": " + e.toString(), e); 5112 } 5113 } 5114 r.setState(ON_DESTROY); 5115 } 5116 schedulePurgeIdler(); 5117 // updatePendingActivityConfiguration() reads from mActivities to update 5118 // ActivityClientRecord which runs in a different thread. Protect modifications to 5119 // mActivities to avoid race. 5120 synchronized (mResourcesManager) { 5121 mActivities.remove(token); 5122 } 5123 StrictMode.decrementExpectedActivityCount(activityClass); 5124 return r; 5125 } 5126 safeToComponentShortString(Intent intent)5127 private static String safeToComponentShortString(Intent intent) { 5128 ComponentName component = intent.getComponent(); 5129 return component == null ? "[Unknown]" : component.toShortString(); 5130 } 5131 5132 @Override getActivitiesToBeDestroyed()5133 public Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed() { 5134 return mActivitiesToBeDestroyed; 5135 } 5136 5137 @Override handleDestroyActivity(IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance, String reason)5138 public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges, 5139 boolean getNonConfigInstance, String reason) { 5140 ActivityClientRecord r = performDestroyActivity(token, finishing, 5141 configChanges, getNonConfigInstance, reason); 5142 if (r != null) { 5143 cleanUpPendingRemoveWindows(r, finishing); 5144 WindowManager wm = r.activity.getWindowManager(); 5145 View v = r.activity.mDecor; 5146 if (v != null) { 5147 if (r.activity.mVisibleFromServer) { 5148 mNumVisibleActivities--; 5149 } 5150 IBinder wtoken = v.getWindowToken(); 5151 if (r.activity.mWindowAdded) { 5152 if (r.mPreserveWindow) { 5153 // Hold off on removing this until the new activity's 5154 // window is being added. 5155 r.mPendingRemoveWindow = r.window; 5156 r.mPendingRemoveWindowManager = wm; 5157 // We can only keep the part of the view hierarchy that we control, 5158 // everything else must be removed, because it might not be able to 5159 // behave properly when activity is relaunching. 5160 r.window.clearContentView(); 5161 } else { 5162 wm.removeViewImmediate(v); 5163 } 5164 } 5165 if (wtoken != null && r.mPendingRemoveWindow == null) { 5166 WindowManagerGlobal.getInstance().closeAll(wtoken, 5167 r.activity.getClass().getName(), "Activity"); 5168 } else if (r.mPendingRemoveWindow != null) { 5169 // We're preserving only one window, others should be closed so app views 5170 // will be detached before the final tear down. It should be done now because 5171 // some components (e.g. WebView) rely on detach callbacks to perform receiver 5172 // unregister and other cleanup. 5173 WindowManagerGlobal.getInstance().closeAllExceptView(token, v, 5174 r.activity.getClass().getName(), "Activity"); 5175 } 5176 r.activity.mDecor = null; 5177 } 5178 if (r.mPendingRemoveWindow == null) { 5179 // If we are delaying the removal of the activity window, then 5180 // we can't clean up all windows here. Note that we can't do 5181 // so later either, which means any windows that aren't closed 5182 // by the app will leak. Well we try to warning them a lot 5183 // about leaking windows, because that is a bug, so if they are 5184 // using this recreate facility then they get to live with leaks. 5185 WindowManagerGlobal.getInstance().closeAll(token, 5186 r.activity.getClass().getName(), "Activity"); 5187 } 5188 5189 // Mocked out contexts won't be participating in the normal 5190 // process lifecycle, but if we're running with a proper 5191 // ApplicationContext we need to have it tear down things 5192 // cleanly. 5193 Context c = r.activity.getBaseContext(); 5194 if (c instanceof ContextImpl) { 5195 ((ContextImpl) c).scheduleFinalCleanup( 5196 r.activity.getClass().getName(), "Activity"); 5197 } 5198 } 5199 if (finishing) { 5200 try { 5201 ActivityTaskManager.getService().activityDestroyed(token); 5202 } catch (RemoteException ex) { 5203 throw ex.rethrowFromSystemServer(); 5204 } 5205 } 5206 mSomeActivitiesChanged = true; 5207 } 5208 5209 @Override prepareRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, MergedConfiguration config, boolean preserveWindow)5210 public ActivityClientRecord prepareRelaunchActivity(IBinder token, 5211 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 5212 int configChanges, MergedConfiguration config, boolean preserveWindow) { 5213 ActivityClientRecord target = null; 5214 boolean scheduleRelaunch = false; 5215 5216 synchronized (mResourcesManager) { 5217 for (int i=0; i<mRelaunchingActivities.size(); i++) { 5218 ActivityClientRecord r = mRelaunchingActivities.get(i); 5219 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r); 5220 if (r.token == token) { 5221 target = r; 5222 if (pendingResults != null) { 5223 if (r.pendingResults != null) { 5224 r.pendingResults.addAll(pendingResults); 5225 } else { 5226 r.pendingResults = pendingResults; 5227 } 5228 } 5229 if (pendingNewIntents != null) { 5230 if (r.pendingIntents != null) { 5231 r.pendingIntents.addAll(pendingNewIntents); 5232 } else { 5233 r.pendingIntents = pendingNewIntents; 5234 } 5235 } 5236 break; 5237 } 5238 } 5239 5240 if (target == null) { 5241 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null"); 5242 target = new ActivityClientRecord(); 5243 target.token = token; 5244 target.pendingResults = pendingResults; 5245 target.pendingIntents = pendingNewIntents; 5246 target.mPreserveWindow = preserveWindow; 5247 mRelaunchingActivities.add(target); 5248 scheduleRelaunch = true; 5249 } 5250 target.createdConfig = config.getGlobalConfiguration(); 5251 target.overrideConfig = config.getOverrideConfiguration(); 5252 target.pendingConfigChanges |= configChanges; 5253 } 5254 5255 return scheduleRelaunch ? target : null; 5256 } 5257 5258 @Override handleRelaunchActivity(ActivityClientRecord tmp, PendingTransactionActions pendingActions)5259 public void handleRelaunchActivity(ActivityClientRecord tmp, 5260 PendingTransactionActions pendingActions) { 5261 // If we are getting ready to gc after going to the background, well 5262 // we are back active so skip it. 5263 unscheduleGcIdler(); 5264 mSomeActivitiesChanged = true; 5265 5266 Configuration changedConfig = null; 5267 int configChanges = 0; 5268 5269 // First: make sure we have the most recent configuration and most 5270 // recent version of the activity, or skip it if some previous call 5271 // had taken a more recent version. 5272 synchronized (mResourcesManager) { 5273 int N = mRelaunchingActivities.size(); 5274 IBinder token = tmp.token; 5275 tmp = null; 5276 for (int i=0; i<N; i++) { 5277 ActivityClientRecord r = mRelaunchingActivities.get(i); 5278 if (r.token == token) { 5279 tmp = r; 5280 configChanges |= tmp.pendingConfigChanges; 5281 mRelaunchingActivities.remove(i); 5282 i--; 5283 N--; 5284 } 5285 } 5286 5287 if (tmp == null) { 5288 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 5289 return; 5290 } 5291 5292 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 5293 + tmp.token + " with configChanges=0x" 5294 + Integer.toHexString(configChanges)); 5295 5296 if (mPendingConfiguration != null) { 5297 changedConfig = mPendingConfiguration; 5298 mPendingConfiguration = null; 5299 } 5300 } 5301 5302 if (tmp.createdConfig != null) { 5303 // If the activity manager is passing us its current config, 5304 // assume that is really what we want regardless of what we 5305 // may have pending. 5306 if (mConfiguration == null 5307 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 5308 && mConfiguration.diff(tmp.createdConfig) != 0)) { 5309 if (changedConfig == null 5310 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 5311 changedConfig = tmp.createdConfig; 5312 } 5313 } 5314 } 5315 5316 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 5317 + tmp.token + ": changedConfig=" + changedConfig); 5318 5319 // If there was a pending configuration change, execute it first. 5320 if (changedConfig != null) { 5321 mCurDefaultDisplayDpi = changedConfig.densityDpi; 5322 updateDefaultDensity(); 5323 handleConfigurationChanged(changedConfig, null); 5324 } 5325 5326 ActivityClientRecord r = mActivities.get(tmp.token); 5327 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 5328 if (r == null) { 5329 return; 5330 } 5331 5332 r.activity.mConfigChangeFlags |= configChanges; 5333 r.mPreserveWindow = tmp.mPreserveWindow; 5334 5335 r.activity.mChangingConfigurations = true; 5336 5337 // If we are preserving the main window across relaunches we would also like to preserve 5338 // the children. However the client side view system does not support preserving 5339 // the child views so we notify the window manager to expect these windows to 5340 // be replaced and defer requests to destroy or hide them. This way we can achieve 5341 // visual continuity. It's important that we do this here prior to pause and destroy 5342 // as that is when we may hide or remove the child views. 5343 // 5344 // There is another scenario, if we have decided locally to relaunch the app from a 5345 // call to recreate, then none of the windows will be prepared for replacement or 5346 // preserved by the server, so we want to notify it that we are preparing to replace 5347 // everything 5348 try { 5349 if (r.mPreserveWindow) { 5350 WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( 5351 r.token, true /* childrenOnly */); 5352 } 5353 } catch (RemoteException e) { 5354 throw e.rethrowFromSystemServer(); 5355 } 5356 5357 // Save the current windowing mode to be restored and compared to the new configuration's 5358 // windowing mode (needed because we update the last reported windowing mode when launching 5359 // an activity and we can't tell inside performLaunchActivity whether we are relaunching) 5360 final int oldWindowingMode = mLastReportedWindowingMode.getOrDefault( 5361 r.activity.getActivityToken(), WINDOWING_MODE_UNDEFINED); 5362 handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents, 5363 pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity"); 5364 mLastReportedWindowingMode.put(r.activity.getActivityToken(), oldWindowingMode); 5365 handleWindowingModeChangeIfNeeded(r.activity, r.activity.mCurrentConfig); 5366 5367 if (pendingActions != null) { 5368 // Only report a successful relaunch to WindowManager. 5369 pendingActions.setReportRelaunchToWindowManager(true); 5370 } 5371 } 5372 5373 /** 5374 * Post a message to relaunch the activity. We do this instead of launching it immediately, 5375 * because this will destroy the activity from which it was called and interfere with the 5376 * lifecycle changes it was going through before. We need to make sure that we have finished 5377 * handling current transaction item before relaunching the activity. 5378 */ scheduleRelaunchActivity(IBinder token)5379 void scheduleRelaunchActivity(IBinder token) { 5380 mH.removeMessages(H.RELAUNCH_ACTIVITY, token); 5381 sendMessage(H.RELAUNCH_ACTIVITY, token); 5382 } 5383 5384 /** Performs the activity relaunch locally vs. requesting from system-server. */ handleRelaunchActivityLocally(IBinder token)5385 private void handleRelaunchActivityLocally(IBinder token) { 5386 final ActivityClientRecord r = mActivities.get(token); 5387 if (r == null) { 5388 Log.w(TAG, "Activity to relaunch no longer exists"); 5389 return; 5390 } 5391 5392 final int prevState = r.getLifecycleState(); 5393 5394 if (prevState < ON_RESUME || prevState > ON_STOP) { 5395 Log.w(TAG, "Activity state must be in [ON_RESUME..ON_STOP] in order to be relaunched," 5396 + "current state is " + prevState); 5397 return; 5398 } 5399 5400 5401 // Initialize a relaunch request. 5402 final MergedConfiguration mergedConfiguration = new MergedConfiguration( 5403 r.createdConfig != null ? r.createdConfig : mConfiguration, 5404 r.overrideConfig); 5405 final ActivityRelaunchItem activityRelaunchItem = ActivityRelaunchItem.obtain( 5406 null /* pendingResults */, null /* pendingIntents */, 0 /* configChanges */, 5407 mergedConfiguration, r.mPreserveWindow); 5408 // Make sure to match the existing lifecycle state in the end of the transaction. 5409 final ActivityLifecycleItem lifecycleRequest = 5410 TransactionExecutorHelper.getLifecycleRequestForCurrentState(r); 5411 // Schedule the transaction. 5412 final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); 5413 transaction.addCallback(activityRelaunchItem); 5414 transaction.setLifecycleStateRequest(lifecycleRequest); 5415 executeTransaction(transaction); 5416 } 5417 handleRelaunchActivityInner(ActivityClientRecord r, int configChanges, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents, PendingTransactionActions pendingActions, boolean startsNotResumed, Configuration overrideConfig, String reason)5418 private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges, 5419 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents, 5420 PendingTransactionActions pendingActions, boolean startsNotResumed, 5421 Configuration overrideConfig, String reason) { 5422 // Preserve last used intent, it may be set from Activity#setIntent(). 5423 final Intent customIntent = r.activity.mIntent; 5424 // Need to ensure state is saved. 5425 if (!r.paused) { 5426 performPauseActivity(r, false, reason, null /* pendingActions */); 5427 } 5428 if (!r.stopped) { 5429 callActivityOnStop(r, true /* saveState */, reason); 5430 } 5431 5432 handleDestroyActivity(r.token, false, configChanges, true, reason); 5433 5434 r.activity = null; 5435 r.window = null; 5436 r.hideForNow = false; 5437 r.nextIdle = null; 5438 // Merge any pending results and pending intents; don't just replace them 5439 if (pendingResults != null) { 5440 if (r.pendingResults == null) { 5441 r.pendingResults = pendingResults; 5442 } else { 5443 r.pendingResults.addAll(pendingResults); 5444 } 5445 } 5446 if (pendingIntents != null) { 5447 if (r.pendingIntents == null) { 5448 r.pendingIntents = pendingIntents; 5449 } else { 5450 r.pendingIntents.addAll(pendingIntents); 5451 } 5452 } 5453 r.startsNotResumed = startsNotResumed; 5454 r.overrideConfig = overrideConfig; 5455 5456 handleLaunchActivity(r, pendingActions, customIntent); 5457 } 5458 5459 @Override reportRelaunch(IBinder token, PendingTransactionActions pendingActions)5460 public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) { 5461 try { 5462 ActivityTaskManager.getService().activityRelaunched(token); 5463 final ActivityClientRecord r = mActivities.get(token); 5464 if (pendingActions.shouldReportRelaunchToWindowManager() && r != null 5465 && r.window != null) { 5466 r.window.reportActivityRelaunched(); 5467 } 5468 } catch (RemoteException e) { 5469 throw e.rethrowFromSystemServer(); 5470 } 5471 } 5472 callActivityOnSaveInstanceState(ActivityClientRecord r)5473 private void callActivityOnSaveInstanceState(ActivityClientRecord r) { 5474 r.state = new Bundle(); 5475 r.state.setAllowFds(false); 5476 if (r.isPersistable()) { 5477 r.persistentState = new PersistableBundle(); 5478 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state, 5479 r.persistentState); 5480 } else { 5481 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 5482 } 5483 } 5484 collectComponentCallbacks( boolean allActivities, Configuration newConfig)5485 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 5486 boolean allActivities, Configuration newConfig) { 5487 ArrayList<ComponentCallbacks2> callbacks 5488 = new ArrayList<ComponentCallbacks2>(); 5489 5490 synchronized (mResourcesManager) { 5491 final int NAPP = mAllApplications.size(); 5492 for (int i=0; i<NAPP; i++) { 5493 callbacks.add(mAllApplications.get(i)); 5494 } 5495 final int NACT = mActivities.size(); 5496 for (int i=0; i<NACT; i++) { 5497 ActivityClientRecord ar = mActivities.valueAt(i); 5498 Activity a = ar.activity; 5499 if (a != null) { 5500 Configuration thisConfig = applyConfigCompatMainThread( 5501 mCurDefaultDisplayDpi, newConfig, 5502 ar.packageInfo.getCompatibilityInfo()); 5503 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 5504 // If the activity is currently resumed, its configuration 5505 // needs to change right now. 5506 callbacks.add(a); 5507 } else if (thisConfig != null) { 5508 // Otherwise, we will tell it about the change 5509 // the next time it is resumed or shown. Note that 5510 // the activity manager may, before then, decide the 5511 // activity needs to be destroyed to handle its new 5512 // configuration. 5513 if (DEBUG_CONFIGURATION) { 5514 Slog.v(TAG, "Setting activity " 5515 + ar.activityInfo.name + " newConfig=" + thisConfig); 5516 } 5517 ar.newConfig = thisConfig; 5518 } 5519 } 5520 } 5521 final int NSVC = mServices.size(); 5522 for (int i=0; i<NSVC; i++) { 5523 final ComponentCallbacks2 serviceComp = mServices.valueAt(i); 5524 if (serviceComp instanceof InputMethodService) { 5525 mHasImeComponent = true; 5526 } 5527 callbacks.add(serviceComp); 5528 } 5529 } 5530 synchronized (mProviderMap) { 5531 final int NPRV = mLocalProviders.size(); 5532 for (int i=0; i<NPRV; i++) { 5533 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider); 5534 } 5535 } 5536 5537 return callbacks; 5538 } 5539 5540 /** 5541 * Updates the configuration for an Activity. The ActivityClientRecord's 5542 * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for 5543 * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering 5544 * the updated Configuration. 5545 * @param r ActivityClientRecord representing the Activity. 5546 * @param newBaseConfig The new configuration to use. This may be augmented with 5547 * {@link ActivityClientRecord#overrideConfig}. 5548 */ performConfigurationChangedForActivity(ActivityClientRecord r, Configuration newBaseConfig)5549 private void performConfigurationChangedForActivity(ActivityClientRecord r, 5550 Configuration newBaseConfig) { 5551 performConfigurationChangedForActivity(r, newBaseConfig, r.activity.getDisplayId(), 5552 false /* movedToDifferentDisplay */); 5553 } 5554 5555 /** 5556 * Updates the configuration for an Activity. The ActivityClientRecord's 5557 * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for 5558 * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering 5559 * the updated Configuration. 5560 * @param r ActivityClientRecord representing the Activity. 5561 * @param newBaseConfig The new configuration to use. This may be augmented with 5562 * {@link ActivityClientRecord#overrideConfig}. 5563 * @param displayId The id of the display where the Activity currently resides. 5564 * @param movedToDifferentDisplay Indicates if the activity was moved to different display. 5565 * @return {@link Configuration} instance sent to client, null if not sent. 5566 */ performConfigurationChangedForActivity(ActivityClientRecord r, Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay)5567 private Configuration performConfigurationChangedForActivity(ActivityClientRecord r, 5568 Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) { 5569 r.tmpConfig.setTo(newBaseConfig); 5570 if (r.overrideConfig != null) { 5571 r.tmpConfig.updateFrom(r.overrideConfig); 5572 } 5573 final Configuration reportedConfig = performActivityConfigurationChanged(r.activity, 5574 r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay); 5575 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); 5576 return reportedConfig; 5577 } 5578 5579 /** 5580 * Creates a new Configuration only if override would modify base. Otherwise returns base. 5581 * @param base The base configuration. 5582 * @param override The update to apply to the base configuration. Can be null. 5583 * @return A Configuration representing base with override applied. 5584 */ createNewConfigAndUpdateIfNotNull(@onNull Configuration base, @Nullable Configuration override)5585 private static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base, 5586 @Nullable Configuration override) { 5587 if (override == null) { 5588 return base; 5589 } 5590 Configuration newConfig = new Configuration(base); 5591 newConfig.updateFrom(override); 5592 return newConfig; 5593 } 5594 5595 /** 5596 * Decides whether to update a component's configuration and whether to inform it. 5597 * @param cb The component callback to notify of configuration change. 5598 * @param newConfig The new configuration. 5599 */ performConfigurationChanged(ComponentCallbacks2 cb, Configuration newConfig)5600 private void performConfigurationChanged(ComponentCallbacks2 cb, Configuration newConfig) { 5601 if (!REPORT_TO_ACTIVITY) { 5602 return; 5603 } 5604 5605 // ContextThemeWrappers may override the configuration for that context. We must check and 5606 // apply any overrides defined. 5607 Configuration contextThemeWrapperOverrideConfig = null; 5608 if (cb instanceof ContextThemeWrapper) { 5609 final ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb; 5610 contextThemeWrapperOverrideConfig = contextThemeWrapper.getOverrideConfiguration(); 5611 } 5612 5613 // Apply the ContextThemeWrapper override if necessary. 5614 // NOTE: Make sure the configurations are not modified, as they are treated as immutable 5615 // in many places. 5616 final Configuration configToReport = createNewConfigAndUpdateIfNotNull( 5617 newConfig, contextThemeWrapperOverrideConfig); 5618 cb.onConfigurationChanged(configToReport); 5619 } 5620 5621 /** 5622 * Decides whether to update an Activity's configuration and whether to inform it. 5623 * @param activity The activity to notify of configuration change. 5624 * @param newConfig The new configuration. 5625 * @param amOverrideConfig The override config that differentiates the Activity's configuration 5626 * from the base global configuration. This is supplied by 5627 * ActivityManager. 5628 * @param displayId Id of the display where activity currently resides. 5629 * @param movedToDifferentDisplay Indicates if the activity was moved to different display. 5630 * @return Configuration sent to client, null if no changes and not moved to different display. 5631 */ performActivityConfigurationChanged(Activity activity, Configuration newConfig, Configuration amOverrideConfig, int displayId, boolean movedToDifferentDisplay)5632 private Configuration performActivityConfigurationChanged(Activity activity, 5633 Configuration newConfig, Configuration amOverrideConfig, int displayId, 5634 boolean movedToDifferentDisplay) { 5635 if (activity == null) { 5636 throw new IllegalArgumentException("No activity provided."); 5637 } 5638 final IBinder activityToken = activity.getActivityToken(); 5639 if (activityToken == null) { 5640 throw new IllegalArgumentException("Activity token not set. Is the activity attached?"); 5641 } 5642 5643 // multi-window / pip mode changes, if any, should be sent before the configuration change 5644 // callback, see also PinnedStackTests#testConfigurationChangeOrderDuringTransition 5645 handleWindowingModeChangeIfNeeded(activity, newConfig); 5646 5647 boolean shouldReportChange = false; 5648 if (activity.mCurrentConfig == null) { 5649 shouldReportChange = true; 5650 } else { 5651 // If the new config is the same as the config this Activity is already running with and 5652 // the override config also didn't change, then don't bother calling 5653 // onConfigurationChanged. 5654 final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig); 5655 if (diff == 0 && !movedToDifferentDisplay 5656 && mResourcesManager.isSameResourcesOverrideConfig(activityToken, 5657 amOverrideConfig)) { 5658 // Nothing significant, don't proceed with updating and reporting. 5659 return null; 5660 } else if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0 5661 || !REPORT_TO_ACTIVITY) { 5662 // If this activity doesn't handle any of the config changes, then don't bother 5663 // calling onConfigurationChanged. Otherwise, report to the activity for the 5664 // changes. 5665 shouldReportChange = true; 5666 } 5667 } 5668 5669 // Propagate the configuration change to ResourcesManager and Activity. 5670 5671 // ContextThemeWrappers may override the configuration for that context. We must check and 5672 // apply any overrides defined. 5673 Configuration contextThemeWrapperOverrideConfig = activity.getOverrideConfiguration(); 5674 5675 // We only update an Activity's configuration if this is not a global configuration change. 5676 // This must also be done before the callback, or else we violate the contract that the new 5677 // resources are available in ComponentCallbacks2#onConfigurationChanged(Configuration). 5678 // Also apply the ContextThemeWrapper override if necessary. 5679 // NOTE: Make sure the configurations are not modified, as they are treated as immutable in 5680 // many places. 5681 final Configuration finalOverrideConfig = createNewConfigAndUpdateIfNotNull( 5682 amOverrideConfig, contextThemeWrapperOverrideConfig); 5683 mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig, 5684 displayId, movedToDifferentDisplay); 5685 5686 activity.mConfigChangeFlags = 0; 5687 activity.mCurrentConfig = new Configuration(newConfig); 5688 5689 // Apply the ContextThemeWrapper override if necessary. 5690 // NOTE: Make sure the configurations are not modified, as they are treated as immutable 5691 // in many places. 5692 final Configuration configToReport = createNewConfigAndUpdateIfNotNull(newConfig, 5693 contextThemeWrapperOverrideConfig); 5694 5695 if (!REPORT_TO_ACTIVITY) { 5696 // Not configured to report to activity. 5697 return configToReport; 5698 } 5699 5700 if (movedToDifferentDisplay) { 5701 activity.dispatchMovedToDisplay(displayId, configToReport); 5702 } 5703 5704 if (shouldReportChange) { 5705 activity.mCalled = false; 5706 activity.onConfigurationChanged(configToReport); 5707 if (!activity.mCalled) { 5708 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + 5709 " did not call through to super.onConfigurationChanged()"); 5710 } 5711 } 5712 5713 return configToReport; 5714 } 5715 applyConfigurationToResources(Configuration config)5716 public final void applyConfigurationToResources(Configuration config) { 5717 synchronized (mResourcesManager) { 5718 mResourcesManager.applyConfigurationToResourcesLocked(config, null); 5719 } 5720 } 5721 applyCompatConfiguration(int displayDensity)5722 final Configuration applyCompatConfiguration(int displayDensity) { 5723 Configuration config = mConfiguration; 5724 if (mCompatConfiguration == null) { 5725 mCompatConfiguration = new Configuration(); 5726 } 5727 mCompatConfiguration.setTo(mConfiguration); 5728 if (mResourcesManager.applyCompatConfigurationLocked(displayDensity, 5729 mCompatConfiguration)) { 5730 config = mCompatConfiguration; 5731 } 5732 return config; 5733 } 5734 5735 @Override handleConfigurationChanged(Configuration config)5736 public void handleConfigurationChanged(Configuration config) { 5737 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged"); 5738 mCurDefaultDisplayDpi = config.densityDpi; 5739 handleConfigurationChanged(config, null /* compat */); 5740 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 5741 } 5742 handleConfigurationChanged(Configuration config, CompatibilityInfo compat)5743 private void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 5744 5745 int configDiff; 5746 boolean equivalent; 5747 5748 final Theme systemTheme = getSystemContext().getTheme(); 5749 final Theme systemUiTheme = getSystemUiContext().getTheme(); 5750 5751 synchronized (mResourcesManager) { 5752 if (mPendingConfiguration != null) { 5753 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 5754 config = mPendingConfiguration; 5755 mCurDefaultDisplayDpi = config.densityDpi; 5756 updateDefaultDensity(); 5757 } 5758 mPendingConfiguration = null; 5759 } 5760 5761 if (config == null) { 5762 // TODO (b/135719017): Temporary log for debugging IME service. 5763 if (Build.IS_DEBUGGABLE && mHasImeComponent) { 5764 Log.w(TAG, "handleConfigurationChanged for IME app but config is null"); 5765 } 5766 return; 5767 } 5768 5769 // This flag tracks whether the new configuration is fundamentally equivalent to the 5770 // existing configuration. This is necessary to determine whether non-activity callbacks 5771 // should receive notice when the only changes are related to non-public fields. 5772 // We do not gate calling {@link #performActivityConfigurationChanged} based on this 5773 // flag as that method uses the same check on the activity config override as well. 5774 equivalent = mConfiguration != null && (0 == mConfiguration.diffPublicOnly(config)); 5775 5776 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 5777 + config); 5778 5779 mResourcesManager.applyConfigurationToResourcesLocked(config, compat); 5780 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), 5781 mResourcesManager.getConfiguration().getLocales()); 5782 5783 if (mConfiguration == null) { 5784 mConfiguration = new Configuration(); 5785 } 5786 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 5787 // TODO (b/135719017): Temporary log for debugging IME service. 5788 if (Build.IS_DEBUGGABLE && mHasImeComponent) { 5789 Log.w(TAG, "handleConfigurationChanged for IME app but config seq is obsolete " 5790 + ", config=" + config 5791 + ", mConfiguration=" + mConfiguration); 5792 } 5793 return; 5794 } 5795 5796 configDiff = mConfiguration.updateFrom(config); 5797 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 5798 5799 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) { 5800 systemTheme.rebase(); 5801 } 5802 5803 if ((systemUiTheme.getChangingConfigurations() & configDiff) != 0) { 5804 systemUiTheme.rebase(); 5805 } 5806 } 5807 5808 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 5809 5810 freeTextLayoutCachesIfNeeded(configDiff); 5811 5812 if (callbacks != null) { 5813 final int N = callbacks.size(); 5814 for (int i=0; i<N; i++) { 5815 ComponentCallbacks2 cb = callbacks.get(i); 5816 if (cb instanceof Activity) { 5817 // If callback is an Activity - call corresponding method to consider override 5818 // config and avoid onConfigurationChanged if it hasn't changed. 5819 Activity a = (Activity) cb; 5820 performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()), 5821 config); 5822 } else if (!equivalent) { 5823 performConfigurationChanged(cb, config); 5824 } else { 5825 // TODO (b/135719017): Temporary log for debugging IME service. 5826 if (Build.IS_DEBUGGABLE && cb instanceof InputMethodService) { 5827 Log.w(TAG, "performConfigurationChanged didn't callback to IME " 5828 + ", configDiff=" + configDiff 5829 + ", mConfiguration=" + mConfiguration); 5830 } 5831 } 5832 } 5833 } 5834 } 5835 5836 /** 5837 * Sends windowing mode change callbacks to {@link Activity} if applicable. 5838 * 5839 * See also {@link Activity#onMultiWindowModeChanged(boolean, Configuration)} and 5840 * {@link Activity#onPictureInPictureModeChanged(boolean, Configuration)} 5841 */ handleWindowingModeChangeIfNeeded(Activity activity, Configuration newConfiguration)5842 private void handleWindowingModeChangeIfNeeded(Activity activity, 5843 Configuration newConfiguration) { 5844 final int newWindowingMode = newConfiguration.windowConfiguration.getWindowingMode(); 5845 final IBinder token = activity.getActivityToken(); 5846 final int oldWindowingMode = mLastReportedWindowingMode.getOrDefault(token, 5847 WINDOWING_MODE_UNDEFINED); 5848 if (oldWindowingMode == newWindowingMode) return; 5849 // PiP callback is sent before the MW one. 5850 if (newWindowingMode == WINDOWING_MODE_PINNED) { 5851 activity.dispatchPictureInPictureModeChanged(true, newConfiguration); 5852 } else if (oldWindowingMode == WINDOWING_MODE_PINNED) { 5853 activity.dispatchPictureInPictureModeChanged(false, newConfiguration); 5854 } 5855 final boolean wasInMultiWindowMode = WindowConfiguration.inMultiWindowMode( 5856 oldWindowingMode); 5857 final boolean nowInMultiWindowMode = WindowConfiguration.inMultiWindowMode( 5858 newWindowingMode); 5859 if (wasInMultiWindowMode != nowInMultiWindowMode) { 5860 activity.dispatchMultiWindowModeChanged(nowInMultiWindowMode, newConfiguration); 5861 } 5862 mLastReportedWindowingMode.put(token, newWindowingMode); 5863 } 5864 5865 /** 5866 * Updates the application info. 5867 * 5868 * This only works in the system process. Must be called on the main thread. 5869 */ handleSystemApplicationInfoChanged(@onNull ApplicationInfo ai)5870 public void handleSystemApplicationInfoChanged(@NonNull ApplicationInfo ai) { 5871 Preconditions.checkState(mSystemThread, "Must only be called in the system process"); 5872 handleApplicationInfoChanged(ai); 5873 } 5874 5875 @VisibleForTesting(visibility = PACKAGE) handleApplicationInfoChanged(@onNull final ApplicationInfo ai)5876 public void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { 5877 // Updates triggered by package installation go through a package update 5878 // receiver. Here we try to capture ApplicationInfo changes that are 5879 // caused by other sources, such as overlays. That means we want to be as conservative 5880 // about code changes as possible. Take the diff of the old ApplicationInfo and the new 5881 // to see if anything needs to change. 5882 LoadedApk apk; 5883 LoadedApk resApk; 5884 // Update all affected loaded packages with new package information 5885 synchronized (mResourcesManager) { 5886 WeakReference<LoadedApk> ref = mPackages.get(ai.packageName); 5887 apk = ref != null ? ref.get() : null; 5888 ref = mResourcePackages.get(ai.packageName); 5889 resApk = ref != null ? ref.get() : null; 5890 } 5891 5892 final String[] oldResDirs = new String[2]; 5893 5894 if (apk != null) { 5895 oldResDirs[0] = apk.getResDir(); 5896 final ArrayList<String> oldPaths = new ArrayList<>(); 5897 LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths); 5898 apk.updateApplicationInfo(ai, oldPaths); 5899 } 5900 if (resApk != null) { 5901 oldResDirs[1] = resApk.getResDir(); 5902 final ArrayList<String> oldPaths = new ArrayList<>(); 5903 LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths); 5904 resApk.updateApplicationInfo(ai, oldPaths); 5905 } 5906 5907 synchronized (mResourcesManager) { 5908 // Update all affected Resources objects to use new ResourcesImpl 5909 mResourcesManager.applyNewResourceDirsLocked(ai, oldResDirs); 5910 } 5911 5912 ApplicationPackageManager.configurationChanged(); 5913 5914 // Trigger a regular Configuration change event, only with a different assetsSeq number 5915 // so that we actually call through to all components. 5916 // TODO(adamlesinski): Change this to make use of ActivityManager's upcoming ability to 5917 // store configurations per-process. 5918 Configuration newConfig = new Configuration(); 5919 newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1; 5920 handleConfigurationChanged(newConfig, null); 5921 5922 // Preserve windows to avoid black flickers when overlays change. 5923 relaunchAllActivities(true /* preserveWindows */); 5924 } 5925 freeTextLayoutCachesIfNeeded(int configDiff)5926 static void freeTextLayoutCachesIfNeeded(int configDiff) { 5927 if (configDiff != 0) { 5928 // Ask text layout engine to free its caches if there is a locale change 5929 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 5930 if (hasLocaleConfigChange) { 5931 Canvas.freeTextLayoutCaches(); 5932 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 5933 } 5934 } 5935 } 5936 5937 /** 5938 * Sets the supplied {@code overrideConfig} as pending for the {@code activityToken}. Calling 5939 * this method prevents any calls to 5940 * {@link #handleActivityConfigurationChanged(IBinder, Configuration, int, boolean)} from 5941 * processing any configurations older than {@code overrideConfig}. 5942 */ 5943 @Override updatePendingActivityConfiguration(IBinder activityToken, Configuration overrideConfig)5944 public void updatePendingActivityConfiguration(IBinder activityToken, 5945 Configuration overrideConfig) { 5946 final ActivityClientRecord r; 5947 synchronized (mResourcesManager) { 5948 r = mActivities.get(activityToken); 5949 } 5950 5951 if (r == null) { 5952 if (DEBUG_CONFIGURATION) { 5953 Slog.w(TAG, "Not found target activity to update its pending config."); 5954 } 5955 return; 5956 } 5957 5958 synchronized (r) { 5959 if (r.mPendingOverrideConfig != null 5960 && !r.mPendingOverrideConfig.isOtherSeqNewer(overrideConfig)) { 5961 if (DEBUG_CONFIGURATION) { 5962 Slog.v(TAG, "Activity has newer configuration pending so drop this" 5963 + " transaction. overrideConfig=" + overrideConfig 5964 + " r.mPendingOverrideConfig=" + r.mPendingOverrideConfig); 5965 } 5966 return; 5967 } 5968 r.mPendingOverrideConfig = overrideConfig; 5969 } 5970 } 5971 5972 /** 5973 * Handle new activity configuration and/or move to a different display. This method is a noop 5974 * if {@link #updatePendingActivityConfiguration(IBinder, Configuration)} has been called with 5975 * a newer config than {@code overrideConfig}. 5976 * 5977 * @param activityToken Target activity token. 5978 * @param overrideConfig Activity override config. 5979 * @param displayId Id of the display where activity was moved to, -1 if there was no move and 5980 * value didn't change. 5981 */ 5982 @Override handleActivityConfigurationChanged(IBinder activityToken, @NonNull Configuration overrideConfig, int displayId)5983 public void handleActivityConfigurationChanged(IBinder activityToken, 5984 @NonNull Configuration overrideConfig, int displayId) { 5985 ActivityClientRecord r = mActivities.get(activityToken); 5986 // Check input params. 5987 if (r == null || r.activity == null) { 5988 if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r); 5989 return; 5990 } 5991 final boolean movedToDifferentDisplay = displayId != INVALID_DISPLAY 5992 && displayId != r.activity.getDisplayId(); 5993 5994 synchronized (r) { 5995 if (overrideConfig.isOtherSeqNewer(r.mPendingOverrideConfig)) { 5996 if (DEBUG_CONFIGURATION) { 5997 Slog.v(TAG, "Activity has newer configuration pending so drop this" 5998 + " transaction. overrideConfig=" + overrideConfig 5999 + " r.mPendingOverrideConfig=" + r.mPendingOverrideConfig); 6000 } 6001 return; 6002 } 6003 r.mPendingOverrideConfig = null; 6004 } 6005 6006 if (r.overrideConfig != null && !r.overrideConfig.isOtherSeqNewer(overrideConfig) 6007 && !movedToDifferentDisplay) { 6008 if (DEBUG_CONFIGURATION) { 6009 Slog.v(TAG, "Activity already handled newer configuration so drop this" 6010 + " transaction. overrideConfig=" + overrideConfig + " r.overrideConfig=" 6011 + r.overrideConfig); 6012 } 6013 return; 6014 } 6015 6016 // Perform updates. 6017 r.overrideConfig = overrideConfig; 6018 final ViewRootImpl viewRoot = r.activity.mDecor != null 6019 ? r.activity.mDecor.getViewRootImpl() : null; 6020 6021 if (movedToDifferentDisplay) { 6022 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity moved to display, activity:" 6023 + r.activityInfo.name + ", displayId=" + displayId 6024 + ", config=" + overrideConfig); 6025 6026 final Configuration reportedConfig = performConfigurationChangedForActivity(r, 6027 mCompatConfiguration, displayId, true /* movedToDifferentDisplay */); 6028 if (viewRoot != null) { 6029 viewRoot.onMovedToDisplay(displayId, reportedConfig); 6030 } 6031 } else { 6032 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 6033 + r.activityInfo.name + ", config=" + overrideConfig); 6034 performConfigurationChangedForActivity(r, mCompatConfiguration); 6035 } 6036 // Notify the ViewRootImpl instance about configuration changes. It may have initiated this 6037 // update to make sure that resources are updated before updating itself. 6038 if (viewRoot != null) { 6039 viewRoot.updateConfiguration(displayId); 6040 } 6041 mSomeActivitiesChanged = true; 6042 } 6043 handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType)6044 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { 6045 if (start) { 6046 try { 6047 switch (profileType) { 6048 default: 6049 mProfiler.setProfiler(profilerInfo); 6050 mProfiler.startProfiling(); 6051 break; 6052 } 6053 } catch (RuntimeException e) { 6054 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile 6055 + " -- can the process access this path?"); 6056 } finally { 6057 profilerInfo.closeFd(); 6058 } 6059 } else { 6060 switch (profileType) { 6061 default: 6062 mProfiler.stopProfiling(); 6063 break; 6064 } 6065 } 6066 } 6067 6068 /** 6069 * Public entrypoint to stop profiling. This is required to end profiling when the app crashes, 6070 * so that profiler data won't be lost. 6071 * 6072 * @hide 6073 */ stopProfiling()6074 public void stopProfiling() { 6075 if (mProfiler != null) { 6076 mProfiler.stopProfiling(); 6077 } 6078 } 6079 handleDumpHeap(DumpHeapData dhd)6080 static void handleDumpHeap(DumpHeapData dhd) { 6081 if (dhd.runGc) { 6082 System.gc(); 6083 System.runFinalization(); 6084 System.gc(); 6085 } 6086 try (ParcelFileDescriptor fd = dhd.fd) { 6087 if (dhd.managed) { 6088 Debug.dumpHprofData(dhd.path, fd.getFileDescriptor()); 6089 } else if (dhd.mallocInfo) { 6090 Debug.dumpNativeMallocInfo(fd.getFileDescriptor()); 6091 } else { 6092 Debug.dumpNativeHeap(fd.getFileDescriptor()); 6093 } 6094 } catch (IOException e) { 6095 if (dhd.managed) { 6096 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 6097 + " -- can the process access this path?", e); 6098 } else { 6099 Slog.w(TAG, "Failed to dump heap", e); 6100 } 6101 } catch (RuntimeException e) { 6102 // This should no longer happening now that we're copying the file descriptor. 6103 Slog.wtf(TAG, "Heap dumper threw a runtime exception", e); 6104 } 6105 try { 6106 ActivityManager.getService().dumpHeapFinished(dhd.path); 6107 } catch (RemoteException e) { 6108 throw e.rethrowFromSystemServer(); 6109 } 6110 if (dhd.finishCallback != null) { 6111 dhd.finishCallback.sendResult(null); 6112 } 6113 } 6114 handleDispatchPackageBroadcast(int cmd, String[] packages)6115 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 6116 boolean hasPkgInfo = false; 6117 switch (cmd) { 6118 case ApplicationThreadConstants.PACKAGE_REMOVED: 6119 case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL: 6120 { 6121 final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED; 6122 if (packages == null) { 6123 break; 6124 } 6125 synchronized (mResourcesManager) { 6126 for (int i = packages.length - 1; i >= 0; i--) { 6127 if (!hasPkgInfo) { 6128 WeakReference<LoadedApk> ref = mPackages.get(packages[i]); 6129 if (ref != null && ref.get() != null) { 6130 hasPkgInfo = true; 6131 } else { 6132 ref = mResourcePackages.get(packages[i]); 6133 if (ref != null && ref.get() != null) { 6134 hasPkgInfo = true; 6135 } 6136 } 6137 } 6138 if (killApp) { 6139 mPackages.remove(packages[i]); 6140 mResourcePackages.remove(packages[i]); 6141 } 6142 } 6143 } 6144 break; 6145 } 6146 case ApplicationThreadConstants.PACKAGE_REPLACED: 6147 { 6148 if (packages == null) { 6149 break; 6150 } 6151 6152 List<String> packagesHandled = new ArrayList<>(); 6153 6154 synchronized (mResourcesManager) { 6155 for (int i = packages.length - 1; i >= 0; i--) { 6156 String packageName = packages[i]; 6157 WeakReference<LoadedApk> ref = mPackages.get(packageName); 6158 LoadedApk pkgInfo = ref != null ? ref.get() : null; 6159 if (pkgInfo != null) { 6160 hasPkgInfo = true; 6161 } else { 6162 ref = mResourcePackages.get(packageName); 6163 pkgInfo = ref != null ? ref.get() : null; 6164 if (pkgInfo != null) { 6165 hasPkgInfo = true; 6166 } 6167 } 6168 // If the package is being replaced, yet it still has a valid 6169 // LoadedApk object, the package was updated with _DONT_KILL. 6170 // Adjust it's internal references to the application info and 6171 // resources. 6172 if (pkgInfo != null) { 6173 packagesHandled.add(packageName); 6174 try { 6175 final ApplicationInfo aInfo = 6176 sPackageManager.getApplicationInfo( 6177 packageName, 6178 PackageManager.GET_SHARED_LIBRARY_FILES, 6179 UserHandle.myUserId()); 6180 6181 if (mActivities.size() > 0) { 6182 for (ActivityClientRecord ar : mActivities.values()) { 6183 if (ar.activityInfo.applicationInfo.packageName 6184 .equals(packageName)) { 6185 ar.activityInfo.applicationInfo = aInfo; 6186 ar.packageInfo = pkgInfo; 6187 } 6188 } 6189 } 6190 6191 final String[] oldResDirs = { pkgInfo.getResDir() }; 6192 6193 final ArrayList<String> oldPaths = new ArrayList<>(); 6194 LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths); 6195 pkgInfo.updateApplicationInfo(aInfo, oldPaths); 6196 6197 synchronized (mResourcesManager) { 6198 // Update affected Resources objects to use new ResourcesImpl 6199 mResourcesManager.applyNewResourceDirsLocked(aInfo, oldResDirs); 6200 } 6201 } catch (RemoteException e) { 6202 } 6203 } 6204 } 6205 } 6206 6207 try { 6208 getPackageManager().notifyPackagesReplacedReceived( 6209 packagesHandled.toArray(new String[0])); 6210 } catch (RemoteException ignored) { 6211 } 6212 6213 break; 6214 } 6215 } 6216 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); 6217 } 6218 handleLowMemory()6219 final void handleLowMemory() { 6220 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 6221 6222 final int N = callbacks.size(); 6223 for (int i=0; i<N; i++) { 6224 callbacks.get(i).onLowMemory(); 6225 } 6226 6227 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 6228 if (Process.myUid() != Process.SYSTEM_UID) { 6229 int sqliteReleased = SQLiteDatabase.releaseMemory(); 6230 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 6231 } 6232 6233 // Ask graphics to free up as much as possible (font/image caches) 6234 Canvas.freeCaches(); 6235 6236 // Ask text layout engine to free also as much as possible 6237 Canvas.freeTextLayoutCaches(); 6238 6239 BinderInternal.forceGc("mem"); 6240 } 6241 handleTrimMemory(int level)6242 private void handleTrimMemory(int level) { 6243 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory"); 6244 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 6245 6246 if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { 6247 for (PropertyInvalidatedCache pic : PropertyInvalidatedCache.getActiveCaches()) { 6248 pic.clear(); 6249 } 6250 } 6251 6252 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 6253 6254 final int N = callbacks.size(); 6255 for (int i = 0; i < N; i++) { 6256 callbacks.get(i).onTrimMemory(level); 6257 } 6258 6259 WindowManagerGlobal.getInstance().trimMemory(level); 6260 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6261 6262 if (SystemProperties.getInt("debug.am.run_gc_trim_level", Integer.MAX_VALUE) <= level) { 6263 unscheduleGcIdler(); 6264 doGcIfNeeded("tm"); 6265 } 6266 if (SystemProperties.getInt("debug.am.run_mallopt_trim_level", Integer.MAX_VALUE) 6267 <= level) { 6268 unschedulePurgeIdler(); 6269 purgePendingResources(); 6270 } 6271 } 6272 setupGraphicsSupport(Context context)6273 private void setupGraphicsSupport(Context context) { 6274 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport"); 6275 6276 // The system package doesn't have real data directories, so don't set up cache paths. 6277 if (!"android".equals(context.getPackageName())) { 6278 // This cache location probably points at credential-encrypted 6279 // storage which may not be accessible yet; assign it anyway instead 6280 // of pointing at device-encrypted storage. 6281 final File cacheDir = context.getCacheDir(); 6282 if (cacheDir != null) { 6283 // Provide a usable directory for temporary files 6284 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 6285 } else { 6286 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property " 6287 + "due to missing cache directory"); 6288 } 6289 6290 // Setup a location to store generated/compiled graphics code. 6291 final Context deviceContext = context.createDeviceProtectedStorageContext(); 6292 final File codeCacheDir = deviceContext.getCodeCacheDir(); 6293 if (codeCacheDir != null) { 6294 try { 6295 int uid = Process.myUid(); 6296 String[] packages = getPackageManager().getPackagesForUid(uid); 6297 if (packages != null) { 6298 HardwareRenderer.setupDiskCache(codeCacheDir); 6299 RenderScriptCacheDir.setupDiskCache(codeCacheDir); 6300 } 6301 } catch (RemoteException e) { 6302 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6303 throw e.rethrowFromSystemServer(); 6304 } 6305 } else { 6306 Log.w(TAG, "Unable to use shader/script cache: missing code-cache directory"); 6307 } 6308 } 6309 6310 GraphicsEnvironment.getInstance().setup(context, mCoreSettings); 6311 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6312 } 6313 updateDefaultDensity()6314 private void updateDefaultDensity() { 6315 final int densityDpi = mCurDefaultDisplayDpi; 6316 if (!mDensityCompatMode 6317 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED 6318 && densityDpi != DisplayMetrics.DENSITY_DEVICE) { 6319 DisplayMetrics.DENSITY_DEVICE = densityDpi; 6320 Bitmap.setDefaultDensity(densityDpi); 6321 } 6322 } 6323 6324 /** 6325 * Returns the correct library directory for the current ABI. 6326 * <p> 6327 * If we're dealing with a multi-arch application that has both 32 and 64 bit shared 6328 * libraries, we might need to choose the secondary depending on what the current 6329 * runtime's instruction set is. 6330 */ getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo)6331 private String getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo) { 6332 if (appInfo.primaryCpuAbi != null && appInfo.secondaryCpuAbi != null 6333 && appInfo.secondaryCpuAbi.equals(insInfo.secondaryCpuAbi)) { 6334 // Get the instruction set supported by the secondary ABI. In the presence 6335 // of a native bridge this might be different than the one secondary ABI used. 6336 String secondaryIsa = 6337 VMRuntime.getInstructionSet(appInfo.secondaryCpuAbi); 6338 final String secondaryDexCodeIsa = 6339 SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa); 6340 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa; 6341 6342 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet(); 6343 if (runtimeIsa.equals(secondaryIsa)) { 6344 return insInfo.secondaryNativeLibraryDir; 6345 } 6346 } 6347 return insInfo.nativeLibraryDir; 6348 } 6349 6350 /** 6351 * The LocaleList set for the app's resources may have been shuffled so that the preferred 6352 * Locale is at position 0. We must find the index of this preferred Locale in the 6353 * original LocaleList. 6354 */ updateLocaleListFromAppContext(Context context, LocaleList newLocaleList)6355 private void updateLocaleListFromAppContext(Context context, LocaleList newLocaleList) { 6356 final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0); 6357 final int newLocaleListSize = newLocaleList.size(); 6358 for (int i = 0; i < newLocaleListSize; i++) { 6359 if (bestLocale.equals(newLocaleList.get(i))) { 6360 LocaleList.setDefault(newLocaleList, i); 6361 return; 6362 } 6363 } 6364 6365 // The app may have overridden the LocaleList with its own Locale 6366 // (not present in the available list). Push the chosen Locale 6367 // to the front of the list. 6368 LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList)); 6369 } 6370 6371 @UnsupportedAppUsage handleBindApplication(AppBindData data)6372 private void handleBindApplication(AppBindData data) { 6373 // Register the UI Thread as a sensitive thread to the runtime. 6374 VMRuntime.registerSensitiveThread(); 6375 // In the case the stack depth property exists, pass it down to the runtime. 6376 String property = SystemProperties.get("debug.allocTracker.stackDepth"); 6377 if (property.length() != 0) { 6378 VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property)); 6379 } 6380 if (data.trackAllocation) { 6381 DdmVmInternal.enableRecentAllocations(true); 6382 } 6383 // Note when this process has started. 6384 Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); 6385 6386 AppCompatCallbacks.install(data.disabledCompatChanges); 6387 mBoundApplication = data; 6388 mConfiguration = new Configuration(data.config); 6389 mCompatConfiguration = new Configuration(data.config); 6390 6391 mProfiler = new Profiler(); 6392 String agent = null; 6393 if (data.initProfilerInfo != null) { 6394 mProfiler.profileFile = data.initProfilerInfo.profileFile; 6395 mProfiler.profileFd = data.initProfilerInfo.profileFd; 6396 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 6397 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 6398 mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput; 6399 if (data.initProfilerInfo.attachAgentDuringBind) { 6400 agent = data.initProfilerInfo.agent; 6401 } 6402 } 6403 6404 // send up app name; do this *before* waiting for debugger 6405 Process.setArgV0(data.processName); 6406 android.ddm.DdmHandleAppName.setAppName(data.processName, 6407 data.appInfo.packageName, 6408 UserHandle.myUserId()); 6409 VMRuntime.setProcessPackageName(data.appInfo.packageName); 6410 6411 // Pass data directory path to ART. This is used for caching information and 6412 // should be set before any application code is loaded. 6413 VMRuntime.setProcessDataDirectory(data.appInfo.dataDir); 6414 6415 if (mProfiler.profileFd != null) { 6416 mProfiler.startProfiling(); 6417 } 6418 6419 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 6420 // implementation to use the pool executor. Normally, we use the 6421 // serialized executor as the default. This has to happen in the 6422 // main thread so the main looper is set right. 6423 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 6424 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 6425 } 6426 6427 // Let the util.*Array classes maintain "undefined" for apps targeting Pie or earlier. 6428 UtilConfig.setThrowExceptionForUpperArrayOutOfBounds( 6429 data.appInfo.targetSdkVersion >= Build.VERSION_CODES.Q); 6430 6431 Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 6432 6433 // Prior to P, internal calls to decode Bitmaps used BitmapFactory, 6434 // which may scale up to account for density. In P, we switched to 6435 // ImageDecoder, which skips the upscale to save memory. ImageDecoder 6436 // needs to still scale up in older apps, in case they rely on the 6437 // size of the Bitmap without considering its density. 6438 ImageDecoder.sApiLevel = data.appInfo.targetSdkVersion; 6439 6440 /* 6441 * Before spawning a new process, reset the time zone to be the system time zone. 6442 * This needs to be done because the system time zone could have changed after the 6443 * the spawning of this process. Without doing this this process would have the incorrect 6444 * system time zone. 6445 */ 6446 TimeZone.setDefault(null); 6447 6448 /* 6449 * Set the LocaleList. This may change once we create the App Context. 6450 */ 6451 LocaleList.setDefault(data.config.getLocales()); 6452 6453 synchronized (mResourcesManager) { 6454 /* 6455 * Update the system configuration since its preloaded and might not 6456 * reflect configuration changes. The configuration object passed 6457 * in AppBindData can be safely assumed to be up to date 6458 */ 6459 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); 6460 mCurDefaultDisplayDpi = data.config.densityDpi; 6461 6462 // This calls mResourcesManager so keep it within the synchronized block. 6463 applyCompatConfiguration(mCurDefaultDisplayDpi); 6464 } 6465 6466 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 6467 6468 if (agent != null) { 6469 handleAttachAgent(agent, data.info); 6470 } 6471 6472 /** 6473 * Switch this process to density compatibility mode if needed. 6474 */ 6475 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 6476 == 0) { 6477 mDensityCompatMode = true; 6478 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 6479 } 6480 updateDefaultDensity(); 6481 6482 final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24); 6483 Boolean is24Hr = null; 6484 if (use24HourSetting != null) { 6485 is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE; 6486 } 6487 // null : use locale default for 12/24 hour formatting, 6488 // false : use 12 hour format, 6489 // true : use 24 hour format. 6490 DateFormat.set24HourTimePref(is24Hr); 6491 6492 updateDebugViewAttributeState(); 6493 6494 StrictMode.initThreadDefaults(data.appInfo); 6495 StrictMode.initVmDefaults(data.appInfo); 6496 6497 if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) { 6498 // XXX should have option to change the port. 6499 Debug.changeDebugPort(8100); 6500 if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) { 6501 Slog.w(TAG, "Application " + data.info.getPackageName() 6502 + " is waiting for the debugger on port 8100..."); 6503 6504 IActivityManager mgr = ActivityManager.getService(); 6505 try { 6506 mgr.showWaitingForDebugger(mAppThread, true); 6507 } catch (RemoteException ex) { 6508 throw ex.rethrowFromSystemServer(); 6509 } 6510 6511 Debug.waitForDebugger(); 6512 6513 try { 6514 mgr.showWaitingForDebugger(mAppThread, false); 6515 } catch (RemoteException ex) { 6516 throw ex.rethrowFromSystemServer(); 6517 } 6518 6519 } else { 6520 Slog.w(TAG, "Application " + data.info.getPackageName() 6521 + " can be debugged on port 8100..."); 6522 } 6523 } 6524 6525 // Allow binder tracing, and application-generated systrace messages if we're profileable. 6526 boolean isAppProfileable = data.appInfo.isProfileableByShell(); 6527 Trace.setAppTracingAllowed(isAppProfileable); 6528 if ((isAppProfileable || Build.IS_DEBUGGABLE) && data.enableBinderTracking) { 6529 Binder.enableTracing(); 6530 } 6531 6532 // Initialize heap profiling. 6533 if (isAppProfileable || Build.IS_DEBUGGABLE) { 6534 nInitZygoteChildHeapProfiling(); 6535 } 6536 6537 // Allow renderer debugging features if we're debuggable. 6538 boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 6539 HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE); 6540 HardwareRenderer.setPackageName(data.appInfo.packageName); 6541 6542 /** 6543 * Initialize the default http proxy in this process for the reasons we set the time zone. 6544 */ 6545 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies"); 6546 final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 6547 if (b != null) { 6548 // In pre-boot mode (doing initial launch to collect password), not 6549 // all system is up. This includes the connectivity service, so don't 6550 // crash if we can't get it. 6551 final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 6552 try { 6553 Proxy.setHttpProxySystemProperty(service.getProxyForNetwork(null)); 6554 } catch (RemoteException e) { 6555 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6556 throw e.rethrowFromSystemServer(); 6557 } 6558 } 6559 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6560 6561 // Instrumentation info affects the class loader, so load it before 6562 // setting up the app context. 6563 final InstrumentationInfo ii; 6564 if (data.instrumentationName != null) { 6565 try { 6566 ii = new ApplicationPackageManager( 6567 null, getPackageManager(), getPermissionManager()) 6568 .getInstrumentationInfo(data.instrumentationName, 0); 6569 } catch (PackageManager.NameNotFoundException e) { 6570 throw new RuntimeException( 6571 "Unable to find instrumentation info for: " + data.instrumentationName); 6572 } 6573 6574 // Warn of potential ABI mismatches. 6575 if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi) 6576 || !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) { 6577 Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: " 6578 + "package[" + data.appInfo.packageName + "]: " 6579 + data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi 6580 + " instrumentation[" + ii.packageName + "]: " 6581 + ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi); 6582 } 6583 6584 mInstrumentationPackageName = ii.packageName; 6585 mInstrumentationAppDir = ii.sourceDir; 6586 mInstrumentationSplitAppDirs = ii.splitSourceDirs; 6587 mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); 6588 mInstrumentedAppDir = data.info.getAppDir(); 6589 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 6590 mInstrumentedLibDir = data.info.getLibDir(); 6591 } else { 6592 ii = null; 6593 } 6594 6595 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); 6596 updateLocaleListFromAppContext(appContext, 6597 mResourcesManager.getConfiguration().getLocales()); 6598 6599 if (!Process.isIsolated()) { 6600 final int oldMask = StrictMode.allowThreadDiskWritesMask(); 6601 try { 6602 setupGraphicsSupport(appContext); 6603 } finally { 6604 StrictMode.setThreadPolicyMask(oldMask); 6605 } 6606 } else { 6607 HardwareRenderer.setIsolatedProcess(true); 6608 } 6609 6610 // Install the Network Security Config Provider. This must happen before the application 6611 // code is loaded to prevent issues with instances of TLS objects being created before 6612 // the provider is installed. 6613 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install"); 6614 NetworkSecurityConfigProvider.install(appContext); 6615 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 6616 6617 // Continue loading instrumentation. 6618 if (ii != null) { 6619 ApplicationInfo instrApp; 6620 try { 6621 instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0, 6622 UserHandle.myUserId()); 6623 } catch (RemoteException e) { 6624 instrApp = null; 6625 } 6626 if (instrApp == null) { 6627 instrApp = new ApplicationInfo(); 6628 } 6629 ii.copyTo(instrApp); 6630 instrApp.initForUser(UserHandle.myUserId()); 6631 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 6632 appContext.getClassLoader(), false, true, false); 6633 6634 // The test context's op package name == the target app's op package name, because 6635 // the app ops manager checks the op package name against the real calling UID, 6636 // which is what the target package name is associated with. 6637 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi, 6638 appContext.getOpPackageName()); 6639 6640 try { 6641 final ClassLoader cl = instrContext.getClassLoader(); 6642 mInstrumentation = (Instrumentation) 6643 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 6644 } catch (Exception e) { 6645 throw new RuntimeException( 6646 "Unable to instantiate instrumentation " 6647 + data.instrumentationName + ": " + e.toString(), e); 6648 } 6649 6650 final ComponentName component = new ComponentName(ii.packageName, ii.name); 6651 mInstrumentation.init(this, instrContext, appContext, component, 6652 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); 6653 6654 if (mProfiler.profileFile != null && !ii.handleProfiling 6655 && mProfiler.profileFd == null) { 6656 mProfiler.handlingProfiling = true; 6657 final File file = new File(mProfiler.profileFile); 6658 file.getParentFile().mkdirs(); 6659 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 6660 } 6661 } else { 6662 mInstrumentation = new Instrumentation(); 6663 mInstrumentation.basicInit(this); 6664 } 6665 6666 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 6667 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 6668 } else { 6669 // Small heap, clamp to the current growth limit and let the heap release 6670 // pages after the growth limit to the non growth limit capacity. b/18387825 6671 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); 6672 } 6673 6674 // Allow disk access during application and provider setup. This could 6675 // block processing ordered broadcasts, but later processing would 6676 // probably end up doing the same disk access. 6677 Application app; 6678 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 6679 final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy(); 6680 try { 6681 // If the app is being launched for full backup or restore, bring it up in 6682 // a restricted environment with the base application class. 6683 app = data.info.makeApplication(data.restrictedBackupMode, null); 6684 6685 // Propagate autofill compat state 6686 app.setAutofillOptions(data.autofillOptions); 6687 6688 // Propagate Content Capture options 6689 app.setContentCaptureOptions(data.contentCaptureOptions); 6690 6691 mInitialApplication = app; 6692 6693 // don't bring up providers in restricted mode; they may depend on the 6694 // app's custom Application class 6695 if (!data.restrictedBackupMode) { 6696 if (!ArrayUtils.isEmpty(data.providers)) { 6697 installContentProviders(app, data.providers); 6698 } 6699 } 6700 6701 // Do this after providers, since instrumentation tests generally start their 6702 // test thread at this point, and we don't want that racing. 6703 try { 6704 mInstrumentation.onCreate(data.instrumentationArgs); 6705 } 6706 catch (Exception e) { 6707 throw new RuntimeException( 6708 "Exception thrown in onCreate() of " 6709 + data.instrumentationName + ": " + e.toString(), e); 6710 } 6711 try { 6712 mInstrumentation.callApplicationOnCreate(app); 6713 } catch (Exception e) { 6714 if (!mInstrumentation.onException(app, e)) { 6715 throw new RuntimeException( 6716 "Unable to create application " + app.getClass().getName() 6717 + ": " + e.toString(), e); 6718 } 6719 } 6720 } finally { 6721 // If the app targets < O-MR1, or doesn't change the thread policy 6722 // during startup, clobber the policy to maintain behavior of b/36951662 6723 if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1 6724 || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) { 6725 StrictMode.setThreadPolicy(savedPolicy); 6726 } 6727 } 6728 6729 // Preload fonts resources 6730 FontsContract.setApplicationContextForResources(appContext); 6731 if (!Process.isIsolated()) { 6732 try { 6733 final ApplicationInfo info = 6734 getPackageManager().getApplicationInfo( 6735 data.appInfo.packageName, 6736 PackageManager.GET_META_DATA /*flags*/, 6737 UserHandle.myUserId()); 6738 if (info.metaData != null) { 6739 final int preloadedFontsResource = info.metaData.getInt( 6740 ApplicationInfo.METADATA_PRELOADED_FONTS, 0); 6741 if (preloadedFontsResource != 0) { 6742 data.info.getResources().preloadFonts(preloadedFontsResource); 6743 } 6744 } 6745 } catch (RemoteException e) { 6746 throw e.rethrowFromSystemServer(); 6747 } 6748 } 6749 } 6750 finishInstrumentation(int resultCode, Bundle results)6751 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 6752 IActivityManager am = ActivityManager.getService(); 6753 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 6754 && mProfiler.profileFd == null) { 6755 Debug.stopMethodTracing(); 6756 } 6757 //Slog.i(TAG, "am: " + ActivityManager.getService() 6758 // + ", app thr: " + mAppThread); 6759 try { 6760 am.finishInstrumentation(mAppThread, resultCode, results); 6761 } catch (RemoteException ex) { 6762 throw ex.rethrowFromSystemServer(); 6763 } 6764 } 6765 6766 @UnsupportedAppUsage installContentProviders( Context context, List<ProviderInfo> providers)6767 private void installContentProviders( 6768 Context context, List<ProviderInfo> providers) { 6769 final ArrayList<ContentProviderHolder> results = new ArrayList<>(); 6770 6771 for (ProviderInfo cpi : providers) { 6772 if (DEBUG_PROVIDER) { 6773 StringBuilder buf = new StringBuilder(128); 6774 buf.append("Pub "); 6775 buf.append(cpi.authority); 6776 buf.append(": "); 6777 buf.append(cpi.name); 6778 Log.i(TAG, buf.toString()); 6779 } 6780 ContentProviderHolder cph = installProvider(context, null, cpi, 6781 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 6782 if (cph != null) { 6783 cph.noReleaseNeeded = true; 6784 results.add(cph); 6785 } 6786 } 6787 6788 try { 6789 ActivityManager.getService().publishContentProviders( 6790 getApplicationThread(), results); 6791 } catch (RemoteException ex) { 6792 throw ex.rethrowFromSystemServer(); 6793 } 6794 } 6795 6796 @UnsupportedAppUsage acquireProvider( Context c, String auth, int userId, boolean stable)6797 public final IContentProvider acquireProvider( 6798 Context c, String auth, int userId, boolean stable) { 6799 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 6800 if (provider != null) { 6801 return provider; 6802 } 6803 6804 // There is a possible race here. Another thread may try to acquire 6805 // the same provider at the same time. When this happens, we want to ensure 6806 // that the first one wins. 6807 // Note that we cannot hold the lock while acquiring and installing the 6808 // provider since it might take a long time to run and it could also potentially 6809 // be re-entrant in the case where the provider is in the same process. 6810 ContentProviderHolder holder = null; 6811 try { 6812 synchronized (getGetProviderLock(auth, userId)) { 6813 holder = ActivityManager.getService().getContentProvider( 6814 getApplicationThread(), c.getOpPackageName(), auth, userId, stable); 6815 } 6816 } catch (RemoteException ex) { 6817 throw ex.rethrowFromSystemServer(); 6818 } 6819 if (holder == null) { 6820 if (UserManager.get(c).isUserUnlocked(userId)) { 6821 Slog.e(TAG, "Failed to find provider info for " + auth); 6822 } else { 6823 Slog.w(TAG, "Failed to find provider info for " + auth + " (user not unlocked)"); 6824 } 6825 return null; 6826 } 6827 6828 // Install provider will increment the reference count for us, and break 6829 // any ties in the race. 6830 holder = installProvider(c, holder, holder.info, 6831 true /*noisy*/, holder.noReleaseNeeded, stable); 6832 return holder.provider; 6833 } 6834 getGetProviderLock(String auth, int userId)6835 private Object getGetProviderLock(String auth, int userId) { 6836 final ProviderKey key = new ProviderKey(auth, userId); 6837 synchronized (mGetProviderLocks) { 6838 Object lock = mGetProviderLocks.get(key); 6839 if (lock == null) { 6840 lock = key; 6841 mGetProviderLocks.put(key, lock); 6842 } 6843 return lock; 6844 } 6845 } 6846 incProviderRefLocked(ProviderRefCount prc, boolean stable)6847 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 6848 if (stable) { 6849 prc.stableCount += 1; 6850 if (prc.stableCount == 1) { 6851 // We are acquiring a new stable reference on the provider. 6852 int unstableDelta; 6853 if (prc.removePending) { 6854 // We have a pending remove operation, which is holding the 6855 // last unstable reference. At this point we are converting 6856 // that unstable reference to our new stable reference. 6857 unstableDelta = -1; 6858 // Cancel the removal of the provider. 6859 if (DEBUG_PROVIDER) { 6860 Slog.v(TAG, "incProviderRef: stable " 6861 + "snatched provider from the jaws of death"); 6862 } 6863 prc.removePending = false; 6864 // There is a race! It fails to remove the message, which 6865 // will be handled in completeRemoveProvider(). 6866 mH.removeMessages(H.REMOVE_PROVIDER, prc); 6867 } else { 6868 unstableDelta = 0; 6869 } 6870 try { 6871 if (DEBUG_PROVIDER) { 6872 Slog.v(TAG, "incProviderRef Now stable - " 6873 + prc.holder.info.name + ": unstableDelta=" 6874 + unstableDelta); 6875 } 6876 ActivityManager.getService().refContentProvider( 6877 prc.holder.connection, 1, unstableDelta); 6878 } catch (RemoteException e) { 6879 //do nothing content provider object is dead any way 6880 } 6881 } 6882 } else { 6883 prc.unstableCount += 1; 6884 if (prc.unstableCount == 1) { 6885 // We are acquiring a new unstable reference on the provider. 6886 if (prc.removePending) { 6887 // Oh look, we actually have a remove pending for the 6888 // provider, which is still holding the last unstable 6889 // reference. We just need to cancel that to take new 6890 // ownership of the reference. 6891 if (DEBUG_PROVIDER) { 6892 Slog.v(TAG, "incProviderRef: unstable " 6893 + "snatched provider from the jaws of death"); 6894 } 6895 prc.removePending = false; 6896 mH.removeMessages(H.REMOVE_PROVIDER, prc); 6897 } else { 6898 // First unstable ref, increment our count in the 6899 // activity manager. 6900 try { 6901 if (DEBUG_PROVIDER) { 6902 Slog.v(TAG, "incProviderRef: Now unstable - " 6903 + prc.holder.info.name); 6904 } 6905 ActivityManager.getService().refContentProvider( 6906 prc.holder.connection, 0, 1); 6907 } catch (RemoteException e) { 6908 //do nothing content provider object is dead any way 6909 } 6910 } 6911 } 6912 } 6913 } 6914 6915 @UnsupportedAppUsage acquireExistingProvider( Context c, String auth, int userId, boolean stable)6916 public final IContentProvider acquireExistingProvider( 6917 Context c, String auth, int userId, boolean stable) { 6918 synchronized (mProviderMap) { 6919 final ProviderKey key = new ProviderKey(auth, userId); 6920 final ProviderClientRecord pr = mProviderMap.get(key); 6921 if (pr == null) { 6922 return null; 6923 } 6924 6925 IContentProvider provider = pr.mProvider; 6926 IBinder jBinder = provider.asBinder(); 6927 if (!jBinder.isBinderAlive()) { 6928 // The hosting process of the provider has died; we can't 6929 // use this one. 6930 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 6931 + ": existing object's process dead"); 6932 handleUnstableProviderDiedLocked(jBinder, true); 6933 return null; 6934 } 6935 6936 // Only increment the ref count if we have one. If we don't then the 6937 // provider is not reference counted and never needs to be released. 6938 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 6939 if (prc != null) { 6940 incProviderRefLocked(prc, stable); 6941 } 6942 return provider; 6943 } 6944 } 6945 6946 @UnsupportedAppUsage releaseProvider(IContentProvider provider, boolean stable)6947 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 6948 if (provider == null) { 6949 return false; 6950 } 6951 6952 IBinder jBinder = provider.asBinder(); 6953 synchronized (mProviderMap) { 6954 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 6955 if (prc == null) { 6956 // The provider has no ref count, no release is needed. 6957 return false; 6958 } 6959 6960 boolean lastRef = false; 6961 if (stable) { 6962 if (prc.stableCount == 0) { 6963 if (DEBUG_PROVIDER) Slog.v(TAG, 6964 "releaseProvider: stable ref count already 0, how?"); 6965 return false; 6966 } 6967 prc.stableCount -= 1; 6968 if (prc.stableCount == 0) { 6969 // What we do at this point depends on whether there are 6970 // any unstable refs left: if there are, we just tell the 6971 // activity manager to decrement its stable count; if there 6972 // aren't, we need to enqueue this provider to be removed, 6973 // and convert to holding a single unstable ref while 6974 // doing so. 6975 lastRef = prc.unstableCount == 0; 6976 try { 6977 if (DEBUG_PROVIDER) { 6978 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 6979 + lastRef + " - " + prc.holder.info.name); 6980 } 6981 ActivityManager.getService().refContentProvider( 6982 prc.holder.connection, -1, lastRef ? 1 : 0); 6983 } catch (RemoteException e) { 6984 //do nothing content provider object is dead any way 6985 } 6986 } 6987 } else { 6988 if (prc.unstableCount == 0) { 6989 if (DEBUG_PROVIDER) Slog.v(TAG, 6990 "releaseProvider: unstable ref count already 0, how?"); 6991 return false; 6992 } 6993 prc.unstableCount -= 1; 6994 if (prc.unstableCount == 0) { 6995 // If this is the last reference, we need to enqueue 6996 // this provider to be removed instead of telling the 6997 // activity manager to remove it at this point. 6998 lastRef = prc.stableCount == 0; 6999 if (!lastRef) { 7000 try { 7001 if (DEBUG_PROVIDER) { 7002 Slog.v(TAG, "releaseProvider: No longer unstable - " 7003 + prc.holder.info.name); 7004 } 7005 ActivityManager.getService().refContentProvider( 7006 prc.holder.connection, 0, -1); 7007 } catch (RemoteException e) { 7008 //do nothing content provider object is dead any way 7009 } 7010 } 7011 } 7012 } 7013 7014 if (lastRef) { 7015 if (!prc.removePending) { 7016 // Schedule the actual remove asynchronously, since we don't know the context 7017 // this will be called in. 7018 if (DEBUG_PROVIDER) { 7019 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 7020 + prc.holder.info.name); 7021 } 7022 prc.removePending = true; 7023 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 7024 mH.sendMessageDelayed(msg, CONTENT_PROVIDER_RETAIN_TIME); 7025 } else { 7026 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 7027 } 7028 } 7029 return true; 7030 } 7031 } 7032 completeRemoveProvider(ProviderRefCount prc)7033 final void completeRemoveProvider(ProviderRefCount prc) { 7034 synchronized (mProviderMap) { 7035 if (!prc.removePending) { 7036 // There was a race! Some other client managed to acquire 7037 // the provider before the removal was completed. 7038 // Abort the removal. We will do it later. 7039 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 7040 + "provider still in use"); 7041 return; 7042 } 7043 7044 // More complicated race!! Some client managed to acquire the 7045 // provider and release it before the removal was completed. 7046 // Continue the removal, and abort the next remove message. 7047 prc.removePending = false; 7048 7049 final IBinder jBinder = prc.holder.provider.asBinder(); 7050 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 7051 if (existingPrc == prc) { 7052 mProviderRefCountMap.remove(jBinder); 7053 } 7054 7055 for (int i=mProviderMap.size()-1; i>=0; i--) { 7056 ProviderClientRecord pr = mProviderMap.valueAt(i); 7057 IBinder myBinder = pr.mProvider.asBinder(); 7058 if (myBinder == jBinder) { 7059 mProviderMap.removeAt(i); 7060 } 7061 } 7062 } 7063 7064 try { 7065 if (DEBUG_PROVIDER) { 7066 Slog.v(TAG, "removeProvider: Invoking ActivityManagerService." 7067 + "removeContentProvider(" + prc.holder.info.name + ")"); 7068 } 7069 ActivityManager.getService().removeContentProvider( 7070 prc.holder.connection, false); 7071 } catch (RemoteException e) { 7072 //do nothing content provider object is dead any way 7073 } 7074 } 7075 7076 @UnsupportedAppUsage handleUnstableProviderDied(IBinder provider, boolean fromClient)7077 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 7078 synchronized (mProviderMap) { 7079 handleUnstableProviderDiedLocked(provider, fromClient); 7080 } 7081 } 7082 handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient)7083 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 7084 ProviderRefCount prc = mProviderRefCountMap.get(provider); 7085 if (prc != null) { 7086 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 7087 + provider + " " + prc.holder.info.name); 7088 mProviderRefCountMap.remove(provider); 7089 for (int i=mProviderMap.size()-1; i>=0; i--) { 7090 ProviderClientRecord pr = mProviderMap.valueAt(i); 7091 if (pr != null && pr.mProvider.asBinder() == provider) { 7092 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString()); 7093 mProviderMap.removeAt(i); 7094 } 7095 } 7096 7097 if (fromClient) { 7098 // We found out about this due to execution in our client 7099 // code. Tell the activity manager about it now, to ensure 7100 // that the next time we go to do anything with the provider 7101 // it knows it is dead (so we don't race with its death 7102 // notification). 7103 try { 7104 ActivityManager.getService().unstableProviderDied( 7105 prc.holder.connection); 7106 } catch (RemoteException e) { 7107 //do nothing content provider object is dead any way 7108 } 7109 } 7110 } 7111 } 7112 appNotRespondingViaProvider(IBinder provider)7113 final void appNotRespondingViaProvider(IBinder provider) { 7114 synchronized (mProviderMap) { 7115 ProviderRefCount prc = mProviderRefCountMap.get(provider); 7116 if (prc != null) { 7117 try { 7118 ActivityManager.getService() 7119 .appNotRespondingViaProvider(prc.holder.connection); 7120 } catch (RemoteException e) { 7121 throw e.rethrowFromSystemServer(); 7122 } 7123 } 7124 } 7125 } 7126 installProviderAuthoritiesLocked(IContentProvider provider, ContentProvider localProvider, ContentProviderHolder holder)7127 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 7128 ContentProvider localProvider, ContentProviderHolder holder) { 7129 final String auths[] = holder.info.authority.split(";"); 7130 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 7131 7132 if (provider != null) { 7133 // If this provider is hosted by the core OS and cannot be upgraded, 7134 // then I guess we're okay doing blocking calls to it. 7135 for (String auth : auths) { 7136 switch (auth) { 7137 case ContactsContract.AUTHORITY: 7138 case CallLog.AUTHORITY: 7139 case CallLog.SHADOW_AUTHORITY: 7140 case BlockedNumberContract.AUTHORITY: 7141 case CalendarContract.AUTHORITY: 7142 case Downloads.Impl.AUTHORITY: 7143 case "telephony": 7144 Binder.allowBlocking(provider.asBinder()); 7145 } 7146 } 7147 } 7148 7149 final ProviderClientRecord pcr = new ProviderClientRecord( 7150 auths, provider, localProvider, holder); 7151 for (String auth : auths) { 7152 final ProviderKey key = new ProviderKey(auth, userId); 7153 final ProviderClientRecord existing = mProviderMap.get(key); 7154 if (existing != null) { 7155 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 7156 + " already published as " + auth); 7157 } else { 7158 mProviderMap.put(key, pcr); 7159 } 7160 } 7161 return pcr; 7162 } 7163 7164 /** 7165 * Installs the provider. 7166 * 7167 * Providers that are local to the process or that come from the system server 7168 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 7169 * Other remote providers are reference counted. The initial reference count 7170 * for all reference counted providers is one. Providers that are not reference 7171 * counted do not have a reference count (at all). 7172 * 7173 * This method detects when a provider has already been installed. When this happens, 7174 * it increments the reference count of the existing provider (if appropriate) 7175 * and returns the existing provider. This can happen due to concurrent 7176 * attempts to acquire the same provider. 7177 */ 7178 @UnsupportedAppUsage installProvider(Context context, ContentProviderHolder holder, ProviderInfo info, boolean noisy, boolean noReleaseNeeded, boolean stable)7179 private ContentProviderHolder installProvider(Context context, 7180 ContentProviderHolder holder, ProviderInfo info, 7181 boolean noisy, boolean noReleaseNeeded, boolean stable) { 7182 ContentProvider localProvider = null; 7183 IContentProvider provider; 7184 if (holder == null || holder.provider == null) { 7185 if (DEBUG_PROVIDER || noisy) { 7186 Slog.d(TAG, "Loading provider " + info.authority + ": " 7187 + info.name); 7188 } 7189 Context c = null; 7190 ApplicationInfo ai = info.applicationInfo; 7191 if (context.getPackageName().equals(ai.packageName)) { 7192 c = context; 7193 } else if (mInitialApplication != null && 7194 mInitialApplication.getPackageName().equals(ai.packageName)) { 7195 c = mInitialApplication; 7196 } else { 7197 try { 7198 c = context.createPackageContext(ai.packageName, 7199 Context.CONTEXT_INCLUDE_CODE); 7200 } catch (PackageManager.NameNotFoundException e) { 7201 // Ignore 7202 } 7203 } 7204 if (c == null) { 7205 Slog.w(TAG, "Unable to get context for package " + 7206 ai.packageName + 7207 " while loading content provider " + 7208 info.name); 7209 return null; 7210 } 7211 7212 if (info.splitName != null) { 7213 try { 7214 c = c.createContextForSplit(info.splitName); 7215 } catch (NameNotFoundException e) { 7216 throw new RuntimeException(e); 7217 } 7218 } 7219 7220 try { 7221 final java.lang.ClassLoader cl = c.getClassLoader(); 7222 LoadedApk packageInfo = peekPackageInfo(ai.packageName, true); 7223 if (packageInfo == null) { 7224 // System startup case. 7225 packageInfo = getSystemContext().mPackageInfo; 7226 } 7227 localProvider = packageInfo.getAppFactory() 7228 .instantiateProvider(cl, info.name); 7229 provider = localProvider.getIContentProvider(); 7230 if (provider == null) { 7231 Slog.e(TAG, "Failed to instantiate class " + 7232 info.name + " from sourceDir " + 7233 info.applicationInfo.sourceDir); 7234 return null; 7235 } 7236 if (DEBUG_PROVIDER) Slog.v( 7237 TAG, "Instantiating local provider " + info.name); 7238 // XXX Need to create the correct context for this provider. 7239 localProvider.attachInfo(c, info); 7240 } catch (java.lang.Exception e) { 7241 if (!mInstrumentation.onException(null, e)) { 7242 throw new RuntimeException( 7243 "Unable to get provider " + info.name 7244 + ": " + e.toString(), e); 7245 } 7246 return null; 7247 } 7248 } else { 7249 provider = holder.provider; 7250 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 7251 + info.name); 7252 } 7253 7254 ContentProviderHolder retHolder; 7255 7256 synchronized (mProviderMap) { 7257 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 7258 + " / " + info.name); 7259 IBinder jBinder = provider.asBinder(); 7260 if (localProvider != null) { 7261 ComponentName cname = new ComponentName(info.packageName, info.name); 7262 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 7263 if (pr != null) { 7264 if (DEBUG_PROVIDER) { 7265 Slog.v(TAG, "installProvider: lost the race, " 7266 + "using existing local provider"); 7267 } 7268 provider = pr.mProvider; 7269 } else { 7270 holder = new ContentProviderHolder(info); 7271 holder.provider = provider; 7272 holder.noReleaseNeeded = true; 7273 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 7274 mLocalProviders.put(jBinder, pr); 7275 mLocalProvidersByName.put(cname, pr); 7276 } 7277 retHolder = pr.mHolder; 7278 } else { 7279 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 7280 if (prc != null) { 7281 if (DEBUG_PROVIDER) { 7282 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 7283 } 7284 // We need to transfer our new reference to the existing 7285 // ref count, releasing the old one... but only if 7286 // release is needed (that is, it is not running in the 7287 // system process). 7288 if (!noReleaseNeeded) { 7289 incProviderRefLocked(prc, stable); 7290 try { 7291 ActivityManager.getService().removeContentProvider( 7292 holder.connection, stable); 7293 } catch (RemoteException e) { 7294 //do nothing content provider object is dead any way 7295 } 7296 } 7297 } else { 7298 ProviderClientRecord client = installProviderAuthoritiesLocked( 7299 provider, localProvider, holder); 7300 if (noReleaseNeeded) { 7301 prc = new ProviderRefCount(holder, client, 1000, 1000); 7302 } else { 7303 prc = stable 7304 ? new ProviderRefCount(holder, client, 1, 0) 7305 : new ProviderRefCount(holder, client, 0, 1); 7306 } 7307 mProviderRefCountMap.put(jBinder, prc); 7308 } 7309 retHolder = prc.holder; 7310 } 7311 } 7312 return retHolder; 7313 } 7314 handleRunIsolatedEntryPoint(String entryPoint, String[] entryPointArgs)7315 private void handleRunIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { 7316 try { 7317 Method main = Class.forName(entryPoint).getMethod("main", String[].class); 7318 main.invoke(null, new Object[]{entryPointArgs}); 7319 } catch (ReflectiveOperationException e) { 7320 throw new AndroidRuntimeException("runIsolatedEntryPoint failed", e); 7321 } 7322 // The process will be empty after this method returns; exit the VM now. 7323 System.exit(0); 7324 } 7325 7326 @UnsupportedAppUsage attach(boolean system, long startSeq)7327 private void attach(boolean system, long startSeq) { 7328 sCurrentActivityThread = this; 7329 mSystemThread = system; 7330 if (!system) { 7331 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 7332 UserHandle.myUserId()); 7333 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 7334 final IActivityManager mgr = ActivityManager.getService(); 7335 try { 7336 mgr.attachApplication(mAppThread, startSeq); 7337 } catch (RemoteException ex) { 7338 throw ex.rethrowFromSystemServer(); 7339 } 7340 // Watch for getting close to heap limit. 7341 BinderInternal.addGcWatcher(new Runnable() { 7342 @Override public void run() { 7343 if (!mSomeActivitiesChanged) { 7344 return; 7345 } 7346 Runtime runtime = Runtime.getRuntime(); 7347 long dalvikMax = runtime.maxMemory(); 7348 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 7349 if (dalvikUsed > ((3*dalvikMax)/4)) { 7350 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 7351 + " total=" + (runtime.totalMemory()/1024) 7352 + " used=" + (dalvikUsed/1024)); 7353 mSomeActivitiesChanged = false; 7354 try { 7355 ActivityTaskManager.getService().releaseSomeActivities(mAppThread); 7356 } catch (RemoteException e) { 7357 throw e.rethrowFromSystemServer(); 7358 } 7359 } 7360 } 7361 }); 7362 } else { 7363 // Don't set application object here -- if the system crashes, 7364 // we can't display an alert, we just want to die die die. 7365 android.ddm.DdmHandleAppName.setAppName("system_process", 7366 UserHandle.myUserId()); 7367 try { 7368 mInstrumentation = new Instrumentation(); 7369 mInstrumentation.basicInit(this); 7370 ContextImpl context = ContextImpl.createAppContext( 7371 this, getSystemContext().mPackageInfo); 7372 mInitialApplication = context.mPackageInfo.makeApplication(true, null); 7373 mInitialApplication.onCreate(); 7374 } catch (Exception e) { 7375 throw new RuntimeException( 7376 "Unable to instantiate Application():" + e.toString(), e); 7377 } 7378 } 7379 7380 ViewRootImpl.ConfigChangedCallback configChangedCallback 7381 = (Configuration globalConfig) -> { 7382 synchronized (mResourcesManager) { 7383 // TODO (b/135719017): Temporary log for debugging IME service. 7384 if (Build.IS_DEBUGGABLE && mHasImeComponent) { 7385 Log.d(TAG, "ViewRootImpl.ConfigChangedCallback for IME, " 7386 + "config=" + globalConfig); 7387 } 7388 7389 // We need to apply this change to the resources immediately, because upon returning 7390 // the view hierarchy will be informed about it. 7391 if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, 7392 null /* compat */)) { 7393 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), 7394 mResourcesManager.getConfiguration().getLocales()); 7395 7396 // This actually changed the resources! Tell everyone about it. 7397 if (mPendingConfiguration == null 7398 || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { 7399 mPendingConfiguration = globalConfig; 7400 sendMessage(H.CONFIGURATION_CHANGED, globalConfig); 7401 } 7402 } 7403 } 7404 }; 7405 ViewRootImpl.addConfigCallback(configChangedCallback); 7406 } 7407 7408 @UnsupportedAppUsage systemMain()7409 public static ActivityThread systemMain() { 7410 // The system process on low-memory devices do not get to use hardware 7411 // accelerated drawing, since this can add too much overhead to the 7412 // process. 7413 if (!ActivityManager.isHighEndGfx()) { 7414 ThreadedRenderer.disable(true); 7415 } else { 7416 ThreadedRenderer.enableForegroundTrimming(); 7417 } 7418 ActivityThread thread = new ActivityThread(); 7419 thread.attach(true, 0); 7420 return thread; 7421 } 7422 updateHttpProxy(@onNull Context context)7423 public static void updateHttpProxy(@NonNull Context context) { 7424 final ConnectivityManager cm = ConnectivityManager.from(context); 7425 Proxy.setHttpProxySystemProperty(cm.getDefaultProxy()); 7426 } 7427 7428 @UnsupportedAppUsage installSystemProviders(List<ProviderInfo> providers)7429 public final void installSystemProviders(List<ProviderInfo> providers) { 7430 if (providers != null) { 7431 installContentProviders(mInitialApplication, providers); 7432 } 7433 } 7434 getCoreSettings()7435 public Bundle getCoreSettings() { 7436 return mCoreSettings; 7437 } 7438 getIntCoreSetting(String key, int defaultValue)7439 public int getIntCoreSetting(String key, int defaultValue) { 7440 synchronized (mResourcesManager) { 7441 if (mCoreSettings != null) { 7442 return mCoreSettings.getInt(key, defaultValue); 7443 } 7444 return defaultValue; 7445 } 7446 } 7447 7448 /** 7449 * Get the string value of the given key from core settings. 7450 */ getStringCoreSetting(String key, String defaultValue)7451 public String getStringCoreSetting(String key, String defaultValue) { 7452 synchronized (mResourcesManager) { 7453 if (mCoreSettings != null) { 7454 return mCoreSettings.getString(key, defaultValue); 7455 } 7456 return defaultValue; 7457 } 7458 } 7459 getFloatCoreSetting(String key, float defaultValue)7460 float getFloatCoreSetting(String key, float defaultValue) { 7461 synchronized (mResourcesManager) { 7462 if (mCoreSettings != null) { 7463 return mCoreSettings.getFloat(key, defaultValue); 7464 } 7465 return defaultValue; 7466 } 7467 } 7468 7469 private static class AndroidOs extends ForwardingOs { 7470 /** 7471 * Install selective syscall interception. For example, this is used to 7472 * implement special filesystem paths that will be redirected to 7473 * {@link ContentResolver#openFileDescriptor(Uri, String)}. 7474 */ install()7475 public static void install() { 7476 // If feature is disabled, we don't need to install 7477 if (!DEPRECATE_DATA_COLUMNS) return; 7478 7479 // Install interception and make sure it sticks! 7480 Os def = null; 7481 do { 7482 def = Os.getDefault(); 7483 } while (!Os.compareAndSetDefault(def, new AndroidOs(def))); 7484 } 7485 AndroidOs(Os os)7486 private AndroidOs(Os os) { 7487 super(os); 7488 } 7489 openDeprecatedDataPath(String path, int mode)7490 private FileDescriptor openDeprecatedDataPath(String path, int mode) throws ErrnoException { 7491 final Uri uri = ContentResolver.translateDeprecatedDataPath(path); 7492 Log.v(TAG, "Redirecting " + path + " to " + uri); 7493 7494 final ContentResolver cr = currentActivityThread().getApplication() 7495 .getContentResolver(); 7496 try { 7497 final FileDescriptor fd = new FileDescriptor(); 7498 fd.setInt$(cr.openFileDescriptor(uri, 7499 FileUtils.translateModePosixToString(mode)).detachFd()); 7500 return fd; 7501 } catch (SecurityException e) { 7502 throw new ErrnoException(e.getMessage(), OsConstants.EACCES); 7503 } catch (FileNotFoundException e) { 7504 throw new ErrnoException(e.getMessage(), OsConstants.ENOENT); 7505 } 7506 } 7507 deleteDeprecatedDataPath(String path)7508 private void deleteDeprecatedDataPath(String path) throws ErrnoException { 7509 final Uri uri = ContentResolver.translateDeprecatedDataPath(path); 7510 Log.v(TAG, "Redirecting " + path + " to " + uri); 7511 7512 final ContentResolver cr = currentActivityThread().getApplication() 7513 .getContentResolver(); 7514 try { 7515 if (cr.delete(uri, null, null) == 0) { 7516 throw new FileNotFoundException(); 7517 } 7518 } catch (SecurityException e) { 7519 throw new ErrnoException(e.getMessage(), OsConstants.EACCES); 7520 } catch (FileNotFoundException e) { 7521 throw new ErrnoException(e.getMessage(), OsConstants.ENOENT); 7522 } 7523 } 7524 7525 @Override access(String path, int mode)7526 public boolean access(String path, int mode) throws ErrnoException { 7527 if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) { 7528 // If we opened it okay, then access check succeeded 7529 IoUtils.closeQuietly( 7530 openDeprecatedDataPath(path, FileUtils.translateModeAccessToPosix(mode))); 7531 return true; 7532 } else { 7533 return super.access(path, mode); 7534 } 7535 } 7536 7537 @Override open(String path, int flags, int mode)7538 public FileDescriptor open(String path, int flags, int mode) throws ErrnoException { 7539 if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) { 7540 return openDeprecatedDataPath(path, mode); 7541 } else { 7542 return super.open(path, flags, mode); 7543 } 7544 } 7545 7546 @Override stat(String path)7547 public StructStat stat(String path) throws ErrnoException { 7548 if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) { 7549 final FileDescriptor fd = openDeprecatedDataPath(path, OsConstants.O_RDONLY); 7550 try { 7551 return android.system.Os.fstat(fd); 7552 } finally { 7553 IoUtils.closeQuietly(fd); 7554 } 7555 } else { 7556 return super.stat(path); 7557 } 7558 } 7559 7560 @Override unlink(String path)7561 public void unlink(String path) throws ErrnoException { 7562 if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) { 7563 deleteDeprecatedDataPath(path); 7564 } else { 7565 super.unlink(path); 7566 } 7567 } 7568 7569 @Override remove(String path)7570 public void remove(String path) throws ErrnoException { 7571 if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) { 7572 deleteDeprecatedDataPath(path); 7573 } else { 7574 super.remove(path); 7575 } 7576 } 7577 7578 @Override rename(String oldPath, String newPath)7579 public void rename(String oldPath, String newPath) throws ErrnoException { 7580 try { 7581 super.rename(oldPath, newPath); 7582 } catch (ErrnoException e) { 7583 // On emulated volumes, we have bind mounts for /Android/data and 7584 // /Android/obb, which prevents move from working across those directories 7585 // and other directories on the filesystem. To work around that, try to 7586 // recover by doing a copy instead. 7587 // Note that we only do this for "/storage/emulated", because public volumes 7588 // don't have these bind mounts, neither do private volumes that are not 7589 // the primary storage. 7590 if (e.errno == OsConstants.EXDEV && oldPath.startsWith("/storage/emulated") 7591 && newPath.startsWith("/storage/emulated")) { 7592 Log.v(TAG, "Recovering failed rename " + oldPath + " to " + newPath); 7593 try { 7594 Files.move(new File(oldPath).toPath(), new File(newPath).toPath(), 7595 StandardCopyOption.REPLACE_EXISTING); 7596 } catch (IOException e2) { 7597 Log.e(TAG, "Rename recovery failed ", e); 7598 throw e; 7599 } 7600 } else { 7601 throw e; 7602 } 7603 } 7604 } 7605 } 7606 main(String[] args)7607 public static void main(String[] args) { 7608 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 7609 7610 // Install selective syscall interception 7611 AndroidOs.install(); 7612 7613 // CloseGuard defaults to true and can be quite spammy. We 7614 // disable it here, but selectively enable it later (via 7615 // StrictMode) on debug builds, but using DropBox, not logs. 7616 CloseGuard.setEnabled(false); 7617 7618 Environment.initForCurrentUser(); 7619 7620 // Make sure TrustedCertificateStore looks in the right place for CA certificates 7621 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); 7622 TrustedCertificateStore.setDefaultUserDirectory(configDir); 7623 7624 // Call per-process mainline module initialization. 7625 initializeMainlineModules(); 7626 7627 Process.setArgV0("<pre-initialized>"); 7628 7629 Looper.prepareMainLooper(); 7630 7631 // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line. 7632 // It will be in the format "seq=114" 7633 long startSeq = 0; 7634 if (args != null) { 7635 for (int i = args.length - 1; i >= 0; --i) { 7636 if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) { 7637 startSeq = Long.parseLong( 7638 args[i].substring(PROC_START_SEQ_IDENT.length())); 7639 } 7640 } 7641 } 7642 ActivityThread thread = new ActivityThread(); 7643 thread.attach(false, startSeq); 7644 7645 if (sMainThreadHandler == null) { 7646 sMainThreadHandler = thread.getHandler(); 7647 } 7648 7649 if (false) { 7650 Looper.myLooper().setMessageLogging(new 7651 LogPrinter(Log.DEBUG, "ActivityThread")); 7652 } 7653 7654 // End of event ActivityThreadMain. 7655 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7656 Looper.loop(); 7657 7658 throw new RuntimeException("Main thread loop unexpectedly exited"); 7659 } 7660 7661 /** 7662 * Call various initializer APIs in mainline modules that need to be called when each process 7663 * starts. 7664 */ initializeMainlineModules()7665 public static void initializeMainlineModules() { 7666 TelephonyFrameworkInitializer.setTelephonyServiceManager(new TelephonyServiceManager()); 7667 StatsFrameworkInitializer.setStatsServiceManager(new StatsServiceManager()); 7668 } 7669 purgePendingResources()7670 private void purgePendingResources() { 7671 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "purgePendingResources"); 7672 nPurgePendingResources(); 7673 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7674 } 7675 7676 // ------------------ Regular JNI ------------------------ nPurgePendingResources()7677 private native void nPurgePendingResources(); nDumpGraphicsInfo(FileDescriptor fd)7678 private native void nDumpGraphicsInfo(FileDescriptor fd); nInitZygoteChildHeapProfiling()7679 private native void nInitZygoteChildHeapProfiling(); 7680 } 7681