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