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