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