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