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