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