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     private ContextImpl mSystemContext;
    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, 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                 mSystemContext = ContextImpl.createSystemContext(this);
   1702             }
   1703             return mSystemContext;
   1704         }
   1705     }
   1706 
   1707     public void installSystemApplicationInfo(ApplicationInfo info) {
   1708         synchronized (this) {
   1709             getSystemContext().installSystemApplicationInfo(info);
   1710 
   1711             // give ourselves a default profiler
   1712             mProfiler = new Profiler();
   1713         }
   1714     }
   1715 
   1716     void ensureJitEnabled() {
   1717         if (!mJitEnabled) {
   1718             mJitEnabled = true;
   1719             dalvik.system.VMRuntime.getRuntime().startJitCompilation();
   1720         }
   1721     }
   1722 
   1723     void scheduleGcIdler() {
   1724         if (!mGcIdlerScheduled) {
   1725             mGcIdlerScheduled = true;
   1726             Looper.myQueue().addIdleHandler(mGcIdler);
   1727         }
   1728         mH.removeMessages(H.GC_WHEN_IDLE);
   1729     }
   1730 
   1731     void unscheduleGcIdler() {
   1732         if (mGcIdlerScheduled) {
   1733             mGcIdlerScheduled = false;
   1734             Looper.myQueue().removeIdleHandler(mGcIdler);
   1735         }
   1736         mH.removeMessages(H.GC_WHEN_IDLE);
   1737     }
   1738 
   1739     void doGcIfNeeded() {
   1740         mGcIdlerScheduled = false;
   1741         final long now = SystemClock.uptimeMillis();
   1742         //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
   1743         //        + "m now=" + now);
   1744         if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
   1745             //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
   1746             BinderInternal.forceGc("bg");
   1747         }
   1748     }
   1749 
   1750     private static final String HEAP_FULL_COLUMN
   1751             = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
   1752     private static final String HEAP_COLUMN
   1753             = "%13s %8s %8s %8s %8s %8s %8s %8s";
   1754 
   1755     // Formatting for checkin service - update version if row format changes
   1756     private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
   1757 
   1758     static void printRow(PrintWriter pw, String format, Object...objs) {
   1759         pw.println(String.format(format, objs));
   1760     }
   1761 
   1762     public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
   1763             boolean dumpFullInfo, boolean dumpDalvik, int pid, String processName,
   1764             long nativeMax, long nativeAllocated, long nativeFree,
   1765             long dalvikMax, long dalvikAllocated, long dalvikFree) {
   1766 
   1767         // For checkin, we print one long comma-separated list of values
   1768         if (checkin) {
   1769             // NOTE: if you change anything significant below, also consider changing
   1770             // ACTIVITY_THREAD_CHECKIN_VERSION.
   1771 
   1772             // Header
   1773             pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
   1774             pw.print(pid); pw.print(',');
   1775             pw.print(processName); pw.print(',');
   1776 
   1777             // Heap info - max
   1778             pw.print(nativeMax); pw.print(',');
   1779             pw.print(dalvikMax); pw.print(',');
   1780             pw.print("N/A,");
   1781             pw.print(nativeMax + dalvikMax); pw.print(',');
   1782 
   1783             // Heap info - allocated
   1784             pw.print(nativeAllocated); pw.print(',');
   1785             pw.print(dalvikAllocated); pw.print(',');
   1786             pw.print("N/A,");
   1787             pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
   1788 
   1789             // Heap info - free
   1790             pw.print(nativeFree); pw.print(',');
   1791             pw.print(dalvikFree); pw.print(',');
   1792             pw.print("N/A,");
   1793             pw.print(nativeFree + dalvikFree); pw.print(',');
   1794 
   1795             // Heap info - proportional set size
   1796             pw.print(memInfo.nativePss); pw.print(',');
   1797             pw.print(memInfo.dalvikPss); pw.print(',');
   1798             pw.print(memInfo.otherPss); pw.print(',');
   1799             pw.print(memInfo.getTotalPss()); pw.print(',');
   1800 
   1801             // Heap info - swappable set size
   1802             pw.print(memInfo.nativeSwappablePss); pw.print(',');
   1803             pw.print(memInfo.dalvikSwappablePss); pw.print(',');
   1804             pw.print(memInfo.otherSwappablePss); pw.print(',');
   1805             pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
   1806 
   1807             // Heap info - shared dirty
   1808             pw.print(memInfo.nativeSharedDirty); pw.print(',');
   1809             pw.print(memInfo.dalvikSharedDirty); pw.print(',');
   1810             pw.print(memInfo.otherSharedDirty); pw.print(',');
   1811             pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
   1812 
   1813             // Heap info - shared clean
   1814             pw.print(memInfo.nativeSharedClean); pw.print(',');
   1815             pw.print(memInfo.dalvikSharedClean); pw.print(',');
   1816             pw.print(memInfo.otherSharedClean); pw.print(',');
   1817             pw.print(memInfo.getTotalSharedClean()); pw.print(',');
   1818 
   1819             // Heap info - private Dirty
   1820             pw.print(memInfo.nativePrivateDirty); pw.print(',');
   1821             pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
   1822             pw.print(memInfo.otherPrivateDirty); pw.print(',');
   1823             pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
   1824 
   1825             // Heap info - private Clean
   1826             pw.print(memInfo.nativePrivateClean); pw.print(',');
   1827             pw.print(memInfo.dalvikPrivateClean); pw.print(',');
   1828             pw.print(memInfo.otherPrivateClean); pw.print(',');
   1829             pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
   1830 
   1831             // Heap info - other areas
   1832             for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
   1833                 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
   1834                 pw.print(memInfo.getOtherPss(i)); pw.print(',');
   1835                 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
   1836                 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
   1837                 pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
   1838                 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
   1839                 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
   1840             }
   1841             return;
   1842         }
   1843 
   1844         // otherwise, show human-readable format
   1845         if (dumpFullInfo) {
   1846             printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
   1847                     "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
   1848             printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
   1849                     "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
   1850             printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
   1851                     "------", "------", "------", "------", "------", "------");
   1852             printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
   1853                     memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
   1854                     memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
   1855                     memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
   1856                     nativeMax, nativeAllocated, nativeFree);
   1857             printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
   1858                     memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
   1859                     memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
   1860                     memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
   1861                     dalvikMax, dalvikAllocated, dalvikFree);
   1862         } else {
   1863             printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
   1864                     "Private", "Swapped", "Heap", "Heap", "Heap");
   1865             printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
   1866                     "Clean", "Dirty", "Size", "Alloc", "Free");
   1867             printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
   1868                     "------", "------", "------", "------", "------");
   1869             printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
   1870                     memInfo.nativePrivateDirty,
   1871                     memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
   1872                     nativeMax, nativeAllocated, nativeFree);
   1873             printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
   1874                     memInfo.dalvikPrivateDirty,
   1875                     memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
   1876                     dalvikMax, dalvikAllocated, dalvikFree);
   1877         }
   1878 
   1879         int otherPss = memInfo.otherPss;
   1880         int otherSwappablePss = memInfo.otherSwappablePss;
   1881         int otherSharedDirty = memInfo.otherSharedDirty;
   1882         int otherPrivateDirty = memInfo.otherPrivateDirty;
   1883         int otherSharedClean = memInfo.otherSharedClean;
   1884         int otherPrivateClean = memInfo.otherPrivateClean;
   1885         int otherSwappedOut = memInfo.otherSwappedOut;
   1886 
   1887         for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
   1888             final int myPss = memInfo.getOtherPss(i);
   1889             final int mySwappablePss = memInfo.getOtherSwappablePss(i);
   1890             final int mySharedDirty = memInfo.getOtherSharedDirty(i);
   1891             final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
   1892             final int mySharedClean = memInfo.getOtherSharedClean(i);
   1893             final int myPrivateClean = memInfo.getOtherPrivateClean(i);
   1894             final int mySwappedOut = memInfo.getOtherSwappedOut(i);
   1895             if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
   1896                     || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) {
   1897                 if (dumpFullInfo) {
   1898                     printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   1899                             myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
   1900                             mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
   1901                 } else {
   1902                     printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   1903                             myPss, myPrivateDirty,
   1904                             myPrivateClean, mySwappedOut, "", "", "");
   1905                 }
   1906                 otherPss -= myPss;
   1907                 otherSwappablePss -= mySwappablePss;
   1908                 otherSharedDirty -= mySharedDirty;
   1909                 otherPrivateDirty -= myPrivateDirty;
   1910                 otherSharedClean -= mySharedClean;
   1911                 otherPrivateClean -= myPrivateClean;
   1912                 otherSwappedOut -= mySwappedOut;
   1913             }
   1914         }
   1915 
   1916         if (dumpFullInfo) {
   1917             printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
   1918                     otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
   1919                     otherSwappedOut, "", "", "");
   1920             printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
   1921                     memInfo.getTotalSwappablePss(),
   1922                     memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
   1923                     memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
   1924                     memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
   1925                     nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
   1926         } else {
   1927             printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
   1928                     otherPrivateDirty, otherPrivateClean, otherSwappedOut,
   1929                     "", "", "");
   1930             printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
   1931                     memInfo.getTotalPrivateDirty(),
   1932                     memInfo.getTotalPrivateClean(),
   1933                     memInfo.getTotalSwappedOut(),
   1934                     nativeMax+dalvikMax,
   1935                     nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
   1936         }
   1937 
   1938         if (dumpDalvik) {
   1939             pw.println(" ");
   1940             pw.println(" Dalvik Details");
   1941 
   1942             for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
   1943                  i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
   1944                 final int myPss = memInfo.getOtherPss(i);
   1945                 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
   1946                 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
   1947                 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
   1948                 final int mySharedClean = memInfo.getOtherSharedClean(i);
   1949                 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
   1950                 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
   1951                 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
   1952                         || mySharedClean != 0 || myPrivateClean != 0) {
   1953                     if (dumpFullInfo) {
   1954                         printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   1955                                 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
   1956                                 mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
   1957                     } else {
   1958                         printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   1959                                 myPss, myPrivateDirty,
   1960                                 myPrivateClean, mySwappedOut, "", "", "");
   1961                     }
   1962                 }
   1963             }
   1964         }
   1965     }
   1966 
   1967     public void registerOnActivityPausedListener(Activity activity,
   1968             OnActivityPausedListener listener) {
   1969         synchronized (mOnPauseListeners) {
   1970             ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
   1971             if (list == null) {
   1972                 list = new ArrayList<OnActivityPausedListener>();
   1973                 mOnPauseListeners.put(activity, list);
   1974             }
   1975             list.add(listener);
   1976         }
   1977     }
   1978 
   1979     public void unregisterOnActivityPausedListener(Activity activity,
   1980             OnActivityPausedListener listener) {
   1981         synchronized (mOnPauseListeners) {
   1982             ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
   1983             if (list != null) {
   1984                 list.remove(listener);
   1985             }
   1986         }
   1987     }
   1988 
   1989     public final ActivityInfo resolveActivityInfo(Intent intent) {
   1990         ActivityInfo aInfo = intent.resolveActivityInfo(
   1991                 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
   1992         if (aInfo == null) {
   1993             // Throw an exception.
   1994             Instrumentation.checkStartActivityResult(
   1995                     ActivityManager.START_CLASS_NOT_FOUND, intent);
   1996         }
   1997         return aInfo;
   1998     }
   1999 
   2000     public final Activity startActivityNow(Activity parent, String id,
   2001         Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
   2002         Activity.NonConfigurationInstances lastNonConfigurationInstances) {
   2003         ActivityClientRecord r = new ActivityClientRecord();
   2004             r.token = token;
   2005             r.ident = 0;
   2006             r.intent = intent;
   2007             r.state = state;
   2008             r.parent = parent;
   2009             r.embeddedID = id;
   2010             r.activityInfo = activityInfo;
   2011             r.lastNonConfigurationInstances = lastNonConfigurationInstances;
   2012         if (localLOGV) {
   2013             ComponentName compname = intent.getComponent();
   2014             String name;
   2015             if (compname != null) {
   2016                 name = compname.toShortString();
   2017             } else {
   2018                 name = "(Intent " + intent + ").getComponent() returned null";
   2019             }
   2020             Slog.v(TAG, "Performing launch: action=" + intent.getAction()
   2021                     + ", comp=" + name
   2022                     + ", token=" + token);
   2023         }
   2024         return performLaunchActivity(r, null);
   2025     }
   2026 
   2027     public final Activity getActivity(IBinder token) {
   2028         return mActivities.get(token).activity;
   2029     }
   2030 
   2031     public final void sendActivityResult(
   2032             IBinder token, String id, int requestCode,
   2033             int resultCode, Intent data) {
   2034         if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
   2035                 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
   2036         ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
   2037         list.add(new ResultInfo(id, requestCode, resultCode, data));
   2038         mAppThread.scheduleSendResult(token, list);
   2039     }
   2040 
   2041     private void sendMessage(int what, Object obj) {
   2042         sendMessage(what, obj, 0, 0, false);
   2043     }
   2044 
   2045     private void sendMessage(int what, Object obj, int arg1) {
   2046         sendMessage(what, obj, arg1, 0, false);
   2047     }
   2048 
   2049     private void sendMessage(int what, Object obj, int arg1, int arg2) {
   2050         sendMessage(what, obj, arg1, arg2, false);
   2051     }
   2052 
   2053     private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
   2054         if (DEBUG_MESSAGES) Slog.v(
   2055             TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
   2056             + ": " + arg1 + " / " + obj);
   2057         Message msg = Message.obtain();
   2058         msg.what = what;
   2059         msg.obj = obj;
   2060         msg.arg1 = arg1;
   2061         msg.arg2 = arg2;
   2062         if (async) {
   2063             msg.setAsynchronous(true);
   2064         }
   2065         mH.sendMessage(msg);
   2066     }
   2067 
   2068     final void scheduleContextCleanup(ContextImpl context, String who,
   2069             String what) {
   2070         ContextCleanupInfo cci = new ContextCleanupInfo();
   2071         cci.context = context;
   2072         cci.who = who;
   2073         cci.what = what;
   2074         sendMessage(H.CLEAN_UP_CONTEXT, cci);
   2075     }
   2076 
   2077     private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
   2078         // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
   2079 
   2080         ActivityInfo aInfo = r.activityInfo;
   2081         if (r.packageInfo == null) {
   2082             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
   2083                     Context.CONTEXT_INCLUDE_CODE);
   2084         }
   2085 
   2086         ComponentName component = r.intent.getComponent();
   2087         if (component == null) {
   2088             component = r.intent.resolveActivity(
   2089                 mInitialApplication.getPackageManager());
   2090             r.intent.setComponent(component);
   2091         }
   2092 
   2093         if (r.activityInfo.targetActivity != null) {
   2094             component = new ComponentName(r.activityInfo.packageName,
   2095                     r.activityInfo.targetActivity);
   2096         }
   2097 
   2098         Activity activity = null;
   2099         try {
   2100             java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
   2101             activity = mInstrumentation.newActivity(
   2102                     cl, component.getClassName(), r.intent);
   2103             StrictMode.incrementExpectedActivityCount(activity.getClass());
   2104             r.intent.setExtrasClassLoader(cl);
   2105             if (r.state != null) {
   2106                 r.state.setClassLoader(cl);
   2107             }
   2108         } catch (Exception e) {
   2109             if (!mInstrumentation.onException(activity, e)) {
   2110                 throw new RuntimeException(
   2111                     "Unable to instantiate activity " + component
   2112                     + ": " + e.toString(), e);
   2113             }
   2114         }
   2115 
   2116         try {
   2117             Application app = r.packageInfo.makeApplication(false, mInstrumentation);
   2118 
   2119             if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
   2120             if (localLOGV) Slog.v(
   2121                     TAG, r + ": app=" + app
   2122                     + ", appName=" + app.getPackageName()
   2123                     + ", pkg=" + r.packageInfo.getPackageName()
   2124                     + ", comp=" + r.intent.getComponent().toShortString()
   2125                     + ", dir=" + r.packageInfo.getAppDir());
   2126 
   2127             if (activity != null) {
   2128                 Context appContext = createBaseContextForActivity(r, activity);
   2129                 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
   2130                 Configuration config = new Configuration(mCompatConfiguration);
   2131                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
   2132                         + r.activityInfo.name + " with config " + config);
   2133                 activity.attach(appContext, this, getInstrumentation(), r.token,
   2134                         r.ident, app, r.intent, r.activityInfo, title, r.parent,
   2135                         r.embeddedID, r.lastNonConfigurationInstances, config);
   2136 
   2137                 if (customIntent != null) {
   2138                     activity.mIntent = customIntent;
   2139                 }
   2140                 r.lastNonConfigurationInstances = null;
   2141                 activity.mStartedActivity = false;
   2142                 int theme = r.activityInfo.getThemeResource();
   2143                 if (theme != 0) {
   2144                     activity.setTheme(theme);
   2145                 }
   2146 
   2147                 activity.mCalled = false;
   2148                 mInstrumentation.callActivityOnCreate(activity, r.state);
   2149                 if (!activity.mCalled) {
   2150                     throw new SuperNotCalledException(
   2151                         "Activity " + r.intent.getComponent().toShortString() +
   2152                         " did not call through to super.onCreate()");
   2153                 }
   2154                 r.activity = activity;
   2155                 r.stopped = true;
   2156                 if (!r.activity.mFinished) {
   2157                     activity.performStart();
   2158                     r.stopped = false;
   2159                 }
   2160                 if (!r.activity.mFinished) {
   2161                     if (r.state != null) {
   2162                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
   2163                     }
   2164                 }
   2165                 if (!r.activity.mFinished) {
   2166                     activity.mCalled = false;
   2167                     mInstrumentation.callActivityOnPostCreate(activity, r.state);
   2168                     if (!activity.mCalled) {
   2169                         throw new SuperNotCalledException(
   2170                             "Activity " + r.intent.getComponent().toShortString() +
   2171                             " did not call through to super.onPostCreate()");
   2172                     }
   2173                 }
   2174             }
   2175             r.paused = true;
   2176 
   2177             mActivities.put(r.token, r);
   2178 
   2179         } catch (SuperNotCalledException e) {
   2180             throw e;
   2181 
   2182         } catch (Exception e) {
   2183             if (!mInstrumentation.onException(activity, e)) {
   2184                 throw new RuntimeException(
   2185                     "Unable to start activity " + component
   2186                     + ": " + e.toString(), e);
   2187             }
   2188         }
   2189 
   2190         return activity;
   2191     }
   2192 
   2193     private Context createBaseContextForActivity(ActivityClientRecord r,
   2194             final Activity activity) {
   2195         ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
   2196         appContext.setOuterContext(activity);
   2197 
   2198         // For debugging purposes, if the activity's package name contains the value of
   2199         // the "debug.use-second-display" system property as a substring, then show
   2200         // its content on a secondary display if there is one.
   2201         Context baseContext = appContext;
   2202         String pkgName = SystemProperties.get("debug.second-display.pkg");
   2203         if (pkgName != null && !pkgName.isEmpty()
   2204                 && r.packageInfo.mPackageName.contains(pkgName)) {
   2205             DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
   2206             for (int displayId : dm.getDisplayIds()) {
   2207                 if (displayId != Display.DEFAULT_DISPLAY) {
   2208                     Display display = dm.getRealDisplay(displayId, r.token);
   2209                     baseContext = appContext.createDisplayContext(display);
   2210                     break;
   2211                 }
   2212             }
   2213         }
   2214         return baseContext;
   2215     }
   2216 
   2217     private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
   2218         // If we are getting ready to gc after going to the background, well
   2219         // we are back active so skip it.
   2220         unscheduleGcIdler();
   2221 
   2222         if (r.profileFd != null) {
   2223             mProfiler.setProfiler(r.profileFile, r.profileFd);
   2224             mProfiler.startProfiling();
   2225             mProfiler.autoStopProfiler = r.autoStopProfiler;
   2226         }
   2227 
   2228         // Make sure we are running with the most recent config.
   2229         handleConfigurationChanged(null, null);
   2230 
   2231         if (localLOGV) Slog.v(
   2232             TAG, "Handling launch of " + r);
   2233         Activity a = performLaunchActivity(r, customIntent);
   2234 
   2235         if (a != null) {
   2236             r.createdConfig = new Configuration(mConfiguration);
   2237             Bundle oldState = r.state;
   2238             handleResumeActivity(r.token, false, r.isForward,
   2239                     !r.activity.mFinished && !r.startsNotResumed);
   2240 
   2241             if (!r.activity.mFinished && r.startsNotResumed) {
   2242                 // The activity manager actually wants this one to start out
   2243                 // paused, because it needs to be visible but isn't in the
   2244                 // foreground.  We accomplish this by going through the
   2245                 // normal startup (because activities expect to go through
   2246                 // onResume() the first time they run, before their window
   2247                 // is displayed), and then pausing it.  However, in this case
   2248                 // we do -not- need to do the full pause cycle (of freezing
   2249                 // and such) because the activity manager assumes it can just
   2250                 // retain the current state it has.
   2251                 try {
   2252                     r.activity.mCalled = false;
   2253                     mInstrumentation.callActivityOnPause(r.activity);
   2254                     // We need to keep around the original state, in case
   2255                     // we need to be created again.  But we only do this
   2256                     // for pre-Honeycomb apps, which always save their state
   2257                     // when pausing, so we can not have them save their state
   2258                     // when restarting from a paused state.  For HC and later,
   2259                     // we want to (and can) let the state be saved as the normal
   2260                     // part of stopping the activity.
   2261                     if (r.isPreHoneycomb()) {
   2262                         r.state = oldState;
   2263                     }
   2264                     if (!r.activity.mCalled) {
   2265                         throw new SuperNotCalledException(
   2266                             "Activity " + r.intent.getComponent().toShortString() +
   2267                             " did not call through to super.onPause()");
   2268                     }
   2269 
   2270                 } catch (SuperNotCalledException e) {
   2271                     throw e;
   2272 
   2273                 } catch (Exception e) {
   2274                     if (!mInstrumentation.onException(r.activity, e)) {
   2275                         throw new RuntimeException(
   2276                                 "Unable to pause activity "
   2277                                 + r.intent.getComponent().toShortString()
   2278                                 + ": " + e.toString(), e);
   2279                     }
   2280                 }
   2281                 r.paused = true;
   2282             }
   2283         } else {
   2284             // If there was an error, for any reason, tell the activity
   2285             // manager to stop us.
   2286             try {
   2287                 ActivityManagerNative.getDefault()
   2288                     .finishActivity(r.token, Activity.RESULT_CANCELED, null);
   2289             } catch (RemoteException ex) {
   2290                 // Ignore
   2291             }
   2292         }
   2293     }
   2294 
   2295     private void deliverNewIntents(ActivityClientRecord r,
   2296             List<Intent> intents) {
   2297         final int N = intents.size();
   2298         for (int i=0; i<N; i++) {
   2299             Intent intent = intents.get(i);
   2300             intent.setExtrasClassLoader(r.activity.getClassLoader());
   2301             r.activity.mFragments.noteStateNotSaved();
   2302             mInstrumentation.callActivityOnNewIntent(r.activity, intent);
   2303         }
   2304     }
   2305 
   2306     public final void performNewIntents(IBinder token,
   2307             List<Intent> intents) {
   2308         ActivityClientRecord r = mActivities.get(token);
   2309         if (r != null) {
   2310             final boolean resumed = !r.paused;
   2311             if (resumed) {
   2312                 r.activity.mTemporaryPause = true;
   2313                 mInstrumentation.callActivityOnPause(r.activity);
   2314             }
   2315             deliverNewIntents(r, intents);
   2316             if (resumed) {
   2317                 r.activity.performResume();
   2318                 r.activity.mTemporaryPause = false;
   2319             }
   2320         }
   2321     }
   2322 
   2323     private void handleNewIntent(NewIntentData data) {
   2324         performNewIntents(data.token, data.intents);
   2325     }
   2326 
   2327     public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
   2328         Bundle data = new Bundle();
   2329         ActivityClientRecord r = mActivities.get(cmd.activityToken);
   2330         if (r != null) {
   2331             r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
   2332             r.activity.onProvideAssistData(data);
   2333         }
   2334         if (data.isEmpty()) {
   2335             data = null;
   2336         }
   2337         IActivityManager mgr = ActivityManagerNative.getDefault();
   2338         try {
   2339             mgr.reportAssistContextExtras(cmd.requestToken, data);
   2340         } catch (RemoteException e) {
   2341         }
   2342     }
   2343 
   2344     public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
   2345         ActivityClientRecord r = mActivities.get(token);
   2346         if (r != null) {
   2347             r.activity.onTranslucentConversionComplete(drawComplete);
   2348         }
   2349     }
   2350 
   2351     public void handleInstallProvider(ProviderInfo info) {
   2352         installContentProviders(mInitialApplication, Lists.newArrayList(info));
   2353     }
   2354 
   2355     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
   2356 
   2357     /**
   2358      * Return the Intent that's currently being handled by a
   2359      * BroadcastReceiver on this thread, or null if none.
   2360      * @hide
   2361      */
   2362     public static Intent getIntentBeingBroadcast() {
   2363         return sCurrentBroadcastIntent.get();
   2364     }
   2365 
   2366     private void handleReceiver(ReceiverData data) {
   2367         // If we are getting ready to gc after going to the background, well
   2368         // we are back active so skip it.
   2369         unscheduleGcIdler();
   2370 
   2371         String component = data.intent.getComponent().getClassName();
   2372 
   2373         LoadedApk packageInfo = getPackageInfoNoCheck(
   2374                 data.info.applicationInfo, data.compatInfo);
   2375 
   2376         IActivityManager mgr = ActivityManagerNative.getDefault();
   2377 
   2378         BroadcastReceiver receiver;
   2379         try {
   2380             java.lang.ClassLoader cl = packageInfo.getClassLoader();
   2381             data.intent.setExtrasClassLoader(cl);
   2382             data.setExtrasClassLoader(cl);
   2383             receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
   2384         } catch (Exception e) {
   2385             if (DEBUG_BROADCAST) Slog.i(TAG,
   2386                     "Finishing failed broadcast to " + data.intent.getComponent());
   2387             data.sendFinished(mgr);
   2388             throw new RuntimeException(
   2389                 "Unable to instantiate receiver " + component
   2390                 + ": " + e.toString(), e);
   2391         }
   2392 
   2393         try {
   2394             Application app = packageInfo.makeApplication(false, mInstrumentation);
   2395 
   2396             if (localLOGV) Slog.v(
   2397                 TAG, "Performing receive of " + data.intent
   2398                 + ": app=" + app
   2399                 + ", appName=" + app.getPackageName()
   2400                 + ", pkg=" + packageInfo.getPackageName()
   2401                 + ", comp=" + data.intent.getComponent().toShortString()
   2402                 + ", dir=" + packageInfo.getAppDir());
   2403 
   2404             ContextImpl context = (ContextImpl)app.getBaseContext();
   2405             sCurrentBroadcastIntent.set(data.intent);
   2406             receiver.setPendingResult(data);
   2407             receiver.onReceive(context.getReceiverRestrictedContext(),
   2408                     data.intent);
   2409         } catch (Exception e) {
   2410             if (DEBUG_BROADCAST) Slog.i(TAG,
   2411                     "Finishing failed broadcast to " + data.intent.getComponent());
   2412             data.sendFinished(mgr);
   2413             if (!mInstrumentation.onException(receiver, e)) {
   2414                 throw new RuntimeException(
   2415                     "Unable to start receiver " + component
   2416                     + ": " + e.toString(), e);
   2417             }
   2418         } finally {
   2419             sCurrentBroadcastIntent.set(null);
   2420         }
   2421 
   2422         if (receiver.getPendingResult() != null) {
   2423             data.finish();
   2424         }
   2425     }
   2426 
   2427     // Instantiate a BackupAgent and tell it that it's alive
   2428     private void handleCreateBackupAgent(CreateBackupAgentData data) {
   2429         if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
   2430 
   2431         // Sanity check the requested target package's uid against ours
   2432         try {
   2433             PackageInfo requestedPackage = getPackageManager().getPackageInfo(
   2434                     data.appInfo.packageName, 0, UserHandle.myUserId());
   2435             if (requestedPackage.applicationInfo.uid != Process.myUid()) {
   2436                 Slog.w(TAG, "Asked to instantiate non-matching package "
   2437                         + data.appInfo.packageName);
   2438                 return;
   2439             }
   2440         } catch (RemoteException e) {
   2441             Slog.e(TAG, "Can't reach package manager", e);
   2442             return;
   2443         }
   2444 
   2445         // no longer idle; we have backup work to do
   2446         unscheduleGcIdler();
   2447 
   2448         // instantiate the BackupAgent class named in the manifest
   2449         LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
   2450         String packageName = packageInfo.mPackageName;
   2451         if (packageName == null) {
   2452             Slog.d(TAG, "Asked to create backup agent for nonexistent package");
   2453             return;
   2454         }
   2455 
   2456         if (mBackupAgents.get(packageName) != null) {
   2457             Slog.d(TAG, "BackupAgent " + "  for " + packageName
   2458                     + " already exists");
   2459             return;
   2460         }
   2461 
   2462         BackupAgent agent = null;
   2463         String classname = data.appInfo.backupAgentName;
   2464 
   2465         // full backup operation but no app-supplied agent?  use the default implementation
   2466         if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
   2467                 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
   2468             classname = "android.app.backup.FullBackupAgent";
   2469         }
   2470 
   2471         try {
   2472             IBinder binder = null;
   2473             try {
   2474                 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
   2475 
   2476                 java.lang.ClassLoader cl = packageInfo.getClassLoader();
   2477                 agent = (BackupAgent) cl.loadClass(classname).newInstance();
   2478 
   2479                 // set up the agent's context
   2480                 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
   2481                 context.setOuterContext(agent);
   2482                 agent.attach(context);
   2483 
   2484                 agent.onCreate();
   2485                 binder = agent.onBind();
   2486                 mBackupAgents.put(packageName, agent);
   2487             } catch (Exception e) {
   2488                 // If this is during restore, fail silently; otherwise go
   2489                 // ahead and let the user see the crash.
   2490                 Slog.e(TAG, "Agent threw during creation: " + e);
   2491                 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
   2492                         && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
   2493                     throw e;
   2494                 }
   2495                 // falling through with 'binder' still null
   2496             }
   2497 
   2498             // tell the OS that we're live now
   2499             try {
   2500                 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
   2501             } catch (RemoteException e) {
   2502                 // nothing to do.
   2503             }
   2504         } catch (Exception e) {
   2505             throw new RuntimeException("Unable to create BackupAgent "
   2506                     + classname + ": " + e.toString(), e);
   2507         }
   2508     }
   2509 
   2510     // Tear down a BackupAgent
   2511     private void handleDestroyBackupAgent(CreateBackupAgentData data) {
   2512         if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
   2513 
   2514         LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
   2515         String packageName = packageInfo.mPackageName;
   2516         BackupAgent agent = mBackupAgents.get(packageName);
   2517         if (agent != null) {
   2518             try {
   2519                 agent.onDestroy();
   2520             } catch (Exception e) {
   2521                 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
   2522                 e.printStackTrace();
   2523             }
   2524             mBackupAgents.remove(packageName);
   2525         } else {
   2526             Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
   2527         }
   2528     }
   2529 
   2530     private void handleCreateService(CreateServiceData data) {
   2531         // If we are getting ready to gc after going to the background, well
   2532         // we are back active so skip it.
   2533         unscheduleGcIdler();
   2534 
   2535         LoadedApk packageInfo = getPackageInfoNoCheck(
   2536                 data.info.applicationInfo, data.compatInfo);
   2537         Service service = null;
   2538         try {
   2539             java.lang.ClassLoader cl = packageInfo.getClassLoader();
   2540             service = (Service) cl.loadClass(data.info.name).newInstance();
   2541         } catch (Exception e) {
   2542             if (!mInstrumentation.onException(service, e)) {
   2543                 throw new RuntimeException(
   2544                     "Unable to instantiate service " + data.info.name
   2545                     + ": " + e.toString(), e);
   2546             }
   2547         }
   2548 
   2549         try {
   2550             if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
   2551 
   2552             ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
   2553             context.setOuterContext(service);
   2554 
   2555             Application app = packageInfo.makeApplication(false, mInstrumentation);
   2556             service.attach(context, this, data.info.name, data.token, app,
   2557                     ActivityManagerNative.getDefault());
   2558             service.onCreate();
   2559             mServices.put(data.token, service);
   2560             try {
   2561                 ActivityManagerNative.getDefault().serviceDoneExecuting(
   2562                         data.token, 0, 0, 0);
   2563             } catch (RemoteException e) {
   2564                 // nothing to do.
   2565             }
   2566         } catch (Exception e) {
   2567             if (!mInstrumentation.onException(service, e)) {
   2568                 throw new RuntimeException(
   2569                     "Unable to create service " + data.info.name
   2570                     + ": " + e.toString(), e);
   2571             }
   2572         }
   2573     }
   2574 
   2575     private void handleBindService(BindServiceData data) {
   2576         Service s = mServices.get(data.token);
   2577         if (DEBUG_SERVICE)
   2578             Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
   2579         if (s != null) {
   2580             try {
   2581                 data.intent.setExtrasClassLoader(s.getClassLoader());
   2582                 try {
   2583                     if (!data.rebind) {
   2584                         IBinder binder = s.onBind(data.intent);
   2585                         ActivityManagerNative.getDefault().publishService(
   2586                                 data.token, data.intent, binder);
   2587                     } else {
   2588                         s.onRebind(data.intent);
   2589                         ActivityManagerNative.getDefault().serviceDoneExecuting(
   2590                                 data.token, 0, 0, 0);
   2591                     }
   2592                     ensureJitEnabled();
   2593                 } catch (RemoteException ex) {
   2594                 }
   2595             } catch (Exception e) {
   2596                 if (!mInstrumentation.onException(s, e)) {
   2597                     throw new RuntimeException(
   2598                             "Unable to bind to service " + s
   2599                             + " with " + data.intent + ": " + e.toString(), e);
   2600                 }
   2601             }
   2602         }
   2603     }
   2604 
   2605     private void handleUnbindService(BindServiceData data) {
   2606         Service s = mServices.get(data.token);
   2607         if (s != null) {
   2608             try {
   2609                 data.intent.setExtrasClassLoader(s.getClassLoader());
   2610                 boolean doRebind = s.onUnbind(data.intent);
   2611                 try {
   2612                     if (doRebind) {
   2613                         ActivityManagerNative.getDefault().unbindFinished(
   2614                                 data.token, data.intent, doRebind);
   2615                     } else {
   2616                         ActivityManagerNative.getDefault().serviceDoneExecuting(
   2617                                 data.token, 0, 0, 0);
   2618                     }
   2619                 } catch (RemoteException ex) {
   2620                 }
   2621             } catch (Exception e) {
   2622                 if (!mInstrumentation.onException(s, e)) {
   2623                     throw new RuntimeException(
   2624                             "Unable to unbind to service " + s
   2625                             + " with " + data.intent + ": " + e.toString(), e);
   2626                 }
   2627             }
   2628         }
   2629     }
   2630 
   2631     private void handleDumpService(DumpComponentInfo info) {
   2632         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   2633         try {
   2634             Service s = mServices.get(info.token);
   2635             if (s != null) {
   2636                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
   2637                         info.fd.getFileDescriptor()));
   2638                 s.dump(info.fd.getFileDescriptor(), pw, info.args);
   2639                 pw.flush();
   2640             }
   2641         } finally {
   2642             IoUtils.closeQuietly(info.fd);
   2643             StrictMode.setThreadPolicy(oldPolicy);
   2644         }
   2645     }
   2646 
   2647     private void handleDumpActivity(DumpComponentInfo info) {
   2648         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   2649         try {
   2650             ActivityClientRecord r = mActivities.get(info.token);
   2651             if (r != null && r.activity != null) {
   2652                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
   2653                         info.fd.getFileDescriptor()));
   2654                 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
   2655                 pw.flush();
   2656             }
   2657         } finally {
   2658             IoUtils.closeQuietly(info.fd);
   2659             StrictMode.setThreadPolicy(oldPolicy);
   2660         }
   2661     }
   2662 
   2663     private void handleDumpProvider(DumpComponentInfo info) {
   2664         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   2665         try {
   2666             ProviderClientRecord r = mLocalProviders.get(info.token);
   2667             if (r != null && r.mLocalProvider != null) {
   2668                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
   2669                         info.fd.getFileDescriptor()));
   2670                 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
   2671                 pw.flush();
   2672             }
   2673         } finally {
   2674             IoUtils.closeQuietly(info.fd);
   2675             StrictMode.setThreadPolicy(oldPolicy);
   2676         }
   2677     }
   2678 
   2679     private void handleServiceArgs(ServiceArgsData data) {
   2680         Service s = mServices.get(data.token);
   2681         if (s != null) {
   2682             try {
   2683                 if (data.args != null) {
   2684                     data.args.setExtrasClassLoader(s.getClassLoader());
   2685                 }
   2686                 int res;
   2687                 if (!data.taskRemoved) {
   2688                     res = s.onStartCommand(data.args, data.flags, data.startId);
   2689                 } else {
   2690                     s.onTaskRemoved(data.args);
   2691                     res = Service.START_TASK_REMOVED_COMPLETE;
   2692                 }
   2693 
   2694                 QueuedWork.waitToFinish();
   2695 
   2696                 try {
   2697                     ActivityManagerNative.getDefault().serviceDoneExecuting(
   2698                             data.token, 1, data.startId, res);
   2699                 } catch (RemoteException e) {
   2700                     // nothing to do.
   2701                 }
   2702                 ensureJitEnabled();
   2703             } catch (Exception e) {
   2704                 if (!mInstrumentation.onException(s, e)) {
   2705                     throw new RuntimeException(
   2706                             "Unable to start service " + s
   2707                             + " with " + data.args + ": " + e.toString(), e);
   2708                 }
   2709             }
   2710         }
   2711     }
   2712 
   2713     private void handleStopService(IBinder token) {
   2714         Service s = mServices.remove(token);
   2715         if (s != null) {
   2716             try {
   2717                 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
   2718                 s.onDestroy();
   2719                 Context context = s.getBaseContext();
   2720                 if (context instanceof ContextImpl) {
   2721                     final String who = s.getClassName();
   2722                     ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
   2723                 }
   2724 
   2725                 QueuedWork.waitToFinish();
   2726 
   2727                 try {
   2728                     ActivityManagerNative.getDefault().serviceDoneExecuting(
   2729                             token, 0, 0, 0);
   2730                 } catch (RemoteException e) {
   2731                     // nothing to do.
   2732                 }
   2733             } catch (Exception e) {
   2734                 if (!mInstrumentation.onException(s, e)) {
   2735                     throw new RuntimeException(
   2736                             "Unable to stop service " + s
   2737                             + ": " + e.toString(), e);
   2738                 }
   2739             }
   2740         }
   2741         //Slog.i(TAG, "Running services: " + mServices);
   2742     }
   2743 
   2744     public final ActivityClientRecord performResumeActivity(IBinder token,
   2745             boolean clearHide) {
   2746         ActivityClientRecord r = mActivities.get(token);
   2747         if (localLOGV) Slog.v(TAG, "Performing resume of " + r
   2748                 + " finished=" + r.activity.mFinished);
   2749         if (r != null && !r.activity.mFinished) {
   2750             if (clearHide) {
   2751                 r.hideForNow = false;
   2752                 r.activity.mStartedActivity = false;
   2753             }
   2754             try {
   2755                 r.activity.mFragments.noteStateNotSaved();
   2756                 if (r.pendingIntents != null) {
   2757                     deliverNewIntents(r, r.pendingIntents);
   2758                     r.pendingIntents = null;
   2759                 }
   2760                 if (r.pendingResults != null) {
   2761                     deliverResults(r, r.pendingResults);
   2762                     r.pendingResults = null;
   2763                 }
   2764                 r.activity.performResume();
   2765 
   2766                 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
   2767                         UserHandle.myUserId(), r.activity.getComponentName().getClassName());
   2768 
   2769                 r.paused = false;
   2770                 r.stopped = false;
   2771                 r.state = null;
   2772             } catch (Exception e) {
   2773                 if (!mInstrumentation.onException(r.activity, e)) {
   2774                     throw new RuntimeException(
   2775                         "Unable to resume activity "
   2776                         + r.intent.getComponent().toShortString()
   2777                         + ": " + e.toString(), e);
   2778                 }
   2779             }
   2780         }
   2781         return r;
   2782     }
   2783 
   2784     static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
   2785         if (r.mPendingRemoveWindow != null) {
   2786             r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
   2787             IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
   2788             if (wtoken != null) {
   2789                 WindowManagerGlobal.getInstance().closeAll(wtoken,
   2790                         r.activity.getClass().getName(), "Activity");
   2791             }
   2792         }
   2793         r.mPendingRemoveWindow = null;
   2794         r.mPendingRemoveWindowManager = null;
   2795     }
   2796 
   2797     final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
   2798             boolean reallyResume) {
   2799         // If we are getting ready to gc after going to the background, well
   2800         // we are back active so skip it.
   2801         unscheduleGcIdler();
   2802 
   2803         ActivityClientRecord r = performResumeActivity(token, clearHide);
   2804 
   2805         if (r != null) {
   2806             final Activity a = r.activity;
   2807 
   2808             if (localLOGV) Slog.v(
   2809                 TAG, "Resume " + r + " started activity: " +
   2810                 a.mStartedActivity + ", hideForNow: " + r.hideForNow
   2811                 + ", finished: " + a.mFinished);
   2812 
   2813             final int forwardBit = isForward ?
   2814                     WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
   2815 
   2816             // If the window hasn't yet been added to the window manager,
   2817             // and this guy didn't finish itself or start another activity,
   2818             // then go ahead and add the window.
   2819             boolean willBeVisible = !a.mStartedActivity;
   2820             if (!willBeVisible) {
   2821                 try {
   2822                     willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
   2823                             a.getActivityToken());
   2824                 } catch (RemoteException e) {
   2825                 }
   2826             }
   2827             if (r.window == null && !a.mFinished && willBeVisible) {
   2828                 r.window = r.activity.getWindow();
   2829                 View decor = r.window.getDecorView();
   2830                 decor.setVisibility(View.INVISIBLE);
   2831                 ViewManager wm = a.getWindowManager();
   2832                 WindowManager.LayoutParams l = r.window.getAttributes();
   2833                 a.mDecor = decor;
   2834                 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
   2835                 l.softInputMode |= forwardBit;
   2836                 if (a.mVisibleFromClient) {
   2837                     a.mWindowAdded = true;
   2838                     wm.addView(decor, l);
   2839                 }
   2840 
   2841             // If the window has already been added, but during resume
   2842             // we started another activity, then don't yet make the
   2843             // window visible.
   2844             } else if (!willBeVisible) {
   2845                 if (localLOGV) Slog.v(
   2846                     TAG, "Launch " + r + " mStartedActivity set");
   2847                 r.hideForNow = true;
   2848             }
   2849 
   2850             // Get rid of anything left hanging around.
   2851             cleanUpPendingRemoveWindows(r);
   2852 
   2853             // The window is now visible if it has been added, we are not
   2854             // simply finishing, and we are not starting another activity.
   2855             if (!r.activity.mFinished && willBeVisible
   2856                     && r.activity.mDecor != null && !r.hideForNow) {
   2857                 if (r.newConfig != null) {
   2858                     if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
   2859                             + r.activityInfo.name + " with newConfig " + r.newConfig);
   2860                     performConfigurationChanged(r.activity, r.newConfig);
   2861                     freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
   2862                     r.newConfig = null;
   2863                 }
   2864                 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
   2865                         + isForward);
   2866                 WindowManager.LayoutParams l = r.window.getAttributes();
   2867                 if ((l.softInputMode
   2868                         & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
   2869                         != forwardBit) {
   2870                     l.softInputMode = (l.softInputMode
   2871                             & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
   2872                             | forwardBit;
   2873                     if (r.activity.mVisibleFromClient) {
   2874                         ViewManager wm = a.getWindowManager();
   2875                         View decor = r.window.getDecorView();
   2876                         wm.updateViewLayout(decor, l);
   2877                     }
   2878                 }
   2879                 r.activity.mVisibleFromServer = true;
   2880                 mNumVisibleActivities++;
   2881                 if (r.activity.mVisibleFromClient) {
   2882                     r.activity.makeVisible();
   2883                 }
   2884             }
   2885 
   2886             if (!r.onlyLocalRequest) {
   2887                 r.nextIdle = mNewActivities;
   2888                 mNewActivities = r;
   2889                 if (localLOGV) Slog.v(
   2890                     TAG, "Scheduling idle handler for " + r);
   2891                 Looper.myQueue().addIdleHandler(new Idler());
   2892             }
   2893             r.onlyLocalRequest = false;
   2894 
   2895             // Tell the activity manager we have resumed.
   2896             if (reallyResume) {
   2897                 try {
   2898                     ActivityManagerNative.getDefault().activityResumed(token);
   2899                 } catch (RemoteException ex) {
   2900                 }
   2901             }
   2902 
   2903         } else {
   2904             // If an exception was thrown when trying to resume, then
   2905             // just end this activity.
   2906             try {
   2907                 ActivityManagerNative.getDefault()
   2908                     .finishActivity(token, Activity.RESULT_CANCELED, null);
   2909             } catch (RemoteException ex) {
   2910             }
   2911         }
   2912     }
   2913 
   2914     private int mThumbnailWidth = -1;
   2915     private int mThumbnailHeight = -1;
   2916     private Bitmap mAvailThumbnailBitmap = null;
   2917     private Canvas mThumbnailCanvas = null;
   2918 
   2919     private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
   2920         Bitmap thumbnail = mAvailThumbnailBitmap;
   2921         try {
   2922             if (thumbnail == null) {
   2923                 int w = mThumbnailWidth;
   2924                 int h;
   2925                 if (w < 0) {
   2926                     Resources res = r.activity.getResources();
   2927                     mThumbnailHeight = h =
   2928                         res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
   2929 
   2930                     mThumbnailWidth = w =
   2931                         res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
   2932                 } else {
   2933                     h = mThumbnailHeight;
   2934                 }
   2935 
   2936                 // On platforms where we don't want thumbnails, set dims to (0,0)
   2937                 if ((w > 0) && (h > 0)) {
   2938                     thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
   2939                             w, h, THUMBNAIL_FORMAT);
   2940                     thumbnail.eraseColor(0);
   2941                 }
   2942             }
   2943 
   2944             if (thumbnail != null) {
   2945                 Canvas cv = mThumbnailCanvas;
   2946                 if (cv == null) {
   2947                     mThumbnailCanvas = cv = new Canvas();
   2948                 }
   2949 
   2950                 cv.setBitmap(thumbnail);
   2951                 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
   2952                     mAvailThumbnailBitmap = thumbnail;
   2953                     thumbnail = null;
   2954                 }
   2955                 cv.setBitmap(null);
   2956             }
   2957 
   2958         } catch (Exception e) {
   2959             if (!mInstrumentation.onException(r.activity, e)) {
   2960                 throw new RuntimeException(
   2961                         "Unable to create thumbnail of "
   2962                         + r.intent.getComponent().toShortString()
   2963                         + ": " + e.toString(), e);
   2964             }
   2965             thumbnail = null;
   2966         }
   2967 
   2968         return thumbnail;
   2969     }
   2970 
   2971     private void handlePauseActivity(IBinder token, boolean finished,
   2972             boolean userLeaving, int configChanges) {
   2973         ActivityClientRecord r = mActivities.get(token);
   2974         if (r != null) {
   2975             //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
   2976             if (userLeaving) {
   2977                 performUserLeavingActivity(r);
   2978             }
   2979 
   2980             r.activity.mConfigChangeFlags |= configChanges;
   2981             performPauseActivity(token, finished, r.isPreHoneycomb());
   2982 
   2983             // Make sure any pending writes are now committed.
   2984             if (r.isPreHoneycomb()) {
   2985                 QueuedWork.waitToFinish();
   2986             }
   2987 
   2988             // Tell the activity manager we have paused.
   2989             try {
   2990                 ActivityManagerNative.getDefault().activityPaused(token);
   2991             } catch (RemoteException ex) {
   2992             }
   2993         }
   2994     }
   2995 
   2996     final void performUserLeavingActivity(ActivityClientRecord r) {
   2997         mInstrumentation.callActivityOnUserLeaving(r.activity);
   2998     }
   2999 
   3000     final Bundle performPauseActivity(IBinder token, boolean finished,
   3001             boolean saveState) {
   3002         ActivityClientRecord r = mActivities.get(token);
   3003         return r != null ? performPauseActivity(r, finished, saveState) : null;
   3004     }
   3005 
   3006     final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
   3007             boolean saveState) {
   3008         if (r.paused) {
   3009             if (r.activity.mFinished) {
   3010                 // If we are finishing, we won't call onResume() in certain cases.
   3011                 // So here we likewise don't want to call onPause() if the activity
   3012                 // isn't resumed.
   3013                 return null;
   3014             }
   3015             RuntimeException e = new RuntimeException(
   3016                     "Performing pause of activity that is not resumed: "
   3017                     + r.intent.getComponent().toShortString());
   3018             Slog.e(TAG, e.getMessage(), e);
   3019         }
   3020         Bundle state = null;
   3021         if (finished) {
   3022             r.activity.mFinished = true;
   3023         }
   3024         try {
   3025             // Next have the activity save its current state and managed dialogs...
   3026             if (!r.activity.mFinished && saveState) {
   3027                 state = new Bundle();
   3028                 state.setAllowFds(false);
   3029                 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
   3030                 r.state = state;
   3031             }
   3032             // Now we are idle.
   3033             r.activity.mCalled = false;
   3034             mInstrumentation.callActivityOnPause(r.activity);
   3035             EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
   3036                     r.activity.getComponentName().getClassName());
   3037             if (!r.activity.mCalled) {
   3038                 throw new SuperNotCalledException(
   3039                     "Activity " + r.intent.getComponent().toShortString() +
   3040                     " did not call through to super.onPause()");
   3041             }
   3042 
   3043         } catch (SuperNotCalledException e) {
   3044             throw e;
   3045 
   3046         } catch (Exception e) {
   3047             if (!mInstrumentation.onException(r.activity, e)) {
   3048                 throw new RuntimeException(
   3049                         "Unable to pause activity "
   3050                         + r.intent.getComponent().toShortString()
   3051                         + ": " + e.toString(), e);
   3052             }
   3053         }
   3054         r.paused = true;
   3055 
   3056         // Notify any outstanding on paused listeners
   3057         ArrayList<OnActivityPausedListener> listeners;
   3058         synchronized (mOnPauseListeners) {
   3059             listeners = mOnPauseListeners.remove(r.activity);
   3060         }
   3061         int size = (listeners != null ? listeners.size() : 0);
   3062         for (int i = 0; i < size; i++) {
   3063             listeners.get(i).onPaused(r.activity);
   3064         }
   3065 
   3066         return state;
   3067     }
   3068 
   3069     final void performStopActivity(IBinder token, boolean saveState) {
   3070         ActivityClientRecord r = mActivities.get(token);
   3071         performStopActivityInner(r, null, false, saveState);
   3072     }
   3073 
   3074     private static class StopInfo implements Runnable {
   3075         ActivityClientRecord activity;
   3076         Bundle state;
   3077         Bitmap thumbnail;
   3078         CharSequence description;
   3079 
   3080         @Override public void run() {
   3081             // Tell activity manager we have been stopped.
   3082             try {
   3083                 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
   3084                 ActivityManagerNative.getDefault().activityStopped(
   3085                     activity.token, state, thumbnail, description);
   3086             } catch (RemoteException ex) {
   3087             }
   3088         }
   3089     }
   3090 
   3091     private static final class ProviderRefCount {
   3092         public final IActivityManager.ContentProviderHolder holder;
   3093         public final ProviderClientRecord client;
   3094         public int stableCount;
   3095         public int unstableCount;
   3096 
   3097         // When this is set, the stable and unstable ref counts are 0 and
   3098         // we have a pending operation scheduled to remove the ref count
   3099         // from the activity manager.  On the activity manager we are still
   3100         // holding an unstable ref, though it is not reflected in the counts
   3101         // here.
   3102         public boolean removePending;
   3103 
   3104         ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
   3105                 ProviderClientRecord inClient, int sCount, int uCount) {
   3106             holder = inHolder;
   3107             client = inClient;
   3108             stableCount = sCount;
   3109             unstableCount = uCount;
   3110         }
   3111     }
   3112 
   3113     /**
   3114      * Core implementation of stopping an activity.  Note this is a little
   3115      * tricky because the server's meaning of stop is slightly different
   3116      * than our client -- for the server, stop means to save state and give
   3117      * it the result when it is done, but the window may still be visible.
   3118      * For the client, we want to call onStop()/onStart() to indicate when
   3119      * the activity's UI visibillity changes.
   3120      */
   3121     private void performStopActivityInner(ActivityClientRecord r,
   3122             StopInfo info, boolean keepShown, boolean saveState) {
   3123         if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
   3124         Bundle state = null;
   3125         if (r != null) {
   3126             if (!keepShown && r.stopped) {
   3127                 if (r.activity.mFinished) {
   3128                     // If we are finishing, we won't call onResume() in certain
   3129                     // cases.  So here we likewise don't want to call onStop()
   3130                     // if the activity isn't resumed.
   3131                     return;
   3132                 }
   3133                 RuntimeException e = new RuntimeException(
   3134                         "Performing stop of activity that is not resumed: "
   3135                         + r.intent.getComponent().toShortString());
   3136                 Slog.e(TAG, e.getMessage(), e);
   3137             }
   3138 
   3139             if (info != null) {
   3140                 try {
   3141                     // First create a thumbnail for the activity...
   3142                     // For now, don't create the thumbnail here; we are
   3143                     // doing that by doing a screen snapshot.
   3144                     info.thumbnail = null; //createThumbnailBitmap(r);
   3145                     info.description = r.activity.onCreateDescription();
   3146                 } catch (Exception e) {
   3147                     if (!mInstrumentation.onException(r.activity, e)) {
   3148                         throw new RuntimeException(
   3149                                 "Unable to save state of activity "
   3150                                 + r.intent.getComponent().toShortString()
   3151                                 + ": " + e.toString(), e);
   3152                     }
   3153                 }
   3154             }
   3155 
   3156             // Next have the activity save its current state and managed dialogs...
   3157             if (!r.activity.mFinished && saveState) {
   3158                 if (r.state == null) {
   3159                     state = new Bundle();
   3160                     state.setAllowFds(false);
   3161                     mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
   3162                     r.state = state;
   3163                 } else {
   3164                     state = r.state;
   3165                 }
   3166             }
   3167 
   3168             if (!keepShown) {
   3169                 try {
   3170                     // Now we are idle.
   3171                     r.activity.performStop();
   3172                 } catch (Exception e) {
   3173                     if (!mInstrumentation.onException(r.activity, e)) {
   3174                         throw new RuntimeException(
   3175                                 "Unable to stop activity "
   3176                                 + r.intent.getComponent().toShortString()
   3177                                 + ": " + e.toString(), e);
   3178                     }
   3179                 }
   3180                 r.stopped = true;
   3181             }
   3182 
   3183             r.paused = true;
   3184         }
   3185     }
   3186 
   3187     private void updateVisibility(ActivityClientRecord r, boolean show) {
   3188         View v = r.activity.mDecor;
   3189         if (v != null) {
   3190             if (show) {
   3191                 if (!r.activity.mVisibleFromServer) {
   3192                     r.activity.mVisibleFromServer = true;
   3193                     mNumVisibleActivities++;
   3194                     if (r.activity.mVisibleFromClient) {
   3195                         r.activity.makeVisible();
   3196                     }
   3197                 }
   3198                 if (r.newConfig != null) {
   3199                     if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
   3200                             + r.activityInfo.name + " with new config " + r.newConfig);
   3201                     performConfigurationChanged(r.activity, r.newConfig);
   3202                     freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
   3203                     r.newConfig = null;
   3204                 }
   3205             } else {
   3206                 if (r.activity.mVisibleFromServer) {
   3207                     r.activity.mVisibleFromServer = false;
   3208                     mNumVisibleActivities--;
   3209                     v.setVisibility(View.INVISIBLE);
   3210                 }
   3211             }
   3212         }
   3213     }
   3214 
   3215     private void handleStopActivity(IBinder token, boolean show, int configChanges) {
   3216         ActivityClientRecord r = mActivities.get(token);
   3217         r.activity.mConfigChangeFlags |= configChanges;
   3218 
   3219         StopInfo info = new StopInfo();
   3220         performStopActivityInner(r, info, show, true);
   3221 
   3222         if (localLOGV) Slog.v(
   3223             TAG, "Finishing stop of " + r + ": show=" + show
   3224             + " win=" + r.window);
   3225 
   3226         updateVisibility(r, show);
   3227 
   3228         // Make sure any pending writes are now committed.
   3229         if (!r.isPreHoneycomb()) {
   3230             QueuedWork.waitToFinish();
   3231         }
   3232 
   3233         // Schedule the call to tell the activity manager we have
   3234         // stopped.  We don't do this immediately, because we want to
   3235         // have a chance for any other pending work (in particular memory
   3236         // trim requests) to complete before you tell the activity
   3237         // manager to proceed and allow us to go fully into the background.
   3238         info.activity = r;
   3239         info.state = r.state;
   3240         mH.post(info);
   3241     }
   3242 
   3243     final void performRestartActivity(IBinder token) {
   3244         ActivityClientRecord r = mActivities.get(token);
   3245         if (r.stopped) {
   3246             r.activity.performRestart();
   3247             r.stopped = false;
   3248         }
   3249     }
   3250 
   3251     private void handleWindowVisibility(IBinder token, boolean show) {
   3252         ActivityClientRecord r = mActivities.get(token);
   3253 
   3254         if (r == null) {
   3255             Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
   3256             return;
   3257         }
   3258 
   3259         if (!show && !r.stopped) {
   3260             performStopActivityInner(r, null, show, false);
   3261         } else if (show && r.stopped) {
   3262             // If we are getting ready to gc after going to the background, well
   3263             // we are back active so skip it.
   3264             unscheduleGcIdler();
   3265 
   3266             r.activity.performRestart();
   3267             r.stopped = false;
   3268         }
   3269         if (r.activity.mDecor != null) {
   3270             if (false) Slog.v(
   3271                 TAG, "Handle window " + r + " visibility: " + show);
   3272             updateVisibility(r, show);
   3273         }
   3274     }
   3275 
   3276     private void handleSleeping(IBinder token, boolean sleeping) {
   3277         ActivityClientRecord r = mActivities.get(token);
   3278 
   3279         if (r == null) {
   3280             Log.w(TAG, "handleSleeping: no activity for token " + token);
   3281             return;
   3282         }
   3283 
   3284         if (sleeping) {
   3285             if (!r.stopped && !r.isPreHoneycomb()) {
   3286                 try {
   3287                     // Now we are idle.
   3288                     r.activity.performStop();
   3289                 } catch (Exception e) {
   3290                     if (!mInstrumentation.onException(r.activity, e)) {
   3291                         throw new RuntimeException(
   3292                                 "Unable to stop activity "
   3293                                 + r.intent.getComponent().toShortString()
   3294                                 + ": " + e.toString(), e);
   3295                     }
   3296                 }
   3297                 r.stopped = true;
   3298             }
   3299 
   3300             // Make sure any pending writes are now committed.
   3301             if (!r.isPreHoneycomb()) {
   3302                 QueuedWork.waitToFinish();
   3303             }
   3304 
   3305             // Tell activity manager we slept.
   3306             try {
   3307                 ActivityManagerNative.getDefault().activitySlept(r.token);
   3308             } catch (RemoteException ex) {
   3309             }
   3310         } else {
   3311             if (r.stopped && r.activity.mVisibleFromServer) {
   3312                 r.activity.performRestart();
   3313                 r.stopped = false;
   3314             }
   3315         }
   3316     }
   3317 
   3318     private void handleSetCoreSettings(Bundle coreSettings) {
   3319         synchronized (mResourcesManager) {
   3320             mCoreSettings = coreSettings;
   3321         }
   3322     }
   3323 
   3324     private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
   3325         LoadedApk apk = peekPackageInfo(data.pkg, false);
   3326         if (apk != null) {
   3327             apk.setCompatibilityInfo(data.info);
   3328         }
   3329         apk = peekPackageInfo(data.pkg, true);
   3330         if (apk != null) {
   3331             apk.setCompatibilityInfo(data.info);
   3332         }
   3333         handleConfigurationChanged(mConfiguration, data.info);
   3334         WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
   3335     }
   3336 
   3337     private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
   3338         final int N = results.size();
   3339         for (int i=0; i<N; i++) {
   3340             ResultInfo ri = results.get(i);
   3341             try {
   3342                 if (ri.mData != null) {
   3343                     ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
   3344                 }
   3345                 if (DEBUG_RESULTS) Slog.v(TAG,
   3346                         "Delivering result to activity " + r + " : " + ri);
   3347                 r.activity.dispatchActivityResult(ri.mResultWho,
   3348                         ri.mRequestCode, ri.mResultCode, ri.mData);
   3349             } catch (Exception e) {
   3350                 if (!mInstrumentation.onException(r.activity, e)) {
   3351                     throw new RuntimeException(
   3352                             "Failure delivering result " + ri + " to activity "
   3353                             + r.intent.getComponent().toShortString()
   3354                             + ": " + e.toString(), e);
   3355                 }
   3356             }
   3357         }
   3358     }
   3359 
   3360     private void handleSendResult(ResultData res) {
   3361         ActivityClientRecord r = mActivities.get(res.token);
   3362         if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
   3363         if (r != null) {
   3364             final boolean resumed = !r.paused;
   3365             if (!r.activity.mFinished && r.activity.mDecor != null
   3366                     && r.hideForNow && resumed) {
   3367                 // We had hidden the activity because it started another
   3368                 // one...  we have gotten a result back and we are not
   3369                 // paused, so make sure our window is visible.
   3370                 updateVisibility(r, true);
   3371             }
   3372             if (resumed) {
   3373                 try {
   3374                     // Now we are idle.
   3375                     r.activity.mCalled = false;
   3376                     r.activity.mTemporaryPause = true;
   3377                     mInstrumentation.callActivityOnPause(r.activity);
   3378                     if (!r.activity.mCalled) {
   3379                         throw new SuperNotCalledException(
   3380                             "Activity " + r.intent.getComponent().toShortString()
   3381                             + " did not call through to super.onPause()");
   3382                     }
   3383                 } catch (SuperNotCalledException e) {
   3384                     throw e;
   3385                 } catch (Exception e) {
   3386                     if (!mInstrumentation.onException(r.activity, e)) {
   3387                         throw new RuntimeException(
   3388                                 "Unable to pause activity "
   3389                                 + r.intent.getComponent().toShortString()
   3390                                 + ": " + e.toString(), e);
   3391                     }
   3392                 }
   3393             }
   3394             deliverResults(r, res.results);
   3395             if (resumed) {
   3396                 r.activity.performResume();
   3397                 r.activity.mTemporaryPause = false;
   3398             }
   3399         }
   3400     }
   3401 
   3402     public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
   3403         return performDestroyActivity(token, finishing, 0, false);
   3404     }
   3405 
   3406     private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
   3407             int configChanges, boolean getNonConfigInstance) {
   3408         ActivityClientRecord r = mActivities.get(token);
   3409         Class<? extends Activity> activityClass = null;
   3410         if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
   3411         if (r != null) {
   3412             activityClass = r.activity.getClass();
   3413             r.activity.mConfigChangeFlags |= configChanges;
   3414             if (finishing) {
   3415                 r.activity.mFinished = true;
   3416             }
   3417             if (!r.paused) {
   3418                 try {
   3419                     r.activity.mCalled = false;
   3420                     mInstrumentation.callActivityOnPause(r.activity);
   3421                     EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
   3422                             r.activity.getComponentName().getClassName());
   3423                     if (!r.activity.mCalled) {
   3424                         throw new SuperNotCalledException(
   3425                             "Activity " + safeToComponentShortString(r.intent)
   3426                             + " did not call through to super.onPause()");
   3427                     }
   3428                 } catch (SuperNotCalledException e) {
   3429                     throw e;
   3430                 } catch (Exception e) {
   3431                     if (!mInstrumentation.onException(r.activity, e)) {
   3432                         throw new RuntimeException(
   3433                                 "Unable to pause activity "
   3434                                 + safeToComponentShortString(r.intent)
   3435                                 + ": " + e.toString(), e);
   3436                     }
   3437                 }
   3438                 r.paused = true;
   3439             }
   3440             if (!r.stopped) {
   3441                 try {
   3442                     r.activity.performStop();
   3443                 } catch (SuperNotCalledException e) {
   3444                     throw e;
   3445                 } catch (Exception e) {
   3446                     if (!mInstrumentation.onException(r.activity, e)) {
   3447                         throw new RuntimeException(
   3448                                 "Unable to stop activity "
   3449                                 + safeToComponentShortString(r.intent)
   3450                                 + ": " + e.toString(), e);
   3451                     }
   3452                 }
   3453                 r.stopped = true;
   3454             }
   3455             if (getNonConfigInstance) {
   3456                 try {
   3457                     r.lastNonConfigurationInstances
   3458                             = r.activity.retainNonConfigurationInstances();
   3459                 } catch (Exception e) {
   3460                     if (!mInstrumentation.onException(r.activity, e)) {
   3461                         throw new RuntimeException(
   3462                                 "Unable to retain activity "
   3463                                 + r.intent.getComponent().toShortString()
   3464                                 + ": " + e.toString(), e);
   3465                     }
   3466                 }
   3467             }
   3468             try {
   3469                 r.activity.mCalled = false;
   3470                 mInstrumentation.callActivityOnDestroy(r.activity);
   3471                 if (!r.activity.mCalled) {
   3472                     throw new SuperNotCalledException(
   3473                         "Activity " + safeToComponentShortString(r.intent) +
   3474                         " did not call through to super.onDestroy()");
   3475                 }
   3476                 if (r.window != null) {
   3477                     r.window.closeAllPanels();
   3478                 }
   3479             } catch (SuperNotCalledException e) {
   3480                 throw e;
   3481             } catch (Exception e) {
   3482                 if (!mInstrumentation.onException(r.activity, e)) {
   3483                     throw new RuntimeException(
   3484                             "Unable to destroy activity " + safeToComponentShortString(r.intent)
   3485                             + ": " + e.toString(), e);
   3486                 }
   3487             }
   3488         }
   3489         mActivities.remove(token);
   3490         StrictMode.decrementExpectedActivityCount(activityClass);
   3491         return r;
   3492     }
   3493 
   3494     private static String safeToComponentShortString(Intent intent) {
   3495         ComponentName component = intent.getComponent();
   3496         return component == null ? "[Unknown]" : component.toShortString();
   3497     }
   3498 
   3499     private void handleDestroyActivity(IBinder token, boolean finishing,
   3500             int configChanges, boolean getNonConfigInstance) {
   3501         ActivityClientRecord r = performDestroyActivity(token, finishing,
   3502                 configChanges, getNonConfigInstance);
   3503         if (r != null) {
   3504             cleanUpPendingRemoveWindows(r);
   3505             WindowManager wm = r.activity.getWindowManager();
   3506             View v = r.activity.mDecor;
   3507             if (v != null) {
   3508                 if (r.activity.mVisibleFromServer) {
   3509                     mNumVisibleActivities--;
   3510                 }
   3511                 IBinder wtoken = v.getWindowToken();
   3512                 if (r.activity.mWindowAdded) {
   3513                     if (r.onlyLocalRequest) {
   3514                         // Hold off on removing this until the new activity's
   3515                         // window is being added.
   3516                         r.mPendingRemoveWindow = v;
   3517                         r.mPendingRemoveWindowManager = wm;
   3518                     } else {
   3519                         wm.removeViewImmediate(v);
   3520                     }
   3521                 }
   3522                 if (wtoken != null && r.mPendingRemoveWindow == null) {
   3523                     WindowManagerGlobal.getInstance().closeAll(wtoken,
   3524                             r.activity.getClass().getName(), "Activity");
   3525                 }
   3526                 r.activity.mDecor = null;
   3527             }
   3528             if (r.mPendingRemoveWindow == null) {
   3529                 // If we are delaying the removal of the activity window, then
   3530                 // we can't clean up all windows here.  Note that we can't do
   3531                 // so later either, which means any windows that aren't closed
   3532                 // by the app will leak.  Well we try to warning them a lot
   3533                 // about leaking windows, because that is a bug, so if they are
   3534                 // using this recreate facility then they get to live with leaks.
   3535                 WindowManagerGlobal.getInstance().closeAll(token,
   3536                         r.activity.getClass().getName(), "Activity");
   3537             }
   3538 
   3539             // Mocked out contexts won't be participating in the normal
   3540             // process lifecycle, but if we're running with a proper
   3541             // ApplicationContext we need to have it tear down things
   3542             // cleanly.
   3543             Context c = r.activity.getBaseContext();
   3544             if (c instanceof ContextImpl) {
   3545                 ((ContextImpl) c).scheduleFinalCleanup(
   3546                         r.activity.getClass().getName(), "Activity");
   3547             }
   3548         }
   3549         if (finishing) {
   3550             try {
   3551                 ActivityManagerNative.getDefault().activityDestroyed(token);
   3552             } catch (RemoteException ex) {
   3553                 // If the system process has died, it's game over for everyone.
   3554             }
   3555         }
   3556     }
   3557 
   3558     public final void requestRelaunchActivity(IBinder token,
   3559             List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
   3560             int configChanges, boolean notResumed, Configuration config,
   3561             boolean fromServer) {
   3562         ActivityClientRecord target = null;
   3563 
   3564         synchronized (mResourcesManager) {
   3565             for (int i=0; i<mRelaunchingActivities.size(); i++) {
   3566                 ActivityClientRecord r = mRelaunchingActivities.get(i);
   3567                 if (r.token == token) {
   3568                     target = r;
   3569                     if (pendingResults != null) {
   3570                         if (r.pendingResults != null) {
   3571                             r.pendingResults.addAll(pendingResults);
   3572                         } else {
   3573                             r.pendingResults = pendingResults;
   3574                         }
   3575                     }
   3576                     if (pendingNewIntents != null) {
   3577                         if (r.pendingIntents != null) {
   3578                             r.pendingIntents.addAll(pendingNewIntents);
   3579                         } else {
   3580                             r.pendingIntents = pendingNewIntents;
   3581                         }
   3582                     }
   3583                     break;
   3584                 }
   3585             }
   3586 
   3587             if (target == null) {
   3588                 target = new ActivityClientRecord();
   3589                 target.token = token;
   3590                 target.pendingResults = pendingResults;
   3591                 target.pendingIntents = pendingNewIntents;
   3592                 if (!fromServer) {
   3593                     ActivityClientRecord existing = mActivities.get(token);
   3594                     if (existing != null) {
   3595                         target.startsNotResumed = existing.paused;
   3596                     }
   3597                     target.onlyLocalRequest = true;
   3598                 }
   3599                 mRelaunchingActivities.add(target);
   3600                 sendMessage(H.RELAUNCH_ACTIVITY, target);
   3601             }
   3602 
   3603             if (fromServer) {
   3604                 target.startsNotResumed = notResumed;
   3605                 target.onlyLocalRequest = false;
   3606             }
   3607             if (config != null) {
   3608                 target.createdConfig = config;
   3609             }
   3610             target.pendingConfigChanges |= configChanges;
   3611         }
   3612     }
   3613 
   3614     private void handleRelaunchActivity(ActivityClientRecord tmp) {
   3615         // If we are getting ready to gc after going to the background, well
   3616         // we are back active so skip it.
   3617         unscheduleGcIdler();
   3618 
   3619         Configuration changedConfig = null;
   3620         int configChanges = 0;
   3621 
   3622         // First: make sure we have the most recent configuration and most
   3623         // recent version of the activity, or skip it if some previous call
   3624         // had taken a more recent version.
   3625         synchronized (mResourcesManager) {
   3626             int N = mRelaunchingActivities.size();
   3627             IBinder token = tmp.token;
   3628             tmp = null;
   3629             for (int i=0; i<N; i++) {
   3630                 ActivityClientRecord r = mRelaunchingActivities.get(i);
   3631                 if (r.token == token) {
   3632                     tmp = r;
   3633                     configChanges |= tmp.pendingConfigChanges;
   3634                     mRelaunchingActivities.remove(i);
   3635                     i--;
   3636                     N--;
   3637                 }
   3638             }
   3639 
   3640             if (tmp == null) {
   3641                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
   3642                 return;
   3643             }
   3644 
   3645             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
   3646                     + tmp.token + " with configChanges=0x"
   3647                     + Integer.toHexString(configChanges));
   3648 
   3649             if (mPendingConfiguration != null) {
   3650                 changedConfig = mPendingConfiguration;
   3651                 mPendingConfiguration = null;
   3652             }
   3653         }
   3654 
   3655         if (tmp.createdConfig != null) {
   3656             // If the activity manager is passing us its current config,
   3657             // assume that is really what we want regardless of what we
   3658             // may have pending.
   3659             if (mConfiguration == null
   3660                     || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
   3661                             && mConfiguration.diff(tmp.createdConfig) != 0)) {
   3662                 if (changedConfig == null
   3663                         || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
   3664                     changedConfig = tmp.createdConfig;
   3665                 }
   3666             }
   3667         }
   3668 
   3669         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
   3670                 + tmp.token + ": changedConfig=" + changedConfig);
   3671 
   3672         // If there was a pending configuration change, execute it first.
   3673         if (changedConfig != null) {
   3674             mCurDefaultDisplayDpi = changedConfig.densityDpi;
   3675             updateDefaultDensity();
   3676             handleConfigurationChanged(changedConfig, null);
   3677         }
   3678 
   3679         ActivityClientRecord r = mActivities.get(tmp.token);
   3680         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
   3681         if (r == null) {
   3682             return;
   3683         }
   3684 
   3685         r.activity.mConfigChangeFlags |= configChanges;
   3686         r.onlyLocalRequest = tmp.onlyLocalRequest;
   3687         Intent currentIntent = r.activity.mIntent;
   3688 
   3689         r.activity.mChangingConfigurations = true;
   3690 
   3691         // Need to ensure state is saved.
   3692         if (!r.paused) {
   3693             performPauseActivity(r.token, false, r.isPreHoneycomb());
   3694         }
   3695         if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
   3696             r.state = new Bundle();
   3697             r.state.setAllowFds(false);
   3698             mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
   3699         }
   3700 
   3701         handleDestroyActivity(r.token, false, configChanges, true);
   3702 
   3703         r.activity = null;
   3704         r.window = null;
   3705         r.hideForNow = false;
   3706         r.nextIdle = null;
   3707         // Merge any pending results and pending intents; don't just replace them
   3708         if (tmp.pendingResults != null) {
   3709             if (r.pendingResults == null) {
   3710                 r.pendingResults = tmp.pendingResults;
   3711             } else {
   3712                 r.pendingResults.addAll(tmp.pendingResults);
   3713             }
   3714         }
   3715         if (tmp.pendingIntents != null) {
   3716             if (r.pendingIntents == null) {
   3717                 r.pendingIntents = tmp.pendingIntents;
   3718             } else {
   3719                 r.pendingIntents.addAll(tmp.pendingIntents);
   3720             }
   3721         }
   3722         r.startsNotResumed = tmp.startsNotResumed;
   3723 
   3724         handleLaunchActivity(r, currentIntent);
   3725     }
   3726 
   3727     private void handleRequestThumbnail(IBinder token) {
   3728         ActivityClientRecord r = mActivities.get(token);
   3729         Bitmap thumbnail = createThumbnailBitmap(r);
   3730         CharSequence description = null;
   3731         try {
   3732             description = r.activity.onCreateDescription();
   3733         } catch (Exception e) {
   3734             if (!mInstrumentation.onException(r.activity, e)) {
   3735                 throw new RuntimeException(
   3736                         "Unable to create description of activity "
   3737                         + r.intent.getComponent().toShortString()
   3738                         + ": " + e.toString(), e);
   3739             }
   3740         }
   3741         //System.out.println("Reporting top thumbnail " + thumbnail);
   3742         try {
   3743             ActivityManagerNative.getDefault().reportThumbnail(
   3744                 token, thumbnail, description);
   3745         } catch (RemoteException ex) {
   3746         }
   3747     }
   3748 
   3749     ArrayList<ComponentCallbacks2> collectComponentCallbacks(
   3750             boolean allActivities, Configuration newConfig) {
   3751         ArrayList<ComponentCallbacks2> callbacks
   3752                 = new ArrayList<ComponentCallbacks2>();
   3753 
   3754         synchronized (mResourcesManager) {
   3755             final int NAPP = mAllApplications.size();
   3756             for (int i=0; i<NAPP; i++) {
   3757                 callbacks.add(mAllApplications.get(i));
   3758             }
   3759             final int NACT = mActivities.size();
   3760             for (int i=0; i<NACT; i++) {
   3761                 ActivityClientRecord ar = mActivities.valueAt(i);
   3762                 Activity a = ar.activity;
   3763                 if (a != null) {
   3764                     Configuration thisConfig = applyConfigCompatMainThread(
   3765                             mCurDefaultDisplayDpi, newConfig,
   3766                             ar.packageInfo.getCompatibilityInfo());
   3767                     if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
   3768                         // If the activity is currently resumed, its configuration
   3769                         // needs to change right now.
   3770                         callbacks.add(a);
   3771                     } else if (thisConfig != null) {
   3772                         // Otherwise, we will tell it about the change
   3773                         // the next time it is resumed or shown.  Note that
   3774                         // the activity manager may, before then, decide the
   3775                         // activity needs to be destroyed to handle its new
   3776                         // configuration.
   3777                         if (DEBUG_CONFIGURATION) {
   3778                             Slog.v(TAG, "Setting activity "
   3779                                     + ar.activityInfo.name + " newConfig=" + thisConfig);
   3780                         }
   3781                         ar.newConfig = thisConfig;
   3782                     }
   3783                 }
   3784             }
   3785             final int NSVC = mServices.size();
   3786             for (int i=0; i<NSVC; i++) {
   3787                 callbacks.add(mServices.valueAt(i));
   3788             }
   3789         }
   3790         synchronized (mProviderMap) {
   3791             final int NPRV = mLocalProviders.size();
   3792             for (int i=0; i<NPRV; i++) {
   3793                 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
   3794             }
   3795         }
   3796 
   3797         return callbacks;
   3798     }
   3799 
   3800     private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
   3801         // Only for Activity objects, check that they actually call up to their
   3802         // superclass implementation.  ComponentCallbacks2 is an interface, so
   3803         // we check the runtime type and act accordingly.
   3804         Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
   3805         if (activity != null) {
   3806             activity.mCalled = false;
   3807         }
   3808 
   3809         boolean shouldChangeConfig = false;
   3810         if ((activity == null) || (activity.mCurrentConfig == null)) {
   3811             shouldChangeConfig = true;
   3812         } else {
   3813 
   3814             // If the new config is the same as the config this Activity
   3815             // is already running with then don't bother calling
   3816             // onConfigurationChanged
   3817             int diff = activity.mCurrentConfig.diff(config);
   3818             if (diff != 0) {
   3819                 // If this activity doesn't handle any of the config changes
   3820                 // then don't bother calling onConfigurationChanged as we're
   3821                 // going to destroy it.
   3822                 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
   3823                     shouldChangeConfig = true;
   3824                 }
   3825             }
   3826         }
   3827 
   3828         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
   3829                 + ": shouldChangeConfig=" + shouldChangeConfig);
   3830         if (shouldChangeConfig) {
   3831             cb.onConfigurationChanged(config);
   3832 
   3833             if (activity != null) {
   3834                 if (!activity.mCalled) {
   3835                     throw new SuperNotCalledException(
   3836                             "Activity " + activity.getLocalClassName() +
   3837                         " did not call through to super.onConfigurationChanged()");
   3838                 }
   3839                 activity.mConfigChangeFlags = 0;
   3840                 activity.mCurrentConfig = new Configuration(config);
   3841             }
   3842         }
   3843     }
   3844 
   3845     public final void applyConfigurationToResources(Configuration config) {
   3846         synchronized (mResourcesManager) {
   3847             mResourcesManager.applyConfigurationToResourcesLocked(config, null);
   3848         }
   3849     }
   3850 
   3851     final Configuration applyCompatConfiguration(int displayDensity) {
   3852         Configuration config = mConfiguration;
   3853         if (mCompatConfiguration == null) {
   3854             mCompatConfiguration = new Configuration();
   3855         }
   3856         mCompatConfiguration.setTo(mConfiguration);
   3857         if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
   3858             config = mCompatConfiguration;
   3859         }
   3860         return config;
   3861     }
   3862 
   3863     final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
   3864 
   3865         int configDiff = 0;
   3866 
   3867         synchronized (mResourcesManager) {
   3868             if (mPendingConfiguration != null) {
   3869                 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
   3870                     config = mPendingConfiguration;
   3871                     mCurDefaultDisplayDpi = config.densityDpi;
   3872                     updateDefaultDensity();
   3873                 }
   3874                 mPendingConfiguration = null;
   3875             }
   3876 
   3877             if (config == null) {
   3878                 return;
   3879             }
   3880 
   3881             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
   3882                     + config);
   3883 
   3884             mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
   3885 
   3886             if (mConfiguration == null) {
   3887                 mConfiguration = new Configuration();
   3888             }
   3889             if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
   3890                 return;
   3891             }
   3892             configDiff = mConfiguration.diff(config);
   3893             mConfiguration.updateFrom(config);
   3894             config = applyCompatConfiguration(mCurDefaultDisplayDpi);
   3895         }
   3896 
   3897         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
   3898 
   3899         // Cleanup hardware accelerated stuff
   3900         WindowManagerGlobal.getInstance().trimLocalMemory();
   3901 
   3902         freeTextLayoutCachesIfNeeded(configDiff);
   3903 
   3904         if (callbacks != null) {
   3905             final int N = callbacks.size();
   3906             for (int i=0; i<N; i++) {
   3907                 performConfigurationChanged(callbacks.get(i), config);
   3908             }
   3909         }
   3910     }
   3911 
   3912     static void freeTextLayoutCachesIfNeeded(int configDiff) {
   3913         if (configDiff != 0) {
   3914             // Ask text layout engine to free its caches if there is a locale change
   3915             boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
   3916             if (hasLocaleConfigChange) {
   3917                 Canvas.freeTextLayoutCaches();
   3918                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
   3919             }
   3920         }
   3921     }
   3922 
   3923     final void handleActivityConfigurationChanged(IBinder token) {
   3924         ActivityClientRecord r = mActivities.get(token);
   3925         if (r == null || r.activity == null) {
   3926             return;
   3927         }
   3928 
   3929         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
   3930                 + r.activityInfo.name);
   3931 
   3932         performConfigurationChanged(r.activity, mCompatConfiguration);
   3933 
   3934         freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
   3935     }
   3936 
   3937     final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
   3938         if (start) {
   3939             try {
   3940                 switch (profileType) {
   3941                     default:
   3942                         mProfiler.setProfiler(pcd.path, pcd.fd);
   3943                         mProfiler.autoStopProfiler = false;
   3944                         mProfiler.startProfiling();
   3945                         break;
   3946                 }
   3947             } catch (RuntimeException e) {
   3948                 Slog.w(TAG, "Profiling failed on path " + pcd.path
   3949                         + " -- can the process access this path?");
   3950             } finally {
   3951                 try {
   3952                     pcd.fd.close();
   3953                 } catch (IOException e) {
   3954                     Slog.w(TAG, "Failure closing profile fd", e);
   3955                 }
   3956             }
   3957         } else {
   3958             switch (profileType) {
   3959                 default:
   3960                     mProfiler.stopProfiling();
   3961                     break;
   3962             }
   3963         }
   3964     }
   3965 
   3966     static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
   3967         if (managed) {
   3968             try {
   3969                 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
   3970             } catch (IOException e) {
   3971                 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
   3972                         + " -- can the process access this path?");
   3973             } finally {
   3974                 try {
   3975                     dhd.fd.close();
   3976                 } catch (IOException e) {
   3977                     Slog.w(TAG, "Failure closing profile fd", e);
   3978                 }
   3979             }
   3980         } else {
   3981             Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
   3982         }
   3983     }
   3984 
   3985     final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
   3986         boolean hasPkgInfo = false;
   3987         if (packages != null) {
   3988             for (int i=packages.length-1; i>=0; i--) {
   3989                 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
   3990                 if (!hasPkgInfo) {
   3991                     WeakReference<LoadedApk> ref;
   3992                     ref = mPackages.get(packages[i]);
   3993                     if (ref != null && ref.get() != null) {
   3994                         hasPkgInfo = true;
   3995                     } else {
   3996                         ref = mResourcePackages.get(packages[i]);
   3997                         if (ref != null && ref.get() != null) {
   3998                             hasPkgInfo = true;
   3999                         }
   4000                     }
   4001                 }
   4002                 mPackages.remove(packages[i]);
   4003                 mResourcePackages.remove(packages[i]);
   4004             }
   4005         }
   4006         ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
   4007                 hasPkgInfo);
   4008     }
   4009 
   4010     final void handleLowMemory() {
   4011         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
   4012 
   4013         final int N = callbacks.size();
   4014         for (int i=0; i<N; i++) {
   4015             callbacks.get(i).onLowMemory();
   4016         }
   4017 
   4018         // Ask SQLite to free up as much memory as it can, mostly from its page caches.
   4019         if (Process.myUid() != Process.SYSTEM_UID) {
   4020             int sqliteReleased = SQLiteDatabase.releaseMemory();
   4021             EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
   4022         }
   4023 
   4024         // Ask graphics to free up as much as possible (font/image caches)
   4025         Canvas.freeCaches();
   4026 
   4027         // Ask text layout engine to free also as much as possible
   4028         Canvas.freeTextLayoutCaches();
   4029 
   4030         BinderInternal.forceGc("mem");
   4031     }
   4032 
   4033     final void handleTrimMemory(int level) {
   4034         if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
   4035 
   4036         final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
   4037         windowManager.startTrimMemory(level);
   4038 
   4039         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
   4040 
   4041         final int N = callbacks.size();
   4042         for (int i = 0; i < N; i++) {
   4043             callbacks.get(i).onTrimMemory(level);
   4044         }
   4045 
   4046         windowManager.endTrimMemory();
   4047     }
   4048 
   4049     private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
   4050         if (Process.isIsolated()) {
   4051             // Isolated processes aren't going to do UI.
   4052             return;
   4053         }
   4054         try {
   4055             int uid = Process.myUid();
   4056             String[] packages = getPackageManager().getPackagesForUid(uid);
   4057 
   4058             // If there are several packages in this application we won't
   4059             // initialize the graphics disk caches
   4060             if (packages != null && packages.length == 1) {
   4061                 HardwareRenderer.setupDiskCache(cacheDir);
   4062                 RenderScript.setupDiskCache(cacheDir);
   4063             }
   4064         } catch (RemoteException e) {
   4065             // Ignore
   4066         }
   4067     }
   4068 
   4069     private void updateDefaultDensity() {
   4070         if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
   4071                 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
   4072                 && !mDensityCompatMode) {
   4073             Slog.i(TAG, "Switching default density from "
   4074                     + DisplayMetrics.DENSITY_DEVICE + " to "
   4075                     + mCurDefaultDisplayDpi);
   4076             DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
   4077             Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
   4078         }
   4079     }
   4080 
   4081     private void handleBindApplication(AppBindData data) {
   4082         mBoundApplication = data;
   4083         mConfiguration = new Configuration(data.config);
   4084         mCompatConfiguration = new Configuration(data.config);
   4085 
   4086         mProfiler = new Profiler();
   4087         mProfiler.profileFile = data.initProfileFile;
   4088         mProfiler.profileFd = data.initProfileFd;
   4089         mProfiler.autoStopProfiler = data.initAutoStopProfiler;
   4090 
   4091         // send up app name; do this *before* waiting for debugger
   4092         Process.setArgV0(data.processName);
   4093         android.ddm.DdmHandleAppName.setAppName(data.processName,
   4094                                                 UserHandle.myUserId());
   4095 
   4096         if (data.persistent) {
   4097             // Persistent processes on low-memory devices do not get to
   4098             // use hardware accelerated drawing, since this can add too much
   4099             // overhead to the process.
   4100             if (!ActivityManager.isHighEndGfx()) {
   4101                 HardwareRenderer.disable(false);
   4102             }
   4103         }
   4104 
   4105         if (mProfiler.profileFd != null) {
   4106             mProfiler.startProfiling();
   4107         }
   4108 
   4109         // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
   4110         // implementation to use the pool executor.  Normally, we use the
   4111         // serialized executor as the default. This has to happen in the
   4112         // main thread so the main looper is set right.
   4113         if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
   4114             AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
   4115         }
   4116 
   4117         /*
   4118          * Before spawning a new process, reset the time zone to be the system time zone.
   4119          * This needs to be done because the system time zone could have changed after the
   4120          * the spawning of this process. Without doing this this process would have the incorrect
   4121          * system time zone.
   4122          */
   4123         TimeZone.setDefault(null);
   4124 
   4125         /*
   4126          * Initialize the default locale in this process for the reasons we set the time zone.
   4127          */
   4128         Locale.setDefault(data.config.locale);
   4129 
   4130         /*
   4131          * Update the system configuration since its preloaded and might not
   4132          * reflect configuration changes. The configuration object passed
   4133          * in AppBindData can be safely assumed to be up to date
   4134          */
   4135         mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
   4136         mCurDefaultDisplayDpi = data.config.densityDpi;
   4137         applyCompatConfiguration(mCurDefaultDisplayDpi);
   4138 
   4139         data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
   4140 
   4141         /**
   4142          * Switch this process to density compatibility mode if needed.
   4143          */
   4144         if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
   4145                 == 0) {
   4146             mDensityCompatMode = true;
   4147             Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
   4148         }
   4149         updateDefaultDensity();
   4150 
   4151         final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
   4152         if (!Process.isIsolated()) {
   4153             final File cacheDir = appContext.getCacheDir();
   4154 
   4155             if (cacheDir != null) {
   4156                 // Provide a usable directory for temporary files
   4157                 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
   4158 
   4159                 setupGraphicsSupport(data.info, cacheDir);
   4160             } else {
   4161                 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
   4162             }
   4163         }
   4164         /**
   4165          * For system applications on userdebug/eng builds, log stack
   4166          * traces of disk and network access to dropbox for analysis.
   4167          */
   4168         if ((data.appInfo.flags &
   4169              (ApplicationInfo.FLAG_SYSTEM |
   4170               ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
   4171             StrictMode.conditionallyEnableDebugLogging();
   4172         }
   4173 
   4174         /**
   4175          * For apps targetting SDK Honeycomb or later, we don't allow
   4176          * network usage on the main event loop / UI thread.
   4177          *
   4178          * Note to those grepping:  this is what ultimately throws
   4179          * NetworkOnMainThreadException ...
   4180          */
   4181         if (data.appInfo.targetSdkVersion > 9) {
   4182             StrictMode.enableDeathOnNetwork();
   4183         }
   4184 
   4185         if (data.debugMode != IApplicationThread.DEBUG_OFF) {
   4186             // XXX should have option to change the port.
   4187             Debug.changeDebugPort(8100);
   4188             if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
   4189                 Slog.w(TAG, "Application " + data.info.getPackageName()
   4190                       + " is waiting for the debugger on port 8100...");
   4191 
   4192                 IActivityManager mgr = ActivityManagerNative.getDefault();
   4193                 try {
   4194                     mgr.showWaitingForDebugger(mAppThread, true);
   4195                 } catch (RemoteException ex) {
   4196                 }
   4197 
   4198                 Debug.waitForDebugger();
   4199 
   4200                 try {
   4201                     mgr.showWaitingForDebugger(mAppThread, false);
   4202                 } catch (RemoteException ex) {
   4203                 }
   4204 
   4205             } else {
   4206                 Slog.w(TAG, "Application " + data.info.getPackageName()
   4207                       + " can be debugged on port 8100...");
   4208             }
   4209         }
   4210 
   4211         // Enable OpenGL tracing if required
   4212         if (data.enableOpenGlTrace) {
   4213             GLUtils.setTracingLevel(1);
   4214         }
   4215 
   4216         // Allow application-generated systrace messages if we're debuggable.
   4217         boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
   4218         Trace.setAppTracingAllowed(appTracingAllowed);
   4219 
   4220         /**
   4221          * Initialize the default http proxy in this process for the reasons we set the time zone.
   4222          */
   4223         IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
   4224         if (b != null) {
   4225             // In pre-boot mode (doing initial launch to collect password), not
   4226             // all system is up.  This includes the connectivity service, so don't
   4227             // crash if we can't get it.
   4228             IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
   4229             try {
   4230                 ProxyProperties proxyProperties = service.getProxy();
   4231                 Proxy.setHttpProxySystemProperty(proxyProperties);
   4232             } catch (RemoteException e) {}
   4233         }
   4234 
   4235         if (data.instrumentationName != null) {
   4236             InstrumentationInfo ii = null;
   4237             try {
   4238                 ii = appContext.getPackageManager().
   4239                     getInstrumentationInfo(data.instrumentationName, 0);
   4240             } catch (PackageManager.NameNotFoundException e) {
   4241             }
   4242             if (ii == null) {
   4243                 throw new RuntimeException(
   4244                     "Unable to find instrumentation info for: "
   4245                     + data.instrumentationName);
   4246             }
   4247 
   4248             mInstrumentationAppDir = ii.sourceDir;
   4249             mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
   4250             mInstrumentationAppPackage = ii.packageName;
   4251             mInstrumentedAppDir = data.info.getAppDir();
   4252             mInstrumentedAppLibraryDir = data.info.getLibDir();
   4253 
   4254             ApplicationInfo instrApp = new ApplicationInfo();
   4255             instrApp.packageName = ii.packageName;
   4256             instrApp.sourceDir = ii.sourceDir;
   4257             instrApp.publicSourceDir = ii.publicSourceDir;
   4258             instrApp.dataDir = ii.dataDir;
   4259             instrApp.nativeLibraryDir = ii.nativeLibraryDir;
   4260             LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
   4261                     appContext.getClassLoader(), false, true);
   4262             ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
   4263 
   4264             try {
   4265                 java.lang.ClassLoader cl = instrContext.getClassLoader();
   4266                 mInstrumentation = (Instrumentation)
   4267                     cl.loadClass(data.instrumentationName.getClassName()).newInstance();
   4268             } catch (Exception e) {
   4269                 throw new RuntimeException(
   4270                     "Unable to instantiate instrumentation "
   4271                     + data.instrumentationName + ": " + e.toString(), e);
   4272             }
   4273 
   4274             mInstrumentation.init(this, instrContext, appContext,
   4275                    new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
   4276                    data.instrumentationUiAutomationConnection);
   4277 
   4278             if (mProfiler.profileFile != null && !ii.handleProfiling
   4279                     && mProfiler.profileFd == null) {
   4280                 mProfiler.handlingProfiling = true;
   4281                 File file = new File(mProfiler.profileFile);
   4282                 file.getParentFile().mkdirs();
   4283                 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
   4284             }
   4285 
   4286         } else {
   4287             mInstrumentation = new Instrumentation();
   4288         }
   4289 
   4290         if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
   4291             dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
   4292         }
   4293 
   4294         // Allow disk access during application and provider setup. This could
   4295         // block processing ordered broadcasts, but later processing would
   4296         // probably end up doing the same disk access.
   4297         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
   4298         try {
   4299             // If the app is being launched for full backup or restore, bring it up in
   4300             // a restricted environment with the base application class.
   4301             Application app = data.info.makeApplication(data.restrictedBackupMode, null);
   4302             mInitialApplication = app;
   4303 
   4304             // don't bring up providers in restricted mode; they may depend on the
   4305             // app's custom Application class
   4306             if (!data.restrictedBackupMode) {
   4307                 List<ProviderInfo> providers = data.providers;
   4308                 if (providers != null) {
   4309                     installContentProviders(app, providers);
   4310                     // For process that contains content providers, we want to
   4311                     // ensure that the JIT is enabled "at some point".
   4312                     mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
   4313                 }
   4314             }
   4315 
   4316             // Do this after providers, since instrumentation tests generally start their
   4317             // test thread at this point, and we don't want that racing.
   4318             try {
   4319                 mInstrumentation.onCreate(data.instrumentationArgs);
   4320             }
   4321             catch (Exception e) {
   4322                 throw new RuntimeException(
   4323                     "Exception thrown in onCreate() of "
   4324                     + data.instrumentationName + ": " + e.toString(), e);
   4325             }
   4326 
   4327             try {
   4328                 mInstrumentation.callApplicationOnCreate(app);
   4329             } catch (Exception e) {
   4330                 if (!mInstrumentation.onException(app, e)) {
   4331                     throw new RuntimeException(
   4332                         "Unable to create application " + app.getClass().getName()
   4333                         + ": " + e.toString(), e);
   4334                 }
   4335             }
   4336         } finally {
   4337             StrictMode.setThreadPolicy(savedPolicy);
   4338         }
   4339     }
   4340 
   4341     /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
   4342         IActivityManager am = ActivityManagerNative.getDefault();
   4343         if (mProfiler.profileFile != null && mProfiler.handlingProfiling
   4344                 && mProfiler.profileFd == null) {
   4345             Debug.stopMethodTracing();
   4346         }
   4347         //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
   4348         //      + ", app thr: " + mAppThread);
   4349         try {
   4350             am.finishInstrumentation(mAppThread, resultCode, results);
   4351         } catch (RemoteException ex) {
   4352         }
   4353     }
   4354 
   4355     private void installContentProviders(
   4356             Context context, List<ProviderInfo> providers) {
   4357         final ArrayList<IActivityManager.ContentProviderHolder> results =
   4358             new ArrayList<IActivityManager.ContentProviderHolder>();
   4359 
   4360         for (ProviderInfo cpi : providers) {
   4361             if (DEBUG_PROVIDER) {
   4362                 StringBuilder buf = new StringBuilder(128);
   4363                 buf.append("Pub ");
   4364                 buf.append(cpi.authority);
   4365                 buf.append(": ");
   4366                 buf.append(cpi.name);
   4367                 Log.i(TAG, buf.toString());
   4368             }
   4369             IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
   4370                     false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
   4371             if (cph != null) {
   4372                 cph.noReleaseNeeded = true;
   4373                 results.add(cph);
   4374             }
   4375         }
   4376 
   4377         try {
   4378             ActivityManagerNative.getDefault().publishContentProviders(
   4379                 getApplicationThread(), results);
   4380         } catch (RemoteException ex) {
   4381         }
   4382     }
   4383 
   4384     public final IContentProvider acquireProvider(
   4385             Context c, String auth, int userId, boolean stable) {
   4386         final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
   4387         if (provider != null) {
   4388             return provider;
   4389         }
   4390 
   4391         // There is a possible race here.  Another thread may try to acquire
   4392         // the same provider at the same time.  When this happens, we want to ensure
   4393         // that the first one wins.
   4394         // Note that we cannot hold the lock while acquiring and installing the
   4395         // provider since it might take a long time to run and it could also potentially
   4396         // be re-entrant in the case where the provider is in the same process.
   4397         IActivityManager.ContentProviderHolder holder = null;
   4398         try {
   4399             holder = ActivityManagerNative.getDefault().getContentProvider(
   4400                     getApplicationThread(), auth, userId, stable);
   4401         } catch (RemoteException ex) {
   4402         }
   4403         if (holder == null) {
   4404             Slog.e(TAG, "Failed to find provider info for " + auth);
   4405             return null;
   4406         }
   4407 
   4408         // Install provider will increment the reference count for us, and break
   4409         // any ties in the race.
   4410         holder = installProvider(c, holder, holder.info,
   4411                 true /*noisy*/, holder.noReleaseNeeded, stable);
   4412         return holder.provider;
   4413     }
   4414 
   4415     private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
   4416         if (stable) {
   4417             prc.stableCount += 1;
   4418             if (prc.stableCount == 1) {
   4419                 // We are acquiring a new stable reference on the provider.
   4420                 int unstableDelta;
   4421                 if (prc.removePending) {
   4422                     // We have a pending remove operation, which is holding the
   4423                     // last unstable reference.  At this point we are converting
   4424                     // that unstable reference to our new stable reference.
   4425                     unstableDelta = -1;
   4426                     // Cancel the removal of the provider.
   4427                     if (DEBUG_PROVIDER) {
   4428                         Slog.v(TAG, "incProviderRef: stable "
   4429                                 + "snatched provider from the jaws of death");
   4430                     }
   4431                     prc.removePending = false;
   4432                     // There is a race! It fails to remove the message, which
   4433                     // will be handled in completeRemoveProvider().
   4434                     mH.removeMessages(H.REMOVE_PROVIDER, prc);
   4435                 } else {
   4436                     unstableDelta = 0;
   4437                 }
   4438                 try {
   4439                     if (DEBUG_PROVIDER) {
   4440                         Slog.v(TAG, "incProviderRef Now stable - "
   4441                                 + prc.holder.info.name + ": unstableDelta="
   4442                                 + unstableDelta);
   4443                     }
   4444                     ActivityManagerNative.getDefault().refContentProvider(
   4445                             prc.holder.connection, 1, unstableDelta);
   4446                 } catch (RemoteException e) {
   4447                     //do nothing content provider object is dead any way
   4448                 }
   4449             }
   4450         } else {
   4451             prc.unstableCount += 1;
   4452             if (prc.unstableCount == 1) {
   4453                 // We are acquiring a new unstable reference on the provider.
   4454                 if (prc.removePending) {
   4455                     // Oh look, we actually have a remove pending for the
   4456                     // provider, which is still holding the last unstable
   4457                     // reference.  We just need to cancel that to take new
   4458                     // ownership of the reference.
   4459                     if (DEBUG_PROVIDER) {
   4460                         Slog.v(TAG, "incProviderRef: unstable "
   4461                                 + "snatched provider from the jaws of death");
   4462                     }
   4463                     prc.removePending = false;
   4464                     mH.removeMessages(H.REMOVE_PROVIDER, prc);
   4465                 } else {
   4466                     // First unstable ref, increment our count in the
   4467                     // activity manager.
   4468                     try {
   4469                         if (DEBUG_PROVIDER) {
   4470                             Slog.v(TAG, "incProviderRef: Now unstable - "
   4471                                     + prc.holder.info.name);
   4472                         }
   4473                         ActivityManagerNative.getDefault().refContentProvider(
   4474                                 prc.holder.connection, 0, 1);
   4475                     } catch (RemoteException e) {
   4476                         //do nothing content provider object is dead any way
   4477                     }
   4478                 }
   4479             }
   4480         }
   4481     }
   4482 
   4483     public final IContentProvider acquireExistingProvider(
   4484             Context c, String auth, int userId, boolean stable) {
   4485         synchronized (mProviderMap) {
   4486             final ProviderKey key = new ProviderKey(auth, userId);
   4487             final ProviderClientRecord pr = mProviderMap.get(key);
   4488             if (pr == null) {
   4489                 return null;
   4490             }
   4491 
   4492             IContentProvider provider = pr.mProvider;
   4493             IBinder jBinder = provider.asBinder();
   4494             if (!jBinder.isBinderAlive()) {
   4495                 // The hosting process of the provider has died; we can't
   4496                 // use this one.
   4497                 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
   4498                         + ": existing object's process dead");
   4499                 handleUnstableProviderDiedLocked(jBinder, true);
   4500                 return null;
   4501             }
   4502 
   4503             // Only increment the ref count if we have one.  If we don't then the
   4504             // provider is not reference counted and never needs to be released.
   4505             ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
   4506             if (prc != null) {
   4507                 incProviderRefLocked(prc, stable);
   4508             }
   4509             return provider;
   4510         }
   4511     }
   4512 
   4513     public final boolean releaseProvider(IContentProvider provider, boolean stable) {
   4514         if (provider == null) {
   4515             return false;
   4516         }
   4517 
   4518         IBinder jBinder = provider.asBinder();
   4519         synchronized (mProviderMap) {
   4520             ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
   4521             if (prc == null) {
   4522                 // The provider has no ref count, no release is needed.
   4523                 return false;
   4524             }
   4525 
   4526             boolean lastRef = false;
   4527             if (stable) {
   4528                 if (prc.stableCount == 0) {
   4529                     if (DEBUG_PROVIDER) Slog.v(TAG,
   4530                             "releaseProvider: stable ref count already 0, how?");
   4531                     return false;
   4532                 }
   4533                 prc.stableCount -= 1;
   4534                 if (prc.stableCount == 0) {
   4535                     // What we do at this point depends on whether there are
   4536                     // any unstable refs left: if there are, we just tell the
   4537                     // activity manager to decrement its stable count; if there
   4538                     // aren't, we need to enqueue this provider to be removed,
   4539                     // and convert to holding a single unstable ref while
   4540                     // doing so.
   4541                     lastRef = prc.unstableCount == 0;
   4542                     try {
   4543                         if (DEBUG_PROVIDER) {
   4544                             Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
   4545                                     + lastRef + " - " + prc.holder.info.name);
   4546                         }
   4547                         ActivityManagerNative.getDefault().refContentProvider(
   4548                                 prc.holder.connection, -1, lastRef ? 1 : 0);
   4549                     } catch (RemoteException e) {
   4550                         //do nothing content provider object is dead any way
   4551                     }
   4552                 }
   4553             } else {
   4554                 if (prc.unstableCount == 0) {
   4555                     if (DEBUG_PROVIDER) Slog.v(TAG,
   4556                             "releaseProvider: unstable ref count already 0, how?");
   4557                     return false;
   4558                 }
   4559                 prc.unstableCount -= 1;
   4560                 if (prc.unstableCount == 0) {
   4561                     // If this is the last reference, we need to enqueue
   4562                     // this provider to be removed instead of telling the
   4563                     // activity manager to remove it at this point.
   4564                     lastRef = prc.stableCount == 0;
   4565                     if (!lastRef) {
   4566                         try {
   4567                             if (DEBUG_PROVIDER) {
   4568                                 Slog.v(TAG, "releaseProvider: No longer unstable - "
   4569                                         + prc.holder.info.name);
   4570                             }
   4571                             ActivityManagerNative.getDefault().refContentProvider(
   4572                                     prc.holder.connection, 0, -1);
   4573                         } catch (RemoteException e) {
   4574                             //do nothing content provider object is dead any way
   4575                         }
   4576                     }
   4577                 }
   4578             }
   4579 
   4580             if (lastRef) {
   4581                 if (!prc.removePending) {
   4582                     // Schedule the actual remove asynchronously, since we don't know the context
   4583                     // this will be called in.
   4584                     // TODO: it would be nice to post a delayed message, so
   4585                     // if we come back and need the same provider quickly
   4586                     // we will still have it available.
   4587                     if (DEBUG_PROVIDER) {
   4588                         Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
   4589                                 + prc.holder.info.name);
   4590                     }
   4591                     prc.removePending = true;
   4592                     Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
   4593                     mH.sendMessage(msg);
   4594                 } else {
   4595                     Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
   4596                 }
   4597             }
   4598             return true;
   4599         }
   4600     }
   4601 
   4602     final void completeRemoveProvider(ProviderRefCount prc) {
   4603         synchronized (mProviderMap) {
   4604             if (!prc.removePending) {
   4605                 // There was a race!  Some other client managed to acquire
   4606                 // the provider before the removal was completed.
   4607                 // Abort the removal.  We will do it later.
   4608                 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
   4609                         + "provider still in use");
   4610                 return;
   4611             }
   4612 
   4613             // More complicated race!! Some client managed to acquire the
   4614             // provider and release it before the removal was completed.
   4615             // Continue the removal, and abort the next remove message.
   4616             prc.removePending = false;
   4617 
   4618             final IBinder jBinder = prc.holder.provider.asBinder();
   4619             ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
   4620             if (existingPrc == prc) {
   4621                 mProviderRefCountMap.remove(jBinder);
   4622             }
   4623 
   4624             for (int i=mProviderMap.size()-1; i>=0; i--) {
   4625                 ProviderClientRecord pr = mProviderMap.valueAt(i);
   4626                 IBinder myBinder = pr.mProvider.asBinder();
   4627                 if (myBinder == jBinder) {
   4628                     mProviderMap.removeAt(i);
   4629                 }
   4630             }
   4631         }
   4632 
   4633         try {
   4634             if (DEBUG_PROVIDER) {
   4635                 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
   4636                         + "removeContentProvider(" + prc.holder.info.name + ")");
   4637             }
   4638             ActivityManagerNative.getDefault().removeContentProvider(
   4639                     prc.holder.connection, false);
   4640         } catch (RemoteException e) {
   4641             //do nothing content provider object is dead any way
   4642         }
   4643     }
   4644 
   4645     final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
   4646         synchronized (mProviderMap) {
   4647             handleUnstableProviderDiedLocked(provider, fromClient);
   4648         }
   4649     }
   4650 
   4651     final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
   4652         ProviderRefCount prc = mProviderRefCountMap.get(provider);
   4653         if (prc != null) {
   4654             if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
   4655                     + provider + " " + prc.holder.info.name);
   4656             mProviderRefCountMap.remove(provider);
   4657             for (int i=mProviderMap.size()-1; i>=0; i--) {
   4658                 ProviderClientRecord pr = mProviderMap.valueAt(i);
   4659                 if (pr != null && pr.mProvider.asBinder() == provider) {
   4660                     Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
   4661                     mProviderMap.removeAt(i);
   4662                 }
   4663             }
   4664 
   4665             if (fromClient) {
   4666                 // We found out about this due to execution in our client
   4667                 // code.  Tell the activity manager about it now, to ensure
   4668                 // that the next time we go to do anything with the provider
   4669                 // it knows it is dead (so we don't race with its death
   4670                 // notification).
   4671                 try {
   4672                     ActivityManagerNative.getDefault().unstableProviderDied(
   4673                             prc.holder.connection);
   4674                 } catch (RemoteException e) {
   4675                     //do nothing content provider object is dead any way
   4676                 }
   4677             }
   4678         }
   4679     }
   4680 
   4681     final void appNotRespondingViaProvider(IBinder provider) {
   4682         synchronized (mProviderMap) {
   4683             ProviderRefCount prc = mProviderRefCountMap.get(provider);
   4684             if (prc != null) {
   4685                 try {
   4686                     ActivityManagerNative.getDefault()
   4687                             .appNotRespondingViaProvider(prc.holder.connection);
   4688                 } catch (RemoteException e) {
   4689                 }
   4690             }
   4691         }
   4692     }
   4693 
   4694     private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
   4695             ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
   4696         final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
   4697         final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
   4698 
   4699         final ProviderClientRecord pcr = new ProviderClientRecord(
   4700                 auths, provider, localProvider, holder);
   4701         for (String auth : auths) {
   4702             final ProviderKey key = new ProviderKey(auth, userId);
   4703             final ProviderClientRecord existing = mProviderMap.get(key);
   4704             if (existing != null) {
   4705                 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
   4706                         + " already published as " + auth);
   4707             } else {
   4708                 mProviderMap.put(key, pcr);
   4709             }
   4710         }
   4711         return pcr;
   4712     }
   4713 
   4714     /**
   4715      * Installs the provider.
   4716      *
   4717      * Providers that are local to the process or that come from the system server
   4718      * may be installed permanently which is indicated by setting noReleaseNeeded to true.
   4719      * Other remote providers are reference counted.  The initial reference count
   4720      * for all reference counted providers is one.  Providers that are not reference
   4721      * counted do not have a reference count (at all).
   4722      *
   4723      * This method detects when a provider has already been installed.  When this happens,
   4724      * it increments the reference count of the existing provider (if appropriate)
   4725      * and returns the existing provider.  This can happen due to concurrent
   4726      * attempts to acquire the same provider.
   4727      */
   4728     private IActivityManager.ContentProviderHolder installProvider(Context context,
   4729             IActivityManager.ContentProviderHolder holder, ProviderInfo info,
   4730             boolean noisy, boolean noReleaseNeeded, boolean stable) {
   4731         ContentProvider localProvider = null;
   4732         IContentProvider provider;
   4733         if (holder == null || holder.provider == null) {
   4734             if (DEBUG_PROVIDER || noisy) {
   4735                 Slog.d(TAG, "Loading provider " + info.authority + ": "
   4736                         + info.name);
   4737             }
   4738             Context c = null;
   4739             ApplicationInfo ai = info.applicationInfo;
   4740             if (context.getPackageName().equals(ai.packageName)) {
   4741                 c = context;
   4742             } else if (mInitialApplication != null &&
   4743                     mInitialApplication.getPackageName().equals(ai.packageName)) {
   4744                 c = mInitialApplication;
   4745             } else {
   4746                 try {
   4747                     c = context.createPackageContext(ai.packageName,
   4748                             Context.CONTEXT_INCLUDE_CODE);
   4749                 } catch (PackageManager.NameNotFoundException e) {
   4750                     // Ignore
   4751                 }
   4752             }
   4753             if (c == null) {
   4754                 Slog.w(TAG, "Unable to get context for package " +
   4755                       ai.packageName +
   4756                       " while loading content provider " +
   4757                       info.name);
   4758                 return null;
   4759             }
   4760             try {
   4761                 final java.lang.ClassLoader cl = c.getClassLoader();
   4762                 localProvider = (ContentProvider)cl.
   4763                     loadClass(info.name).newInstance();
   4764                 provider = localProvider.getIContentProvider();
   4765                 if (provider == null) {
   4766                     Slog.e(TAG, "Failed to instantiate class " +
   4767                           info.name + " from sourceDir " +
   4768                           info.applicationInfo.sourceDir);
   4769                     return null;
   4770                 }
   4771                 if (DEBUG_PROVIDER) Slog.v(
   4772                     TAG, "Instantiating local provider " + info.name);
   4773                 // XXX Need to create the correct context for this provider.
   4774                 localProvider.attachInfo(c, info);
   4775             } catch (java.lang.Exception e) {
   4776                 if (!mInstrumentation.onException(null, e)) {
   4777                     throw new RuntimeException(
   4778                             "Unable to get provider " + info.name
   4779                             + ": " + e.toString(), e);
   4780                 }
   4781                 return null;
   4782             }
   4783         } else {
   4784             provider = holder.provider;
   4785             if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
   4786                     + info.name);
   4787         }
   4788 
   4789         IActivityManager.ContentProviderHolder retHolder;
   4790 
   4791         synchronized (mProviderMap) {
   4792             if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
   4793                     + " / " + info.name);
   4794             IBinder jBinder = provider.asBinder();
   4795             if (localProvider != null) {
   4796                 ComponentName cname = new ComponentName(info.packageName, info.name);
   4797                 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
   4798                 if (pr != null) {
   4799                     if (DEBUG_PROVIDER) {
   4800                         Slog.v(TAG, "installProvider: lost the race, "
   4801                                 + "using existing local provider");
   4802                     }
   4803                     provider = pr.mProvider;
   4804                 } else {
   4805                     holder = new IActivityManager.ContentProviderHolder(info);
   4806                     holder.provider = provider;
   4807                     holder.noReleaseNeeded = true;
   4808                     pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
   4809                     mLocalProviders.put(jBinder, pr);
   4810                     mLocalProvidersByName.put(cname, pr);
   4811                 }
   4812                 retHolder = pr.mHolder;
   4813             } else {
   4814                 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
   4815                 if (prc != null) {
   4816                     if (DEBUG_PROVIDER) {
   4817                         Slog.v(TAG, "installProvider: lost the race, updating ref count");
   4818                     }
   4819                     // We need to transfer our new reference to the existing
   4820                     // ref count, releasing the old one...  but only if
   4821                     // release is needed (that is, it is not running in the
   4822                     // system process).
   4823                     if (!noReleaseNeeded) {
   4824                         incProviderRefLocked(prc, stable);
   4825                         try {
   4826                             ActivityManagerNative.getDefault().removeContentProvider(
   4827                                     holder.connection, stable);
   4828                         } catch (RemoteException e) {
   4829                             //do nothing content provider object is dead any way
   4830                         }
   4831                     }
   4832                 } else {
   4833                     ProviderClientRecord client = installProviderAuthoritiesLocked(
   4834                             provider, localProvider, holder);
   4835                     if (noReleaseNeeded) {
   4836                         prc = new ProviderRefCount(holder, client, 1000, 1000);
   4837                     } else {
   4838                         prc = stable
   4839                                 ? new ProviderRefCount(holder, client, 1, 0)
   4840                                 : new ProviderRefCount(holder, client, 0, 1);
   4841                     }
   4842                     mProviderRefCountMap.put(jBinder, prc);
   4843                 }
   4844                 retHolder = prc.holder;
   4845             }
   4846         }
   4847 
   4848         return retHolder;
   4849     }
   4850 
   4851     private void attach(boolean system) {
   4852         sCurrentActivityThread = this;
   4853         mSystemThread = system;
   4854         if (!system) {
   4855             ViewRootImpl.addFirstDrawHandler(new Runnable() {
   4856                 @Override
   4857                 public void run() {
   4858                     ensureJitEnabled();
   4859                 }
   4860             });
   4861             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
   4862                                                     UserHandle.myUserId());
   4863             RuntimeInit.setApplicationObject(mAppThread.asBinder());
   4864             IActivityManager mgr = ActivityManagerNative.getDefault();
   4865             try {
   4866                 mgr.attachApplication(mAppThread);
   4867             } catch (RemoteException ex) {
   4868                 // Ignore
   4869             }
   4870         } else {
   4871             // Don't set application object here -- if the system crashes,
   4872             // we can't display an alert, we just want to die die die.
   4873             android.ddm.DdmHandleAppName.setAppName("system_process",
   4874                                                     UserHandle.myUserId());
   4875             try {
   4876                 mInstrumentation = new Instrumentation();
   4877                 ContextImpl context = ContextImpl.createAppContext(
   4878                         this, getSystemContext().mPackageInfo);
   4879                 Application app = Instrumentation.newApplication(Application.class, context);
   4880                 mAllApplications.add(app);
   4881                 mInitialApplication = app;
   4882                 app.onCreate();
   4883             } catch (Exception e) {
   4884                 throw new RuntimeException(
   4885                         "Unable to instantiate Application():" + e.toString(), e);
   4886             }
   4887         }
   4888 
   4889         // add dropbox logging to libcore
   4890         DropBox.setReporter(new DropBoxReporter());
   4891 
   4892         ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
   4893             @Override
   4894             public void onConfigurationChanged(Configuration newConfig) {
   4895                 synchronized (mResourcesManager) {
   4896                     // We need to apply this change to the resources
   4897                     // immediately, because upon returning the view
   4898                     // hierarchy will be informed about it.
   4899                     if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
   4900                         // This actually changed the resources!  Tell
   4901                         // everyone about it.
   4902                         if (mPendingConfiguration == null ||
   4903                                 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
   4904                             mPendingConfiguration = newConfig;
   4905 
   4906                             sendMessage(H.CONFIGURATION_CHANGED, newConfig);
   4907                         }
   4908                     }
   4909                 }
   4910             }
   4911             @Override
   4912             public void onLowMemory() {
   4913             }
   4914             @Override
   4915             public void onTrimMemory(int level) {
   4916             }
   4917         });
   4918     }
   4919 
   4920     public static ActivityThread systemMain() {
   4921         HardwareRenderer.disable(true);
   4922         ActivityThread thread = new ActivityThread();
   4923         thread.attach(true);
   4924         return thread;
   4925     }
   4926 
   4927     public final void installSystemProviders(List<ProviderInfo> providers) {
   4928         if (providers != null) {
   4929             installContentProviders(mInitialApplication, providers);
   4930         }
   4931     }
   4932 
   4933     public int getIntCoreSetting(String key, int defaultValue) {
   4934         synchronized (mResourcesManager) {
   4935             if (mCoreSettings != null) {
   4936                 return mCoreSettings.getInt(key, defaultValue);
   4937             }
   4938             return defaultValue;
   4939         }
   4940     }
   4941 
   4942     private static class EventLoggingReporter implements EventLogger.Reporter {
   4943         @Override
   4944         public void report (int code, Object... list) {
   4945             EventLog.writeEvent(code, list);
   4946         }
   4947     }
   4948 
   4949     private class DropBoxReporter implements DropBox.Reporter {
   4950 
   4951         private DropBoxManager dropBox;
   4952 
   4953         public DropBoxReporter() {
   4954             dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
   4955         }
   4956 
   4957         @Override
   4958         public void addData(String tag, byte[] data, int flags) {
   4959             dropBox.addData(tag, data, flags);
   4960         }
   4961 
   4962         @Override
   4963         public void addText(String tag, String data) {
   4964             dropBox.addText(tag, data);
   4965         }
   4966     }
   4967 
   4968     public static void main(String[] args) {
   4969         SamplingProfilerIntegration.start();
   4970 
   4971         // CloseGuard defaults to true and can be quite spammy.  We
   4972         // disable it here, but selectively enable it later (via
   4973         // StrictMode) on debug builds, but using DropBox, not logs.
   4974         CloseGuard.setEnabled(false);
   4975 
   4976         Environment.initForCurrentUser();
   4977 
   4978         // Set the reporter for event logging in libcore
   4979         EventLogger.setReporter(new EventLoggingReporter());
   4980 
   4981         Security.addProvider(new AndroidKeyStoreProvider());
   4982 
   4983         Process.setArgV0("<pre-initialized>");
   4984 
   4985         Looper.prepareMainLooper();
   4986 
   4987         ActivityThread thread = new ActivityThread();
   4988         thread.attach(false);
   4989 
   4990         if (sMainThreadHandler == null) {
   4991             sMainThreadHandler = thread.getHandler();
   4992         }
   4993 
   4994         AsyncTask.init();
   4995 
   4996         if (false) {
   4997             Looper.myLooper().setMessageLogging(new
   4998                     LogPrinter(Log.DEBUG, "ActivityThread"));
   4999         }
   5000 
   5001         Looper.loop();
   5002 
   5003         throw new RuntimeException("Main thread loop unexpectedly exited");
   5004     }
   5005 }
   5006