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