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