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