Merge "Turning off accessibility feature reboots the device"
diff --git a/api/current.txt b/api/current.txt
index 035da89..5a599ce 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -911,6 +911,8 @@
     field public static final int stretchMode = 16843030; // 0x1010116
     field public static final int subtitle = 16843473; // 0x10102d1
     field public static final int subtitleTextStyle = 16843513; // 0x10102f9
+    field public static final int subtypeExtraValue = 16843684; // 0x10103a4
+    field public static final int subtypeLocale = 16843683; // 0x10103a3
     field public static final int suggestActionMsg = 16843228; // 0x10101dc
     field public static final int suggestActionMsgColumn = 16843229; // 0x10101dd
     field public static final int suggestionsEnabled = 16843632; // 0x1010370
@@ -14095,6 +14097,7 @@
     method public static long getNativeHeapAllocatedSize();
     method public static long getNativeHeapFreeSize();
     method public static long getNativeHeapSize();
+    method public static long getPss();
     method public static int getThreadAllocCount();
     method public static int getThreadAllocSize();
     method public static deprecated int getThreadExternalAllocCount();
@@ -24267,6 +24270,9 @@
     method public android.content.ComponentName getComponent();
     method public java.lang.String getId();
     method public java.lang.String getPackageName();
+    method public java.lang.String getSettingsActivity();
+    method public android.view.textservice.SpellCheckerSubtype getSubtypeAt(int);
+    method public int getSubtypeCount();
     method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
     method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
     method public void writeToParcel(android.os.Parcel, int);
@@ -24286,6 +24292,16 @@
     method public abstract void onGetSuggestions(android.view.textservice.SuggestionsInfo[]);
   }
 
+  public final class SpellCheckerSubtype implements android.os.Parcelable {
+    ctor public SpellCheckerSubtype(int, java.lang.String, java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getExtraValue();
+    method public java.lang.String getLocale();
+    method public int getNameResId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public final class SuggestionsInfo implements android.os.Parcelable {
     ctor public SuggestionsInfo(int, java.lang.String[]);
     ctor public SuggestionsInfo(int, java.lang.String[], int, int);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d207a0a..f7e5cf1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -864,6 +864,15 @@
          */
         public boolean lowMemory;
 
+        /** @hide */
+        public long hiddenAppThreshold;
+        /** @hide */
+        public long secondaryServerThreshold;
+        /** @hide */
+        public long visibleAppThreshold;
+        /** @hide */
+        public long foregroundAppThreshold;
+
         public MemoryInfo() {
         }
 
@@ -875,12 +884,20 @@
             dest.writeLong(availMem);
             dest.writeLong(threshold);
             dest.writeInt(lowMemory ? 1 : 0);
+            dest.writeLong(hiddenAppThreshold);
+            dest.writeLong(secondaryServerThreshold);
+            dest.writeLong(visibleAppThreshold);
+            dest.writeLong(foregroundAppThreshold);
         }
         
         public void readFromParcel(Parcel source) {
             availMem = source.readLong();
             threshold = source.readLong();
             lowMemory = source.readInt() != 0;
+            hiddenAppThreshold = source.readLong();
+            secondaryServerThreshold = source.readLong();
+            visibleAppThreshold = source.readLong();
+            foregroundAppThreshold = source.readLong();
         }
 
         public static final Creator<MemoryInfo> CREATOR
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b7cd829..a73e10a 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1523,6 +1523,15 @@
             return true;
         }
 
+        case GET_PROCESS_PSS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int[] pids = data.createIntArray();
+            long[] pss = getProcessPss(pids);
+            reply.writeNoException();
+            reply.writeLongArray(pss);
+            return true;
+        }
+
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3432,5 +3441,18 @@
         reply.recycle();
     }
 
+    public long[] getProcessPss(int[] pids) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeIntArray(pids);
+        mRemote.transact(GET_PROCESS_PSS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        long[] res = reply.createLongArray();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c566104..d5f630a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -729,17 +729,19 @@
         }
 
         @Override
-        public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, String[] args) {
+        public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
+                boolean all, String[] args) {
             FileOutputStream fout = new FileOutputStream(fd);
             PrintWriter pw = new PrintWriter(fout);
             try {
-                return dumpMemInfo(pw, args);
+                return dumpMemInfo(pw, checkin, all, args);
             } finally {
                 pw.flush();
             }
         }
 
-        private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, String[] args) {
+        private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all,
+                String[] args) {
             long nativeMax = Debug.getNativeHeapSize() / 1024;
             long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
             long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -747,6 +749,10 @@
             Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
             Debug.getMemoryInfo(memInfo);
 
+            if (!all) {
+                return memInfo;
+            }
+
             Runtime runtime = Runtime.getRuntime();
 
             long dalvikMax = runtime.totalMemory() / 1024;
@@ -765,16 +771,8 @@
             long sqliteAllocated = SQLiteDebug.getHeapAllocatedSize() / 1024;
             SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
 
-            // Check to see if we were called by checkin server. If so, print terse format.
-            boolean doCheckinFormat = false;
-            if (args != null) {
-                for (String arg : args) {
-                    if ("-c".equals(arg)) doCheckinFormat = true;
-                }
-            }
-
             // For checkin, we print one long comma-separated list of values
-            if (doCheckinFormat) {
+            if (checkin) {
                 // NOTE: if you change anything significant below, also consider changing
                 // ACTIVITY_THREAD_CHECKIN_VERSION.
                 String processName = (mBoundApplication != null)
@@ -841,13 +839,17 @@
                 pw.print(sqliteAllocated); pw.print(',');
                 pw.print(stats.memoryUsed / 1024); pw.print(',');
                 pw.print(stats.pageCacheOverflo / 1024); pw.print(',');
-                pw.print(stats.largestMemAlloc / 1024); pw.print(',');
+                pw.print(stats.largestMemAlloc / 1024);
                 for (int i = 0; i < stats.dbStats.size(); i++) {
                     DbStats dbStats = stats.dbStats.get(i);
-                    printRow(pw, DB_INFO_FORMAT, dbStats.pageSize, dbStats.dbSize,
-                            dbStats.lookaside, dbStats.cache, dbStats.dbName);
-                    pw.print(',');
+                    pw.print(','); pw.print(dbStats.dbName);
+                    pw.print(','); pw.print(dbStats.pageSize);
+                    pw.print(','); pw.print(dbStats.dbSize);
+                    pw.print(','); pw.print(dbStats.lookaside);
+                    pw.print(','); pw.print(dbStats.cache);
+                    pw.print(','); pw.print(dbStats.cache);
                 }
+                pw.println();
 
                 return memInfo;
             }
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 9a5b527..bea057e 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -491,11 +491,13 @@
         {
             data.enforceInterface(IApplicationThread.descriptor);
             ParcelFileDescriptor fd = data.readFileDescriptor();
+            boolean checkin = data.readInt() != 0;
+            boolean all = data.readInt() != 0;
             String[] args = data.readStringArray();
             Debug.MemoryInfo mi = null;
             if (fd != null) {
                 try {
-                    mi = dumpMemInfo(fd.getFileDescriptor(), args);
+                    mi = dumpMemInfo(fd.getFileDescriptor(), checkin, all, args);
                 } finally {
                     try {
                         fd.close();
@@ -1049,11 +1051,14 @@
                 IBinder.FLAG_ONEWAY);
     }
 
-    public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, String[] args) throws RemoteException {
+    public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all,
+            String[] args) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeFileDescriptor(fd);
+        data.writeInt(checkin ? 1 : 0);
+        data.writeInt(all ? 1 : 0);
         data.writeStringArray(args);
         mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0);
         reply.readException();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 64d77e8..b1b0583 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -364,7 +364,9 @@
     public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException;
 
     public void updatePersistentConfiguration(Configuration values) throws RemoteException;
-    
+
+    public long[] getProcessPss(int[] pids) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -593,4 +595,5 @@
     int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
     int IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+134;
     int UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+135;
+    int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136;
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index d0607d0..3a8eb28 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -120,7 +120,8 @@
     void setCoreSettings(Bundle coreSettings) throws RemoteException;
     void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
     void scheduleTrimMemory(int level) throws RemoteException;
-    Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, String[] args) throws RemoteException;
+    Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all,
+            String[] args) throws RemoteException;
     void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index b668f30..6ba3451 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -21,6 +21,7 @@
 import android.os.Parcelable;
 
 import java.lang.UnsupportedOperationException;
+import java.nio.charset.Charset;
 import java.nio.charset.Charsets;
 import java.util.Arrays;
 
@@ -139,6 +140,22 @@
      */
     public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
 
+    /**
+     * RTD Android app type. For use with TNF_EXTERNAL.
+     * <p>
+     * The payload of a record with type RTD_ANDROID_APP
+     * should be the package name identifying an application.
+     * Multiple RTD_ANDROID_APP records may be included
+     * in a single {@link NdefMessage}.
+     * <p>
+     * Use {@link #createApplicationRecord(String)} to create
+     * RTD_ANDROID_APP records.
+     * @hide
+     */
+    // TODO unhide for ICS
+    // TODO recheck docs
+    public static final byte[] RTD_ANDROID_APP = "android.com:pkg".getBytes();
+
     private static final byte FLAG_MB = (byte) 0x80;
     private static final byte FLAG_ME = (byte) 0x40;
     private static final byte FLAG_CF = (byte) 0x20;
@@ -333,6 +350,29 @@
     }
 
     /**
+     * Creates an Android application NDEF record.
+     * <p>
+     * When an Android device dispatches an {@link NdefMessage}
+     * containing one or more Android application records,
+     * the applications contained in those records will be the
+     * preferred target for the NDEF_DISCOVERED intent, in
+     * the order in which they appear in the {@link NdefMessage}.
+     * <p>
+     * If none of the applications are installed on the device,
+     * a Market link will be opened to the first application.
+     * <p>
+     * Note that Android application records do not overrule
+     * applications that have called {@link NfcAdapter#enableForegroundDispatch}.
+     * @hide
+     */
+    // TODO unhide for ICS
+    // TODO recheck javadoc - should mention this works from ICS only
+    public static NdefRecord createApplicationRecord(String packageName) {
+        return new NdefRecord(TNF_EXTERNAL_TYPE, RTD_ANDROID_APP, new byte[] {},
+                packageName.getBytes(Charsets.US_ASCII));
+    }
+
+    /**
      * Creates an NDEF record of well known type URI.
      */
     public static NdefRecord createUri(Uri uri) {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index da2afb6..20a731e 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -818,6 +818,18 @@
     public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
 
     /**
+     * Retrieves the PSS memory used by the process as given by the
+     * smaps.
+     */
+    public static native long getPss();
+
+    /**
+     * Retrieves the PSS memory used by the process as given by the
+     * smaps. @hide
+     */
+    public static native long getPss(int pid);
+
+    /**
      * Establish an object allocation limit in the current thread.
      * This feature was never enabled in release builds.  The
      * allocation limits feature was removed in Honeycomb.  This
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a6c3387..1ecdfce 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3042,7 +3042,7 @@
 
         /**
          * Boolean to determine whether to notify on disabling a network.  Secure setting used
-         * to notify user only once.  This setting is not monitored continuously.
+         * to notify user only once.
          * @hide
          */
         public static final String WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP =
@@ -3166,6 +3166,18 @@
         public static final String TTY_MODE_ENABLED = "tty_mode_enabled";
 
         /**
+         * The number of milliseconds to delay before sending out Connectivyt Change broadcasts
+         * @hide
+         */
+        public static final String CONNECTIVITY_CHANGE_DELAY = "connectivity_change_delay";
+
+        /**
+         * Default value for CONNECTIVITY_CHANGE_DELAY in milliseconds.
+         * @hide
+         */
+        public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000;
+
+        /**
          * Controls whether settings backup is enabled.
          * Type: int ( 0 = disabled, 1 = enabled )
          * @hide
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index f498bb2..8c04853 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -194,7 +194,7 @@
     }
 
     private synchronized void onBluetoothEnable() {
-        String devices = mBluetoothService.getProperty("Devices");
+        String devices = mBluetoothService.getProperty("Devices", true);
         if (devices != null) {
             String [] paths = devices.split(",");
             for (String path: paths) {
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 3029c9d..0357958 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -798,8 +798,15 @@
         return true;
     }
 
-    /*package*/ synchronized String getProperty(String name) {
-        if (!isEnabledInternal()) return null;
+    /*package*/ synchronized String getProperty(String name, boolean checkState) {
+        // If checkState is false, check if the event loop is running.
+        // before making the call to Bluez
+        if (checkState) {
+            if (!isEnabledInternal()) return null;
+        } else if (!mEventLoop.isEventLoopRunning()) {
+            return null;
+        }
+
         return mAdapterProperties.getProperty(name);
     }
 
@@ -825,17 +832,19 @@
 
     public synchronized String getAddress() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return getProperty("Address");
+        // Don't check state since we want to provide address, even if BT is off
+        return getProperty("Address", false);
     }
 
     public synchronized String getName() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return getProperty("Name");
+        // Don't check state since we want to provide name, even if BT is off
+        return getProperty("Name", false);
     }
 
     public synchronized ParcelUuid[] getUuids() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        String value =  getProperty("UUIDs");
+        String value =  getProperty("UUIDs", true);
         if (value == null) return null;
         return convertStringToParcelUuid(value);
     }
@@ -915,7 +924,7 @@
      */
     public synchronized int getDiscoverableTimeout() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        String timeout = getProperty("DiscoverableTimeout");
+        String timeout = getProperty("DiscoverableTimeout", true);
         if (timeout != null)
            return Integer.valueOf(timeout);
         else
@@ -927,8 +936,8 @@
         if (!isEnabledInternal())
             return BluetoothAdapter.SCAN_MODE_NONE;
 
-        boolean pairable = getProperty("Pairable").equals("true");
-        boolean discoverable = getProperty("Discoverable").equals("true");
+        boolean pairable = getProperty("Pairable", true).equals("true");
+        boolean discoverable = getProperty("Discoverable", true).equals("true");
         return bluezStringToScanMode (pairable, discoverable);
     }
 
@@ -951,7 +960,7 @@
     public synchronized boolean isDiscovering() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
-        String discoveringProperty = mAdapterProperties.getProperty("Discovering");
+        String discoveringProperty = getProperty("Discovering", false);
         if (discoveringProperty == null) {
             return false;
         }
@@ -2341,7 +2350,7 @@
 
     synchronized String[] getKnownDevices() {
         String[] bonds = null;
-        String val = getProperty("Devices");
+        String val = getProperty("Devices", true);
         if (val != null) {
             bonds = val.split(",");
         }
@@ -2350,7 +2359,7 @@
 
     private void initProfileState() {
         String[] bonds = null;
-        String val = mAdapterProperties.getProperty("Devices");
+        String val = getProperty("Devices", false);
         if (val != null) {
             bonds = val.split(",");
         }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 81cd798..c7bf8e3 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -184,6 +184,13 @@
      */
     int watchRotation(IRotationWatcher watcher);
 
+    /**
+     * Determine the preferred edge of the screen to pin the compact options menu against.
+     * @return a Gravity value for the options menu panel
+     * @hide
+     */
+    int getPreferredOptionsPanelGravity();
+
 	/**
 	 * Lock the device orientation to the current rotation. Sensor input will
 	 * be ignored until thawRotation() is called.
diff --git a/core/java/android/view/textservice/SpellCheckerInfo.java b/core/java/android/view/textservice/SpellCheckerInfo.java
index d88a39f..89cb11c 100644
--- a/core/java/android/view/textservice/SpellCheckerInfo.java
+++ b/core/java/android/view/textservice/SpellCheckerInfo.java
@@ -16,30 +16,122 @@
 
 package android.view.textservice;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.util.Xml;
+
+import java.io.IOException;
+import java.util.ArrayList;
 
 /**
  * This class is used to specify meta information of an spell checker.
  */
 public final class SpellCheckerInfo implements Parcelable {
+    private static final String TAG = SpellCheckerInfo.class.getSimpleName();
     private final ResolveInfo mService;
     private final String mId;
+    private final int mLabel;
+
+    /**
+     * The spell checker setting activity's name, used by the system settings to
+     * launch the setting activity.
+     */
+    private final String mSettingsActivityName;
+
+    /**
+     * The array of the subtypes.
+     */
+    private final ArrayList<SpellCheckerSubtype> mSubtypes = new ArrayList<SpellCheckerSubtype>();
 
     /**
      * Constructor.
      * @hide
      */
-    public SpellCheckerInfo(Context context, ResolveInfo service) {
+    public SpellCheckerInfo(Context context, ResolveInfo service)
+            throws XmlPullParserException, IOException {
         mService = service;
         ServiceInfo si = service.serviceInfo;
         mId = new ComponentName(si.packageName, si.name).flattenToShortString();
+
+        final PackageManager pm = context.getPackageManager();
+        int label = 0;
+        String settingsActivityComponent = null;
+        int isDefaultResId = 0;
+
+        XmlResourceParser parser = null;
+        try {
+            parser = si.loadXmlMetaData(pm, SpellCheckerSession.SERVICE_META_DATA);
+            if (parser == null) {
+                throw new XmlPullParserException("No "
+                        + SpellCheckerSession.SERVICE_META_DATA + " meta-data");
+            }
+
+            final Resources res = pm.getResourcesForApplication(si.applicationInfo);
+            final AttributeSet attrs = Xml.asAttributeSet(parser);
+            int type;
+            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+                    && type != XmlPullParser.START_TAG) {
+            }
+
+            final String nodeName = parser.getName();
+            if (!"spell-checker".equals(nodeName)) {
+                throw new XmlPullParserException(
+                        "Meta-data does not start with spell-checker tag");
+            }
+
+            TypedArray sa = res.obtainAttributes(attrs,
+                    com.android.internal.R.styleable.SpellChecker);
+            label = sa.getResourceId(com.android.internal.R.styleable.SpellChecker_label, 0);
+            settingsActivityComponent = sa.getString(
+                    com.android.internal.R.styleable.SpellChecker_settingsActivity);
+            sa.recycle();
+
+            final int depth = parser.getDepth();
+            // Parse all subtypes
+            while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                    && type != XmlPullParser.END_DOCUMENT) {
+                if (type == XmlPullParser.START_TAG) {
+                    final String subtypeNodeName = parser.getName();
+                    if (!"subtype".equals(subtypeNodeName)) {
+                        throw new XmlPullParserException(
+                                "Meta-data in spell-checker does not start with subtype tag");
+                    }
+                    final TypedArray a = res.obtainAttributes(
+                            attrs, com.android.internal.R.styleable.SpellChecker_Subtype);
+                    SpellCheckerSubtype subtype = new SpellCheckerSubtype(
+                            a.getResourceId(com.android.internal.R.styleable
+                                    .SpellChecker_Subtype_label, 0),
+                            a.getString(com.android.internal.R.styleable
+                                    .SpellChecker_Subtype_subtypeLocale),
+                            a.getString(com.android.internal.R.styleable
+                                    .SpellChecker_Subtype_subtypeExtraValue));
+                    mSubtypes.add(subtype);
+                }
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Caught exception: " + e);
+            throw new XmlPullParserException(
+                    "Unable to create context for: " + si.packageName);
+        } finally {
+            if (parser != null) parser.close();
+        }
+        mLabel = label;
+        mSettingsActivityName = settingsActivityComponent;
     }
 
     /**
@@ -47,8 +139,11 @@
      * @hide
      */
     public SpellCheckerInfo(Parcel source) {
+        mLabel = source.readInt();
         mId = source.readString();
+        mSettingsActivityName = source.readString();
         mService = ResolveInfo.CREATOR.createFromParcel(source);
+        source.readTypedList(mSubtypes, SpellCheckerSubtype.CREATOR);
     }
 
     /**
@@ -69,7 +164,7 @@
     }
 
     /**
-     * Return the .apk package that implements this input method.
+     * Return the .apk package that implements this.
      */
     public String getPackageName() {
         return mService.serviceInfo.packageName;
@@ -83,8 +178,11 @@
      */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mLabel);
         dest.writeString(mId);
+        dest.writeString(mSettingsActivityName);
         mService.writeToParcel(dest, flags);
+        dest.writeTypedList(mSubtypes);
     }
 
 
@@ -110,7 +208,8 @@
      * @param pm Supply a PackageManager used to load the spell checker's resources.
      */
     public CharSequence loadLabel(PackageManager pm) {
-        return mService.loadLabel(pm);
+        if (mLabel == 0 || pm == null) return "";
+        return pm.getText(getPackageName(), mLabel, mService.serviceInfo.applicationInfo);
     }
 
     /**
@@ -123,6 +222,35 @@
     }
 
     /**
+     * Return the class name of an activity that provides a settings UI.
+     * You can launch this activity be starting it with
+     * an {@link android.content.Intent} whose action is MAIN and with an
+     * explicit {@link android.content.ComponentName}
+     * composed of {@link #getPackageName} and the class name returned here.
+     *
+     * <p>A null will be returned if there is no settings activity.
+     */
+    public String getSettingsActivity() {
+        return mSettingsActivityName;
+    }
+
+    /**
+     * Return the count of the subtypes.
+     */
+    public int getSubtypeCount() {
+        return mSubtypes.size();
+    }
+
+    /**
+     * Return the subtype at the specified index.
+     *
+     * @param index the index of the subtype to return.
+     */
+    public SpellCheckerSubtype getSubtypeAt(int index) {
+        return mSubtypes.get(index);
+    }
+
+    /**
      * Used to make this class parcelable.
      */
     @Override
diff --git a/core/java/android/view/textservice/SpellCheckerSubtype.aidl b/core/java/android/view/textservice/SpellCheckerSubtype.aidl
new file mode 100644
index 0000000..1c790e7
--- /dev/null
+++ b/core/java/android/view/textservice/SpellCheckerSubtype.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textservice;
+
+parcelable SpellCheckerSubtype;
diff --git a/core/java/android/view/textservice/SpellCheckerSubtype.java b/core/java/android/view/textservice/SpellCheckerSubtype.java
new file mode 100644
index 0000000..dbd3081
--- /dev/null
+++ b/core/java/android/view/textservice/SpellCheckerSubtype.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textservice;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * This class is used to specify meta information of a subtype contained in a spell checker.
+ * Subtype can describe locale (e.g. en_US, fr_FR...) used for settings.
+ */
+public final class SpellCheckerSubtype implements Parcelable {
+
+    private final int mSubtypeHashCode;
+    private final int mSubtypeNameResId;
+    private final String mSubtypeLocale;
+    private final String mSubtypeExtraValue;
+
+    /**
+     * Constructor
+     * @param nameId The name of the subtype
+     * @param locale The locale supported by the subtype
+     * @param extraValue The extra value of the subtype
+     */
+    public SpellCheckerSubtype(int nameId, String locale, String extraValue) {
+        mSubtypeNameResId = nameId;
+        mSubtypeLocale = locale != null ? locale : "";
+        mSubtypeExtraValue = extraValue != null ? extraValue : "";
+        mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeExtraValue);
+    }
+
+    SpellCheckerSubtype(Parcel source) {
+        String s;
+        mSubtypeNameResId = source.readInt();
+        s = source.readString();
+        mSubtypeLocale = s != null ? s : "";
+        s = source.readString();
+        mSubtypeExtraValue = s != null ? s : "";
+        mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeExtraValue);
+    }
+
+    /**
+     * @return the name of the subtype
+     */
+    public int getNameResId() {
+        return mSubtypeNameResId;
+    }
+
+    /**
+     * @return the locale of the subtype
+     */
+    public String getLocale() {
+        return mSubtypeLocale;
+    }
+
+    /**
+     * @return the extra value of the subtype
+     */
+    public String getExtraValue() {
+        return mSubtypeExtraValue;
+    }
+
+    @Override
+    public int hashCode() {
+        return mSubtypeHashCode;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof SpellCheckerSubtype) {
+            SpellCheckerSubtype subtype = (SpellCheckerSubtype) o;
+            return (subtype.hashCode() == hashCode())
+                && (subtype.getNameResId() == getNameResId())
+                && (subtype.getLocale().equals(getLocale()))
+                && (subtype.getExtraValue().equals(getExtraValue()));
+        }
+        return false;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int parcelableFlags) {
+        dest.writeInt(mSubtypeNameResId);
+        dest.writeString(mSubtypeLocale);
+        dest.writeString(mSubtypeExtraValue);
+    }
+
+    public static final Parcelable.Creator<SpellCheckerSubtype> CREATOR
+            = new Parcelable.Creator<SpellCheckerSubtype>() {
+        @Override
+        public SpellCheckerSubtype createFromParcel(Parcel source) {
+            return new SpellCheckerSubtype(source);
+        }
+
+        @Override
+        public SpellCheckerSubtype[] newArray(int size) {
+            return new SpellCheckerSubtype[size];
+        }
+    };
+
+    private static int hashCodeInternal(String locale, String extraValue) {
+        return Arrays.hashCode(new Object[] {locale, extraValue});
+    }
+
+    /**
+     * Sort the list of subtypes
+     * @param context Context will be used for getting localized strings
+     * @param flags Flags for the sort order
+     * @param sci SpellCheckerInfo of which subtypes are subject to be sorted
+     * @param subtypeList List which will be sorted
+     * @return Sorted list of subtypes
+     * @hide
+     */
+    public static List<SpellCheckerSubtype> sort(Context context, int flags, SpellCheckerInfo sci,
+            List<SpellCheckerSubtype> subtypeList) {
+        if (sci == null) return subtypeList;
+        final HashSet<SpellCheckerSubtype> subtypesSet = new HashSet<SpellCheckerSubtype>(
+                subtypeList);
+        final ArrayList<SpellCheckerSubtype> sortedList = new ArrayList<SpellCheckerSubtype>();
+        int N = sci.getSubtypeCount();
+        for (int i = 0; i < N; ++i) {
+            SpellCheckerSubtype subtype = sci.getSubtypeAt(i);
+            if (subtypesSet.contains(subtype)) {
+                sortedList.add(subtype);
+                subtypesSet.remove(subtype);
+            }
+        }
+        // If subtypes in subtypesSet remain, that means these subtypes are not
+        // contained in sci, so the remaining subtypes will be appended.
+        for (SpellCheckerSubtype subtype: subtypesSet) {
+            sortedList.add(subtype);
+        }
+        return sortedList;
+    }
+}
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index d977029..390002b 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -395,10 +395,6 @@
      */
     public void setUseDefaultMargins(boolean useDefaultMargins) {
         mUseDefaultMargins = useDefaultMargins;
-        if (useDefaultMargins) {
-            int padding = mDefaultGap;
-            setPadding(padding, padding, padding, padding);
-        }
         requestLayout();
     }
 
