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