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