@@ -740,6 +736,10 @@
         graphics.drawLine(dx + x1, dy + y1, dx + x2, dy + y2, paint);
     }
 
+    private static void drawRect(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint) {
+        canvas.drawRect(x1, y1, x2 - 1, y2 - 1, paint);
+    }
+
     @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
@@ -772,14 +772,14 @@
             paint.setColor(Color.BLUE);
             for (int i = 0; i < getChildCount(); i++) {
                 View c = getChildAt(i);
-                canvas.drawRect(c.getLeft(), c.getTop(), c.getRight(), c.getBottom(), paint);
+                drawRect(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(), paint);
             }
 
             // Draw margins
             paint.setColor(Color.MAGENTA);
             for (int i = 0; i < getChildCount(); i++) {
                 View c = getChildAt(i);
-                canvas.drawRect(
+                drawRect(canvas,
                         c.getLeft() - getMargin1(c, true, true),
                         c.getTop() - getMargin1(c, false, true),
                         c.getRight() + getMargin1(c, true, false),
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index f057d07..307959b 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -1092,7 +1092,7 @@
         }
 
         final int listContent = mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
-                0, ListView.NO_POSITION, maxHeight - otherHeights, 2);
+                0, ListView.NO_POSITION, maxHeight - otherHeights, -1);
         // add padding only if the list has items in it, that way we don't show
         // the popup if it is not needed
         if (listContent > 0) otherHeights += padding;
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
new file mode 100644
index 0000000..850e1f0
--- /dev/null
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import java.io.FileInputStream;
+
+import android.os.StrictMode;
+
+public class MemInfoReader {
+    byte[] mBuffer = new byte[1024];
+
+    private long mTotalSize;
+    private long mFreeSize;
+    private long mCachedSize;
+
+    private boolean matchText(byte[] buffer, int index, String text) {
+        int N = text.length();
+        if ((index+N) >= buffer.length) {
+            return false;
+        }
+        for (int i=0; i<N; i++) {
+            if (buffer[index+i] != text.charAt(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private long extractMemValue(byte[] buffer, int index) {
+        while (index < buffer.length && buffer[index] != '\n') {
+            if (buffer[index] >= '0' && buffer[index] <= '9') {
+                int start = index;
+                index++;
+                while (index < buffer.length && buffer[index] >= '0'
+                    && buffer[index] <= '9') {
+                    index++;
+                }
+                String str = new String(buffer, 0, start, index-start);
+                return ((long)Integer.parseInt(str)) * 1024;
+            }
+            index++;
+        }
+        return 0;
+    }
+
+    public void readMemInfo() {
+        // Permit disk reads here, as /proc/meminfo isn't really "on
+        // disk" and should be fast.  TODO: make BlockGuard ignore
+        // /proc/ and /sys/ files perhaps?
+        StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+        try {
+            mTotalSize = 0;
+            mFreeSize = 0;
+            mCachedSize = 0;
+            FileInputStream is = new FileInputStream("/proc/meminfo");
+            int len = is.read(mBuffer);
+            is.close();
+            final int BUFLEN = mBuffer.length;
+            int count = 0;
+            for (int i=0; i<len && count < 3; i++) {
+                if (matchText(mBuffer, i, "MemTotal")) {
+                    i += 8;
+                    mTotalSize = extractMemValue(mBuffer, i);
+                    count++;
+                } else if (matchText(mBuffer, i, "MemFree")) {
+                    i += 7;
+                    mFreeSize = extractMemValue(mBuffer, i);
+                    count++;
+                } else if (matchText(mBuffer, i, "Cached")) {
+                    i += 6;
+                    mCachedSize = extractMemValue(mBuffer, i);
+                    count++;
+                }
+                while (i < BUFLEN && mBuffer[i] != '\n') {
+                    i++;
+                }
+            }
+        } catch (java.io.FileNotFoundException e) {
+        } catch (java.io.IOException e) {
+        } finally {
+            StrictMode.setThreadPolicy(savedPolicy);
+        }
+    }
+
+    public long getTotalSize() {
+        return mTotalSize;
+    }
+
+    public long getFreeSize() {
+        return mFreeSize;
+    }
+
+    public long getCachedSize() {
+        return mCachedSize;
+    }
+}
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 3a3f07e..85fac5f 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -279,6 +279,39 @@
     android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
 }
 
+static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid)
+{
+    char line[1024];
+    jlong pss = 0;
+    unsigned temp;
+
+    char tmp[128];
+    FILE *fp;
+
+    sprintf(tmp, "/proc/%d/smaps", pid);
+    fp = fopen(tmp, "r");
+    if (fp == 0) return 0;
+
+    while (true) {
+        if (fgets(line, 1024, fp) == 0) {
+            break;
+        }
+
+        if (sscanf(line, "Pss: %d kB", &temp) == 1) {
+            pss += temp;
+        }
+    }
+
+    fclose(fp);
+
+    return pss;
+}
+
+static jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz)
+{
+    return android_os_Debug_getPssPid(env, clazz, getpid());
+}
+
 static jint read_binder_stat(const char* stat)
 {
     FILE* fp = fopen(BINDER_STATS, "r");
@@ -520,6 +553,10 @@
             (void*) android_os_Debug_getDirtyPages },
     { "getMemoryInfo",          "(ILandroid/os/Debug$MemoryInfo;)V",
             (void*) android_os_Debug_getDirtyPagesPid },
+    { "getPss",                 "()J",
+            (void*) android_os_Debug_getPss },
+    { "getPss",                 "(I)J",
+            (void*) android_os_Debug_getPssPid },
     { "dumpNativeHeap",         "(Ljava/io/FileDescriptor;)V",
             (void*) android_os_Debug_dumpNativeHeap },
     { "getBinderSentTransactions", "()I",
diff --git a/core/res/res/drawable-hdpi/spinner_ab_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_dark.9.png
new file mode 100644
index 0000000..d471c30
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_activated_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_light.9.png
new file mode 100644
index 0000000..d471c30
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
new file mode 100644
index 0000000..001cfbb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
new file mode 100644
index 0000000..5e278c8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
new file mode 100644
index 0000000..cf2e149
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
new file mode 100644
index 0000000..63f212d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
new file mode 100644
index 0000000..85663e6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
new file mode 100644
index 0000000..85663e6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
new file mode 100644
index 0000000..afddbe8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
new file mode 100644
index 0000000..0ad6476
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_active_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_active_holo_dark.9.png
deleted file mode 100644
index 7cad0c9..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_active_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_active_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_active_holo_light.9.png
deleted file mode 100644
index 7cad0c9..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_active_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_default_holo_dark.9.png
deleted file mode 100644
index b3f3cf7..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_default_holo_light.9.png
deleted file mode 100644
index af46631..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_dark.9.png
deleted file mode 100644
index e672c95..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_light.9.png
deleted file mode 100644
index f499540..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_focused_holo_dark.9.png
deleted file mode 100644
index f4900a5..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_focused_holo_light.9.png
deleted file mode 100644
index 1286542..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_dark.9.png
deleted file mode 100644
index 8b6f9dd..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_light.9.png
deleted file mode 100644
index 4f0c476..0000000
--- a/core/res/res/drawable-hdpi/spinner_cab_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
index 62e3274..288b809 100644
--- a/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
index b7512fa..7866e06 100644
--- a/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
index bfc6f83..699552d 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
index 708ba90..543afa2 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
index 0da1e9c..e1a5e70 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
index 2e93557..e79e95b 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
index 7aeaad6..8a5d810 100644
--- a/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
index cf46f32..177b631 100644
--- a/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_dark.9.png
new file mode 100644
index 0000000..34c9188
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_activated_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_light.9.png
new file mode 100644
index 0000000..34c9188
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
new file mode 100644
index 0000000..b92abaf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
new file mode 100644
index 0000000..91f0e87
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
new file mode 100644
index 0000000..dab7eda0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
new file mode 100644
index 0000000..bf14605
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
new file mode 100644
index 0000000..c733260
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
new file mode 100644
index 0000000..c733260
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
new file mode 100644
index 0000000..6d290a6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
new file mode 100644
index 0000000..6dae484
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_active_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_active_holo_dark.9.png
deleted file mode 100644
index 617c379..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_active_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_active_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_active_holo_light.9.png
deleted file mode 100644
index 617c379..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_active_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_default_holo_dark.9.png
deleted file mode 100644
index d76b123..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_default_holo_light.9.png
deleted file mode 100644
index ee91044..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_dark.9.png
deleted file mode 100644
index fc9c109..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_light.9.png
deleted file mode 100644
index 7fc7cc1..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_focused_holo_dark.9.png
deleted file mode 100644
index 0f49fe9..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_focused_holo_light.9.png
deleted file mode 100644
index 032d5d3..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_dark.9.png
deleted file mode 100644
index df0a935..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_light.9.png
deleted file mode 100644
index b43177b..0000000
--- a/core/res/res/drawable-mdpi/spinner_cab_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
index 62e3274..faaa6c2 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
index b7512fa..ec44405 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
index bfc6f83..1cc76a3 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
index 708ba90..2593760 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
index 0da1e9c..8688d6a 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
index 2e93557..3f4c282 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
index 7aeaad6..8692528 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
index cf46f32..849af73 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_dark.9.png
new file mode 100644
index 0000000..85d8540
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_light.9.png
new file mode 100644
index 0000000..85d8540
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
new file mode 100644
index 0000000..31b39d7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
new file mode 100644
index 0000000..1527c5c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
new file mode 100644
index 0000000..e4cef9a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
new file mode 100644
index 0000000..1c37ece
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
new file mode 100644
index 0000000..6aae46b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
new file mode 100644
index 0000000..6aae46b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
new file mode 100644
index 0000000..db2e034
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
new file mode 100644
index 0000000..77bb433
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_default_holo_dark.9.png
new file mode 100644
index 0000000..1a1a9c4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_default_holo_light.9.png
new file mode 100644
index 0000000..462cea6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_dark.9.png
new file mode 100644
index 0000000..3e178b2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_light.9.png
new file mode 100644
index 0000000..4c34b93
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_dark.9.png
new file mode 100644
index 0000000..cf1b3ca
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_light.9.png
new file mode 100644
index 0000000..0ee383b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_dark.9.png
new file mode 100644
index 0000000..42c019e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_light.9.png
new file mode 100644
index 0000000..63efe71
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/spinner_cab_background_holo_dark.xml b/core/res/res/drawable/spinner_ab_holo_dark.xml
similarity index 66%
rename from core/res/res/drawable/spinner_cab_background_holo_dark.xml
rename to core/res/res/drawable/spinner_ab_holo_dark.xml
index 5572450..708b6ab 100644
--- a/core/res/res/drawable/spinner_cab_background_holo_dark.xml
+++ b/core/res/res/drawable/spinner_ab_holo_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -16,10 +16,12 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:drawable="@drawable/spinner_cab_disabled_holo_dark" />
+          android:drawable="@drawable/spinner_ab_disabled_holo_dark" />
     <item android:state_pressed="true"
-          android:drawable="@drawable/spinner_cab_pressed_holo_dark" />
+          android:drawable="@drawable/spinner_ab_pressed_holo_dark" />
     <item android:state_pressed="false" android:state_focused="true"
-          android:drawable="@drawable/spinner_cab_focused_holo_dark" />
-    <item android:drawable="@drawable/spinner_cab_default_holo_dark" />
+          android:drawable="@drawable/spinner_ab_focused_holo_dark" />
+    <item android:state_activated="true"
+          android:drawable="@drawable/spinner_ab_activated_holo_dark" />
+    <item android:drawable="@drawable/spinner_ab_default_holo_dark" />
 </selector>
diff --git a/core/res/res/drawable/spinner_cab_background_holo_light.xml b/core/res/res/drawable/spinner_ab_holo_light.xml
similarity index 70%
rename from core/res/res/drawable/spinner_cab_background_holo_light.xml
rename to core/res/res/drawable/spinner_ab_holo_light.xml
index 98ff48d..c4901ca 100644
--- a/core/res/res/drawable/spinner_cab_background_holo_light.xml
+++ b/core/res/res/drawable/spinner_ab_holo_light.xml
@@ -16,10 +16,12 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_enabled="false"
-          android:drawable="@drawable/spinner_cab_disabled_holo_light" />
+          android:drawable="@drawable/spinner_ab_disabled_holo_light" />
     <item android:state_pressed="true"
-          android:drawable="@drawable/spinner_cab_pressed_holo_light" />
+          android:drawable="@drawable/spinner_ab_pressed_holo_light" />
     <item android:state_pressed="false" android:state_focused="true"
-          android:drawable="@drawable/spinner_cab_focused_holo_light" />
-    <item android:drawable="@drawable/spinner_cab_default_holo_light" />
+          android:drawable="@drawable/spinner_ab_focused_holo_light" />
+    <item android:state_activated="true"
+          android:drawable="@drawable/spinner_ab_activated_holo_light" />
+    <item android:drawable="@drawable/spinner_ab_default_holo_light" />
 </selector>
diff --git a/core/res/res/layout/expanded_menu_layout.xml b/core/res/res/layout/expanded_menu_layout.xml
index 5d98773..f44a83f 100644
--- a/core/res/res/layout/expanded_menu_layout.xml
+++ b/core/res/res/layout/expanded_menu_layout.xml
@@ -16,5 +16,5 @@
 
 <com.android.internal.view.menu.ExpandedMenuView xmlns:android="http://schemas.android.com/apk/res/android"
 	android:id="@+android:id/expanded_menu" 
-	android:layout_width="296dip"
+	android:layout_width="?android:attr/panelMenuListWidth"
 	android:layout_height="wrap_content" />
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index c2536b7..452b982 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -24,15 +24,17 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:rowCount="7"
+    android:rowCount="8"
     android:id="@+id/root"
-    android:clipChildren="false">
+    android:clipChildren="false"
+    android:rowOrderPreserved="false">
 
     <!-- Column 0 -->
     <com.android.internal.widget.DigitalClock android:id="@+id/time"
         android:layout_marginTop="8dip"
         android:layout_marginBottom="8dip"
-        android:layout_gravity="right">
+        android:layout_gravity="right"
+        android:layout_rowSpan="2">
 
        <!-- Because we can't have multi-tone fonts, we render two TextViews, one on
         top of the other. Hence the redundant layout... -->
@@ -118,24 +120,33 @@
     />
 
     <!-- Column 1 -->
-    <Space android:layout_width="16dip" android:layout_rowSpan="7" />
+    <Space
+        android:layout_width="16dip"
+        android:layout_rowSpan="8"
+        android:layout_gravity="fill_vertical" />
 
     <!-- Column 2 - password entry field and PIN keyboard -->
-    <EditText android:id="@+id/passwordEntry"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:layout_gravity="fill"
-        android:gravity="center"
-        android:singleLine="true"
-        android:textStyle="normal"
-        android:inputType="textPassword"
-        android:textSize="24sp"
-        android:minEms="8"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:background="@drawable/lockscreen_password_field_dark"
-        android:textColor="?android:attr/textColorPrimary"
-        android:imeOptions="flagNoFullscreen|actionDone"
-        />
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="270dip"
+        android:layout_gravity="center_vertical">
+
+        <EditText android:id="@+id/passwordEntry"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:gravity="center"
+            android:singleLine="true"
+            android:textStyle="normal"
+            android:inputType="textPassword"
+            android:textSize="24sp"
+            android:minEms="8"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:background="@drawable/lockscreen_password_field_dark"
+            android:textColor="?android:attr/textColorPrimary"
+            android:imeOptions="flagNoFullscreen|actionDone"
+            />
+
+    </LinearLayout>
 
     <!-- Numeric keyboard -->
     <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
@@ -146,7 +157,7 @@
         android:layout_marginTop="5dip"
         android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
         android:visibility="gone"
-        android:layout_rowSpan="6"
+        android:layout_rowSpan="7"
     />
 
     <!-- Music transport control -->
@@ -154,7 +165,7 @@
         layout="@layout/keyguard_transport_control"
         android:layout_row="0"
         android:layout_column="0"
-        android:layout_rowSpan="5"
+        android:layout_rowSpan="6"
         android:layout_columnSpan="1"
         android:layout_gravity="fill"
         />
diff --git a/core/res/res/layout/list_menu_item_layout.xml b/core/res/res/layout/list_menu_item_layout.xml
index 57091a1..aaff4c7 100644
--- a/core/res/res/layout/list_menu_item_layout.xml
+++ b/core/res/res/layout/list_menu_item_layout.xml
@@ -16,7 +16,7 @@
 
 <com.android.internal.view.menu.ListMenuItemView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight">
+    android:layout_height="?android:attr/listPreferredItemHeightSmall">
     
     <!-- Icon will be inserted here. -->
     
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index fa9f1d1..753e4ac 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -217,14 +217,18 @@
        <item>@drawable/scrollbar_handle_vertical</item>
        <item>@drawable/spinner_background_holo_dark</item>
        <item>@drawable/spinner_background_holo_light</item>
-       <item>@drawable/spinner_cab_default_holo_dark</item>
-       <item>@drawable/spinner_cab_default_holo_light</item>
-       <item>@drawable/spinner_cab_disabled_holo_dark</item>
-       <item>@drawable/spinner_cab_disabled_holo_light</item>
-       <item>@drawable/spinner_cab_focused_holo_dark</item>
-       <item>@drawable/spinner_cab_focused_holo_light</item>
-       <item>@drawable/spinner_cab_pressed_holo_dark</item>
-       <item>@drawable/spinner_cab_pressed_holo_light</item>
+       <item>@drawable/spinner_ab_default_holo_dark</item>
+       <item>@drawable/spinner_ab_default_holo_light</item>
+       <item>@drawable/spinner_ab_disabled_holo_dark</item>
+       <item>@drawable/spinner_ab_disabled_holo_light</item>
+       <item>@drawable/spinner_ab_focused_holo_dark</item>
+       <item>@drawable/spinner_ab_focused_holo_light</item>
+       <item>@drawable/spinner_ab_pressed_holo_dark</item>
+       <item>@drawable/spinner_ab_pressed_holo_light</item>
+       <item>@drawable/spinner_ab_activated_holo_dark</item>
+       <item>@drawable/spinner_ab_activated_holo_light</item>
+       <item>@drawable/spinner_ab_holo_dark</item>
+       <item>@drawable/spinner_ab_holo_light</item>
        <item>@drawable/spinner_default_holo_dark</item>
        <item>@drawable/spinner_default_holo_light</item>
        <item>@drawable/spinner_disabled_holo_dark</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f70319b..63b49bd 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -439,6 +439,10 @@
         <!-- Default appearance of panel text. -->
         <attr name="panelTextAppearance" format="reference" />
 
+        <attr name="panelMenuIsCompact" format="boolean" />
+        <attr name="panelMenuListWidth" format="dimension" />
+        <attr name="panelMenuListTheme" format="reference" />
+
         <!-- =================== -->
         <!-- Other widget styles -->
         <!-- =================== -->
@@ -2220,6 +2224,34 @@
         <attr name="imeSubtypeExtraValue" format="string" />
     </declare-styleable>
 
+    <!-- Use <code>spell-checker</code> as the root tag of the XML resource that
+         describes an
+         {@link android.service.textservice.SpellCheckerService} service, which is
+         referenced from its
+         {@link android.view.textservice.SpellCheckerSession#SERVICE_META_DATA}
+         meta-data entry.  Described here are the attributes that can be
+         included in that tag. -->
+    <declare-styleable name="SpellChecker">
+        <!-- The name of the spell checker. -->
+        <attr name="label" />
+        <!-- Component name of an activity that allows the user to modify
+             the settings for this service. -->
+        <attr name="settingsActivity"/>
+    </declare-styleable>
+
+    <!-- This is the subtype of the spell checker. Subtype can describe locales (e.g. en_US, fr_FR...) -->
+    <declare-styleable name="SpellChecker_Subtype">
+        <!-- The name of the subtype. -->
+        <attr name="label" />
+        <!-- The locale of the subtype. This string should be a locale (e.g. en_US, fr_FR...)
+             This is also used by the framework to know the supported locales
+             of the spell checker.  -->
+        <attr name="subtypeLocale" format="string" />
+        <!-- The extra value of the subtype. This string can be any string and will be passed to
+             the SpellChecker.  -->
+        <attr name="subtypeExtraValue" format="string" />
+    </declare-styleable>
+
     <!-- Use <code>accessibility-service</code> as the root tag of the XML resource that
          describes an {@link android.accessibilityservice.AccessibilityService} service,
          which is referenced from its
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f85dd85..1ba54cf 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1785,6 +1785,9 @@
   <public type="attr" name="actionBarWidgetTheme" />
   <public type="attr" name="uiOptions" />
 
+  <public type="attr" name="subtypeLocale" />
+  <public type="attr" name="subtypeExtraValue" />
+
   <public type="style" name="TextAppearance.SuggestionHighlight" />
 
   <public type="style" name="Theme.Holo.Light.DarkActionBar" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6a3c2d5..aa4387e5 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -212,8 +212,8 @@
     <!-- android.net.http Error strings --> <skip />
     <!-- Displayed when a web request was successful. -->
     <string name="httpErrorOk">OK</string>
-    <!-- Displayed when a web request failed because we don't know the exact reason. -->
-    <string name="httpError">The Web page contains an error.</string>
+    <!-- Displayed when a web request failed with a generic network error. -->
+    <string name="httpError">A network error occurred.</string>
     <!-- Displayed when a web request failed because the URL could not be found. -->
     <string name="httpErrorLookup">The URL could not be found.</string>
     <!-- Displayed when a web request failed because the site's authentication scheme is not supported by us. -->
@@ -2583,10 +2583,10 @@
         <item quantity="other">Open Wi-Fi networks available</item>
     </plurals>
 
-     <!-- A notification is shown the first time a wireless network is disabled due to bad connectivity.  This is the notification's title / ticker. -->
-    <string name="wifi_watchdog_network_disabled">A Wi-Fi network was disabled</string>
-    <!--  A notification is shown the first time a wireless network is disabled due to bad connectivity.  This is the notification's message which leads to the settings pane -->
-    <string name="wifi_watchdog_network_disabled_detailed">A Wi-Fi network was temporarily disabled due to bad connectivity.</string>
+     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  This is the notification's title / ticker. -->
+     <string name="wifi_watchdog_network_disabled">Couldn\'t connect to Wi-Fi</string>
+     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  This is a partial string of the message, which will also include the (possibly truncated) hotspot name. -->
+    <string name="wifi_watchdog_network_disabled_detailed"> has a poor internet connection.</string>
 
     <!-- Do not translate. Default access point SSID used for tethering -->
     <string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 21f1cef..0c6e20f 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1744,6 +1744,7 @@
     </style>
 
     <style name="Widget.Holo.Spinner.DropDown.ActionBar">
+        <item name="android:background">@android:drawable/spinner_ab_holo_dark</item>
     </style>
 
     <style name="Widget.Holo.CompoundButton.Star" parent="Widget.CompoundButton.Star">
@@ -2131,6 +2132,7 @@
     </style>
 
     <style name="Widget.Holo.Light.Spinner.DropDown.ActionBar">
+        <item name="android:background">@android:drawable/spinner_ab_holo_light</item>
     </style>
 
     <style name="Widget.Holo.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 615a37d..82299b8 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -185,6 +185,9 @@
         <item name="panelColorForeground">?android:attr/textColorPrimary</item>
         <item name="panelTextAppearance">?android:attr/textAppearance</item>
 
+        <item name="panelMenuIsCompact">false</item>
+        <item name="panelMenuListWidth">296dip</item>
+
         <!-- Scrollbar attributes -->
         <item name="scrollbarFadeDuration">250</item>
         <item name="scrollbarDefaultDelayBeforeFade">300</item> 
@@ -755,6 +758,22 @@
         <item name="android:background">@null</item>
     </style>
 
+    <style name="Theme.Holo.CompactMenu">
+        <!-- Menu/item attributes -->
+        <item name="android:itemTextAppearance">?android:attr/textAppearanceMedium</item>
+        <item name="android:listViewStyle">@android:style/Widget.Holo.ListView</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.DropDownUp</item>
+        <item name="android:background">@null</item>
+    </style>
+
+    <style name="Theme.Holo.Light.CompactMenu">
+        <!-- Menu/item attributes -->
+        <item name="android:itemTextAppearance">?android:attr/textAppearanceMedium</item>
+        <item name="android:listViewStyle">@android:style/Widget.Holo.Light.ListView</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.DropDownUp</item>
+        <item name="android:background">@null</item>
+    </style>
+
     <!-- @hide -->
     <style name="Theme.Dialog.AppError" parent="Theme.Holo.Dialog">
         <item name="windowFrame">@null</item>
@@ -947,13 +966,17 @@
         <item name="toastFrameBackground">@android:drawable/toast_frame_holo</item>
         
         <!-- Panel attributes -->
-        <item name="panelBackground">@android:drawable/menu_background</item>
+        <item name="panelBackground">@android:drawable/menu_dropdown_panel_holo_dark</item>
         <item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>
         <!-- These three attributes do not seems to be used by the framework. Declared public though -->
         <item name="panelColorBackground">#000</item>
         <item name="panelColorForeground">?android:attr/textColorPrimary</item>
         <item name="panelTextAppearance">?android:attr/textAppearance</item>
 
+        <item name="panelMenuIsCompact">true</item>
+        <item name="panelMenuListWidth">250dip</item>
+        <item name="panelMenuListTheme">@android:style/Theme.Holo.CompactMenu</item>
+
         <!-- Scrollbar attributes -->
         <item name="scrollbarFadeDuration">250</item>
         <item name="scrollbarDefaultDelayBeforeFade">300</item> 
@@ -1244,13 +1267,17 @@
         <item name="toastFrameBackground">@android:drawable/toast_frame_holo</item>
         
         <!-- Panel attributes -->
-        <item name="panelBackground">@android:drawable/menu_background</item>
+        <item name="panelBackground">@android:drawable/menu_dropdown_panel_holo_light</item>
         <item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item>
         <!-- These three attributes do not seems to be used by the framework. Declared public though -->
         <item name="panelColorBackground">#000</item>
         <item name="panelColorForeground">?android:attr/textColorPrimary</item>
         <item name="panelTextAppearance">?android:attr/textAppearance</item>
 
+        <item name="panelMenuIsCompact">true</item>
+        <item name="panelMenuListWidth">250dip</item>
+        <item name="panelMenuListTheme">@android:style/Theme.Holo.Light.CompactMenu</item>
+
         <!-- Scrollbar attributes -->
         <item name="scrollbarFadeDuration">250</item>
         <item name="scrollbarDefaultDelayBeforeFade">300</item>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index ef98a6a..49d6b62 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -677,20 +677,36 @@
   <td>The application uses basic touch interaction events, such as "click down", "click
 up", and drag.</td>
   <td>When declared, this indicates that the application is compatible with a device that offers an
-emulated touchscreen (or better). A device that offers an emulated touchscreen provides a user input
-system that can emulate a subset of touchscreen capabilities. An example of such an input system is
-a mouse or remote control that drives an on-screen cursor. If your application does not require
-complicated gestures and you want your application available to devices that use an on-screen
-cursor to emulate touch events, you should declare this feature.</td>
+emulated touchscreen ("fake touch" interface), or better. A device that offers a fake touch 
+interface provides a user input system that emulates a subset of touchscreen capabilities. For
+example, a mouse or remote control that drives an on-screen cursor provides a fake touch interface.
+If your application requires only basic point and click interaction, you should declare this
+feature. Because this is the minimum level of touch interaction, your app will also be compatible
+with devices that offer more complex touch interfaces.
+  <p class="note"><strong>Note:</strong> Because applications require the {@code
+android.hardware.touchscreen} feature by default, if you want your application to be available to
+devices that provide a fake touch interface, you must also explicitly declare that a touch screen is
+<em>not</em> required by declaring {@code &lt;uses-feature
+android:name="android.hardware.touchscreen" <strong>android:required="false"</strong>
+/&gt;}</p></td>
 </tr>
 <tr>
   <td><code>android.hardware.touchscreen</code></td>
-  <td>The application uses touchscreen capabilities, for gestures more interactive
-than basic touches, such as a fling. This is a superset of the faketouch features.</td>
-  <td>By default, this is assumed to be required, unless you declare
-<code>android.hardware.faketouch</code> (the subset touch mode). As such, your application is
-<em>not</em> available to devices that provide only an emulated touch interface ("fake touch") by
-default.</td>
+  <td>The application uses touchscreen capabilities for gestures that are more interactive
+than basic touch events, such as a fling. This is a superset of the faketouch features.</td>
+  <td>By default, your application requires this. As such, your application is
+<em>not</em> available to devices that provide only an emulated touch interface ("fake touch"), by
+default. If you want your application available to devices that provide a fake touch interface,
+you must explicitly declare that a touch screen is not required, by
+declaring {@code android.hardware.touchscreen} with {@code android:required="false"}. You should
+do so even if your application uses&mdash;but does not <em>require</em>&mdash;a real touch screen
+interface.
+<p>If your application <em>does require</em> a basic touch interface (in order to perform touch
+gestures such as a fling), then you don't need to do anything, because this is required by default.
+However, it's best if you explicitly declare all features used by your application, so you should
+still declare this if your app uses it.</p>
+  <p>If you require more complex touch interaction, such as multi-finger gestures, you
+should declare the advanced touch screen features below.</p></td>
 </tr>
 <tr>
   <td><code>android.hardware.touchscreen.multitouch</code></td>
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 4856ab6..571b895 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -19,6 +19,8 @@
 import java.lang.reflect.Field;
 
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -28,6 +30,7 @@
 import android.view.Surface;
 
 
+
 /**
  * RenderScript base master class.  An instance of this class creates native
  * worker threads for processing commands from this object.  This base class
@@ -79,26 +82,26 @@
 
     // Methods below are wrapped to protect the non-threadsafe
     // lockless fifo.
-    native int  rsnContextCreateGL(int dev, int ver,
+    native int  rsnContextCreateGL(int dev, int ver, int sdkVer,
                  int colorMin, int colorPref,
                  int alphaMin, int alphaPref,
                  int depthMin, int depthPref,
                  int stencilMin, int stencilPref,
                  int samplesMin, int samplesPref, float samplesQ, int dpi);
-    synchronized int nContextCreateGL(int dev, int ver,
+    synchronized int nContextCreateGL(int dev, int ver, int sdkVer,
                  int colorMin, int colorPref,
                  int alphaMin, int alphaPref,
                  int depthMin, int depthPref,
                  int stencilMin, int stencilPref,
                  int samplesMin, int samplesPref, float samplesQ, int dpi) {
-        return rsnContextCreateGL(dev, ver, colorMin, colorPref,
+        return rsnContextCreateGL(dev, ver, sdkVer, colorMin, colorPref,
                                   alphaMin, alphaPref, depthMin, depthPref,
                                   stencilMin, stencilPref,
                                   samplesMin, samplesPref, samplesQ, dpi);
     }
-    native int  rsnContextCreate(int dev, int ver);
-    synchronized int nContextCreate(int dev, int ver) {
-        return rsnContextCreate(dev, ver);
+    native int  rsnContextCreate(int dev, int ver, int sdkVer);
+    synchronized int nContextCreate(int dev, int ver, int sdkVer) {
+        return rsnContextCreate(dev, ver, sdkVer);
     }
     native void rsnContextDestroy(int con);
     synchronized void nContextDestroy() {
@@ -864,6 +867,16 @@
         return mApplicationContext;
     }
 
+    static int getTargetSdkVersion(Context ctx) {
+        try {
+            PackageManager pm = ctx.getPackageManager();
+            ApplicationInfo app = pm.getApplicationInfo(ctx.getPackageName(), 0);
+            return app.targetSdkVersion;
+        } catch (Exception e) {
+            throw new RSDriverException("Error calculating target SDK version for RS.");
+        }
+    }
+
     /**
      * Create a basic RenderScript context.
      *
@@ -873,8 +886,10 @@
     public static RenderScript create(Context ctx) {
         RenderScript rs = new RenderScript(ctx);
 
+        int sdkVersion = getTargetSdkVersion(ctx);
+
         rs.mDev = rs.nDeviceCreate();
-        rs.mContext = rs.nContextCreate(rs.mDev, 0);
+        rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion);
         if (rs.mContext == 0) {
             throw new RSDriverException("Failed to create RS context.");
         }
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 935b75a..2dfcc83f 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -160,11 +160,13 @@
         super(ctx);
         mSurfaceConfig = new SurfaceConfig(sc);
 
+        int sdkVersion = getTargetSdkVersion(ctx);
+
         mWidth = 0;
         mHeight = 0;
         mDev = nDeviceCreate();
         int dpi = ctx.getResources().getDisplayMetrics().densityDpi;
-        mContext = nContextCreateGL(mDev, 0,
+        mContext = nContextCreateGL(mDev, 0, sdkVersion,
                                     mSurfaceConfig.mColorMin, mSurfaceConfig.mColorPref,
                                     mSurfaceConfig.mAlphaMin, mSurfaceConfig.mAlphaPref,
                                     mSurfaceConfig.mDepthMin, mSurfaceConfig.mDepthPref,
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 3476bd5..d7ac5d8 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -149,14 +149,14 @@
 }
 
 static jint
-nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver)
+nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer)
 {
     LOG_API("nContextCreate");
-    return (jint)rsContextCreate((RsDevice)dev, ver);
+    return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer);
 }
 
 static jint
-nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver,
+nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer,
                  int colorMin, int colorPref,
                  int alphaMin, int alphaPref,
                  int depthMin, int depthPref,
@@ -176,7 +176,7 @@
     sc.samplesQ = samplesQ;
 
     LOG_API("nContextCreateGL");
-    return (jint)rsContextCreateGL((RsDevice)dev, ver, sc, dpi);
+    return (jint)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
 }
 
 static void
@@ -1213,8 +1213,8 @@
 
 
 // All methods below are thread protected in java.
-{"rsnContextCreate",                 "(II)I",                                 (void*)nContextCreate },
-{"rsnContextCreateGL",               "(IIIIIIIIIIIIFI)I",                     (void*)nContextCreateGL },
+{"rsnContextCreate",                 "(III)I",                                (void*)nContextCreate },
+{"rsnContextCreateGL",               "(IIIIIIIIIIIIIFI)I",                    (void*)nContextCreateGL },
 {"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
 {"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
 {"rsnContextSetSurface",             "(IIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 535f713..3ba0123 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -52,8 +52,8 @@
 RsDevice rsDeviceCreate();
 void rsDeviceDestroy(RsDevice dev);
 void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value);
-RsContext rsContextCreate(RsDevice dev, uint32_t version);
-RsContext rsContextCreateGL(RsDevice dev, uint32_t version, RsSurfaceConfig sc, uint32_t dpi);
+RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion);
+RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion, RsSurfaceConfig sc, uint32_t dpi);
 
 #include "rsgApiFuncDecl.h"
 
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 86bec6e..fb2df37 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -19,7 +19,7 @@
 #include "rsdBcc.h"
 #include "rsdRuntime.h"
 
-#include <bcinfo/bcinfo.h>
+#include <bcinfo/MetadataExtractor.h>
 
 #include "rsContext.h"
 #include "rsScriptC.h"
@@ -40,7 +40,7 @@
 
     BCCScriptRef mBccScript;
 
-    struct BCScriptMetadata *mScriptMetadata;
+    bcinfo::MetadataExtractor *ME;
 
     InvokeFunc_t *mInvokeFunctions;
     void ** mFieldAddress;
@@ -71,7 +71,9 @@
 
     pthread_mutex_lock(&rsdgInitMutex);
     char *cachePath = NULL;
-    struct BCScriptMetadata *md = NULL;
+    size_t exportFuncCount = 0;
+    size_t exportVarCount = 0;
+    size_t objectSlotCount = 0;
 
     DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
     if (drv == NULL) {
@@ -84,13 +86,13 @@
     drv->mScriptText = bitcode;
     drv->mScriptTextLength = bitcodeSize;
 
-    md = bcinfoGetScriptMetadata((const char*)drv->mScriptText,
-                                 drv->mScriptTextLength, 0);
-    if (!md) {
+
+    drv->ME = new bcinfo::MetadataExtractor((const char*)drv->mScriptText,
+                                            drv->mScriptTextLength);
+    if (!drv->ME->extract()) {
       LOGE("bcinfo: failed to read script metadata");
       goto error;
     }
-    drv->mScriptMetadata = md;
 
     //LOGE("mBccScript %p", script->mBccScript);
 
@@ -122,40 +124,41 @@
     drv->mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(drv->mBccScript, "root"));
     drv->mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, "init"));
 
-    if (md->exportFuncCount > 0) {
-        drv->mInvokeFunctions = (InvokeFunc_t*) calloc(md->exportFuncCount,
+    exportFuncCount = drv->ME->getExportFuncCount();
+    if (exportFuncCount > 0) {
+        drv->mInvokeFunctions = (InvokeFunc_t*) calloc(exportFuncCount,
                                                        sizeof(InvokeFunc_t));
-        bccGetExportFuncList(drv->mBccScript,
-                             md->exportFuncCount,
+        bccGetExportFuncList(drv->mBccScript, exportFuncCount,
                              (void **) drv->mInvokeFunctions);
     } else {
         drv->mInvokeFunctions = NULL;
     }
 
-    if (md->exportVarCount > 0) {
-        drv->mFieldAddress = (void **) calloc(md->exportVarCount,
-                                              sizeof(void*));
-        drv->mFieldIsObject = (bool *) calloc(md->exportVarCount, sizeof(bool));
-        bccGetExportVarList(drv->mBccScript,
-                            md->exportVarCount,
+    exportVarCount = drv->ME->getExportVarCount();
+    if (exportVarCount > 0) {
+        drv->mFieldAddress = (void **) calloc(exportVarCount, sizeof(void*));
+        drv->mFieldIsObject = (bool *) calloc(exportVarCount, sizeof(bool));
+        bccGetExportVarList(drv->mBccScript, exportVarCount,
                             (void **) drv->mFieldAddress);
     } else {
         drv->mFieldAddress = NULL;
         drv->mFieldIsObject = NULL;
     }
 
-    if (md->objectSlotCount) {
-        for (uint32_t ct=0; ct < md->objectSlotCount; ct++) {
-            drv->mFieldIsObject[md->objectSlotList[ct]] = true;
+    objectSlotCount = drv->ME->getObjectSlotCount();
+    if (objectSlotCount > 0) {
+        const uint32_t *objectSlotList = drv->ME->getObjectSlotList();
+        for (uint32_t ct=0; ct < objectSlotCount; ct++) {
+            drv->mFieldIsObject[objectSlotList[ct]] = true;
         }
     }
 
     // Copy info over to runtime
-    script->mHal.info.exportedFunctionCount = md->exportFuncCount;
-    script->mHal.info.exportedVariableCount = md->exportVarCount;
-    script->mHal.info.exportedPragmaCount = md->pragmaCount;
-    script->mHal.info.exportedPragmaKeyList = md->pragmaKeyList;
-    script->mHal.info.exportedPragmaValueList = md->pragmaValueList;
+    script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount();
+    script->mHal.info.exportedVariableCount = drv->ME->getExportVarCount();
+    script->mHal.info.exportedPragmaCount = drv->ME->getPragmaCount();
+    script->mHal.info.exportedPragmaKeyList = drv->ME->getPragmaKeyList();
+    script->mHal.info.exportedPragmaValueList = drv->ME->getPragmaValueList();
     script->mHal.info.root = drv->mRoot;
 
     pthread_mutex_unlock(&rsdgInitMutex);
@@ -164,6 +167,10 @@
 error:
 
     pthread_mutex_unlock(&rsdgInitMutex);
+    if (drv->ME) {
+        delete drv->ME;
+        drv->ME = NULL;
+    }
     free(drv);
     return false;
 
@@ -445,10 +452,10 @@
 
 void rsdScriptDestroy(const Context *dc, Script *script) {
     DrvScript *drv = (DrvScript *)script->mHal.drv;
-    struct BCScriptMetadata *md = drv->mScriptMetadata;
 
     if (drv->mFieldAddress) {
-        for (size_t ct = 0; ct < md->exportVarCount; ct++) {
+        size_t exportVarCount = drv->ME->getExportVarCount();
+        for (size_t ct = 0; ct < exportVarCount; ct++) {
             if (drv->mFieldIsObject[ct]) {
                 // The field address can be NULL if the script-side has
                 // optimized the corresponding global variable away.
@@ -467,7 +474,8 @@
         drv->mInvokeFunctions = NULL;
     }
 
-    bcinfoReleaseScriptMetadata(&drv->mScriptMetadata);
+    delete drv->ME;
+    drv->ME = NULL;
 
     free(drv);
     script->mHal.drv = NULL;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index decd9f1..6a30b17 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -333,6 +333,7 @@
     mPaused = false;
     mObjHead = NULL;
     mError = RS_ERROR_NONE;
+    mTargetSdkVersion = 14;
     mDPI = 96;
     mIsContextLite = false;
 }
@@ -678,19 +679,25 @@
 }
 }
 
-RsContext rsContextCreate(RsDevice vdev, uint32_t version) {
+RsContext rsContextCreate(RsDevice vdev, uint32_t version,
+                          uint32_t sdkVersion) {
     LOGV("rsContextCreate %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, NULL);
+    if (rsc) {
+        rsc->setTargetSdkVersion(sdkVersion);
+    }
     return rsc;
 }
 
 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
-                            RsSurfaceConfig sc, uint32_t dpi) {
+                            uint32_t sdkVersion, RsSurfaceConfig sc,
+                            uint32_t dpi) {
     LOGV("rsContextCreateGL %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, &sc);
     if (rsc) {
+        rsc->setTargetSdkVersion(sdkVersion);
         rsc->setDPI(dpi);
     }
     LOGV("rsContextCreateGL ret %p ", rsc);
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 309fe95..3c7a3d2 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -199,9 +199,13 @@
     uint32_t getDPI() const {return mDPI;}
     void setDPI(uint32_t dpi) {mDPI = dpi;}
 
+    uint32_t getTargetSdkVersion() const {return mTargetSdkVersion;}
+    void setTargetSdkVersion(uint32_t sdkVer) {mTargetSdkVersion = sdkVer;}
+
     Device *mDev;
 protected:
 
+    uint32_t mTargetSdkVersion;
     uint32_t mDPI;
     uint32_t mWidth;
     uint32_t mHeight;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index e8b1014..dccf71f 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -19,6 +19,10 @@
 #include "utils/Timers.h"
 #include "utils/StopWatch.h"
 
+#ifndef ANDROID_RS_SERIALIZE
+#include <bcinfo/BitcodeTranslator.h>
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
@@ -28,9 +32,18 @@
     ScriptC * sc = (ScriptC *) tls->mScript
 
 ScriptC::ScriptC(Context *rsc) : Script(rsc) {
+#ifndef ANDROID_RS_SERIALIZE
+    BT = NULL;
+#endif
 }
 
 ScriptC::~ScriptC() {
+#ifndef ANDROID_RS_SERIALIZE
+    if (BT) {
+        delete BT;
+        BT = NULL;
+    }
+#endif
     mRSC->mHal.funcs.script.destroy(mRSC, this);
 }
 
@@ -181,6 +194,22 @@
                           size_t bitcodeLen) {
 
     //LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
+#ifndef ANDROID_RS_SERIALIZE
+    uint32_t sdkVersion = rsc->getTargetSdkVersion();
+    if (BT) {
+        delete BT;
+    }
+    BT = new bcinfo::BitcodeTranslator((const char *)bitcode, bitcodeLen,
+                                       sdkVersion);
+    if (!BT->translate()) {
+        LOGE("Failed to translate bitcode from version: %u", sdkVersion);
+        delete BT;
+        BT = NULL;
+        return false;
+    }
+    bitcode = (const uint8_t *) BT->getTranslatedBitcode();
+    bitcodeLen = BT->getTranslatedBitcodeSize();
+#endif
 
     rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0);
 
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 5c191d9..c65a5bf 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -21,6 +21,9 @@
 
 #include "RenderScriptEnv.h"
 
+#ifndef ANDROID_RS_SERIALIZE
+#include "bcinfo/BitcodeTranslator.h"
+#endif
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -61,6 +64,10 @@
     void setupScript(Context *);
     void setupGLState(Context *);
     Script * setTLS(Script *);
+  private:
+#ifndef ANDROID_RS_SERIALIZE
+    bcinfo::BitcodeTranslator *BT;
+#endif
 };
 
 class ScriptCState {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e7a306b..ed6d87e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1757,6 +1757,26 @@
 
     /**
      * @hide
+     * Returns the current remote control client.
+     * @param rcClientId the counter value that matches the extra
+     *     {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the
+     *     {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event
+     * @return the current IRemoteControlClient from which information to display on the remote
+     *     control can be retrieved, or null if rcClientId doesn't match the current generation
+     *     counter.
+     */
+    public IRemoteControlClient getRemoteControlClient(int rcClientId) {
+        IAudioService service = getService();
+        try {
+            return service.getRemoteControlClient(rcClientId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in getRemoteControlClient "+e);
+            return null;
+        }
+    }
+
+    /**
+     * @hide
      * Definitions of constants to be used in {@link android.media.IRemoteControlClient}.
      */
     public final class RemoteControlParameters {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index bf1585d..cb56bc6 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -2845,20 +2845,20 @@
         }
     }
 
-    private final static Object mCurrentRcLock = new Object();
+    private final Object mCurrentRcLock = new Object();
     /**
      * The one remote control client to be polled for display information.
      * This object is never null, but its reference might.
      * Access protected by mCurrentRcLock.
      */
-    private static SoftReference<IRemoteControlClient> mCurrentRcClientRef =
+    private SoftReference<IRemoteControlClient> mCurrentRcClientRef =
             new SoftReference<IRemoteControlClient>(null);
 
     /**
      * A monotonically increasing generation counter for mCurrentRcClientRef.
      * Only accessed with a lock on mCurrentRcLock.
      */
-    private static int mCurrentRcClientGen = 0;
+    private int mCurrentRcClientGen = 0;
 
     /**
      * Returns the current remote control client.
@@ -2869,7 +2869,7 @@
      *     control can be retrieved, or null if rcClientId doesn't match the current generation
      *     counter.
      */
-    public static IRemoteControlClient getRemoteControlClient(int rcClientId) {
+    public IRemoteControlClient getRemoteControlClient(int rcClientId) {
         synchronized(mCurrentRcLock) {
             if (rcClientId == mCurrentRcClientGen) {
                 return mCurrentRcClientRef.get();
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 9afe553..25b9a1b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -93,6 +93,8 @@
     void registerRemoteControlClient(in ComponentName eventReceiver,
            in IRemoteControlClient rcClient, in String callingPackageName);
 
+    IRemoteControlClient getRemoteControlClient(in int rcClientId);
+
     void notifyRemoteControlInformationChanged(in ComponentName eventReceiver);
 
     void startBluetoothSco(IBinder cb);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 8339e4b..02017a1 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -307,7 +307,7 @@
     private Uri mThumbsUri;
     private Uri mPlaylistsUri;
     private Uri mFilesUri;
-    private boolean mProcessPlaylists;
+    private boolean mProcessPlaylists, mProcessGenres;
     private int mMtpObjectHandle;
 
     private final String mExternalStoragePath;
@@ -612,7 +612,8 @@
                 mAlbum = value.trim();
             } else if (name.equalsIgnoreCase("composer") || name.startsWith("composer;")) {
                 mComposer = value.trim();
-            } else if (name.equalsIgnoreCase("genre") || name.startsWith("genre;")) {
+            } else if (mProcessGenres &&
+                    (name.equalsIgnoreCase("genre") || name.startsWith("genre;"))) {
                 mGenre = getGenreName(value);
             } else if (name.equalsIgnoreCase("year") || name.startsWith("year;")) {
                 mYear = parseSubstring(value, 0, 0);
@@ -1151,6 +1152,7 @@
         if (!volumeName.equals("internal")) {
             // we only support playlists on external media
             mProcessPlaylists = true;
+            mProcessGenres = true;
             mPlaylistsUri = Playlists.getContentUri(volumeName);
 
             mCaseInsensitivePaths = true;
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
index 7dfa53e..6504435 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
@@ -21,13 +21,15 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="match_parent" 
               android:layout_height="match_parent"
-              android:orientation="vertical"
-              android:padding="16dp" >
+              android:orientation="vertical" >
 
-    <ScrollView 
+    <ScrollView
             android:layout_height="0dp"
             android:layout_weight="1"
-            android:layout_width="match_parent">
+            android:layout_width="match_parent"
+            android:padding="16dp"
+            android:clipToPadding="false" >
+
         <LinearLayout
                 android:orientation="vertical"
                 android:layout_height="wrap_content"
@@ -76,24 +78,29 @@
         </LinearLayout>
     </ScrollView>
 
+    <!-- button bar divider -->
+    <View android:background="?android:attr/dividerHorizontal"
+          android:layout_height="1dp"
+          android:layout_width="match_parent" />
+
+    <!-- button bar -->
     <LinearLayout android:orientation="horizontal"
+                  style="?android:attr/buttonBarStyle"                 
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:layout_gravity="bottom">
 
-    <Button android:id="@+id/button_allow"
-            android:filterTouchesWhenObscured="true"
-            android:text="@string/allow_backup_button_label"
-            android:layout_below="@id/package_name"
+    <Button android:id="@+id/button_deny"
+            style="?android:attr/buttonBarButtonStyle"
+            android:text="@string/deny_backup_button_label"
             android:layout_height="wrap_content"
             android:layout_width="0dp"
             android:layout_weight="1" />
 
-    <Button android:id="@+id/button_deny"
-            android:text="@string/deny_backup_button_label"
-            android:layout_below="@id/package_name"
-            android:layout_toRightOf="@id/button_allow"
-            android:layout_alignTop="@id/button_allow"
+    <Button android:id="@+id/button_allow"
+            style="?android:attr/buttonBarButtonStyle"
+            android:filterTouchesWhenObscured="true"
+            android:text="@string/allow_backup_button_label"
             android:layout_height="wrap_content"
             android:layout_width="0dp"
             android:layout_weight="1" />
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
index 4927cbb..3522e7c 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
@@ -76,24 +76,29 @@
         </LinearLayout>
     </ScrollView>
 
+    <!-- button bar divider -->
+    <View android:background="?android:attr/dividerHorizontal"
+          android:layout_height="1dp"
+          android:layout_width="match_parent" />
+
+    <!-- button bar -->
     <LinearLayout android:orientation="horizontal"
+                  style="?android:attr/buttonBarStyle"                 
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:layout_gravity="bottom">
 
-        <Button android:id="@+id/button_allow"
-                android:filterTouchesWhenObscured="true"
-                android:text="@string/allow_restore_button_label"
-                android:layout_below="@id/package_name"
+        <Button android:id="@+id/button_deny"
+                style="?android:attr/buttonBarButtonStyle"
+                android:text="@string/deny_restore_button_label"
                 android:layout_height="wrap_content"
                 android:layout_width="0dp"
                 android:layout_weight="1" />
 
-        <Button android:id="@+id/button_deny"
-                android:text="@string/deny_restore_button_label"
-                android:layout_below="@id/package_name"
-                android:layout_toRightOf="@id/button_allow"
-                android:layout_alignTop="@id/button_allow"
+        <Button android:id="@+id/button_allow"
+                style="?android:attr/buttonBarButtonStyle"
+                android:filterTouchesWhenObscured="true"
+                android:text="@string/allow_restore_button_label"
                 android:layout_height="wrap_content"
                 android:layout_width="0dp"
                 android:layout_weight="1" />
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index f65a62f..5448e0b 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -48,6 +48,8 @@
     static final String TAG = "BackupRestoreConfirmation";
     static final boolean DEBUG = true;
 
+    static final String DID_ACKNOWLEDGE = "did_acknowledge";
+
     static final int MSG_START_BACKUP = 1;
     static final int MSG_BACKUP_PACKAGE = 2;
     static final int MSG_END_BACKUP = 3;
@@ -149,7 +151,13 @@
         mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService(Context.BACKUP_SERVICE));
 
         mHandler = new ObserverHandler(getApplicationContext());
-        mObserver = new FullObserver();
+        final Object oldObserver = getLastNonConfigurationInstance();
+        if (oldObserver == null) {
+            mObserver = new FullObserver(mHandler);
+        } else {
+            mObserver = (FullObserver) oldObserver;
+            mObserver.setHandler(mHandler);
+        }
 
         setContentView(layoutId);
 
@@ -189,16 +197,24 @@
                 mDenyButton.setEnabled(false);
             }
         });
+
+        // if we're a relaunch we may need to adjust button enable state
+        if (icicle != null) {
+            mDidAcknowledge = icicle.getBoolean(DID_ACKNOWLEDGE, false);
+            mAllowButton.setEnabled(!mDidAcknowledge);
+            mDenyButton.setEnabled(!mDidAcknowledge);
+        }
+    }
+
+    // Preserve the restore observer callback binder across activity relaunch
+    @Override
+    public Object onRetainNonConfigurationInstance() {
+        return mObserver;
     }
 
     @Override
-    public void onStop() {
-        super.onStop();
-
-        // We explicitly equate departure from the UI with refusal.  This includes the
-        // implicit configuration-changed stop/restart cycle.
-        sendAcknowledgement(mToken, false, null);
-        finish();
+    protected void onSaveInstanceState(Bundle outState) {
+        outState.putBoolean(DID_ACKNOWLEDGE, mDidAcknowledge);
     }
 
     void sendAcknowledgement(int token, boolean allow, IFullBackupRestoreObserver observer) {
@@ -230,6 +246,16 @@
      * the notifications onto the main thread.
      */
     class FullObserver extends IFullBackupRestoreObserver.Stub {
+        private Handler mHandler;
+
+        public FullObserver(Handler h) {
+            mHandler = h;
+        }
+
+        public void setHandler(Handler h) {
+            mHandler = h;
+        }
+
         //
         // IFullBackupRestoreObserver implementation
         //
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index f527447..f4890e0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -907,20 +907,12 @@
         if (upgradeVersion == 68) {
             // Enable all system sounds by default
             db.beginTransaction();
-            SQLiteStatement stmt = null;
             try {
-                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
-                        + " VALUES(?,?);");
-                loadDefaultHapticSettings(stmt);
-                loadUISoundEffectsSettings(stmt);
                 db.execSQL("DELETE FROM system WHERE name='"
                         + Settings.System.NOTIFICATIONS_USE_RING_VOLUME + "'");
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
-                if (stmt != null)
-                    stmt.close();
             }
             upgradeVersion = 69;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 7cc5ff7..e1231a5 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -93,9 +93,12 @@
             }
 
             super.onCreate(surfaceHolder);
-            IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
-            mReceiver = new WallpaperObserver();
-            registerReceiver(mReceiver, filter, null, mHandler);
+            
+            // Don't need this currently because the wallpaper service
+            // will restart the image wallpaper whenever the image changes.
+            //IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
+            //mReceiver = new WallpaperObserver();
+            //registerReceiver(mReceiver, filter, null, mHandler);
 
             updateSurfaceSize(surfaceHolder);
         }
@@ -103,7 +106,9 @@
         @Override
         public void onDestroy() {
             super.onDestroy();
-            unregisterReceiver(mReceiver);
+            if (mReceiver != null) {
+                unregisterReceiver(mReceiver);
+            }
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4ce1c89..7d1aedc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1366,7 +1366,7 @@
         } else if (CHATTY) {
             if (event.getAction() == MotionEvent.ACTION_DOWN) {
                 Slog.d(TAG, String.format(
-                            "panel: ACTION_DOWN at (%d, %d) mDisabled=0x%08x",
+                            "panel: ACTION_DOWN at (%f, %f) mDisabled=0x%08x",
                             event.getRawX(), event.getRawY(), mDisabled));
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index ae19cb1..7f56d45 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -1077,7 +1077,10 @@
 
         mCompatModeButton.refresh();
         if (mCompatModeButton.getVisibility() == View.VISIBLE) {
+            if (DEBUG_COMPAT_HELP
+                    || ! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) {
                 showCompatibilityHelp();
+            }
         } else {
             hideCompatibilityHelp();
             mCompatModePanel.closePanel();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 21a8c14..afa92f1 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -266,7 +266,7 @@
                 case OWNER_INFO:
                 case CARRIER_TEXT:
                 default:
-                    Log.w(TAG, "Not showing message id " + what + ", str=" + string);
+                    if (DEBUG) Log.w(TAG, "Not showing message id " + what + ", str=" + string);
             }
         } else {
             updateStatusLines(mShowingStatus);
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 7faf1a4..77f1932 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Configuration;
 import android.database.ContentObserver;
 import static android.os.BatteryManager.BATTERY_STATUS_CHARGING;
 import static android.os.BatteryManager.BATTERY_STATUS_FULL;
@@ -29,7 +28,6 @@
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.Message;
-import android.os.SystemClock;
 import android.provider.Settings;
 import android.provider.Telephony;
 import static android.provider.Telephony.Intents.EXTRA_PLMN;
@@ -503,7 +501,8 @@
         if (!mSimStateCallbacks.contains(callback)) {
             mSimStateCallbacks.add(callback);
         } else {
-            Log.e(TAG, "Object tried to add another SIM callback", new Exception("Whoops"));
+            if (DEBUG) Log.e(TAG, "Object tried to add another SIM callback",
+                    new Exception("Whoops"));
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index e5a7d64..6ee5861 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -127,10 +127,10 @@
         }
 
         if (enableScreenRotation) {
-            Log.d(TAG, "Rotation sensor for lock screen On!");
+            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");
             mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
         } else {
-            Log.d(TAG, "Rotation sensor for lock screen Off!");
+            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");
             mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
         }
 
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 47d34b3..ee6d2ee 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -646,7 +646,7 @@
      * @see #onWakeKeyWhenKeyguardShowingTq(int)
      */
     private void wakeWhenReadyLocked(int keyCode) {
-        if (true || DBG_WAKE) Log.d(TAG, "wakeWhenReadyLocked(" + keyCode + ")");
+        if (DBG_WAKE) Log.d(TAG, "wakeWhenReadyLocked(" + keyCode + ")");
 
         /**
          * acquire the handoff lock that will keep the cpu running.  this will
@@ -741,7 +741,7 @@
 
                 int sequence = intent.getIntExtra("seq", 0);
 
-                if (false) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
+                if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
                         + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
 
                 if (mDelayedShowingSequence == sequence) {
@@ -1033,13 +1033,15 @@
                         sfx.setStreamType(AudioManager.STREAM_SYSTEM);
                         sfx.play();
                     } else {
-                        Log.d(TAG, "playSounds: failed to load ringtone from uri: " + soundUri);
+                        if (DEBUG) Log.d(TAG, "playSounds: failed to load ringtone from uri: "
+                                + soundUri);
                     }
                 } else {
-                    Log.d(TAG, "playSounds: could not parse Uri: " + soundPath);
+                    if (DEBUG) Log.d(TAG, "playSounds: could not parse Uri: " + soundPath);
                 }
             } else {
-                Log.d(TAG, "playSounds: whichSound = " + whichSound + "; soundPath was null");
+                if (DEBUG) Log.d(TAG, "playSounds: whichSound = " + whichSound
+                        + "; soundPath was null");
             }
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 14f7c11..6dd4948 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -51,8 +51,11 @@
 import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.AndroidRuntimeException;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -61,6 +64,8 @@
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.Gravity;
+import android.view.IRotationWatcher;
+import android.view.IWindowManager;
 import android.view.InputQueue;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -85,6 +90,9 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
 /**
  * Android-specific Window.
  * <p>
@@ -177,6 +185,13 @@
 
     private int mUiOptions = 0;
 
+    static class WindowManagerHolder {
+        static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
+                ServiceManager.getService("window"));
+    }
+
+    static final RotationWatcher sRotationWatcher = new RotationWatcher();
+
     public PhoneWindow(Context context) {
         super(context);
         mLayoutInflater = LayoutInflater.from(context);
@@ -415,8 +430,8 @@
                     if (st.iconMenuPresenter != null) {
                         st.iconMenuPresenter.saveHierarchyState(state);
                     }
-                    if (st.expandedMenuPresenter != null) {
-                        st.expandedMenuPresenter.saveHierarchyState(state);
+                    if (st.listMenuPresenter != null) {
+                        st.listMenuPresenter.saveHierarchyState(state);
                     }
 
                     // Remove the menu views since they need to be recreated
@@ -430,8 +445,8 @@
                     if (st.iconMenuPresenter != null) {
                         st.iconMenuPresenter.restoreHierarchyState(state);
                     }
-                    if (st.expandedMenuPresenter != null) {
-                        st.expandedMenuPresenter.restoreHierarchyState(state);
+                    if (st.listMenuPresenter != null) {
+                        st.listMenuPresenter.restoreHierarchyState(state);
                     }
 
                 } else {
@@ -552,7 +567,7 @@
             if (!st.shownPanelView.hasFocus()) {
                 st.shownPanelView.requestFocus();
             }
-        } else if (!st.isInExpandedMode) {
+        } else if (!st.isInListMode()) {
             width = MATCH_PARENT;
         }
 
@@ -567,7 +582,13 @@
                 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 st.decorView.mDefaultOpacity);
 
-        lp.gravity = st.gravity;
+        if (st.isCompact) {
+            lp.gravity = getOptionsPanelGravity();
+            sRotationWatcher.addWindow(this);
+        } else {
+            lp.gravity = st.gravity;
+        }
+
         lp.windowAnimations = st.windowAnimations;
         
         wm.addView(st.decorView, lp);
@@ -610,6 +631,9 @@
             if (st.decorView != null) {
                 wm.removeView(st.decorView);
                 // Log.v(TAG, "Removing main menu from window manager.");
+                if (st.isCompact) {
+                    sRotationWatcher.removeWindow(this);
+                }
             }
 
             if (doCallback) {
@@ -961,6 +985,36 @@
     }
 
     /**
+     * Determine the gravity value for the options panel. This can
+     * differ in compact mode.
+     *
+     * @return gravity value to use for the panel window
+     */
+    private int getOptionsPanelGravity() {
+        try {
+            return WindowManagerHolder.sWindowManager.getPreferredOptionsPanelGravity();
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Couldn't getOptionsPanelGravity; using default", ex);
+            return Gravity.CENTER | Gravity.BOTTOM;
+        }
+    }
+
+    void onOptionsPanelRotationChanged() {
+        final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
+        if (st == null) return;
+
+        final WindowManager.LayoutParams lp = st.decorView != null ?
+                (WindowManager.LayoutParams) st.decorView.getLayoutParams() : null;
+        if (lp != null) {
+            lp.gravity = getOptionsPanelGravity();
+            final ViewManager wm = getWindowManager();
+            if (wm != null) {
+                wm.updateViewLayout(st.decorView, lp);
+            }
+        }
+    }
+
+    /**
      * Initializes the panel associated with the panel feature state. You must
      * at the very least set PanelFeatureState.panel to the View implementing
      * its contents. The default implementation gets the panel from the menu.
@@ -982,8 +1036,8 @@
             mPanelMenuPresenterCallback = new PanelMenuPresenterCallback();
         }
 
-        MenuView menuView = st.isInExpandedMode
-                ? st.getExpandedMenuView(mPanelMenuPresenterCallback)
+        MenuView menuView = st.isInListMode()
+                ? st.getListMenuView(mPanelMenuPresenterCallback)
                 : st.getIconMenuView(mPanelMenuPresenterCallback);
 
         st.shownPanelView = (View) menuView;
@@ -3015,7 +3069,13 @@
         MenuBuilder menu;
 
         IconMenuPresenter iconMenuPresenter;
-        ListMenuPresenter expandedMenuPresenter;
+        ListMenuPresenter listMenuPresenter;
+
+        /** true if this menu will show in single-list compact mode */
+        boolean isCompact;
+
+        /** Theme resource ID for list elements of the panel menu */
+        int listPresenterTheme;
 
         /**
          * Whether the panel has been prepared (see
@@ -3065,11 +3125,15 @@
             refreshDecorView = false;
         }
 
+        public boolean isInListMode() {
+            return isInExpandedMode || isCompact;
+        }
+
         public boolean hasPanelItems() {
             if (shownPanelView == null) return false;
 
-            if (isInExpandedMode) {
-                return expandedMenuPresenter.getAdapter().getCount() > 0;
+            if (isCompact || isInExpandedMode) {
+                return listMenuPresenter.getAdapter().getCount() > 0;
             } else {
                 return ((ViewGroup) shownPanelView).getChildCount() > 0;
             }
@@ -3081,10 +3145,10 @@
         public void clearMenuPresenters() {
             if (menu != null) {
                 menu.removeMenuPresenter(iconMenuPresenter);
-                menu.removeMenuPresenter(expandedMenuPresenter);
+                menu.removeMenuPresenter(listMenuPresenter);
             }
             iconMenuPresenter = null;
-            expandedMenuPresenter = null;
+            listMenuPresenter = null;
         }
 
         void setStyle(Context context) {
@@ -3095,6 +3159,11 @@
                     com.android.internal.R.styleable.Theme_panelFullBackground, 0);
             windowAnimations = a.getResourceId(
                     com.android.internal.R.styleable.Theme_windowAnimationStyle, 0);
+            isCompact = a.getBoolean(
+                    com.android.internal.R.styleable.Theme_panelMenuIsCompact, false);
+            listPresenterTheme = a.getResourceId(
+                    com.android.internal.R.styleable.Theme_panelMenuListTheme,
+                    com.android.internal.R.style.Theme_ExpandedMenu);
             a.recycle();
         }
 
@@ -3102,22 +3171,26 @@
             this.menu = menu;
         }
 
-        MenuView getExpandedMenuView(MenuPresenter.Callback cb) {
+        MenuView getListMenuView(MenuPresenter.Callback cb) {
             if (menu == null) return null;
 
-            getIconMenuView(cb); // Need this initialized to know where our offset goes
-
-            if (expandedMenuPresenter == null) {
-                expandedMenuPresenter = new ListMenuPresenter(
-                        com.android.internal.R.layout.list_menu_item_layout,
-                        com.android.internal.R.style.Theme_ExpandedMenu);
-                expandedMenuPresenter.setCallback(cb);
-                expandedMenuPresenter.setId(com.android.internal.R.id.list_menu_presenter);
-                menu.addMenuPresenter(expandedMenuPresenter);
+            if (!isCompact) {
+                getIconMenuView(cb); // Need this initialized to know where our offset goes
             }
 
-            expandedMenuPresenter.setItemIndexOffset(iconMenuPresenter.getNumActualItemsShown());
-            MenuView result = expandedMenuPresenter.getMenuView(decorView);
+            if (listMenuPresenter == null) {
+                listMenuPresenter = new ListMenuPresenter(
+                        com.android.internal.R.layout.list_menu_item_layout, listPresenterTheme);
+                listMenuPresenter.setCallback(cb);
+                listMenuPresenter.setId(com.android.internal.R.id.list_menu_presenter);
+                menu.addMenuPresenter(listMenuPresenter);
+            }
+
+            if (iconMenuPresenter != null) {
+                listMenuPresenter.setItemIndexOffset(
+                        iconMenuPresenter.getNumActualItemsShown());
+            }
+            MenuView result = listMenuPresenter.getMenuView(decorView);
 
             return result;
         }
@@ -3224,6 +3297,69 @@
 
     }
 
+    static class RotationWatcher extends IRotationWatcher.Stub {
+        private Handler mHandler;
+        private final Runnable mRotationChanged = new Runnable() {
+            public void run() {
+                dispatchRotationChanged();
+            }
+        };
+        private final ArrayList<WeakReference<PhoneWindow>> mWindows =
+                new ArrayList<WeakReference<PhoneWindow>>();
+        private boolean mIsWatching;
+
+        @Override
+        public void onRotationChanged(int rotation) throws RemoteException {
+            mHandler.post(mRotationChanged);
+        }
+
+        public void addWindow(PhoneWindow phoneWindow) {
+            synchronized (mWindows) {
+                if (!mIsWatching) {
+                    try {
+                        WindowManagerHolder.sWindowManager.watchRotation(this);
+                        mHandler = new Handler();
+                        mIsWatching = true;
+                    } catch (RemoteException ex) {
+                        Log.e(TAG, "Couldn't start watching for device rotation", ex);
+                    }
+                }
+                mWindows.add(new WeakReference<PhoneWindow>(phoneWindow));
+            }
+        }
+
+        public void removeWindow(PhoneWindow phoneWindow) {
+            synchronized (mWindows) {
+                int i = 0;
+                while (i < mWindows.size()) {
+                    final WeakReference<PhoneWindow> ref = mWindows.get(i);
+                    final PhoneWindow win = ref.get();
+                    if (win == null || win == phoneWindow) {
+                        mWindows.remove(i);
+                    } else {
+                        i++;
+                    }
+                }
+            }
+        }
+
+        void dispatchRotationChanged() {
+            synchronized (mWindows) {
+                int i = 0;
+                while (i < mWindows.size()) {
+                    final WeakReference<PhoneWindow> ref = mWindows.get(i);
+                    final PhoneWindow win = ref.get();
+                    if (win != null) {
+                        win.onOptionsPanelRotationChanged();
+                        i++;
+                    } else {
+                        mWindows.remove(i);
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Simple implementation of MenuBuilder.Callback that:
      * <li> Opens a submenu when selected.
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 2e3d6dd..8b7d3a8 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -2034,6 +2034,15 @@
                 boolean compressing = COMPRESS_FULL_BACKUPS;
                 OutputStream finalOutput = ofstream;
 
+                // Verify that the given password matches the currently-active
+                // backup password, if any
+                if (hasBackupPassword()) {
+                    if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) {
+                        if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
+                        return;
+                    }
+                }
+
                 // Write the global file header.  All strings are UTF-8 encoded; lines end
                 // with a '\n' byte.  Actual backup data begins immediately following the
                 // final '\n'.
@@ -2068,15 +2077,6 @@
                 try {
                     // Set up the encryption stage if appropriate, and emit the correct header
                     if (encrypting) {
-                        // Verify that the given password matches the currently-active
-                        // backup password, if any
-                        if (hasBackupPassword()) {
-                            if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) {
-                                if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
-                                return;
-                            }
-                        }
-
                         finalOutput = emitAesBackupHeader(headerbuf, finalOutput);
                     } else {
                         headerbuf.append("none\n");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index bf9e014..3ae7a3f 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -254,6 +254,12 @@
     private static final int EVENT_RESTORE_DNS =
             MAX_NETWORK_STATE_TRACKER_EVENT + 11;
 
+    /**
+     * used internally to send a sticky broadcast delayed.
+     */
+    private static final int EVENT_SEND_STICKY_BROADCAST_INTENT =
+            MAX_NETWORK_STATE_TRACKER_EVENT + 12;
+
     private Handler mHandler;
 
     // list of DeathRecipients used to make sure features are turned off when
@@ -559,6 +565,17 @@
         }
     }
 
+    private int getConnectivityChangeDelay() {
+        final ContentResolver cr = mContext.getContentResolver();
+
+        /** Check system properties for the default value then use secure settings value, if any. */
+        int defaultDelay = SystemProperties.getInt(
+                "conn." + Settings.Secure.CONNECTIVITY_CHANGE_DELAY,
+                Settings.Secure.CONNECTIVITY_CHANGE_DELAY_DEFAULT);
+        return Settings.Secure.getInt(cr, Settings.Secure.CONNECTIVITY_CHANGE_DELAY,
+                defaultDelay);
+    }
+
     private int getPersistedNetworkPreference() {
         final ContentResolver cr = mContext.getContentResolver();
 
@@ -1437,13 +1454,14 @@
         // do this before we broadcast the change
         handleConnectivityChange(prevNetType, doReset);
 
-        sendStickyBroadcast(intent);
+        sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
         /*
          * If the failover network is already connected, then immediately send
          * out a followup broadcast indicating successful failover
          */
         if (mActiveDefaultNetwork != -1) {
-            sendConnectedBroadcast(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo());
+            sendConnectedBroadcastDelayed(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo(),
+                    getConnectivityChangeDelay());
         }
     }
 
@@ -1497,11 +1515,15 @@
         sendGeneralBroadcast(info, ConnectivityManager.CONNECTIVITY_ACTION);
     }
 
+    private void sendConnectedBroadcastDelayed(NetworkInfo info, int delayMs) {
+        sendGeneralBroadcastDelayed(info, ConnectivityManager.CONNECTIVITY_ACTION, delayMs);
+    }
+
     private void sendInetConditionBroadcast(NetworkInfo info) {
         sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
     }
 
-    private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
+    private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
         Intent intent = new Intent(bcastType);
         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
         if (info.isFailover()) {
@@ -1516,7 +1538,15 @@
                     info.getExtraInfo());
         }
         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
-        sendStickyBroadcast(intent);
+        return intent;
+    }
+
+    private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
+        sendStickyBroadcast(makeGeneralIntent(info, bcastType));
+    }
+
+    private void sendGeneralBroadcastDelayed(NetworkInfo info, String bcastType, int delayMs) {
+        sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
     }
 
     /**
@@ -1581,10 +1611,25 @@
                 mInitialBroadcast = new Intent(intent);
             }
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+            if (DBG) {
+                log("sendStickyBroadcast: NetworkInfo=" +
+                    intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO));
+            }
+
             mContext.sendStickyBroadcast(intent);
         }
     }
 
+    private void sendStickyBroadcastDelayed(Intent intent, int delayMs) {
+        if (delayMs <= 0) {
+            sendStickyBroadcast(intent);
+        } else {
+            if (DBG) log("sendStickyBroadcastDelayed: delayMs=" + delayMs + " intent=" + intent);
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(
+                    EVENT_SEND_STICKY_BROADCAST_INTENT, intent), delayMs);
+        }
+    }
+
     void systemReady() {
         synchronized(this) {
             mSystemReady = true;
@@ -1658,7 +1703,7 @@
         thisNet.setTeardownRequested(false);
         updateNetworkSettings(thisNet);
         handleConnectivityChange(type, false);
-        sendConnectedBroadcast(info);
+        sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
     }
 
     /**
@@ -2240,6 +2285,13 @@
                     }
                     break;
                 }
+                case EVENT_SEND_STICKY_BROADCAST_INTENT:
+                {
+                    Intent intent = (Intent)msg.obj;
+                    log("EVENT_SEND_STICKY_BROADCAST_INTENT: sendStickyBroadcast intent=" + intent);
+                    sendStickyBroadcast(intent);
+                    break;
+                }
             }
         }
     }
@@ -2435,10 +2487,13 @@
             if (DBG) log("event hold for obsolete network - aborting");
             return;
         }
-        if (mDefaultInetConditionPublished == mDefaultInetCondition) {
-            if (DBG) log("no change in condition - aborting");
-            return;
-        }
+        // TODO: Figure out why this optimization sometimes causes a
+        //       change in mDefaultInetCondition to be missed and the
+        //       UI to not be updated.
+        //if (mDefaultInetConditionPublished == mDefaultInetCondition) {
+        //    if (DBG) log("no change in condition - aborting");
+        //    return;
+        //}
         NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
         if (networkInfo.isConnected() == false) {
             if (DBG) log("default network not connected - aborting");
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 8031c4e..6edb132 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -325,6 +325,7 @@
             
             if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
                     || action.equals(Intent.ACTION_PACKAGE_RESTARTED)
+                    || action.equals(Intent.ACTION_PACKAGE_CHANGED)
                     || (queryRestart=action.equals(Intent.ACTION_QUERY_PACKAGE_RESTART))
                     || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
                 String pkgList[] = null;
@@ -430,6 +431,7 @@
         mContext.registerReceiver(mIntentReceiver, filter);
         IntentFilter pkgFilter = new IntentFilter();
         pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        pkgFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
         pkgFilter.addDataScheme("package");
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 238b747..90824a6 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -23,6 +23,8 @@
 import com.android.internal.textservice.ITextServicesManager;
 import com.android.internal.textservice.ITextServicesSessionListener;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -40,6 +42,7 @@
 import android.util.Slog;
 import android.view.textservice.SpellCheckerInfo;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -125,9 +128,15 @@
                 continue;
             }
             if (DBG) Slog.d(TAG, "Add: " + compName);
-            final SpellCheckerInfo sci = new SpellCheckerInfo(context, ri);
-            list.add(sci);
-            map.put(sci.getId(), sci);
+            try {
+                final SpellCheckerInfo sci = new SpellCheckerInfo(context, ri);
+                list.add(sci);
+                map.put(sci.getId(), sci);
+            } catch (XmlPullParserException e) {
+                Slog.w(TAG, "Unable to load the spell checker " + compName, e);
+            } catch (IOException e) {
+                Slog.w(TAG, "Unable to load the spell checker " + compName, e);
+            }
         }
         if (DBG) {
             Slog.d(TAG, "buildSpellCheckerMapLocked: " + list.size() + "," + map.size());
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 2460fd6..9765f2a 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -118,6 +118,10 @@
                         File changedFile = new File(WALLPAPER_DIR, path);
                         if (WALLPAPER_FILE.equals(changedFile)) {
                             notifyCallbacksLocked();
+                            if (mWallpaperComponent == null ||
+                                    mWallpaperComponent.equals(mImageWallpaperComponent)) {
+                                bindWallpaperComponentLocked(mWallpaperComponent, true);
+                            }
                         }
                     }
                 }
@@ -191,7 +195,7 @@
                     if (!mWallpaperUpdating && (mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
                                 > SystemClock.uptimeMillis()) {
                         Slog.w(TAG, "Reverting to built-in wallpaper!");
-                        bindWallpaperComponentLocked(null);
+                        bindWallpaperComponentLocked(null, true);
                     }
                 }
             }
@@ -220,7 +224,7 @@
                     mWallpaperUpdating = false;
                     ComponentName comp = mWallpaperComponent;
                     clearWallpaperComponentLocked();
-                    bindWallpaperComponentLocked(comp);
+                    bindWallpaperComponentLocked(comp, false);
                 }
             }
         }
@@ -312,11 +316,11 @@
         if (DEBUG) Slog.v(TAG, "systemReady");
         synchronized (mLock) {
             try {
-                bindWallpaperComponentLocked(mNextWallpaperComponent);
+                bindWallpaperComponentLocked(mNextWallpaperComponent, false);
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Failure starting previous wallpaper", e);
                 try {
-                    bindWallpaperComponentLocked(null);
+                    bindWallpaperComponentLocked(null, false);
                 } catch (RuntimeException e2) {
                     Slog.w(TAG, "Failure starting default wallpaper", e2);
                     clearWallpaperComponentLocked();
@@ -339,7 +343,7 @@
         }
         final long ident = Binder.clearCallingIdentity();
         try {
-            bindWallpaperComponentLocked(null);
+            bindWallpaperComponentLocked(null, false);
         } catch (IllegalArgumentException e) {
             // This can happen if the default wallpaper component doesn't
             // exist.  This should be a system configuration problem, but
@@ -430,7 +434,7 @@
                 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
                 if (pfd != null) {
                     // Bind the wallpaper to an ImageWallpaper
-                    bindWallpaperComponentLocked(mImageWallpaperComponent);
+                    bindWallpaperComponentLocked(mImageWallpaperComponent, false);
                     saveSettingsLocked();
                 }
                 return pfd;
@@ -459,28 +463,30 @@
         synchronized (mLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                bindWallpaperComponentLocked(name);
+                bindWallpaperComponentLocked(name, false);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
         }
     }
     
-    void bindWallpaperComponentLocked(ComponentName componentName) {
+    void bindWallpaperComponentLocked(ComponentName componentName, boolean force) {
         if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
         
         // Has the component changed?
-        if (mWallpaperConnection != null) {
-            if (mWallpaperComponent == null) {
-                if (componentName == null) {
-                    if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
-                    // Still using default wallpaper.
+        if (!force) {
+            if (mWallpaperConnection != null) {
+                if (mWallpaperComponent == null) {
+                    if (componentName == null) {
+                        if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
+                        // Still using default wallpaper.
+                        return;
+                    }
+                } else if (mWallpaperComponent.equals(componentName)) {
+                    // Changing to same wallpaper.
+                    if (DEBUG) Slog.v(TAG, "same wallpaper");
                     return;
                 }
-            } else if (mWallpaperComponent.equals(componentName)) {
-                // Changing to same wallpaper.
-                if (DEBUG) Slog.v(TAG, "same wallpaper");
-                return;
             }
         }
         
@@ -599,7 +605,7 @@
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
             if (!mWallpaperUpdating) {
-                bindWallpaperComponentLocked(null);
+                bindWallpaperComponentLocked(null, false);
             }
         }
     }
@@ -645,7 +651,8 @@
             out.attribute(null, "width", Integer.toString(mWidth));
             out.attribute(null, "height", Integer.toString(mHeight));
             out.attribute(null, "name", mName);
-            if (mWallpaperComponent != null) {
+            if (mWallpaperComponent != null &&
+                    !mWallpaperComponent.equals(mImageWallpaperComponent)) {
                 out.attribute(null, "component",
                         mWallpaperComponent.flattenToShortString());
             }
@@ -691,6 +698,10 @@
                         mNextWallpaperComponent = comp != null
                                 ? ComponentName.unflattenFromString(comp)
                                 : null;
+                        if (mNextWallpaperComponent == null ||
+                                "android".equals(mNextWallpaperComponent.getPackageName())) {
+                            mNextWallpaperComponent = mImageWallpaperComponent;
+                        }
                           
                         if (DEBUG) {
                             Slog.v(TAG, "mWidth:" + mWidth);
@@ -749,12 +760,12 @@
             if (mNextWallpaperComponent != null && 
                     !mNextWallpaperComponent.equals(mImageWallpaperComponent)) {
                 try {
-                    bindWallpaperComponentLocked(mNextWallpaperComponent);
+                    bindWallpaperComponentLocked(mNextWallpaperComponent, false);
                 } catch (IllegalArgumentException e) {
                     // No such live wallpaper or other failure; fall back to the default
                     // live wallpaper (since the profile being restored indicated that the
                     // user had selected a live rather than static one).
-                    bindWallpaperComponentLocked(null);
+                    bindWallpaperComponentLocked(null, false);
                 }
                 success = true;
             } else {
@@ -769,7 +780,7 @@
                 }
                 if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
                 if (success) {
-                    bindWallpaperComponentLocked(mImageWallpaperComponent);
+                    bindWallpaperComponentLocked(null, false);
                 }
             }
         }
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index f9f63b1..a80a2b8 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -289,6 +289,10 @@
                     mWifiStateMachine.startWps(msg.replyTo, (WpsConfiguration)msg.obj);
                     break;
                 }
+                case WifiManager.CMD_DISABLE_NETWORK: {
+                    mWifiStateMachine.disableNetwork(msg.replyTo, msg.arg1, msg.arg2);
+                    break;
+                }
                 default: {
                     Slog.d(TAG, "WifiServicehandler.handleMessage ignoring msg=" + msg);
                     break;
@@ -1592,7 +1596,10 @@
                 for (int i = scanResults.size() - 1; i >= 0; i--) {
                     ScanResult scanResult = scanResults.get(i);
 
-                    if (TextUtils.isEmpty(scanResult.capabilities)) {
+                    //A capability of [ESS] represents an open access point
+                    //that is available for an STA to connect
+                    if (scanResult.capabilities != null &&
+                            scanResult.capabilities.equals("[ESS]")) {
                         numOpenNetworks++;
                     }
                 }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 14c6306..d3e12f7 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -248,135 +248,9 @@
     // How long we wait until we timeout on key dispatching.
     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
 
-    // The minimum time we allow between crashes, for us to consider this
-    // application to be bad and stop and its services and reject broadcasts.
-    static final int MIN_CRASH_INTERVAL = 60*1000;
-
     // How long we wait until we timeout on key dispatching during instrumentation.
     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
 
-    // OOM adjustments for processes in various states:
-
-    // This is a process without anything currently running in it.  Definitely
-    // the first to go! Value set in system/rootdir/init.rc on startup.
-    // This value is initalized in the constructor, careful when refering to
-    // this static variable externally.
-    static final int EMPTY_APP_ADJ;
-
-    // This is a process only hosting activities that are not visible,
-    // so it can be killed without any disruption. Value set in
-    // system/rootdir/init.rc on startup.
-    static final int HIDDEN_APP_MAX_ADJ;
-    static int HIDDEN_APP_MIN_ADJ;
-
-    // This is a process holding the home application -- we want to try
-    // avoiding killing it, even if it would normally be in the background,
-    // because the user interacts with it so much.
-    static final int HOME_APP_ADJ;
-
-    // This is a process currently hosting a backup operation.  Killing it
-    // is not entirely fatal but is generally a bad idea.
-    static final int BACKUP_APP_ADJ;
-
-    // This is a process holding a secondary server -- killing it will not
-    // have much of an impact as far as the user is concerned. Value set in
-    // system/rootdir/init.rc on startup.
-    static final int SECONDARY_SERVER_ADJ;
-
-    // This is a process with a heavy-weight application.  It is in the
-    // background, but we want to try to avoid killing it.  Value set in
-    // system/rootdir/init.rc on startup.
-    static final int HEAVY_WEIGHT_APP_ADJ;
-
-    // This is a process only hosting components that are perceptible to the
-    // user, and we really want to avoid killing them, but they are not
-    // immediately visible. An example is background music playback.  Value set in
-    // system/rootdir/init.rc on startup.
-    static final int PERCEPTIBLE_APP_ADJ;
-
-    // This is a process only hosting activities that are visible to the
-    // user, so we'd prefer they don't disappear. Value set in
-    // system/rootdir/init.rc on startup.
-    static final int VISIBLE_APP_ADJ;
-
-    // This is the process running the current foreground app.  We'd really
-    // rather not kill it! Value set in system/rootdir/init.rc on startup.
-    static final int FOREGROUND_APP_ADJ;
-
-    // This is a process running a core server, such as telephony.  Definitely
-    // don't want to kill it, but doing so is not completely fatal.
-    static final int CORE_SERVER_ADJ = -12;
-
-    // The system process runs at the default adjustment.
-    static final int SYSTEM_ADJ = -16;
-
-    // Memory pages are 4K.
-    static final int PAGE_SIZE = 4*1024;
-    
-    // Corresponding memory levels for above adjustments.
-    static final int EMPTY_APP_MEM;
-    static final int HIDDEN_APP_MEM;
-    static final int HOME_APP_MEM;
-    static final int BACKUP_APP_MEM;
-    static final int SECONDARY_SERVER_MEM;
-    static final int HEAVY_WEIGHT_APP_MEM;
-    static final int PERCEPTIBLE_APP_MEM;
-    static final int VISIBLE_APP_MEM;
-    static final int FOREGROUND_APP_MEM;
-
-    // The minimum number of hidden apps we want to be able to keep around,
-    // without empty apps being able to push them out of memory.
-    static final int MIN_HIDDEN_APPS = 2;
-    
-    // The maximum number of hidden processes we will keep around before
-    // killing them; this is just a control to not let us go too crazy with
-    // keeping around processes on devices with large amounts of RAM.
-    static final int MAX_HIDDEN_APPS = 15;
-    
-    // We put empty content processes after any hidden processes that have
-    // been idle for less than 15 seconds.
-    static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
-    
-    // We put empty content processes after any hidden processes that have
-    // been idle for less than 120 seconds.
-    static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
-    
-    static int getIntProp(String name, boolean allowZero) {
-        String str = SystemProperties.get(name);
-        if (str == null) {
-            throw new IllegalArgumentException("Property not defined: " + name);
-        }
-        int val = Integer.valueOf(str);
-        if (val == 0 && !allowZero) {
-            throw new IllegalArgumentException("Property must not be zero: " + name);
-        }
-        return val;
-    }
-    
-    static {
-        // These values are set in system/rootdir/init.rc on startup.
-        FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
-        VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
-        PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
-        HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
-        SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
-        BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
-        HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
-        HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
-        EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
-        // These days we use the last empty slot for hidden apps as well.
-        HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
-        FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
-        VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
-        PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
-        HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
-        SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
-        BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
-        HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
-        HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
-        EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
-    }
-    
     static final int MY_PID = Process.myPid();
     
     static final String[] EMPTY_STRING_ARRAY = new String[0];
@@ -437,6 +311,11 @@
     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
 
     /**
+     * Process management.
+     */
+    final ProcessList mProcessList = new ProcessList();
+
+    /**
      * All of the applications we currently have running organized by name.
      * The keys are strings of the application package name (as
      * returned by the package manager), and the keys are ApplicationRecord
@@ -900,7 +779,7 @@
      */
     boolean mBooted = false;
 
-    int mProcessLimit = MAX_HIDDEN_APPS;
+    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
     int mProcessLimitOverride = -1;
 
     WindowManagerService mWindowManager;
@@ -1327,7 +1206,7 @@
                         info.processName);
                 app.persistent = true;
                 app.pid = MY_PID;
