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