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