-                app.maxAdj = SYSTEM_ADJ;
+                app.maxAdj = ProcessList.SYSTEM_ADJ;
                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
                 synchronized (mSelf.mPidsSelfLocked) {
                     mSelf.mPidsSelfLocked.put(app.pid, app);
@@ -1702,23 +1581,23 @@
         } else if (app.pubProviders.size() > 0) {
             // If this process contains content providers, we want to keep
             // it a little more strongly.
-            app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
+            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
             // Also don't let it kick out the first few "real" hidden processes.
-            skipTop = MIN_HIDDEN_APPS;
+            skipTop = ProcessList.MIN_HIDDEN_APPS;
         } else {
             // If this process doesn't have activities, we less strongly
             // want to keep it around, and generally want to avoid getting
             // in front of any very recently used activities.
-            app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
+            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
             // Also don't let it kick out the first few "real" hidden processes.
-            skipTop = MIN_HIDDEN_APPS;
+            skipTop = ProcessList.MIN_HIDDEN_APPS;
         }
         
         while (i >= 0) {
             ProcessRecord p = mLruProcesses.get(i);
             // If this app shouldn't be in front of the first N background
             // apps, then skip over that many that are currently hidden.
-            if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
+            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
                 skipTop--;
             }
             if (p.lruWeight <= app.lruWeight || i < bestPos) {
@@ -2800,7 +2679,7 @@
                 boolean haveBg = false;
                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
                     ProcessRecord rec = mLruProcesses.get(i);
-                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
+                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
                         haveBg = true;
                         break;
                     }
