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