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