@@ -2817,7 +2696,7 @@
                             // The low memory report is overriding any current
                             // state for a GC request.  Make sure to do
                             // heavy/important/visible/foreground processes first.
-                            if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
+                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                                 rec.lastRequestedGc = 0;
                             } else {
                                 rec.lastRequestedGc = rec.lastLowMemory;
@@ -3195,7 +3074,7 @@
                     return;
                 }
                 killPackageProcessesLocked(packageName, pkgUid,
-                        SECONDARY_SERVER_ADJ, false, true, true);
+                        ProcessList.SECONDARY_SERVER_ADJ, false, true, true);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -3317,6 +3196,14 @@
         return infos;
     }
 
+    public long[] getProcessPss(int[] pids) throws RemoteException {
+        long[] pss = new long[pids.length];
+        for (int i=pids.length-1; i>=0; i--) {
+            pss[i] = Debug.getPss(pids[i]);
+        }
+        return pss;
+    }
+
     public void killApplicationProcess(String processName, int uid) {
         if (processName == null) {
             return;
@@ -4159,7 +4046,7 @@
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                 "setProcessLimit()");
         synchronized (this) {
-            mProcessLimit = max < 0 ? MAX_HIDDEN_APPS : max;
+            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
             mProcessLimitOverride = max;
         }
         trimApplications();
@@ -4908,10 +4795,18 @@
     }
 
     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
