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