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