+        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
+        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
         outInfo.availMem = Process.getFreeMemory();
-        outInfo.threshold = HOME_APP_MEM;
-        outInfo.lowMemory = outInfo.availMem <
-                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
+        outInfo.threshold = homeAppMem;
+        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
+        outInfo.hiddenAppThreshold = hiddenAppMem;
+        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
+                ProcessList.SECONDARY_SERVER_ADJ);
+        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
+                ProcessList.VISIBLE_APP_ADJ);
+        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
+                ProcessList.FOREGROUND_APP_ADJ);
     }
     
     // =========================================================
@@ -5633,7 +5528,7 @@
                         r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
                     }
                     cpr.clients.add(r);
-                    if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
+                    if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
                         // If this is a perceptible app accessing the provider,
                         // make sure to count it as being accessed and thus
                         // back up on the LRU list.  This is good because
@@ -6023,7 +5918,7 @@
         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
             app.persistent = true;
-            app.maxAdj = CORE_SERVER_ADJ;
+            app.maxAdj = ProcessList.CORE_SERVER_ADJ;
         }
         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
             mPersistentStartingProcesses.add(app);
@@ -6397,14 +6292,14 @@
             
             // If the worst oom_adj is somewhere in the hidden proc LRU range,
             // then constrain it so we will kill all hidden procs.
