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