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