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