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