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