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