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