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