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