-            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
-                worstType = HIDDEN_APP_MIN_ADJ;
+            if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
+                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
             }
 
             // If this is not a secure call, don't let it kill processes that
             // are important.
-            if (!secure && worstType < SECONDARY_SERVER_ADJ) {
-                worstType = SECONDARY_SERVER_ADJ;
+            if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
+                worstType = ProcessList.SECONDARY_SERVER_ADJ;
             }
 
             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
@@ -6818,7 +6713,7 @@
 
         Long crashTime = mProcessCrashTimes.get(app.info.processName,
                 app.info.uid);
-        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
+        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
             // This process loses!
             Slog.w(TAG, "Process " + app.info.processName
                     + " has crashed too many times: killing!");
@@ -7547,21 +7442,21 @@
                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
                     }
                     int adj = app.curAdj;
-                    if (adj >= EMPTY_APP_ADJ) {
+                    if (adj >= ProcessList.EMPTY_APP_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
-                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
+                    } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
-                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
-                    } else if (adj >= HOME_APP_ADJ) {
+                        currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
+                    } else if (adj >= ProcessList.HOME_APP_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
                         currApp.lru = 0;
-                    } else if (adj >= SECONDARY_SERVER_ADJ) {
+                    } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
-                    } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
+                    } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
-                    } else if (adj >= PERCEPTIBLE_APP_ADJ) {
+                    } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
-                    } else if (adj >= VISIBLE_APP_ADJ) {
+                    } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
                     } else {
                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
@@ -8068,17 +7963,17 @@
             if (needSep) pw.println(" ");
             needSep = true;
             pw.println("  OOM levels:");
-            pw.print("    SYSTEM_ADJ: "); pw.println(SYSTEM_ADJ);
-            pw.print("    CORE_SERVER_ADJ: "); pw.println(CORE_SERVER_ADJ);
-            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(FOREGROUND_APP_ADJ);
-            pw.print("    VISIBLE_APP_ADJ: "); pw.println(VISIBLE_APP_ADJ);
-            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(PERCEPTIBLE_APP_ADJ);
-            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(HEAVY_WEIGHT_APP_ADJ);
-            pw.print("    BACKUP_APP_ADJ: "); pw.println(BACKUP_APP_ADJ);
-            pw.print("    SECONDARY_SERVER_ADJ: "); pw.println(SECONDARY_SERVER_ADJ);
-            pw.print("    HOME_APP_ADJ: "); pw.println(HOME_APP_ADJ);
-            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(HIDDEN_APP_MIN_ADJ);
-            pw.print("    EMPTY_APP_ADJ: "); pw.println(EMPTY_APP_ADJ);
+            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
+            pw.print("    CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
+            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
+            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
+            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
+            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
+            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
+            pw.print("    SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
+            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
+            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
+            pw.print("    EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
 
             if (needSep) pw.println(" ");
             needSep = true;
@@ -8746,28 +8641,28 @@
         for (int i=N; i>=0; i--) {
             ProcessRecord r = list.get(i);
             String oomAdj;
-            if (r.setAdj >= EMPTY_APP_ADJ) {
-                oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
-            } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
-                oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
-            } else if (r.setAdj >= HOME_APP_ADJ) {
-                oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
-            } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
-                oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
-            } else if (r.setAdj >= BACKUP_APP_ADJ) {
-                oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
-            } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
-                oomAdj = buildOomTag("hvy  ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
-            } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
-                oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
-            } else if (r.setAdj >= VISIBLE_APP_ADJ) {
-                oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
-            } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
-                oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
-            } else if (r.setAdj >= CORE_SERVER_ADJ) {
-                oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
-            } else if (r.setAdj >= SYSTEM_ADJ) {
-                oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
+            if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
+                oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
+            } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
+            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
+                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
+            } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
+                oomAdj = buildOomTag("svc", "  ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
+            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
+                oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
+            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
+                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
+            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
+                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
+            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
+                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
+            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
+            } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
+                oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
+            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
+                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
             } else {
                 oomAdj = Integer.toString(r.setAdj);
             }
@@ -8868,15 +8763,15 @@
         }
     }
 
-    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
+    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
         ArrayList<ProcessRecord> procs;
         synchronized (this) {
-            if (args != null && args.length > 0
-                    && args[0].charAt(0) != '-') {
+            if (args != null && args.length > start
+                    && args[start].charAt(0) != '-') {
                 procs = new ArrayList<ProcessRecord>();
                 int pid = -1;
                 try {
-                    pid = Integer.parseInt(args[0]);
+                    pid = Integer.parseInt(args[start]);
                 } catch (NumberFormatException e) {
 
                 }
@@ -8884,12 +8779,12 @@
                     ProcessRecord proc = mLruProcesses.get(i);
                     if (proc.pid == pid) {
                         procs.add(proc);
-                    } else if (proc.processName.equals(args[0])) {
+                    } else if (proc.processName.equals(args[start])) {
                         procs.add(proc);
                     }
                 }
                 if (procs.size() <= 0) {
-                    pw.println("No process found for: " + args[0]);
+                    pw.println("No process found for: " + args[start]);
                     return null;
                 }
             } else {
@@ -8901,7 +8796,7 @@
 
     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
             PrintWriter pw, String[] args) {
-        ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
+        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
         if (procs == null) {
             return;
         }
@@ -8945,18 +8840,21 @@
         }
     }
 
-    final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items) {
-        Collections.sort(items, new Comparator<MemItem>() {
-            @Override
-            public int compare(MemItem lhs, MemItem rhs) {
-                if (lhs.pss < rhs.pss) {
-                    return 1;
-                } else if (lhs.pss > rhs.pss) {
-                    return -1;
+    final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
+            boolean sort) {
+        if (sort) {
+            Collections.sort(items, new Comparator<MemItem>() {
+                @Override
+                public int compare(MemItem lhs, MemItem rhs) {
+                    if (lhs.pss < rhs.pss) {
+                        return 1;
+                    } else if (lhs.pss > rhs.pss) {
+                        return -1;
+                    }
+                    return 0;
                 }
-                return 0;
-            }
-        });
+            });
+        }
 
         for (int i=0; i<items.size(); i++) {
             MemItem mi = items.get(i);
@@ -8966,7 +8864,29 @@
 
     final void dumpApplicationMemoryUsage(FileDescriptor fd,
             PrintWriter pw, String prefix, String[] args) {
-        ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
+        boolean dumpAll = false;
+        
+        int opti = 0;
+        while (opti < args.length) {
+            String opt = args[opti];
+            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
+                break;
+            }
+            opti++;
+            if ("-a".equals(opt)) {
+                dumpAll = true;
+            } else if ("-h".equals(opt)) {
+                pw.println("meminfo dump options: [-a] [process]");
+                pw.println("  -a: include all available information for each process.");
+                pw.println("If [process] is specified it can be the name or ");
+                pw.println("pid of a specific process to dump.");
+                return;
+            } else {
+                pw.println("Unknown argument: " + opt + "; use -h for help");
+            }
+        }
+        
+        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
         if (procs == null) {
             return;
         }
@@ -8974,7 +8894,11 @@
         final boolean isCheckinRequest = scanArgs(args, "--checkin");
         long uptime = SystemClock.uptimeMillis();
         long realtime = SystemClock.elapsedRealtime();
-        
+
+        if (procs.size() == 1 || isCheckinRequest) {
+            dumpAll = true;
+        }
+
         if (isCheckinRequest) {
             // short checkin version
             pw.println(uptime + "," + realtime);
@@ -8984,29 +8908,53 @@
             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
         }
 
+        String[] innerArgs = new String[args.length-opti];
+        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
+
         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
         long nativePss=0, dalvikPss=0, otherPss=0;
         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
 
+        final int[] oomAdj = new int[] {
+            ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
+            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
+            ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
+        };
+        final String[] oomLabel = new String[] {
+                "System", "Persistent", "Foreground",
+                "Visible", "Perceptible", "Heavy Weight",
+                "Backup", "Services", "Home", "Background"
+        };
+        long oomPss[] = new long[oomLabel.length];
+
+        long totalPss = 0;
+
         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
             ProcessRecord r = procs.get(i);
             if (r.thread != null) {
-                if (!isCheckinRequest) {
+                if (!isCheckinRequest && dumpAll) {
                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
                     pw.flush();
                 }
                 Debug.MemoryInfo mi = null;
-                try {
-                    mi = r.thread.dumpMemInfo(fd, args);
-                } catch (RemoteException e) {
-                    if (!isCheckinRequest) {
-                        pw.println("Got RemoteException!");
-                        pw.flush();
+                if (dumpAll) {
+                    try {
+                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
+                    } catch (RemoteException e) {
+                        if (!isCheckinRequest) {
+                            pw.println("Got RemoteException!");
+                            pw.flush();
+                        }
                     }
+                } else {
+                    mi = new Debug.MemoryInfo();
+                    Debug.getMemoryInfo(r.pid, mi);
                 }
+
                 if (!isCheckinRequest && mi != null) {
-                    procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")",
-                            mi.getTotalPss()));
+                    long myTotalPss = mi.getTotalPss();
+                    totalPss += myTotalPss;
+                    procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
 
                     nativePss += mi.nativePss;
                     dalvikPss += mi.dalvikPss;
@@ -9016,6 +8964,13 @@
                         miscPss[j] += mem;
                         otherPss -= mem;
                     }
+
+                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
+                        if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
+                            oomPss[oomIndex] += myTotalPss;
+                            break;
+                        }
+                    }
                 }
             }
         }
@@ -9030,12 +8985,24 @@
                 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
             }
 
+            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
+            for (int j=0; j<oomPss.length; j++) {
+                if (oomPss[j] != 0) {
+                    oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
+                }
+            }
+
             pw.println();
             pw.println("Total PSS by process:");
-            dumpMemItems(pw, "  ", procMems);
+            dumpMemItems(pw, "  ", procMems, true);
+            pw.println();
+            pw.println("Total PSS by OOM adjustment:");
+            dumpMemItems(pw, "  ", oomMems, false);
             pw.println();
             pw.println("Total PSS by category:");
-            dumpMemItems(pw, "  ", catMems);
+            dumpMemItems(pw, "  ", catMems, true);
+            pw.println();
+            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
         }
     }
 
@@ -12458,7 +12425,11 @@
                 // sentinel: fetch the current configuration from the window manager
                 values = mWindowManager.computeNewConfiguration();
             }
-            
+
+            if (mWindowManager != null) {
+                mProcessList.applyDisplaySize(mWindowManager);
+            }
+
             final long origId = Binder.clearCallingIdentity();
             if (values != null) {
                 Settings.System.clearConfiguration(values);
@@ -12608,7 +12579,7 @@
         if (app.thread == null) {
             app.adjSeq = mAdjSeq;
             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
-            return (app.curAdj=EMPTY_APP_ADJ);
+            return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
         }
 
         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
@@ -12619,7 +12590,7 @@
 
         final int activitiesSize = app.activities.size();
 
-        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
+        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
             // The max adjustment doesn't allow this app to be anything
             // below foreground, so it is not worth doing work for it.
             app.adjType = "fixed";
@@ -12659,26 +12630,26 @@
         int schedGroup;
         if (app == TOP_APP) {
             // The last app on the list is the foreground app.
-            adj = FOREGROUND_APP_ADJ;
+            adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "top-activity";
             app.foregroundActivities = true;
         } else if (app.instrumentationClass != null) {
             // Don't want to kill running instrumentation.
-            adj = FOREGROUND_APP_ADJ;
+            adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "instrumentation";
         } else if (app.curReceiver != null ||
                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
             // An app that is currently receiving a broadcast also
             // counts as being in the foreground.
-            adj = FOREGROUND_APP_ADJ;
+            adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "broadcast";
         } else if (app.executingServices.size() > 0) {
             // An app that is currently executing a service callback also
             // counts as being in the foreground.
-            adj = FOREGROUND_APP_ADJ;
+            adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "exec-service";
         } else if (activitiesSize > 0) {
@@ -12704,8 +12675,8 @@
                 final ActivityRecord r = app.activities.get(j);
                 if (r.visible) {
                     // App has a visible activity; only upgrade adjustment.
-                    if (adj > VISIBLE_APP_ADJ) {
-                        adj = VISIBLE_APP_ADJ;
+                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
+                        adj = ProcessList.VISIBLE_APP_ADJ;
                         app.adjType = "visible";
                     }
                     schedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -12715,8 +12686,8 @@
                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
                         || r.state == ActivityState.STOPPING) {
                     // Only upgrade adjustment.
-                    if (adj > PERCEPTIBLE_APP_ADJ) {
-                        adj = PERCEPTIBLE_APP_ADJ;
+                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "stopping";
                     }
                     app.foregroundActivities = true;
@@ -12724,32 +12695,32 @@
             }
         }
 
-        if (adj > PERCEPTIBLE_APP_ADJ) {
+        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
             if (app.foregroundServices) {
                 // The user is aware of this app, so make it visible.
-                adj = PERCEPTIBLE_APP_ADJ;
+                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                 app.adjType = "foreground-service";
                 schedGroup = Process.THREAD_GROUP_DEFAULT;
             } else if (app.forcingToForeground != null) {
                 // The user is aware of this app, so make it visible.
-                adj = PERCEPTIBLE_APP_ADJ;
+                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                 app.adjType = "force-foreground";
                 app.adjSource = app.forcingToForeground;
                 schedGroup = Process.THREAD_GROUP_DEFAULT;
             }
         }
 
-        if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
+        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
             // We don't want to kill the current heavy-weight process.
-            adj = HEAVY_WEIGHT_APP_ADJ;
+            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
             app.adjType = "heavy";
         }
 
-        if (adj > HOME_APP_ADJ && app == mHomeProcess) {
+        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
             // This process is hosting what we currently consider to be the
             // home app, so we don't want to let it go into the background.
-            adj = HOME_APP_ADJ;
+            adj = ProcessList.HOME_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
             app.adjType = "home";
         }
@@ -12765,21 +12736,21 @@
 
         if (mBackupTarget != null && app == mBackupTarget.app) {
             // If possible we want to avoid killing apps while they're being backed up
-            if (adj > BACKUP_APP_ADJ) {
+            if (adj > ProcessList.BACKUP_APP_ADJ) {
                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
-                adj = BACKUP_APP_ADJ;
+                adj = ProcessList.BACKUP_APP_ADJ;
                 app.adjType = "backup";
                 app.hidden = false;
             }
         }
 
-        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
+        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
             final long now = SystemClock.uptimeMillis();
             // This process is more important if the top activity is
             // bound to the service.
             Iterator<ServiceRecord> jt = app.services.iterator();
-            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
+            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
                 ServiceRecord s = jt.next();
                 if (s.startRequested) {
                     if (app.hasShownUi) {
@@ -12787,7 +12758,7 @@
                         // go to the LRU list because it may be pretty heavy with
                         // UI stuff.  We'll tag it with a label just to help
                         // debug and understand what is going on.
-                        if (adj > SECONDARY_SERVER_ADJ) {
+                        if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
                             app.adjType = "started-bg-ui-services";
                         }
                     } else {
@@ -12795,8 +12766,8 @@
                             // This service has seen some activity within
                             // recent memory, so we will keep its process ahead
                             // of the background processes.
-                            if (adj > SECONDARY_SERVER_ADJ) {
-                                adj = SECONDARY_SERVER_ADJ;
+                            if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
+                                adj = ProcessList.SECONDARY_SERVER_ADJ;
                                 app.adjType = "started-services";
                                 app.hidden = false;
                             }
@@ -12804,7 +12775,7 @@
                         // If we have let the service slide into the background
                         // state, still have some text describing what it is doing
                         // even though the service no longer has an impact.
-                        if (adj > SECONDARY_SERVER_ADJ) {
+                        if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
                             app.adjType = "started-bg-services";
                         }
                     }
@@ -12812,13 +12783,13 @@
                     // has said it is doing work.
                     app.keeping = true;
                 }
-                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
+                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
                     Iterator<ArrayList<ConnectionRecord>> kt
                             = s.connections.values().iterator();
-                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
+                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
                         ArrayList<ConnectionRecord> clist = kt.next();
-                        for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
+                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
                             // XXX should compute this based on the max of
                             // all connected clients.
                             ConnectionRecord cr = clist.get(i);
@@ -12831,10 +12802,10 @@
                                 int clientAdj = adj;
                                 int myHiddenAdj = hiddenAdj;
                                 if (myHiddenAdj > client.hiddenAdj) {
-                                    if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
+                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
                                         myHiddenAdj = client.hiddenAdj;
                                     } else {
-                                        myHiddenAdj = VISIBLE_APP_ADJ;
+                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
                                     }
                                 }
                                 clientAdj = computeOomAdjLocked(
@@ -12874,16 +12845,16 @@
                                     // about letting this process get into the LRU
                                     // list to be killed and restarted if needed for
                                     // memory.
-                                    if (app.hasShownUi && clientAdj > PERCEPTIBLE_APP_ADJ) {
+                                    if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                                         adjType = "bound-bg-ui-services";
                                     } else {
                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
                                                 |Context.BIND_IMPORTANT)) != 0) {
                                             adj = clientAdj;
-                                        } else if (clientAdj >= VISIBLE_APP_ADJ) {
+                                        } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
                                             adj = clientAdj;
                                         } else {
-                                            adj = VISIBLE_APP_ADJ;
+                                            adj = ProcessList.VISIBLE_APP_ADJ;
                                         }
                                         if (!client.hidden) {
                                             app.hidden = false;
@@ -12909,10 +12880,10 @@
                             }
                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
                                 ActivityRecord a = cr.activity;
-                                if (a != null && adj > FOREGROUND_APP_ADJ &&
+                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
                                         (a.visible || a.state == ActivityState.RESUMED
                                          || a.state == ActivityState.PAUSING)) {
-                                    adj = FOREGROUND_APP_ADJ;
+                                    adj = ProcessList.FOREGROUND_APP_ADJ;
                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
                                     }
@@ -12941,15 +12912,15 @@
             }
         }
 
-        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
+        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
-            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
+            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
                 ContentProviderRecord cpr = jt.next();
                 if (cpr.clients.size() != 0) {
                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
-                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
+                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
                         ProcessRecord client = kt.next();
                         if (client == app) {
                             // Being our own client is not interesting.
@@ -12957,20 +12928,20 @@
                         }
                         int myHiddenAdj = hiddenAdj;
                         if (myHiddenAdj > client.hiddenAdj) {
-                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
+                            if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
                                 myHiddenAdj = client.hiddenAdj;
                             } else {
-                                myHiddenAdj = FOREGROUND_APP_ADJ;
+                                myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
                             }
                         }
                         int clientAdj = computeOomAdjLocked(
                             client, myHiddenAdj, TOP_APP, true);
                         if (adj > clientAdj) {
-                            if (app.hasShownUi && clientAdj > PERCEPTIBLE_APP_ADJ) {
+                            if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                                 app.adjType = "bg-ui-provider";
                             } else {
-                                adj = clientAdj > FOREGROUND_APP_ADJ
-                                        ? clientAdj : FOREGROUND_APP_ADJ;
+                                adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
+                                        ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
                                 app.adjType = "provider";
                             }
                             if (!client.hidden) {
@@ -12993,8 +12964,8 @@
                 // dependencies, ensure that its adjustment is at least
                 // FOREGROUND_APP_ADJ.
                 if (cpr.externals != 0) {
-                    if (adj > FOREGROUND_APP_ADJ) {
-                        adj = FOREGROUND_APP_ADJ;
+                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
+                        adj = ProcessList.FOREGROUND_APP_ADJ;
                         schedGroup = Process.THREAD_GROUP_DEFAULT;
                         app.hidden = false;
                         app.keeping = true;
@@ -13011,11 +12982,11 @@
         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
         if (adj > app.maxAdj) {
             adj = app.maxAdj;
-            if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
+            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
                 schedGroup = Process.THREAD_GROUP_DEFAULT;
             }
         }
-        if (adj < HIDDEN_APP_MIN_ADJ) {
+        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
             app.keeping = true;
         }
 
@@ -13025,15 +12996,15 @@
             // in order to honor the request.  We want to drop it by one adjustment
             // level...  but there is special meaning applied to various levels so
             // we will skip some of them.
-            if (adj < FOREGROUND_APP_ADJ) {
+            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
                 // System process will not get dropped, ever
-            } else if (adj < VISIBLE_APP_ADJ) {
-                adj = VISIBLE_APP_ADJ;
-            } else if (adj < PERCEPTIBLE_APP_ADJ) {
-                adj = PERCEPTIBLE_APP_ADJ;
-            } else if (adj < HIDDEN_APP_MIN_ADJ) {
-                adj = HIDDEN_APP_MIN_ADJ;
-            } else if (adj < EMPTY_APP_ADJ) {
+            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
+                adj = ProcessList.VISIBLE_APP_ADJ;
+            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
+                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
+                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
+            } else if (adj < ProcessList.EMPTY_APP_ADJ) {
                 adj++;
             }
         }
@@ -13090,7 +13061,7 @@
         if (canGcNowLocked()) {
             while (mProcessesToGc.size() > 0) {
                 ProcessRecord proc = mProcessesToGc.remove(0);
-                if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
+                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
                             <= SystemClock.uptimeMillis()) {
                         // To avoid spamming the system, we will GC processes one
@@ -13290,13 +13261,13 @@
         computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
 
         if (app.curRawAdj != app.setRawAdj) {
-            if (app.curRawAdj > FOREGROUND_APP_ADJ
-                    && app.setRawAdj <= FOREGROUND_APP_ADJ) {
+            if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
+                    && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
                 // If this app is transitioning from foreground to
                 // non-foreground, have it do a gc.
                 scheduleAppGcLocked(app);
-            } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
-                    && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
+            } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
+                    && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
                 // Likewise do a gc when an app is moving in to the
                 // background (such as a service stopping).
                 scheduleAppGcLocked(app);
@@ -13376,14 +13347,14 @@
         final ActivityRecord TOP_ACT = resumedAppLocked();
         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
         int curAdj = app.curAdj;
-        final boolean wasHidden = curAdj >= HIDDEN_APP_MIN_ADJ
-            && curAdj <= HIDDEN_APP_MAX_ADJ;
+        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
+            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
 
         mAdjSeq++;
 
         updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
-        final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
-            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
+        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
+            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
         if (nowHidden != wasHidden) {
             // Changed to/from hidden state, so apps after it in the LRU
             // list may also be changed.
@@ -13407,7 +13378,7 @@
         // how many slots we have for background processes; we may want
         // to put multiple processes in a slot of there are enough of
         // them.
-        int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
+        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
         int factor = (mLruProcesses.size()-4)/numSlots;
         if (factor < 1) factor = 1;
         int step = 0;
@@ -13416,14 +13387,14 @@
         // First update the OOM adjustment for each of the
         // application processes based on their current state.
         int i = mLruProcesses.size();
-        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
+        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
         int numBg = 0;
         while (i > 0) {
             i--;
             ProcessRecord app = mLruProcesses.get(i);
             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
             updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
-            if (curHiddenAdj < EMPTY_APP_ADJ
+            if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
                 && app.curAdj == curHiddenAdj) {
                 step++;
                 if (step >= factor) {
@@ -13432,7 +13403,7 @@
                 }
             }
             if (!app.killedBackground) {
-                if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
+                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
                     numHidden++;
                     if (numHidden > mProcessLimit) {
                         Slog.i(TAG, "No longer want " + app.processName
@@ -13444,7 +13415,7 @@
                     } else {
                         numBg++;
                     }
-                } else if (app.curAdj >= HOME_APP_ADJ) {
+                } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
                     numBg++;
                 }
             }
@@ -13456,14 +13427,14 @@
         // are managing to keep around is less than half the maximum we desire;
         // if we are keeping a good number around, we'll let them use whatever
         // memory they want.
-        if (numHidden <= (MAX_HIDDEN_APPS/2)) {
+        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
             final int N = mLruProcesses.size();
             factor = numBg/3;
             step = 0;
             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
             for (i=0; i<N; i++) {
                 ProcessRecord app = mLruProcesses.get(i);
-                if (app.curAdj >= HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
+                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
                         try {
                             app.thread.scheduleTrimMemory(curLevel);
@@ -13487,7 +13458,7 @@
                                 break;
                         }
                     }
-                } else if (app.curAdj == HEAVY_WEIGHT_APP_ADJ) {
+                } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
                             && app.thread != null) {
                         try {
@@ -13497,7 +13468,7 @@
                         }
                     }
                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
-                } else if ((app.curAdj > VISIBLE_APP_ADJ || app.systemNoUi)
+                } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
                         && app.pendingUiClean) {
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
                             && app.thread != null) {
@@ -13517,7 +13488,7 @@
             final int N = mLruProcesses.size();
             for (i=0; i<N; i++) {
                 ProcessRecord app = mLruProcesses.get(i);
-                if ((app.curAdj > VISIBLE_APP_ADJ || app.systemNoUi)
+                if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
                         && app.pendingUiClean) {
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
                             && app.thread != null) {
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
new file mode 100644
index 0000000..dfcc0bfa
--- /dev/null
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import com.android.internal.util.MemInfoReader;
+import com.android.server.wm.WindowManagerService;
+
+import android.graphics.Point;
+import android.os.StrictMode;
+import android.util.Slog;
+
+/**
+ * Activity manager code dealing with processes.
+ */
+class ProcessList {
+    // The minimum time we allow between crashes, for us to consider this
+    // application to be bad and stop and its services and reject broadcasts.
+    static final int MIN_CRASH_INTERVAL = 60*1000;
+
+    // OOM adjustments for processes in various states:
+
+    // This is a process without anything currently running in it.  Definitely
+    // the first to go! Value set in system/rootdir/init.rc on startup.
+    // This value is initalized in the constructor, careful when refering to
+    // this static variable externally.
+    static final int EMPTY_APP_ADJ = 15;
+
+    // This is a process only hosting activities that are not visible,
+    // so it can be killed without any disruption. Value set in
+    // system/rootdir/init.rc on startup.
+    static final int HIDDEN_APP_MAX_ADJ = 15;
+    static int HIDDEN_APP_MIN_ADJ = 7;
+
+    // This is a process holding the home application -- we want to try
+    // avoiding killing it, even if it would normally be in the background,
+    // because the user interacts with it so much.
+    static final int HOME_APP_ADJ = 6;
+
+    // This is a process holding a secondary server -- killing it will not
+    // have much of an impact as far as the user is concerned. Value set in
+    // system/rootdir/init.rc on startup.
+    static final int SECONDARY_SERVER_ADJ = 5;
+
+    // This is a process currently hosting a backup operation.  Killing it
+    // is not entirely fatal but is generally a bad idea.
+    static final int BACKUP_APP_ADJ = 4;
+
+    // This is a process with a heavy-weight application.  It is in the
+    // background, but we want to try to avoid killing it.  Value set in
+    // system/rootdir/init.rc on startup.
+    static final int HEAVY_WEIGHT_APP_ADJ = 3;
+
+    // This is a process only hosting components that are perceptible to the
+    // user, and we really want to avoid killing them, but they are not
+    // immediately visible. An example is background music playback.  Value set in
+    // system/rootdir/init.rc on startup.
+    static final int PERCEPTIBLE_APP_ADJ = 2;
+
+    // This is a process only hosting activities that are visible to the
+    // user, so we'd prefer they don't disappear. Value set in
+    // system/rootdir/init.rc on startup.
+    static final int VISIBLE_APP_ADJ = 1;
+
+    // This is the process running the current foreground app.  We'd really
+    // rather not kill it! Value set in system/rootdir/init.rc on startup.
+    static final int FOREGROUND_APP_ADJ = 0;
+
+    // This is a process running a core server, such as telephony.  Definitely
+    // don't want to kill it, but doing so is not completely fatal.
+    static final int CORE_SERVER_ADJ = -12;
+
+    // The system process runs at the default adjustment.
+    static final int SYSTEM_ADJ = -16;
+
+    // Memory pages are 4K.
+    static final int PAGE_SIZE = 4*1024;
+
+    // The minimum number of hidden apps we want to be able to keep around,
+    // without empty apps being able to push them out of memory.
+    static final int MIN_HIDDEN_APPS = 2;
+
+    // The maximum number of hidden processes we will keep around before
+    // killing them; this is just a control to not let us go too crazy with
+    // keeping around processes on devices with large amounts of RAM.
+    static final int MAX_HIDDEN_APPS = 15;
+
+    // We put empty content processes after any hidden processes that have
+    // been idle for less than 15 seconds.
+    static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
+
+    // We put empty content processes after any hidden processes that have
+    // been idle for less than 120 seconds.
+    static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
+
+    // These are the various interesting memory levels that we will give to
+    // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
+    // can't give it a different value for every possible kind of process.
+    private final int[] mOomAdj = new int[] {
+            FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
+            BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, EMPTY_APP_ADJ
+    };
+    // These are the low-end OOM level limits.  This is appropriate for an
+    // HVGA or smaller phone with less than 512MB.  Values are in KB.
+    private final long[] mOomMinFreeLow = new long[] {
+            8192, 12288, 16384,
+            24576, 28672, 32768
+    };
+    // These are the high-end OOM level limits.  This is appropriate for a
+    // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
+    private final long[] mOomMinFreeHigh = new long[] {
+            32768, 40960, 49152,
+            57344, 65536, 81920
+    };
+    // The actual OOM killer memory levels we are using.
+    private final long[] mOomMinFree = new long[mOomAdj.length];
+
+    private final long mTotalMemMb;
+
+    private boolean mHaveDisplaySize;
+
+    ProcessList() {
+        MemInfoReader minfo = new MemInfoReader();
+        minfo.readMemInfo();
+        mTotalMemMb = minfo.getTotalSize()/(1024*1024);
+        updateOomLevels(0, 0, false);
+    }
+
+    void applyDisplaySize(WindowManagerService wm) {
+        if (!mHaveDisplaySize) {
+            Point p = new Point();
+            wm.getInitialDisplaySize(p);
+            if (p.x != 0 && p.y != 0) {
+                updateOomLevels(p.x, p.y, true);
+                mHaveDisplaySize = true;
+            }
+        }
+    }
+
+    private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
+        // Scale buckets from avail memory: at 300MB we use the lowest values to
+        // 700MB or more for the top values.
+        float scaleMem = ((float)(mTotalMemMb-300))/(700-300);
+
+        // Scale buckets from screen size.
+        int minSize = 320*480;  //  153600
+        int maxSize = 1280*800; // 1024000  230400 870400  .264
+        float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
+        Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
+
+        StringBuilder adjString = new StringBuilder();
+        StringBuilder memString = new StringBuilder();
+
+        float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
+        if (scale < 0) scale = 0;
+        else if (scale > 1) scale = 1;
+        for (int i=0; i<mOomAdj.length; i++) {
+            long low = mOomMinFreeLow[i];
+            long high = mOomMinFreeHigh[i];
+            mOomMinFree[i] = (long)(low + ((high-low)*scale));
+
+            if (i > 0) {
+                adjString.append(',');
+                memString.append(',');
+            }
+            adjString.append(mOomAdj[i]);
+            memString.append((mOomMinFree[i]*1024)/PAGE_SIZE);
+        }
+
+        //Slog.i("XXXXXXX", "******************************* MINFREE: " + memString);
+        if (write) {
+            writeFile("/sys/module/lowmemorykiller/parameters/adj", adjString.toString());
+            writeFile("/sys/module/lowmemorykiller/parameters/minfree", memString.toString());
+        }
+        // GB: 2048,3072,4096,6144,7168,8192
+        // HC: 8192,10240,12288,14336,16384,20480
+    }
+
+    long getMemLevel(int adjustment) {
+        for (int i=0; i<mOomAdj.length; i++) {
+            if (adjustment <= mOomAdj[i]) {
+                return mOomMinFree[i] * 1024;
+            }
+        }
+        return mOomMinFree[mOomAdj.length-1] * 1024;
+    }
+
+    private void writeFile(String path, String data) {
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(path);
+            fos.write(data.getBytes());
+        } catch (IOException e) {
+            Slog.w(ActivityManagerService.TAG, "Unable to write " + path);
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index a896ce4..24d92cf 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -270,8 +270,8 @@
         processName = _processName;
         pkgList.add(_info.packageName);
         thread = _thread;
-        maxAdj = ActivityManagerService.EMPTY_APP_ADJ;
-        hiddenAdj = ActivityManagerService.HIDDEN_APP_MIN_ADJ;
+        maxAdj = ProcessList.EMPTY_APP_ADJ;
+        hiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
         curRawAdj = setRawAdj = -100;
         curAdj = setAdj = -100;
         persistent = false;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 36371a57..463f801 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -432,7 +432,7 @@
         PackageHandler(Looper looper) {
             super(looper);
         }
-        
+
         public void handleMessage(Message msg) {
             try {
                 doHandleMessage(msg);
@@ -490,7 +490,34 @@
                     } else if (mPendingInstalls.size() > 0) {
                         HandlerParams params = mPendingInstalls.get(0);
                         if (params != null) {
-                            params.startCopy();
+                            if (params.startCopy()) {
+                                // We are done...  look for more work or to
+                                // go idle.
+                                if (DEBUG_SD_INSTALL) Log.i(TAG,
+                                        "Checking for more work or unbind...");
+                                // Delete pending install
+                                if (mPendingInstalls.size() > 0) {
+                                    mPendingInstalls.remove(0);
+                                }
+                                if (mPendingInstalls.size() == 0) {
+                                    if (mBound) {
+                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
+                                                "Posting delayed MCS_UNBIND");
+                                        removeMessages(MCS_UNBIND);
+                                        Message ubmsg = obtainMessage(MCS_UNBIND);
+                                        // Unbind after a little delay, to avoid
+                                        // continual thrashing.
+                                        sendMessageDelayed(ubmsg, 10000);
+                                    }
+                                } else {
+                                    // There are more pending requests in queue.
+                                    // Just post MCS_BOUND message to trigger processing
+                                    // of next pending install.
+                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
+                                            "Posting MCS_BOUND for next woek");
+                                    mHandler.sendEmptyMessage(MCS_BOUND);
+                                }
+                            }
                         }
                     } else {
                         // Should never happen ideally.
@@ -517,11 +544,8 @@
                     break;
                 }
                 case MCS_UNBIND : {
+                    // If there is no actual work left, then time to unbind.
                     if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_unbind");
-                    // Delete pending install
-                    if (mPendingInstalls.size() > 0) {
-                        mPendingInstalls.remove(0);
-                    }
                     if (mPendingInstalls.size() == 0) {
                         if (mBound) {
                             disconnectService();
@@ -4814,7 +4838,8 @@
     abstract class HandlerParams {
         final static int MAX_RETRIES = 4;
         int retry = 0;
-        final void startCopy() {
+        final boolean startCopy() {
+            boolean res;
             try {
                 if (DEBUG_SD_INSTALL) Log.i(TAG, "startCopy");
                 retry++;
@@ -4822,17 +4847,18 @@
                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
                     handleServiceError();
-                    return;
+                    return false;
                 } else {
                     handleStartCopy();
-                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting install MCS_UNBIND");
-                    mHandler.sendEmptyMessage(MCS_UNBIND);
+                    res = true;
                 }
             } catch (RemoteException e) {
                 if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting install MCS_RECONNECT");
                 mHandler.sendEmptyMessage(MCS_RECONNECT);
+                res = false;
             }
             handleReturnCode();
+            return res;
         }
 
         final void serviceError() {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index e0b5e17..f80be1b 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -95,6 +95,7 @@
 import android.util.SparseIntArray;
 import android.util.TypedValue;
 import android.view.Display;
+import android.view.Gravity;
 import android.view.IApplicationToken;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
@@ -5163,6 +5164,57 @@
     }
 
     /**
+     * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
+     * theme attribute) on devices that feature a physical options menu key attempt to position
+     * their menu panel window along the edge of the screen nearest the physical menu key.
+     * This lowers the travel distance between invoking the menu panel and selecting
+     * a menu option.
+     *
+     * This method helps control where that menu is placed. Its current implementation makes
+     * assumptions about the menu key and its relationship to the screen based on whether
+     * the device's natural orientation is portrait (width < height) or landscape.
+     *
+     * The menu key is assumed to be located along the bottom edge of natural-portrait
+     * devices and along the right edge of natural-landscape devices. If these assumptions
+     * do not hold for the target device, this method should be changed to reflect that.
+     *
+     * @return A {@link Gravity} value for placing the options menu window
+     */
+    public int getPreferredOptionsPanelGravity() {
+        synchronized (mWindowMap) {
+            final int rotation = getRotation();
+
+            if (mInitialDisplayWidth < mInitialDisplayHeight) {
+                // On devices with a natural orientation of portrait
+                switch (rotation) {
+                    default:
+                    case Surface.ROTATION_0:
+                        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+                    case Surface.ROTATION_90:
+                        return Gravity.RIGHT | Gravity.CENTER_VERTICAL;
+                    case Surface.ROTATION_180:
+                        return Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+                    case Surface.ROTATION_270:
+                        return Gravity.LEFT | Gravity.CENTER_VERTICAL;
+                }
+            } else {
+                // On devices with a natural orientation of landscape
+                switch (rotation) {
+                    default:
+                    case Surface.ROTATION_0:
+                        return Gravity.RIGHT | Gravity.CENTER_VERTICAL;
+                    case Surface.ROTATION_90:
+                        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+                    case Surface.ROTATION_180:
+                        return Gravity.LEFT | Gravity.CENTER_VERTICAL;
+                    case Surface.ROTATION_270:
+                        return Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+                }
+            }
+        }
+    }
+
+    /**
      * Starts the view server on the specified port.
      *
      * @param port The port to listener to.
@@ -6612,6 +6664,13 @@
         }
     }
 
+    public void getInitialDisplaySize(Point size) {
+        synchronized(mWindowMap) {
+            size.x = mInitialDisplayWidth;
+            size.y = mInitialDisplayHeight;
+        }
+    }
+
     public int getMaximumSizeDimension() {
         synchronized(mWindowMap) {
             // Do this based on the raw screen size, until we are smarter.
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 4d86903..134227a 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -484,8 +484,7 @@
         // Note: it needs to be confirmed which CDMA network types
         // can support voice and data calls concurrently.
         // For the time-being, the return value will be false.
-        // return (networkType >= ServiceState.RADIO_TECHNOLOGY_LTE);
-        return false;
+        return (networkType == ServiceState.RADIO_TECHNOLOGY_LTE);
     }
 
     /**
diff --git a/tests/BiDiTests/res/layout/basic.xml b/tests/BiDiTests/res/layout/basic.xml
index ed91c49..18f193e 100644
--- a/tests/BiDiTests/res/layout/basic.xml
+++ b/tests/BiDiTests/res/layout/basic.xml
@@ -34,17 +34,32 @@
                     android:textSize="32dip"
                     />
 
-            <TextView android:id="@+id/textview"
+            <TextView android:id="@+id/textview_ltr"
                       android:layout_height="wrap_content"
                       android:layout_width="wrap_content"
                       android:textSize="32dip"
-                      android:text="@string/textview_text"
+                      android:text="@string/textview_ltr_text"
                     />
 
-            <EditText android:id="@+id/edittext"
+            <EditText android:id="@+id/edittext_ltr"
                       android:layout_height="wrap_content"
                       android:layout_width="match_parent"
                       android:textSize="32dip"
+                      android:textDirection="ltr"
+                    />
+
+            <TextView android:id="@+id/textview_rtl"
+                      android:layout_height="wrap_content"
+                      android:layout_width="wrap_content"
+                      android:textSize="32dip"
+                      android:text="@string/textview_rtl_text"
+                    />
+
+            <EditText android:id="@+id/edittext_rtl"
+                      android:layout_height="wrap_content"
+                      android:layout_width="match_parent"
+                      android:textSize="32dip"
+                      android:textDirection="rtl"
                     />
 
         </LinearLayout>
diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml
index 1f6be7f..f4ce0f7 100644
--- a/tests/BiDiTests/res/values/strings.xml
+++ b/tests/BiDiTests/res/values/strings.xml
@@ -25,6 +25,8 @@
     <string name="button_requestlayout_text">Request Layout</string>
     <string name="button_alert_dialog_text">AlertDialog</string>
     <string name="textview_text">This is a text for a TextView</string>
+    <string name="textview_ltr_text">This is a text for a LTR TextView</string>
+    <string name="textview_rtl_text">This is a text for a RTL TextView</string>
     <string name="edittext_text">mmmmmmmmmmmmmmmmmmmmmmmm</string>
     <string name="normal_text">Normal String</string>
     <string name="normal_long_text">mmmmmmmmmmmmmmmmmmmmmmmm</string>
diff --git a/tests/GridLayoutTest/res/layout/grid3.xml b/tests/GridLayoutTest/res/layout/grid3.xml
index 2eca384..0e53613 100644
--- a/tests/GridLayoutTest/res/layout/grid3.xml
+++ b/tests/GridLayoutTest/res/layout/grid3.xml
@@ -22,6 +22,7 @@
 
         android:useDefaultMargins="true"
         android:alignmentMode="alignBounds"
+        android:rowOrderPreserved="false"
 
         android:columnCount="4"
         >
@@ -49,7 +50,7 @@
             />
 
     <EditText
-            android:layout_width="64dip"
+            android:ems="10"
             />
 
     <TextView
@@ -60,13 +61,13 @@
             />
 
     <EditText
-            android:layout_width="32dip"
+            android:ems="8"
             />
 
     <Space
-            android:layout_row="4"
+            android:layout_row="2"
+            android:layout_rowSpan="3"
             android:layout_column="2"
-            android:layout_margin="0dip"
             android:layout_gravity="fill"
             />
 
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
index 907ee9c..8974f37 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
@@ -38,7 +38,6 @@
         p.setUseDefaultMargins(true);
         p.setAlignmentMode(ALIGN_BOUNDS);
         p.setRowOrderPreserved(false);
-        p.setPadding(0, 0, 0, 0);
 
         Spec row1 = spec(0);
         Spec row2 = spec(1);
@@ -75,12 +74,9 @@
         }
         {
             EditText c = new EditText(context);
+            c.setEms(10);
             c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
-            {
-                LayoutParams lp = new LayoutParams(row3, col2);
-                lp.width = (int) c.getPaint().measureText("Frederick.W.Flintstone");
-                p.addView(c, lp);
-            }
+            p.addView(c, new LayoutParams(row3, col2));
         }
         {
             TextView c = new TextView(context);
@@ -89,17 +85,13 @@
         }
         {
             TextView c = new EditText(context);
+            c.setEms(8);
             c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
-            {
-                LayoutParams lp = new LayoutParams(row4, col2);
-                lp.width = (int) c.getPaint().measureText("************");
-                p.addView(c, lp);
-            }
+            p.addView(c, new LayoutParams(row4, col2));
         }
         {
             Space c = new Space(context);
             LayoutParams lp = new LayoutParams(row5, col3);
-            lp.setMargins(0, 0, 0, 0);
             p.addView(c, lp);
         }
         {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index d94f369..5952c37 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -28,6 +28,7 @@
 import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.Display_Delegate;
+import android.view.Gravity;
 import android.view.IApplicationToken;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
@@ -455,4 +456,9 @@
         return null;
     }
 
+    @Override
+    public int getPreferredOptionsPanelGravity() throws RemoteException {
+        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+    }
+
 }
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index 9168e62..cbd284c 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -89,7 +89,7 @@
             mNetworksDisabledDuringConnect = false;
         }
         /* Disable failed network */
-        WifiConfigStore.disableNetwork(netId);
+        WifiConfigStore.disableNetwork(netId, WifiConfiguration.DISABLED_AUTH_FAILURE);
     }
 
     private void transitionOnSupplicantStateChange(StateChangeResult stateChangeResult) {
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index d83b968..9a51d5e 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -195,8 +195,9 @@
      * or a failure event from supplicant
      *
      * @param config The configuration details in WifiConfiguration
+     * @return the networkId now associated with the specified configuration
      */
-    static void selectNetwork(WifiConfiguration config) {
+    static int selectNetwork(WifiConfiguration config) {
         if (config != null) {
             NetworkUpdateResult result = addOrUpdateNetworkNative(config);
             int netId = result.getNetworkId();
@@ -205,7 +206,9 @@
             } else {
                 Log.e(TAG, "Failed to update network " + config);
             }
+            return netId;
         }
+        return INVALID_NETWORK_ID;
     }
 
     /**
@@ -351,10 +354,22 @@
      * @param netId network to be disabled
      */
     static boolean disableNetwork(int netId) {
+        return disableNetwork(netId, WifiConfiguration.DISABLED_UNKNOWN_REASON);
+    }
+
+    /**
+     * Disable a network. Note that there is no saveConfig operation.
+     * @param netId network to be disabled
+     * @param reason reason code network was disabled
+     */
+    static boolean disableNetwork(int netId, int reason) {
         boolean ret = WifiNative.disableNetworkCommand(netId);
         synchronized (sConfiguredNetworks) {
             WifiConfiguration config = sConfiguredNetworks.get(netId);
-            if (config != null) config.status = Status.DISABLED;
+            if (config != null) {
+                config.status = Status.DISABLED;
+                config.disableReason = reason;
+            }
         }
         sendConfiguredNetworksChangedBroadcast();
         return ret;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 28a5bc6..d2a0b30 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -211,6 +211,15 @@
         public static final String[] strings = { "current", "disabled", "enabled" };
     }
 
+    /** @hide */
+    public static final int DISABLED_UNKNOWN_REASON                         = 0;
+    /** @hide */
+    public static final int DISABLED_DNS_FAILURE                            = 1;
+    /** @hide */
+    public static final int DISABLED_DHCP_FAILURE                           = 2;
+    /** @hide */
+    public static final int DISABLED_AUTH_FAILURE                           = 3;
+
     /**
      * The ID number that the supplicant uses to identify this
      * network configuration entry. This must be passed as an argument
@@ -223,6 +232,14 @@
      * @see Status
      */
     public int status;
+
+    /**
+     * The code referring to a reason for disabling the network
+     * Valid when {@link #status} == Status.DISABLED
+     * @hide
+     */
+    public int disableReason;
+
     /**
      * The network's SSID. Can either be an ASCII string,
      * which must be enclosed in double quotation marks
@@ -351,6 +368,7 @@
         BSSID = null;
         priority = 0;
         hiddenSSID = false;
+        disableReason = DISABLED_UNKNOWN_REASON;
         allowedKeyManagement = new BitSet();
         allowedProtocols = new BitSet();
         allowedAuthAlgorithms = new BitSet();
@@ -367,12 +385,13 @@
         linkProperties = new LinkProperties();
     }
 
+    @Override
     public String toString() {
-        StringBuffer sbuf = new StringBuffer();
+        StringBuilder sbuf = new StringBuilder();
         if (this.status == WifiConfiguration.Status.CURRENT) {
             sbuf.append("* ");
         } else if (this.status == WifiConfiguration.Status.DISABLED) {
-            sbuf.append("- ");
+            sbuf.append("- DSBLE: ").append(this.disableReason).append(" ");
         }
         sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).
                 append(" BSSID: ").append(this.BSSID).append(" PRIO: ").append(this.priority).
@@ -541,6 +560,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(networkId);
         dest.writeInt(status);
+        dest.writeInt(disableReason);
         dest.writeString(SSID);
         dest.writeString(BSSID);
         dest.writeString(preSharedKey);
@@ -571,6 +591,7 @@
                 WifiConfiguration config = new WifiConfiguration();
                 config.networkId = in.readInt();
                 config.status = in.readInt();
+                config.disableReason = in.readInt();
                 config.SSID = in.readString();
                 config.BSSID = in.readString();
                 config.preSharedKey = in.readString();
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 7bb927b..d5b404e 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -70,6 +70,7 @@
     private InetAddress mIpAddress;
 
     private String mMacAddress;
+    private boolean mExplicitConnect;
 
     WifiInfo() {
         mSSID = null;
@@ -79,6 +80,7 @@
         mRssi = -9999;
         mLinkSpeed = -1;
         mHiddenSSID = false;
+        mExplicitConnect = false;
     }
 
     /**
@@ -96,6 +98,7 @@
             mLinkSpeed = source.mLinkSpeed;
             mIpAddress = source.mIpAddress;
             mMacAddress = source.mMacAddress;
+            mExplicitConnect = source.mExplicitConnect;
         }
     }
 
@@ -172,6 +175,22 @@
         mNetworkId = id;
     }
 
+
+    /**
+     * @hide
+     */
+    public boolean isExplicitConnect() {
+        return mExplicitConnect;
+    }
+
+    /**
+     * @hide
+     */
+    public void setExplicitConnect(boolean explicitConnect) {
+        this.mExplicitConnect = explicitConnect;
+    }
+
+
     /**
      * Each configured network has a unique small integer ID, used to identify
      * the network when performing operations on the supplicant. This method
@@ -260,7 +279,8 @@
             append(mSupplicantState == null ? none : mSupplicantState).
             append(", RSSI: ").append(mRssi).
             append(", Link speed: ").append(mLinkSpeed).
-            append(", Net ID: ").append(mNetworkId);
+            append(", Net ID: ").append(mNetworkId).
+            append(", Explicit connect: ").append(mExplicitConnect);
 
         return sb.toString();
     }
@@ -284,6 +304,7 @@
         dest.writeString(getSSID());
         dest.writeString(mBSSID);
         dest.writeString(mMacAddress);
+        dest.writeByte(mExplicitConnect ? (byte)1 : (byte)0);
         mSupplicantState.writeToParcel(dest, flags);
     }
 
@@ -303,6 +324,7 @@
                 info.setSSID(in.readString());
                 info.mBSSID = in.readString();
                 info.mMacAddress = in.readString();
+                info.mExplicitConnect = in.readByte() == 1 ? true : false;
                 info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
                 return info;
             }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index cd6621f..5f8385c 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -615,6 +615,17 @@
     }
 
     /**
+     * Disable a configured network asynchronously.  This call is for abnormal network
+     * events, and the user may be notified of network change, if they recently attempted
+     * to connect to the specified network.
+     * @param netId the ID of the network as returned by {@link #addNetwork}.
+     * @hide
+     */
+    public void disableNetwork(int netId, int reason) {
+        mAsyncChannel.sendMessage(CMD_DISABLE_NETWORK, netId, reason);
+    }
+
+    /**
      * Disassociate from the currently active access point. This may result
      * in the asynchronous delivery of state change events.
      * @return {@code true} if the operation succeeded
@@ -1058,6 +1069,8 @@
     public static final int CMD_SAVE_NETWORK                = 3;
     /** @hide */
     public static final int CMD_START_WPS                   = 4;
+    /** @hide */
+    public static final int CMD_DISABLE_NETWORK             = 5;
 
     /* Events from WifiService */
     /** @hide */
@@ -1617,4 +1630,4 @@
              return false;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 331d5c0..82ff0de 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -68,12 +68,14 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LruCache;
+import android.util.Slog;
 
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.AsyncChannel;
@@ -482,6 +484,11 @@
     private final WorkSource mLastRunningWifiUids = new WorkSource();
 
     private final IBatteryStats mBatteryStats;
+    private boolean mNextWifiActionExplicit = false;
+    private int mLastExplicitNetworkId;
+    private long mLastNetworkChoiceTime;
+    private static final long EXPLICIT_CONNECT_ALLOWED_DELAY_MS = 2 * 60 * 1000;
+
 
     public WifiStateMachine(Context context, String wlanInterface) {
         super(TAG);
@@ -821,7 +828,8 @@
      * @return {@code true} if the operation succeeds, {@code false} otherwise
      */
     public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId);
+        Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId,
+                WifiConfiguration.DISABLED_UNKNOWN_REASON);
         boolean result = (resultMsg.arg1 != FAILURE);
         resultMsg.recycle();
         return result;
@@ -866,6 +874,12 @@
         sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
     }
 
+    public void disableNetwork(Messenger replyTo, int netId, int reason) {
+        Message message = obtainMessage(CMD_DISABLE_NETWORK, netId, reason);
+        message.replyTo = replyTo;
+        sendMessage(message);
+    }
+
     public void startWps(Messenger replyTo, WpsConfiguration config) {
         Message msg = obtainMessage(CMD_START_WPS, config);
         msg.replyTo = replyTo;
@@ -1534,6 +1548,7 @@
         mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
         mWifiInfo.setRssi(MIN_RSSI);
         mWifiInfo.setLinkSpeed(-1);
+        mWifiInfo.setExplicitConnect(false);
 
         /* send event to CM & network change broadcast */
         setNetworkDetailedState(DetailedState.DISCONNECTED);
@@ -1631,7 +1646,8 @@
         if (++mReconnectCount > getMaxDhcpRetries()) {
             Log.e(TAG, "Failed " +
                     mReconnectCount + " times, Disabling " + mLastNetworkId);
-            WifiConfigStore.disableNetwork(mLastNetworkId);
+            WifiConfigStore.disableNetwork(mLastNetworkId,
+                    WifiConfiguration.DISABLED_DHCP_FAILURE);
             mReconnectCount = 0;
         }
 
@@ -2169,7 +2185,7 @@
                     WifiConfigStore.enableAllNetworks();
                     break;
                 case CMD_DISABLE_NETWORK:
-                    ok = WifiConfigStore.disableNetwork(message.arg1);
+                    ok = WifiConfigStore.disableNetwork(message.arg1, message.arg2);
                     mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
                     break;
                 case CMD_BLACKLIST_NETWORK:
@@ -2605,7 +2621,7 @@
                      * a connection to the enabled network.
                      */
                     if (config != null) {
-                        WifiConfigStore.selectNetwork(config);
+                        netId = WifiConfigStore.selectNetwork(config);
                     } else {
                         WifiConfigStore.selectNetwork(netId);
                     }
@@ -2614,7 +2630,10 @@
                     mSupplicantStateTracker.sendMessage(CMD_CONNECT_NETWORK);
 
                     WifiNative.reconnectCommand();
-
+                    mLastExplicitNetworkId = netId;
+                    mLastNetworkChoiceTime  = SystemClock.elapsedRealtime();
+                    mNextWifiActionExplicit = true;
+                    Slog.d(TAG, "Setting wifi connect explicit for netid " + netId);
                     /* Expect a disconnection from the old connection */
                     transitionTo(mDisconnectingState);
                     break;
@@ -2636,6 +2655,13 @@
                     mWifiInfo.setSSID(fetchSSID());
                     mWifiInfo.setBSSID(mLastBssid);
                     mWifiInfo.setNetworkId(mLastNetworkId);
+                    if (mNextWifiActionExplicit &&
+                        mWifiInfo.getNetworkId() == mLastExplicitNetworkId &&
+                        SystemClock.elapsedRealtime() < mLastNetworkChoiceTime +
+                                                            EXPLICIT_CONNECT_ALLOWED_DELAY_MS) {
+                        mWifiInfo.setExplicitConnect(true);
+                    }
+                    mNextWifiActionExplicit = false;
                     /* send event to CM & network change broadcast */
                     setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
                     sendNetworkStateChangeBroadcast(mLastBssid);
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 168c68b..5c8926c 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -70,6 +70,7 @@
     private static final boolean VDBG = false;
     private static final boolean DBG = true;
     private static final String WWSM_TAG = "WifiWatchdogStateMachine";
+    private static final String WATCHDOG_NOTIFICATION_ID = "Android.System.WifiWatchdog";
 
     private static final int WIFI_SIGNAL_LEVELS = 4;
     /**
@@ -157,7 +158,7 @@
     /**
      * The {@link WifiInfo} object passed to WWSM on network broadcasts
      */
-    private WifiInfo mInitialConnInfo;
+    private WifiInfo mConnectionInfo;
     private int mNetEventCounter = 0;
 
     /**
@@ -173,7 +174,9 @@
      * It triggers a disableNetwork call if a DNS check fails.
      */
     public boolean mDisableAPNextFailure = false;
-    public ConnectivityManager mConnectivityManager;
+    private ConnectivityManager mConnectivityManager;
+    private boolean mNotificationShown;
+    public boolean mHasConnectedWifiManager = false;
 
     /**
      * STATE MAP
@@ -212,8 +215,6 @@
 
         setInitialState(mWatchdogDisabledState);
         updateSettings();
-        mShowDisabledNotification = getSettingsBoolean(mContentResolver,
-                Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP, true);
     }
 
     public static WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Context context) {
@@ -318,6 +319,9 @@
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL),
                 false, contentObserver);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP)
+                , false, contentObserver);
     }
 
     /**
@@ -356,7 +360,7 @@
     public void dump(PrintWriter pw) {
         pw.print("WatchdogStatus: ");
         pw.print("State " + getCurrentState());
-        pw.println(", network [" + mInitialConnInfo + "]");
+        pw.println(", network [" + mConnectionInfo + "]");
         pw.print("checkFailures   " + mNumCheckFailures);
         pw.println(", bssids: " + mBssids);
         pw.println("lastSingleCheck: " + mOnlineWatchState.lastCheckTime);
@@ -396,6 +400,8 @@
         mWalledGardenIntervalMs = Secure.getLong(mContentResolver,
                 Secure.WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS,
                 DEFAULT_WALLED_GARDEN_INTERVAL_MS);
+        mShowDisabledNotification = getSettingsBoolean(mContentResolver,
+                Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP, true);
     }
 
     /**
@@ -420,17 +426,42 @@
     }
 
     /**
-   *
-   */
+     * Uses {@link #mConnectionInfo}.
+     */
+    private void updateBssids() {
+        String curSsid = mConnectionInfo.getSSID();
+        List<ScanResult> results = mWifiManager.getScanResults();
+        int oldNumBssids = mBssids.size();
+
+        if (results == null) {
+            if (DBG) {
+                Slog.d(WWSM_TAG, "updateBssids: Got null scan results!");
+            }
+            return;
+        }
+
+        for (ScanResult result : results) {
+            if (result == null || result.SSID == null) {
+                if (DBG) {
+                    Slog.d(WWSM_TAG, "Received invalid scan result: " + result);
+                }
+                continue;
+            }
+            if (curSsid.equals(result.SSID))
+                mBssids.add(result.BSSID);
+        }
+    }
+
     private void resetWatchdogState() {
         if (VDBG) {
             Slog.v(WWSM_TAG, "Resetting watchdog state...");
         }
-        mInitialConnInfo = null;
+        mConnectionInfo = null;
         mDisableAPNextFailure = false;
         mLastWalledGardenCheckTime = null;
         mNumCheckFailures = 0;
         mBssids.clear();
+        cancelNetworkNotification();
     }
 
     private void popUpBrowser() {
@@ -441,11 +472,11 @@
         mContext.startActivity(intent);
     }
 
-    private void displayDisabledNetworkNotification() {
+    private void displayDisabledNetworkNotification(String ssid) {
         Resources r = Resources.getSystem();
         CharSequence title =
                 r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled);
-        CharSequence msg =
+        String msg = ssid +
                 r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled_detailed);
 
         Notification wifiDisabledWarning = new Notification.Builder(mContext)
@@ -455,7 +486,7 @@
             .setContentTitle(title)
             .setContentText(msg)
             .setContentIntent(PendingIntent.getActivity(mContext, 0,
-                    new Intent(Settings.ACTION_WIFI_IP_SETTINGS)
+                    new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK)
                         .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0))
             .setWhen(System.currentTimeMillis())
             .setAutoCancel(true)
@@ -464,7 +495,17 @@
         NotificationManager notificationManager = (NotificationManager) mContext
                 .getSystemService(Context.NOTIFICATION_SERVICE);
 
-        notificationManager.notify("WifiWatchdog", wifiDisabledWarning.icon, wifiDisabledWarning);
+        notificationManager.notify(WATCHDOG_NOTIFICATION_ID, 1, wifiDisabledWarning);
+        mNotificationShown = true;
+    }
+
+    public void cancelNetworkNotification() {
+        if (mNotificationShown) {
+            NotificationManager notificationManager = (NotificationManager) mContext
+                    .getSystemService(Context.NOTIFICATION_SERVICE);
+            notificationManager.cancel(WATCHDOG_NOTIFICATION_ID, 1);
+            mNotificationShown = false;
+        }
     }
 
     /**
@@ -537,6 +578,7 @@
 
                     switch (networkInfo.getState()) {
                         case CONNECTED:
+                            cancelNetworkNotification();
                             WifiInfo wifiInfo = (WifiInfo)
                                 stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
                             if (wifiInfo == null) {
@@ -551,6 +593,8 @@
                             }
 
                             initConnection(wifiInfo);
+                            mConnectionInfo = wifiInfo;
+                            updateBssids();
                             transitionTo(mDnsCheckingState);
                             mNetEventCounter++;
                             return HANDLED;
@@ -579,16 +623,15 @@
          */
         private void initConnection(WifiInfo wifiInfo) {
             if (VDBG) {
-                Slog.v(WWSM_TAG, "Connected:: old " + wifiInfoToStr(mInitialConnInfo) +
+                Slog.v(WWSM_TAG, "Connected:: old " + wifiInfoToStr(mConnectionInfo) +
                         " ==> new " + wifiInfoToStr(wifiInfo));
             }
 
-            if (mInitialConnInfo == null || !wifiInfo.getSSID().equals(mInitialConnInfo.getSSID())) {
+            if (mConnectionInfo == null || !wifiInfo.getSSID().equals(mConnectionInfo.getSSID())) {
                 resetWatchdogState();
-            } else if (!wifiInfo.getBSSID().equals(mInitialConnInfo.getBSSID())) {
+            } else if (!wifiInfo.getBSSID().equals(mConnectionInfo.getBSSID())) {
                 mDisableAPNextFailure = false;
             }
-            mInitialConnInfo = wifiInfo;
         }
 
         @Override
@@ -606,27 +649,7 @@
         public boolean processMessage(Message msg) {
             switch (msg.what) {
                 case EVENT_SCAN_RESULTS_AVAILABLE:
-                    String curSsid = mInitialConnInfo.getSSID();
-                    List<ScanResult> results = mWifiManager.getScanResults();
-                    int oldNumBssids = mBssids.size();
-
-                    if (results == null) {
-                        if (DBG) {
-                            Slog.d(WWSM_TAG, "updateBssids: Got null scan results!");
-                        }
-                        return HANDLED;
-                    }
-
-                    for (ScanResult result : results) {
-                        if (result == null || result.SSID == null) {
-                            if (VDBG) {
-                                Slog.v(WWSM_TAG, "Received invalid scan result: " + result);
-                            }
-                            continue;
-                        }
-                        if (curSsid.equals(result.SSID))
-                            mBssids.add(result.BSSID);
-                    }
+                    updateBssids();
                     return HANDLED;
                 case EVENT_WATCHDOG_SETTINGS_CHANGE:
                     // Stop current checks, but let state update
@@ -635,7 +658,6 @@
             }
             return NOT_HANDLED;
         }
-
     }
 
     class DnsCheckingState extends State {
@@ -653,7 +675,7 @@
             if (DBG) {
                 Slog.d(WWSM_TAG, "Starting DNS pings at " + SystemClock.elapsedRealtime());
                 dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ",
-                        dns, mInitialConnInfo.getSSID());
+                        mDnsPinger.getDns(), mConnectionInfo.getSSID());
             }
 
             for (int i=0; i < mNumDnsPings; i++) {
@@ -905,7 +927,8 @@
                 return HANDLED;
             }
 
-            if (mDisableAPNextFailure || mNumCheckFailures >= mMaxSsidBlacklists) {
+            if (mDisableAPNextFailure || mNumCheckFailures >= mBssids.size()
+                    || mNumCheckFailures >= mMaxSsidBlacklists) {
                 if (hasNoMobileData()) {
                     Slog.w(WWSM_TAG, "Would disable bad network, but device has no mobile data!" +
                             "  Going idle...");
@@ -913,23 +936,26 @@
                     transitionTo(mNotConnectedState);
                     return HANDLED;
                 }
+
                 // TODO : Unban networks if they had low signal ?
-                Slog.i(WWSM_TAG, "Disabling current SSID " + wifiInfoToStr(mInitialConnInfo)
+                Slog.i(WWSM_TAG, "Disabling current SSID " + wifiInfoToStr(mConnectionInfo)
                         + ".  " + "numCheckFailures " + mNumCheckFailures
                         + ", numAPs " + mBssids.size());
-                mWifiManager.disableNetwork(mInitialConnInfo.getNetworkId());
-                if (mShowDisabledNotification) {
-                    displayDisabledNetworkNotification();
-                    mShowDisabledNotification = false;
-                    putSettingsBoolean(mContentResolver,
-                            Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP, false);
+                int networkId = mConnectionInfo.getNetworkId();
+                if (!mHasConnectedWifiManager) {
+                    mWifiManager.asyncConnect(mContext, getHandler());
+                    mHasConnectedWifiManager = true;
+                }
+                mWifiManager.disableNetwork(networkId, WifiConfiguration.DISABLED_DNS_FAILURE);
+                if (mShowDisabledNotification && mConnectionInfo.isExplicitConnect()) {
+                    displayDisabledNetworkNotification(mConnectionInfo.getSSID());
                 }
                 transitionTo(mNotConnectedState);
             } else {
-                Slog.i(WWSM_TAG, "Blacklisting current BSSID.  " + wifiInfoToStr(mInitialConnInfo)
+                Slog.i(WWSM_TAG, "Blacklisting current BSSID.  " + wifiInfoToStr(mConnectionInfo)
                        + "numCheckFailures " + mNumCheckFailures + ", numAPs " + mBssids.size());
 
-                mWifiManager.addToBlacklist(mInitialConnInfo.getBSSID());
+                mWifiManager.addToBlacklist(mConnectionInfo.getBSSID());
                 mWifiManager.reassociate();
                 transitionTo(mBlacklistedApState);
             }