Merge "turn off log spew"
diff --git a/api/current.xml b/api/current.xml
index 1f3b5fd..22d82ce 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -57955,6 +57955,17 @@
  visibility="public"
 >
 </field>
+<field name="CONFIG_SCREEN_SIZE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="CONFIG_TOUCHSCREEN"
  type="int"
  transient="false"
@@ -64017,6 +64028,28 @@
  visibility="public"
 >
 </field>
+<field name="SCREEN_HEIGHT_DP_UNDEFINED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREEN_WIDTH_DP_UNDEFINED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TOUCHSCREEN_FINGER"
  type="int"
  transient="false"
@@ -64260,6 +64293,16 @@
  visibility="public"
 >
 </field>
+<field name="screenHeightDp"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="screenLayout"
  type="int"
  transient="false"
@@ -64270,6 +64313,16 @@
  visibility="public"
 >
 </field>
+<field name="screenWidthDp"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="touchscreen"
  type="int"
  transient="false"
@@ -144074,6 +144127,17 @@
  visibility="public"
 >
 </field>
+<field name="ICE_CREAM_SANDWICH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10000"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="Bundle"
  extends="java.lang.Object"
@@ -267777,7 +267841,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 46f611f..64c437d 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -334,6 +334,12 @@
     public static final int CONFIG_UI_MODE = 0x0200;
     /**
      * Bit in {@link #configChanges} that indicates that the activity
+     * can itself handle the screen size. Set from the
+     * {@link android.R.attr#configChanges} attribute.
+     */
+    public static final int CONFIG_SCREEN_SIZE = 0x0400;
+    /**
+     * Bit in {@link #configChanges} that indicates that the activity
      * can itself handle changes to the font scaling factor.  Set from the
      * {@link android.R.attr#configChanges} attribute.  This is
      * not a core resource configutation, but a higher-level value, so its
@@ -341,6 +347,37 @@
      */
     public static final int CONFIG_FONT_SCALE = 0x40000000;
     
+    /** @hide
+     * Unfortunately the constants for config changes in native code are
+     * different from ActivityInfo. :(  Here are the values we should use for the
+     * native side given the bit we have assigned in ActivityInfo.
+     */
+    public static int[] CONFIG_NATIVE_BITS = new int[] {
+        0x0001, // MNC
+        0x0002, // MCC
+        0x0004, // LOCALE
+        0x0008, // TOUCH SCREEN
+        0x0010, // KEYBOARD
+        0x0020, // KEYBOARD HIDDEN
+        0x0040, // NAVIGATION
+        0x0080, // ORIENTATION
+        0x0800, // SCREEN LAYOUT
+        0x1000, // UI MODE
+        0x0200, // SCREEN SIZE
+    };
+    /** @hide
+     * Convert Java change bits to native.
+     */
+    public static int activityInfoConfigToNative(int input) {
+        int output = 0;
+        for (int i=0; i<CONFIG_NATIVE_BITS.length; i++) {
+            if ((input&(1<<i)) != 0) {
+                output |= CONFIG_NATIVE_BITS[i];
+            }
+        }
+        return output;
+    }
+
     /**
      * Bit mask of kinds of configuration changes that this activity
      * can handle itself (without being restarted by the system).
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 7ebfda4..8dfdaa8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -396,7 +396,7 @@
             int cookie = assmgr.addAssetPath(mArchiveSourcePath);
             if (cookie != 0) {
                 res = new Resources(assmgr, metrics, null);
-                assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                         Build.VERSION.RESOURCES_SDK_INT);
                 parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
                 assetError = false;
@@ -596,7 +596,7 @@
         AssetManager assmgr = null;
         try {
             assmgr = new AssetManager();
-            assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     Build.VERSION.RESOURCES_SDK_INT);
             int cookie = assmgr.addAssetPath(packageFilePath);
             parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
@@ -1931,6 +1931,10 @@
             a.info.configChanges = sa.getInt(
                     com.android.internal.R.styleable.AndroidManifestActivity_configChanges,
                     0);
+            if (owner.applicationInfo.targetSdkVersion
+                        < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+                a.info.configChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
+            }
             a.info.softInputMode = sa.getInt(
                     com.android.internal.R.styleable.AndroidManifestActivity_windowSoftInputMode,
                     0);
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index e279f64..afa68c3 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -652,7 +652,8 @@
     public native final void setConfiguration(int mcc, int mnc, String locale,
             int orientation, int touchscreen, int density, int keyboard,
             int keyboardHidden, int navigation, int screenWidth, int screenHeight,
-            int screenLayout, int uiMode, int majorVersion);
+            int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode,
+            int majorVersion);
 
     /**
      * Retrieve the resource identifier for the given resource name.
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 72fa07c..28ba4e7 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -241,6 +241,20 @@
      */
     public int uiMode;
 
+    public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
+
+    /**
+     * The current width of the available screen space, in dp units.
+     */
+    public int screenWidthDp;
+
+    public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
+
+    /**
+     * The current height of the available screen space, in dp units.
+     */
+    public int screenHeightDp;
+
     /**
      * @hide Internal book-keeping.
      */
@@ -278,6 +292,8 @@
         orientation = o.orientation;
         screenLayout = o.screenLayout;
         uiMode = o.uiMode;
+        screenWidthDp = o.screenWidthDp;
+        screenHeightDp = o.screenHeightDp;
         seq = o.seq;
     }
     
@@ -316,6 +332,10 @@
         sb.append(java.lang.Integer.toHexString(screenLayout));
         sb.append(" uiMode=0x");
         sb.append(java.lang.Integer.toHexString(uiMode));
+        sb.append(" wdp=");
+        sb.append(screenWidthDp);
+        sb.append(" hdp=");
+        sb.append(screenHeightDp);
         if (seq != 0) {
             sb.append(" seq=");
             sb.append(seq);
@@ -341,6 +361,8 @@
         orientation = ORIENTATION_UNDEFINED;
         screenLayout = SCREENLAYOUT_SIZE_UNDEFINED;
         uiMode = UI_MODE_TYPE_UNDEFINED;
+        screenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
+        screenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
         seq = 0;
     }
 
@@ -434,6 +456,16 @@
                         | (delta.uiMode&UI_MODE_NIGHT_MASK);
             }
         }
+        if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
+                && screenWidthDp != delta.screenWidthDp) {
+            changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+            screenWidthDp = delta.screenWidthDp;
+        }
+        if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
+                && screenHeightDp != delta.screenHeightDp) {
+            changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+            screenHeightDp = delta.screenHeightDp;
+        }
         
         if (delta.seq != 0) {
             seq = delta.seq;
@@ -463,9 +495,11 @@
      * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
      * PackageManager.ActivityInfo.CONFIG_NAVIGATION},
      * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
-     * PackageManager.ActivityInfo.CONFIG_ORIENTATION}, or
+     * PackageManager.ActivityInfo.CONFIG_ORIENTATION},
      * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
-     * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}.
+     * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}, or
+     * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
+     * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}.
      */
     public int diff(Configuration delta) {
         int changed = 0;
@@ -518,6 +552,14 @@
                 && uiMode != delta.uiMode) {
             changed |= ActivityInfo.CONFIG_UI_MODE;
         }
+        if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
+                && screenWidthDp != delta.screenWidthDp) {
+            changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+        }
+        if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
+                && screenHeightDp != delta.screenHeightDp) {
+            changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+        }
         
         return changed;
     }
@@ -599,6 +641,8 @@
         dest.writeInt(orientation);
         dest.writeInt(screenLayout);
         dest.writeInt(uiMode);
+        dest.writeInt(screenWidthDp);
+        dest.writeInt(screenHeightDp);
         dest.writeInt(seq);
     }
 
@@ -620,6 +664,8 @@
         orientation = source.readInt();
         screenLayout = source.readInt();
         uiMode = source.readInt();
+        screenWidthDp = source.readInt();
+        screenHeightDp = source.readInt();
         seq = source.readInt();
     }
     
@@ -680,6 +726,10 @@
         n = this.screenLayout - that.screenLayout;
         if (n != 0) return n;
         n = this.uiMode - that.uiMode;
+        if (n != 0) return n;
+        n = this.screenWidthDp - that.screenWidthDp;
+        if (n != 0) return n;
+        n = this.screenHeightDp - that.screenHeightDp;
         //if (n != 0) return n;
         return n;
     }
@@ -704,6 +754,7 @@
                 + this.touchscreen
                 + this.keyboard + this.keyboardHidden + this.hardKeyboardHidden
                 + this.navigation + this.navigationHidden
-                + this.orientation + this.screenLayout + this.uiMode;
+                + this.orientation + this.screenLayout + this.uiMode
+                + this.screenWidthDp + this.screenHeightDp;
     }
 }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 81eb09c..2e6ae70 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -21,6 +21,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.pm.ActivityInfo;
 import android.graphics.Movie;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.ColorDrawable;
@@ -1404,6 +1405,7 @@
             int configChanges = 0xfffffff;
             if (config != null) {
                 configChanges = mConfiguration.updateFrom(config);
+                configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
             }
             if (mConfiguration.locale == null) {
                 mConfiguration.locale = Locale.getDefault();
@@ -1443,6 +1445,7 @@
                     mConfiguration.touchscreen,
                     (int)(mMetrics.density*160), mConfiguration.keyboard,
                     keyboardHidden, mConfiguration.navigation, width, height,
+                    mConfiguration.screenWidthDp, mConfiguration.screenHeightDp,
                     mConfiguration.screenLayout, mConfiguration.uiMode,
                     Build.VERSION.RESOURCES_SDK_INT);
 
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 3bb0821..24d5369 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -230,6 +230,11 @@
          * Newest version of Android, version 3.1.
          */
         public static final int HONEYCOMB_MR1 = 12;
+
+        /**
+         * Current version under development.
+         */
+        public static final int ICE_CREAM_SANDWICH = CUR_DEVELOPMENT;
     }
     
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6deb5a0..c75b0fe 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3303,12 +3303,20 @@
         public static final String WIFI_IDLE_MS = "wifi_idle_ms";
 
         /**
-         * The interval in milliseconds to issue scans when the driver is
-         * started. This is necessary to allow wifi to connect to an
-         * access point when the driver is suspended.
+         * The interval in milliseconds to issue wake up scans when wifi needs
+         * to connect. This is necessary to connect to an access point when
+         * device is on the move and the screen is off.
          * @hide
          */
-        public static final String WIFI_SCAN_INTERVAL_MS = "wifi_scan_interval_ms";
+        public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS =
+                "wifi_framework_scan_interval_ms";
+
+        /**
+         * The interval in milliseconds to scan as used by the wifi supplicant
+         * @hide
+         */
+        public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS =
+                "wifi_supplicant_scan_interval_ms";
 
         /**
          * The interval in milliseconds at which to check packet counts on the
diff --git a/core/java/android/server/BluetoothAdapterProperties.java b/core/java/android/server/BluetoothAdapterProperties.java
index ae8104b..9723f60 100644
--- a/core/java/android/server/BluetoothAdapterProperties.java
+++ b/core/java/android/server/BluetoothAdapterProperties.java
@@ -76,14 +76,13 @@
         for (int i = 0; i < properties.length; i++) {
             String name = properties[i];
             String newValue = null;
-            int len;
             if (name == null) {
                 Log.e(TAG, "Error:Adapter Property at index " + i + " is null");
                 continue;
             }
             if (name.equals("Devices") || name.equals("UUIDs")) {
                 StringBuilder str = new StringBuilder();
-                len = Integer.valueOf(properties[++i]);
+                int len = Integer.valueOf(properties[++i]);
                 for (int j = 0; j < len; j++) {
                     str.append(properties[++i]);
                     str.append(",");
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index de18f9f..b319a74 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -137,7 +137,6 @@
 
 #define RETURN_ERR_IF_NULL(value)   do { if (!(value)) { assert(0); return -1; } } while (false)
 
-int register_android_graphics_Movie(JNIEnv* env);
 int register_android_graphics_Movie(JNIEnv* env)
 {
     gMovie_class = env->FindClass(kClassPathName);
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index ff13c2b..10e2e41 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -215,4 +215,309 @@
     LOGD("------------------------------------------------");
 }
 
+/**
+ * TextLayoutCacheKey
+ */
+TextLayoutCacheKey::TextLayoutCacheKey() : text(NULL), start(0), count(0), contextCount(0),
+        dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
+        hinting(SkPaint::kNo_Hinting)  {
+}
+
+TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint,
+        const UChar* text, size_t start, size_t count,
+        size_t contextCount, int dirFlags) :
+            text(text), start(start), count(count), contextCount(contextCount),
+            dirFlags(dirFlags) {
+    typeface = paint->getTypeface();
+    textSize = paint->getTextSize();
+    textSkewX = paint->getTextSkewX();
+    textScaleX = paint->getTextScaleX();
+    flags = paint->getFlags();
+    hinting = paint->getHinting();
+}
+
+bool TextLayoutCacheKey::operator<(const TextLayoutCacheKey& rhs) const {
+    LTE_INT(count) {
+        LTE_INT(contextCount) {
+            LTE_INT(start) {
+                LTE_INT(typeface) {
+                    LTE_FLOAT(textSize) {
+                        LTE_FLOAT(textSkewX) {
+                            LTE_FLOAT(textScaleX) {
+                                LTE_INT(flags) {
+                                    LTE_INT(hinting) {
+                                        LTE_INT(dirFlags) {
+                                            return strncmp16(text, rhs.text, contextCount) < 0;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
+void TextLayoutCacheKey::internalTextCopy() {
+    textCopy.setTo(text, contextCount);
+    text = textCopy.string();
+}
+
+size_t TextLayoutCacheKey::getSize() {
+    return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount;
+}
+
+/**
+ * TextLayoutCacheValue
+ */
+TextLayoutCacheValue::TextLayoutCacheValue() {
+    advances = NULL;
+    totalAdvance = 0;
+}
+
+TextLayoutCacheValue::~TextLayoutCacheValue() {
+    delete[] advances;
+}
+
+void TextLayoutCacheValue::setElapsedTime(uint32_t time) {
+    elapsedTime = time;
+}
+
+uint32_t TextLayoutCacheValue::getElapsedTime() {
+    return elapsedTime;
+}
+
+void TextLayoutCacheValue::computeAdvances(SkPaint* paint, const UChar* chars, size_t start,
+        size_t count, size_t contextCount, int dirFlags) {
+    advances = new float[count];
+    this->count = count;
+
+#if RTL_USE_HARFBUZZ
+    computeAdvancesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+            advances, &totalAdvance);
+#else
+    computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags,
+            advances, &totalAdvance);
+#endif
+#if DEBUG_ADVANCES
+    LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - "
+            "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, totalAdvance,
+            advances[0], advances[1], advances[2], advances[3]);
+#endif
+}
+
+void TextLayoutCacheValue::copyResult(jfloat* outAdvances, jfloat* outTotalAdvance) {
+    memcpy(outAdvances, advances, count * sizeof(jfloat));
+    *outTotalAdvance = totalAdvance;
+}
+
+size_t TextLayoutCacheValue::getSize() {
+    return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * count;
+}
+
+void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font,
+        FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
+        size_t contextCount, int dirFlags) {
+    bool isRTL = dirFlags & 0x1;
+
+    font->klass = &harfbuzzSkiaClass;
+    font->userData = 0;
+    // The values which harfbuzzSkiaClass returns are already scaled to
+    // pixel units, so we just set all these to one to disable further
+    // scaling.
+    font->x_ppem = 1;
+    font->y_ppem = 1;
+    font->x_scale = 1;
+    font->y_scale = 1;
+
+    memset(shaperItem, 0, sizeof(*shaperItem));
+    shaperItem->font = font;
+    shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable);
+
+    shaperItem->kerning_applied = false;
+
+    // We cannot know, ahead of time, how many glyphs a given script run
+    // will produce. We take a guess that script runs will not produce more
+    // than twice as many glyphs as there are code points plus a bit of
+    // padding and fallback if we find that we are wrong.
+    createGlyphArrays(shaperItem, (contextCount + 2) * 2);
+
+    // Free memory for clusters if needed and recreate the clusters array
+    if (shaperItem->log_clusters) {
+        delete shaperItem->log_clusters;
+    }
+    shaperItem->log_clusters = new unsigned short[contextCount];
+
+    shaperItem->item.pos = start;
+    shaperItem->item.length = count;
+    shaperItem->item.bidiLevel = isRTL;
+    shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common;
+
+    shaperItem->string = chars;
+    shaperItem->stringLength = contextCount;
+
+    fontData->typeFace = paint->getTypeface();
+    fontData->textSize = paint->getTextSize();
+    fontData->textSkewX = paint->getTextSkewX();
+    fontData->textScaleX = paint->getTextScaleX();
+    fontData->flags = paint->getFlags();
+    fontData->hinting = paint->getHinting();
+
+    shaperItem->font->userData = fontData;
+}
+
+void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font,
+        FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
+        size_t contextCount, int dirFlags) {
+    // Setup Harfbuzz Shaper
+    setupShaperItem(shaperItem, font, fontData, paint, chars, start, count,
+            contextCount, dirFlags);
+
+    // Shape
+    resetGlyphArrays(shaperItem);
+    while (!HB_ShapeItem(shaperItem)) {
+        // We overflowed our arrays. Resize and retry.
+        // HB_ShapeItem fills in shaperItem.num_glyphs with the needed size.
+        deleteGlyphArrays(shaperItem);
+        createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1);
+        resetGlyphArrays(shaperItem);
+    }
+}
+
+void TextLayoutCacheValue::computeAdvancesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+        size_t start, size_t count, size_t contextCount, int dirFlags,
+        jfloat* outAdvances, jfloat* outTotalAdvance) {
+
+    bool isRTL = dirFlags & 0x1;
+
+    HB_ShaperItem shaperItem;
+    HB_FontRec font;
+    FontData fontData;
+    shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count,
+            contextCount, dirFlags);
+
+#if DEBUG_ADVANCES
+    LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs,
+            shaperItem.kerning_applied);
+    LOGD("         -- string= '%s'", String8(chars, contextCount).string());
+    LOGD("         -- isDevKernText=%d", paint->isDevKernText());
+#endif
+
+    jfloat totalAdvance = 0;
+
+    for (size_t i = 0; i < count; i++) {
+        totalAdvance += outAdvances[i] = HBFixedToFloat(shaperItem.advances[i]);
+
+#if DEBUG_ADVANCES
+        LOGD("hb-adv = %d - rebased = %f - total = %f", shaperItem.advances[i], outAdvances[i],
+                totalAdvance);
+#endif
+    }
+
+    deleteGlyphArrays(&shaperItem);
+    HB_FreeFace(shaperItem.face);
+
+    *outTotalAdvance = totalAdvance;
+}
+
+void TextLayoutCacheValue::computeAdvancesWithICU(SkPaint* paint, const UChar* chars,
+        size_t start, size_t count, size_t contextCount, int dirFlags,
+        jfloat* outAdvances, jfloat* outTotalAdvance) {
+
+    SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount);
+    jchar* buffer = tempBuffer.get();
+
+    SkScalar* scalarArray = (SkScalar*)outAdvances;
+
+    // this is where we'd call harfbuzz
+    // for now we just use ushape.c
+    size_t widths;
+    const jchar* text;
+    if (dirFlags & 0x1) { // rtl, call arabic shaping in case
+        UErrorCode status = U_ZERO_ERROR;
+        // Use fixed length since we need to keep start and count valid
+        u_shapeArabic(chars, contextCount, buffer, contextCount,
+                U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
+                U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE |
+                U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
+        // we shouldn't fail unless there's an out of memory condition,
+        // in which case we're hosed anyway
+        for (int i = start, e = i + count; i < e; ++i) {
+            if (buffer[i] == UNICODE_NOT_A_CHAR) {
+                buffer[i] = UNICODE_ZWSP; // zero-width-space for skia
+            }
+        }
+        text = buffer + start;
+        widths = paint->getTextWidths(text, count << 1, scalarArray);
+    } else {
+        text = chars + start;
+        widths = paint->getTextWidths(text, count << 1, scalarArray);
+    }
+
+    jfloat totalAdvance = 0;
+    if (widths < count) {
+#if DEBUG_ADVANCES
+    LOGD("ICU -- count=%d", widths);
+#endif
+        // Skia operates on code points, not code units, so surrogate pairs return only
+        // one value. Expand the result so we have one value per UTF-16 code unit.
+
+        // Note, skia's getTextWidth gets confused if it encounters a surrogate pair,
+        // leaving the remaining widths zero.  Not nice.
+        for (size_t i = 0, p = 0; i < widths; ++i) {
+            totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]);
+            if (p < count &&
+                    text[p] >= UNICODE_FIRST_LOW_SURROGATE &&
+                    text[p] < UNICODE_FIRST_PRIVATE_USE &&
+                    text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE &&
+                    text[p-1] < UNICODE_FIRST_LOW_SURROGATE) {
+                outAdvances[p++] = 0;
+            }
+#if DEBUG_ADVANCES
+            LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
+#endif
+        }
+    } else {
+#if DEBUG_ADVANCES
+    LOGD("ICU -- count=%d", count);
+#endif
+        for (size_t i = 0; i < count; i++) {
+            totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]);
+#if DEBUG_ADVANCES
+            LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
+#endif
+        }
+    }
+    *outTotalAdvance = totalAdvance;
+}
+
+void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) {
+    delete[] shaperItem->glyphs;
+    delete[] shaperItem->attributes;
+    delete[] shaperItem->advances;
+    delete[] shaperItem->offsets;
+}
+
+void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem* shaperItem, int size) {
+    shaperItem->glyphs = new HB_Glyph[size];
+    shaperItem->attributes = new HB_GlyphAttributes[size];
+    shaperItem->advances = new HB_Fixed[size];
+    shaperItem->offsets = new HB_FixedPoint[size];
+    shaperItem->num_glyphs = size;
+}
+
+void TextLayoutCacheValue::resetGlyphArrays(HB_ShaperItem* shaperItem) {
+    int size = shaperItem->num_glyphs;
+    // All the types here don't have pointers. It is safe to reset to
+    // zero unless Harfbuzz breaks the compatibility in the future.
+    memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0]));
+    memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0]));
+    memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0]));
+    memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0]));
+}
+
+
 } // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 8438d78..cd5a58d 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -64,62 +64,24 @@
  */
 class TextLayoutCacheKey {
 public:
-    TextLayoutCacheKey() : text(NULL), start(0), count(0), contextCount(0),
-            dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
-            hinting(SkPaint::kNo_Hinting)  {
-    }
+    TextLayoutCacheKey();
 
     TextLayoutCacheKey(const SkPaint* paint,
             const UChar* text, size_t start, size_t count,
-            size_t contextCount, int dirFlags) :
-                text(text), start(start), count(count), contextCount(contextCount),
-                dirFlags(dirFlags) {
-        typeface = paint->getTypeface();
-        textSize = paint->getTextSize();
-        textSkewX = paint->getTextSkewX();
-        textScaleX = paint->getTextScaleX();
-        flags = paint->getFlags();
-        hinting = paint->getHinting();
-    }
+            size_t contextCount, int dirFlags);
 
-    bool operator<(const TextLayoutCacheKey& rhs) const {
-        LTE_INT(count) {
-            LTE_INT(contextCount) {
-                LTE_INT(start) {
-                    LTE_INT(typeface) {
-                        LTE_FLOAT(textSize) {
-                            LTE_FLOAT(textSkewX) {
-                                LTE_FLOAT(textScaleX) {
-                                    LTE_INT(flags) {
-                                        LTE_INT(hinting) {
-                                            LTE_INT(dirFlags) {
-                                                return strncmp16(text, rhs.text, contextCount) < 0;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }
+    bool operator<(const TextLayoutCacheKey& rhs) const;
 
-    // We need to copy the text when we insert the key into the cache itself.
-    // We don't need to copy the text when we are only comparing keys.
-    void internalTextCopy() {
-        textCopy.setTo(text, contextCount);
-        text = textCopy.string();
-    }
+    /**
+     * We need to copy the text when we insert the key into the cache itself.
+     * We don't need to copy the text when we are only comparing keys.
+     */
+    void internalTextCopy();
 
     /**
      * Get the size of the Cache key.
      */
-    size_t getSize() {
-        return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount;
-    }
+    size_t getSize();
 
 private:
     const UChar* text;
@@ -137,232 +99,41 @@
 }; // TextLayoutCacheKey
 
 /*
- * TextLayoutCacheEntry is the Cache entry
+ * TextLayoutCacheValue is the Cache value
  */
 class TextLayoutCacheValue {
 public:
-    TextLayoutCacheValue() {
-        advances = NULL;
-        totalAdvance = 0;
-    }
+    TextLayoutCacheValue();
+    ~TextLayoutCacheValue();
 
-    ~TextLayoutCacheValue() {
-        delete[] advances;
-    }
-
-    void setElapsedTime(uint32_t time) {
-        elapsedTime = time;
-    }
-
-    uint32_t getElapsedTime() {
-        return elapsedTime;
-    }
+    void setElapsedTime(uint32_t time);
+    uint32_t getElapsedTime();
 
     void computeAdvances(SkPaint* paint, const UChar* chars, size_t start, size_t count,
-            size_t contextCount, int dirFlags) {
-        advances = new float[count];
-        this->count = count;
+            size_t contextCount, int dirFlags);
 
-#if RTL_USE_HARFBUZZ
-        computeAdvancesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
-                advances, &totalAdvance);
-#else
-        computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags,
-                advances, &totalAdvance);
-#endif
-#if DEBUG_ADVANCES
-        LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - "
-                "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, totalAdvance,
-                advances[0], advances[1], advances[2], advances[3]);
-#endif
-    }
-
-    void copyResult(jfloat* outAdvances, jfloat* outTotalAdvance) {
-        memcpy(outAdvances, advances, count * sizeof(jfloat));
-        *outTotalAdvance = totalAdvance;
-    }
+    void copyResult(jfloat* outAdvances, jfloat* outTotalAdvance);
 
     /**
      * Get the size of the Cache entry
      */
-    size_t getSize() {
-        return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * count;
-    }
+    size_t getSize();
 
     static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
             SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
-            int dirFlags) {
-        bool isRTL = dirFlags & 0x1;
-
-        font->klass = &harfbuzzSkiaClass;
-        font->userData = 0;
-        // The values which harfbuzzSkiaClass returns are already scaled to
-        // pixel units, so we just set all these to one to disable further
-        // scaling.
-        font->x_ppem = 1;
-        font->y_ppem = 1;
-        font->x_scale = 1;
-        font->y_scale = 1;
-
-        memset(shaperItem, 0, sizeof(*shaperItem));
-        shaperItem->font = font;
-        shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable);
-
-        shaperItem->kerning_applied = false;
-
-        // We cannot know, ahead of time, how many glyphs a given script run
-        // will produce. We take a guess that script runs will not produce more
-        // than twice as many glyphs as there are code points plus a bit of
-        // padding and fallback if we find that we are wrong.
-        createGlyphArrays(shaperItem, (contextCount + 2) * 2);
-
-        // Free memory for clusters if needed and recreate the clusters array
-        if (shaperItem->log_clusters) {
-            delete shaperItem->log_clusters;
-        }
-        shaperItem->log_clusters = new unsigned short[contextCount];
-
-        shaperItem->item.pos = start;
-        shaperItem->item.length = count;
-        shaperItem->item.bidiLevel = isRTL;
-        shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common;
-
-        shaperItem->string = chars;
-        shaperItem->stringLength = contextCount;
-
-        fontData->typeFace = paint->getTypeface();
-        fontData->textSize = paint->getTextSize();
-        fontData->textSkewX = paint->getTextSkewX();
-        fontData->textScaleX = paint->getTextScaleX();
-        fontData->flags = paint->getFlags();
-        fontData->hinting = paint->getHinting();
-
-        shaperItem->font->userData = fontData;
-    }
+            int dirFlags);
 
     static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
             SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
-            int dirFlags) {
-        // Setup Harfbuzz Shaper
-        setupShaperItem(shaperItem, font, fontData, paint, chars, start, count,
-                contextCount, dirFlags);
-
-        // Shape
-        resetGlyphArrays(shaperItem);
-        while (!HB_ShapeItem(shaperItem)) {
-            // We overflowed our arrays. Resize and retry.
-            // HB_ShapeItem fills in shaperItem.num_glyphs with the needed size.
-            deleteGlyphArrays(shaperItem);
-            createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1);
-            resetGlyphArrays(shaperItem);
-        }
-    }
+            int dirFlags);
 
     static void computeAdvancesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
             size_t count, size_t contextCount, int dirFlags,
-            jfloat* outAdvances, jfloat* outTotalAdvance) {
-
-        bool isRTL = dirFlags & 0x1;
-
-        HB_ShaperItem shaperItem;
-        HB_FontRec font;
-        FontData fontData;
-        shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count,
-                contextCount, dirFlags);
-
-#if DEBUG_ADVANCES
-        LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs, shaperItem.kerning_applied);
-        LOGD("         -- string= '%s'", String8(chars, contextCount).string());
-        LOGD("         -- isDevKernText=%d", paint->isDevKernText());
-#endif
-
-        jfloat totalAdvance = 0;
-
-        for (size_t i = 0; i < count; i++) {
-            totalAdvance += outAdvances[i] = HBFixedToFloat(shaperItem.advances[i]);
-
-#if DEBUG_ADVANCES
-            LOGD("hb-adv = %d - rebased = %f - total = %f", shaperItem.advances[i], outAdvances[i],
-                    totalAdvance);
-#endif
-        }
-
-        deleteGlyphArrays(&shaperItem);
-        HB_FreeFace(shaperItem.face);
-
-        *outTotalAdvance = totalAdvance;
-    }
+            jfloat* outAdvances, jfloat* outTotalAdvance);
 
     static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start,
             size_t count, size_t contextCount, int dirFlags,
-            jfloat* outAdvances, jfloat* outTotalAdvance) {
-
-        SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount);
-        jchar* buffer = tempBuffer.get();
-
-        SkScalar* scalarArray = (SkScalar*)outAdvances;
-
-        // this is where we'd call harfbuzz
-        // for now we just use ushape.c
-        size_t widths;
-        const jchar* text;
-        if (dirFlags & 0x1) { // rtl, call arabic shaping in case
-            UErrorCode status = U_ZERO_ERROR;
-            // Use fixed length since we need to keep start and count valid
-            u_shapeArabic(chars, contextCount, buffer, contextCount,
-                    U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
-                    U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE |
-                    U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
-            // we shouldn't fail unless there's an out of memory condition,
-            // in which case we're hosed anyway
-            for (int i = start, e = i + count; i < e; ++i) {
-                if (buffer[i] == UNICODE_NOT_A_CHAR) {
-                    buffer[i] = UNICODE_ZWSP; // zero-width-space for skia
-                }
-            }
-            text = buffer + start;
-            widths = paint->getTextWidths(text, count << 1, scalarArray);
-        } else {
-            text = chars + start;
-            widths = paint->getTextWidths(text, count << 1, scalarArray);
-        }
-
-        jfloat totalAdvance = 0;
-        if (widths < count) {
-#if DEBUG_ADVANCES
-        LOGD("ICU -- count=%d", widths);
-#endif
-            // Skia operates on code points, not code units, so surrogate pairs return only
-            // one value. Expand the result so we have one value per UTF-16 code unit.
-
-            // Note, skia's getTextWidth gets confused if it encounters a surrogate pair,
-            // leaving the remaining widths zero.  Not nice.
-            for (size_t i = 0, p = 0; i < widths; ++i) {
-                totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]);
-                if (p < count &&
-                        text[p] >= UNICODE_FIRST_LOW_SURROGATE &&
-                        text[p] < UNICODE_FIRST_PRIVATE_USE &&
-                        text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE &&
-                        text[p-1] < UNICODE_FIRST_LOW_SURROGATE) {
-                    outAdvances[p++] = 0;
-                }
-#if DEBUG_ADVANCES
-                LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
-#endif
-            }
-        } else {
-#if DEBUG_ADVANCES
-        LOGD("ICU -- count=%d", count);
-#endif
-            for (size_t i = 0; i < count; i++) {
-                totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]);
-#if DEBUG_ADVANCES
-                LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
-#endif
-            }
-        }
-        *outTotalAdvance = totalAdvance;
-    }
+            jfloat* outAdvances, jfloat* outTotalAdvance);
 
 private:
     jfloat* advances;
@@ -371,32 +142,11 @@
 
     uint32_t elapsedTime;
 
-    static void deleteGlyphArrays(HB_ShaperItem* shaperItem) {
-        delete[] shaperItem->glyphs;
-        delete[] shaperItem->attributes;
-        delete[] shaperItem->advances;
-        delete[] shaperItem->offsets;
-    }
+    static void deleteGlyphArrays(HB_ShaperItem* shaperItem);
+    static void createGlyphArrays(HB_ShaperItem* shaperItem, int size);
+    static void resetGlyphArrays(HB_ShaperItem* shaperItem);
 
-    static void createGlyphArrays(HB_ShaperItem* shaperItem, int size) {
-        shaperItem->glyphs = new HB_Glyph[size];
-        shaperItem->attributes = new HB_GlyphAttributes[size];
-        shaperItem->advances = new HB_Fixed[size];
-        shaperItem->offsets = new HB_FixedPoint[size];
-        shaperItem->num_glyphs = size;
-    }
-
-    static void resetGlyphArrays(HB_ShaperItem* shaperItem) {
-        int size = shaperItem->num_glyphs;
-        // All the types here don't have pointers. It is safe to reset to
-        // zero unless Harfbuzz breaks the compatibility in the future.
-        memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0]));
-        memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0]));
-        memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0]));
-        memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0]));
-    }
-
-}; // TextLayoutCacheEntry
+}; // TextLayoutCacheValue
 
 
 class TextLayoutCache: public OnEntryRemoved<TextLayoutCacheKey, TextLayoutCacheValue*>
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
index acf858a..cb742a3 100755
--- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
+++ b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
@@ -484,21 +484,21 @@
         lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
     }
 
-	if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
-		LOGE("Can't set RFCOMM link mode");
-		close(sk);
-		return -1;
-	}
+    if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
+        LOGE("Can't set RFCOMM link mode");
+        close(sk);
+        return -1;
+    }
 
     laddr.rc_family = AF_BLUETOOTH;
-    bacpy(&laddr.rc_bdaddr, BDADDR_ANY);
+    memcpy(&laddr.rc_bdaddr, BDADDR_ANY, sizeof(bdaddr_t));
     laddr.rc_channel = channel;
 
-	if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
-		LOGE("Can't bind RFCOMM socket");
-		close(sk);
-		return -1;
-	}
+    if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
+        LOGE("Can't bind RFCOMM socket");
+        close(sk);
+        return -1;
+    }
 
     listen(sk, 10);
     return sk;
diff --git a/core/jni/android_bluetooth_common.cpp b/core/jni/android_bluetooth_common.cpp
index aae0f21..6ae3e35 100644
--- a/core/jni/android_bluetooth_common.cpp
+++ b/core/jni/android_bluetooth_common.cpp
@@ -43,6 +43,7 @@
     {"Icon", DBUS_TYPE_STRING},
     {"Class", DBUS_TYPE_UINT32},
     {"UUIDs", DBUS_TYPE_ARRAY},
+    {"Services", DBUS_TYPE_ARRAY},
     {"Paired", DBUS_TYPE_BOOLEAN},
     {"Connected", DBUS_TYPE_BOOLEAN},
     {"Trusted", DBUS_TYPE_BOOLEAN},
@@ -52,7 +53,8 @@
     {"Adapter", DBUS_TYPE_OBJECT_PATH},
     {"LegacyPairing", DBUS_TYPE_BOOLEAN},
     {"RSSI", DBUS_TYPE_INT16},
-    {"TX", DBUS_TYPE_UINT32}
+    {"TX", DBUS_TYPE_UINT32},
+    {"Broadcaster", DBUS_TYPE_BOOLEAN}
 };
 
 static Properties adapter_properties[] = {
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index b6619ab..1b6b24f 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -41,7 +41,6 @@
 
 struct fields_t {
     // these fields provide access from C++ to the...
-    jclass    audioRecordClass;      //... AudioRecord class
     jmethodID postNativeEventInJava; //... event post callback method
     int       PCM16;                 //...  format constants
     int       PCM8;                  //...  format constants
@@ -520,22 +519,20 @@
 // ----------------------------------------------------------------------------
 int register_android_media_AudioRecord(JNIEnv *env)
 {
-    javaAudioRecordFields.audioRecordClass = NULL;
     javaAudioRecordFields.postNativeEventInJava = NULL;
     javaAudioRecordFields.nativeRecorderInJavaObj = NULL;
     javaAudioRecordFields.nativeCallbackCookie = NULL;
     
 
     // Get the AudioRecord class
-    javaAudioRecordFields.audioRecordClass = env->FindClass(kClassPathName);
-    if (javaAudioRecordFields.audioRecordClass == NULL) {
+    jclass audioRecordClass = env->FindClass(kClassPathName);
+    if (audioRecordClass == NULL) {
         LOGE("Can't find %s", kClassPathName);
         return -1;
     }
-    
     // Get the postEvent method
     javaAudioRecordFields.postNativeEventInJava = env->GetStaticMethodID(
-            javaAudioRecordFields.audioRecordClass,
+            audioRecordClass,
             JAVA_POSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;IIILjava/lang/Object;)V");
     if (javaAudioRecordFields.postNativeEventInJava == NULL) {
         LOGE("Can't find AudioRecord.%s", JAVA_POSTEVENT_CALLBACK_NAME);
@@ -545,7 +542,7 @@
     // Get the variables
     //    mNativeRecorderInJavaObj
     javaAudioRecordFields.nativeRecorderInJavaObj = 
-        env->GetFieldID(javaAudioRecordFields.audioRecordClass,
+        env->GetFieldID(audioRecordClass,
                         JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME, "I");
     if (javaAudioRecordFields.nativeRecorderInJavaObj == NULL) {
         LOGE("Can't find AudioRecord.%s", JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME);
@@ -553,7 +550,7 @@
     }
     //     mNativeCallbackCookie
     javaAudioRecordFields.nativeCallbackCookie = env->GetFieldID(
-            javaAudioRecordFields.audioRecordClass,
+            audioRecordClass,
             JAVA_NATIVECALLBACKINFO_FIELD_NAME, "I");
     if (javaAudioRecordFields.nativeCallbackCookie == NULL) {
         LOGE("Can't find AudioRecord.%s", JAVA_NATIVECALLBACKINFO_FIELD_NAME);
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 44d2a52..587a16c 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -43,7 +43,6 @@
 
 struct fields_t {
     // these fields provide access from C++ to the...
-    jclass    audioTrackClass;       //... AudioTrack class
     jmethodID postNativeEventInJava; //... event post callback method
     int       PCM16;                 //...  format constants
     int       PCM8;                  //...  format constants
@@ -915,20 +914,19 @@
 // ----------------------------------------------------------------------------
 int register_android_media_AudioTrack(JNIEnv *env)
 {
-    javaAudioTrackFields.audioTrackClass = NULL;
     javaAudioTrackFields.nativeTrackInJavaObj = NULL;
     javaAudioTrackFields.postNativeEventInJava = NULL;
 
     // Get the AudioTrack class
-    javaAudioTrackFields.audioTrackClass = env->FindClass(kClassPathName);
-    if (javaAudioTrackFields.audioTrackClass == NULL) {
+    jclass audioTrackClass = env->FindClass(kClassPathName);
+    if (audioTrackClass == NULL) {
         LOGE("Can't find %s", kClassPathName);
         return -1;
     }
 
     // Get the postEvent method
     javaAudioTrackFields.postNativeEventInJava = env->GetStaticMethodID(
-            javaAudioTrackFields.audioTrackClass,
+            audioTrackClass,
             JAVA_POSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;IIILjava/lang/Object;)V");
     if (javaAudioTrackFields.postNativeEventInJava == NULL) {
         LOGE("Can't find AudioTrack.%s", JAVA_POSTEVENT_CALLBACK_NAME);
@@ -938,7 +936,7 @@
     // Get the variables fields
     //      nativeTrackInJavaObj
     javaAudioTrackFields.nativeTrackInJavaObj = env->GetFieldID(
-            javaAudioTrackFields.audioTrackClass,
+            audioTrackClass,
             JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME, "I");
     if (javaAudioTrackFields.nativeTrackInJavaObj == NULL) {
         LOGE("Can't find AudioTrack.%s", JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME);
@@ -946,7 +944,7 @@
     }
     //      jniData;
     javaAudioTrackFields.jniData = env->GetFieldID(
-            javaAudioTrackFields.audioTrackClass,
+            audioTrackClass,
             JAVA_JNIDATA_FIELD_NAME, "I");
     if (javaAudioTrackFields.jniData == NULL) {
         LOGE("Can't find AudioTrack.%s", JAVA_JNIDATA_FIELD_NAME);
@@ -954,10 +952,10 @@
     }
 
     // Get the memory mode constants
-    if ( !android_media_getIntConstantFromClass(env, javaAudioTrackFields.audioTrackClass,
+    if ( !android_media_getIntConstantFromClass(env, audioTrackClass,
                kClassPathName, 
                JAVA_CONST_MODE_STATIC_NAME, &(javaAudioTrackFields.MODE_STATIC))
-         || !android_media_getIntConstantFromClass(env, javaAudioTrackFields.audioTrackClass,
+         || !android_media_getIntConstantFromClass(env, audioTrackClass,
                kClassPathName, 
                JAVA_CONST_MODE_STREAM_NAME, &(javaAudioTrackFields.MODE_STREAM)) ) {
         // error log performed in android_media_getIntConstantFromClass() 
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 3adf770..db132ec 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -55,7 +55,6 @@
  * to look them up every time.
  */
 static struct fieldIds {
-    jclass dhcpInfoInternalClass;
     jmethodID constructorId;
     jfieldID ipaddress;
     jfieldID gateway;
@@ -163,7 +162,7 @@
     result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
                                         dns1, dns2, server, &lease);
     env->ReleaseStringUTFChars(ifname, nameStr);
-    if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
+    if (result == 0) {
         env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
         env->SetObjectField(info, dhcpInfoInternalFieldIds.gateway, env->NewStringUTF(gateway));
         env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength);
@@ -229,17 +228,16 @@
     jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
     LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
 
-    dhcpInfoInternalFieldIds.dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal");
-    if (dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
-        dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "<init>", "()V");
-        dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;");
-        dhcpInfoInternalFieldIds.gateway = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "gateway", "Ljava/lang/String;");
-        dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "prefixLength", "I");
-        dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns1", "Ljava/lang/String;");
-        dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
-        dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
-        dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "leaseDuration", "I");
-    }
+    jclass dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal");
+    LOG_FATAL_IF(dhcpInfoInternalClass == NULL, "Unable to find class android/net/DhcpInfoInternal");
+    dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalClass, "<init>", "()V");
+    dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;");
+    dhcpInfoInternalFieldIds.gateway = env->GetFieldID(dhcpInfoInternalClass, "gateway", "Ljava/lang/String;");
+    dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalClass, "prefixLength", "I");
+    dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalClass, "dns1", "Ljava/lang/String;");
+    dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
+    dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
+    dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalClass, "leaseDuration", "I");
 
     return AndroidRuntime::registerNativeMethods(env,
             NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 667ba75..494dc27 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -556,7 +556,7 @@
     return doBooleanCommand(cmdstr, "OK");
 }
 
-static void android_net_wifi_enableBackgroundScan(JNIEnv* env, jobject clazz, jboolean enable)
+static void android_net_wifi_enableBackgroundScanCommand(JNIEnv* env, jobject clazz, jboolean enable)
 {
     //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml
     //and will need an update if the names are changed
@@ -568,6 +568,16 @@
     }
 }
 
+static void android_net_wifi_setScanIntervalCommand(JNIEnv* env, jobject clazz, jint scanInterval)
+{
+    char cmdstr[BUF_SIZE];
+
+    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "SCAN_INTERVAL %d", scanInterval);
+
+    if(numWritten < (int)sizeof(cmdstr)) doBooleanCommand(cmdstr, "OK");
+}
+
+
 // ----------------------------------------------------------------------------
 
 /*
@@ -635,7 +645,8 @@
         (void*) android_net_wifi_setSuspendOptimizationsCommand},
     { "setCountryCodeCommand", "(Ljava/lang/String;)Z",
         (void*) android_net_wifi_setCountryCodeCommand},
-    { "enableBackgroundScan", "(Z)V", (void*) android_net_wifi_enableBackgroundScan},
+    { "enableBackgroundScanCommand", "(Z)V", (void*) android_net_wifi_enableBackgroundScanCommand},
+    { "setScanIntervalCommand", "(I)V", (void*) android_net_wifi_setScanIntervalCommand},
 };
 
 int register_android_net_wifi_WifiManager(JNIEnv* env)
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index afaade8..dced1a5 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -373,7 +373,6 @@
     }
     dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
                              DBUS_TYPE_STRING, &capabilities,
-                             DBUS_TYPE_BOOLEAN, &oob,
                              DBUS_TYPE_INVALID);
 
     dbus_error_init(&err);
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 158e475..5c6958a 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -695,9 +695,7 @@
            str_array =  parse_remote_device_properties(env, &iter);
         dbus_message_unref(reply);
 
-        env->PopLocalFrame(NULL);
-
-        return str_array;
+        return (jobjectArray) env->PopLocalFrame(str_array);
     }
 #endif
     return NULL;
@@ -731,8 +729,7 @@
             str_array = parse_adapter_properties(env, &iter);
         dbus_message_unref(reply);
 
-        env->PopLocalFrame(NULL);
-        return str_array;
+        return (jobjectArray) env->PopLocalFrame(str_array);
     }
 #endif
     return NULL;
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index fdb7fda..65b5990 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -532,6 +532,7 @@
                                                           jint keyboard, jint keyboardHidden,
                                                           jint navigation,
                                                           jint screenWidth, jint screenHeight,
+                                                          jint screenWidthDp, jint screenHeightDp,
                                                           jint screenLayout, jint uiMode,
                                                           jint sdkVersion)
 {
@@ -555,6 +556,8 @@
     config.navigation = (uint8_t)navigation;
     config.screenWidth = (uint16_t)screenWidth;
     config.screenHeight = (uint16_t)screenHeight;
+    config.screenWidthDp = (uint16_t)screenWidthDp;
+    config.screenHeightDp = (uint16_t)screenHeightDp;
     config.screenLayout = (uint8_t)screenLayout;
     config.uiMode = (uint8_t)uiMode;
     config.sdkVersion = (uint16_t)sdkVersion;
@@ -1693,7 +1696,7 @@
         (void*) android_content_AssetManager_setLocale },
     { "getLocales",      "()[Ljava/lang/String;",
         (void*) android_content_AssetManager_getLocales },
-    { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIII)V",
+    { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIII)V",
         (void*) android_content_AssetManager_setConfiguration },
     { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
         (void*) android_content_AssetManager_getResourceIdentifier },
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 9a727a7..f31bba9 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -736,9 +736,9 @@
 
 int register_android_app_ActivityThread(JNIEnv* env)
 {
-    jclass gFileDescriptorClass = env->FindClass("java/io/FileDescriptor");
+    jclass fileDescriptorClass = env->FindClass("java/io/FileDescriptor");
     LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor");
-    gFileDescriptorField = env->GetFieldID(gFileDescriptorClass, "descriptor", "I");
+    gFileDescriptorField = env->GetFieldID(fileDescriptorClass, "descriptor", "I");
     LOG_FATAL_IF(gFileDescriptorField == NULL,
                  "Unable to find descriptor field in java.io.FileDescriptor");
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index e8f30ad..80beaa5 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -590,6 +590,11 @@
         <!-- The global user interface mode has changed.  For example,
              going in or out of car mode, night mode changing, etc. -->
         <flag name="uiMode" value="0x0200" />
+        <!-- The physical screen size has changed.  If applications don't
+             target at least {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}
+             then the activity will always handle this itself (the change
+             will not result in a restart). -->
+        <flag name="screenSize" value="0x0400" />
         <!-- The font scaling factor has changed, that is the user has
              selected a new global font size. -->
         <flag name="fontScale" value="0x40000000" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5d65b72..51a32b0 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -226,6 +226,15 @@
          The driver commands needed to support the feature are BGSCAN-START and BGSCAN-STOP -->
     <bool translatable="false" name="config_wifi_background_scan_support">false</bool>
 
+    <!-- Integer indicating wpa_supplicant scan interval in milliseconds -->
+    <integer translatable="false" name="config_wifi_supplicant_scan_interval">15000</integer>
+
+    <!-- Integer indicating the framework scan interval in milliseconds. This is used in the scenario
+         where the chipset does not support background scanning (config_wifi_background_scan_suport
+         is false) to set up a periodic wake up scan so that the device can connect to a new access
+         point on the move. A value of 0 means no periodic scans will be used in the framework. -->
+    <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer>
+
     <!-- Flag indicating whether the keyguard should be bypassed when
          the slider is open.  This can be set or unset depending how easily
          the slider can be opened (for example, in a pocket or purse). -->
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 1da2622..10d25bb 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -383,6 +383,46 @@
 which indicates whether the screen is long.</p>
       </td>
     </tr>
+    <tr id="ScreenWidthQualifier">
+      <td>Screen width</td>
+      <td>Examples:<br/>
+        <code>w720dp</code><br/>
+        <code>w1024dp</code><br/>
+        etc.
+      </td>
+      <td>
+        <p>Specifies a minimum screen width, in "dp" units, at which the resource
+          should be used.  This configuration value will change when the orientation
+          changes between landscape and portrait to match the current actual width.
+          When multiple screen width configurations are available, the closest to
+          the current screen width will be used.  The value specified here is
+          approximate; screen decorations like a status bar or system bar may cause
+          the actual space available in your UI to be slightly smaller.
+        <p><em>Added in API Level 13.</em></p>
+        <p>Also see the {@link android.content.res.Configuration#screenWidthDp}
+          configuration field, which holds the current screen width.</p>
+      </td>
+    </tr>
+    <tr id="ScreenHeightQualifier">
+      <td>Screen height</td>
+      <td>Examples:<br/>
+        <code>h720dp</code><br/>
+        <code>h1024dp</code><br/>
+        etc.
+      </td>
+      <td>
+        <p>Specifies a minimum screen height, in "dp" units, at which the resource
+          should be used.  This configuration value will change when the orientation
+          changes between landscape and portrait to match the current actual height.
+          When multiple screen height configurations are available, the closest to
+          the current screen height will be used.  The value specified here is
+          approximate; screen decorations like a status bar or system bar may cause
+          the actual space available in your UI to be slightly smaller.
+        <p><em>Added in API Level 13.</em></p>
+        <p>Also see the {@link android.content.res.Configuration#screenHeightDp}
+          configuration field, which holds the current screen width.</p>
+      </td>
+    </tr>
     <tr id="OrientationQualifier">
       <td>Screen orientation</td>
       <td>
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index b89d36d..cf8749b 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -55,18 +55,6 @@
         mCullMode = CullMode.BACK;
     }
 
-    void setLineWidth(float w) {
-        mRS.validate();
-        mLineWidth = w;
-        mRS.nProgramRasterSetLineWidth(getID(), w);
-    }
-
-    void setCullMode(CullMode m) {
-        mRS.validate();
-        mCullMode = m;
-        mRS.nProgramRasterSetCullMode(getID(), m.mID);
-    }
-
     public static ProgramRaster CULL_BACK(RenderScript rs) {
         if(rs.mProgramRaster_CULL_BACK == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -119,16 +107,11 @@
             return this;
         }
 
-        static synchronized ProgramRaster internalCreate(RenderScript rs, Builder b) {
-            int id = rs.nProgramRasterCreate(b.mPointSmooth, b.mLineSmooth, b.mPointSprite);
-            ProgramRaster pr = new ProgramRaster(id, rs);
-            pr.setCullMode(b.mCullMode);
-            return pr;
-        }
-
         public ProgramRaster create() {
             mRS.validate();
-            return internalCreate(mRS, this);
+            int id = mRS.nProgramRasterCreate(mPointSmooth, mLineSmooth, mPointSprite,
+                                             1.f, mCullMode.mID);
+            return new ProgramRaster(id, mRS);
         }
     }
 
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index c46e6b9..7a84d8b 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -333,27 +333,15 @@
             return this;
         }
 
-        static synchronized ProgramStore internalCreate(RenderScript rs, Builder b) {
-            rs.nProgramStoreBegin(0, 0);
-            rs.nProgramStoreDepthFunc(b.mDepthFunc.mID);
-            rs.nProgramStoreDepthMask(b.mDepthMask);
-            rs.nProgramStoreColorMask(b.mColorMaskR,
-                                              b.mColorMaskG,
-                                              b.mColorMaskB,
-                                              b.mColorMaskA);
-            rs.nProgramStoreBlendFunc(b.mBlendSrc.mID, b.mBlendDst.mID);
-            rs.nProgramStoreDither(b.mDither);
-
-            int id = rs.nProgramStoreCreate();
-            return new ProgramStore(id, rs);
-        }
-
         /**
         * Creates a program store from the current state of the builder
         */
         public ProgramStore create() {
             mRS.validate();
-            return internalCreate(mRS, this);
+            int id = mRS.nProgramStoreCreate(mColorMaskR, mColorMaskG, mColorMaskB, mColorMaskA,
+                                             mDepthMask, mDither,
+                                             mBlendSrc.mID, mBlendDst.mID, mDepthFunc.mID);
+            return new ProgramStore(id, mRS);
         }
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index f577532..8f05dc3 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -485,56 +485,24 @@
         return rsnSamplerCreate(mContext);
     }
 
-    native void rsnProgramStoreBegin(int con, int in, int out);
-    synchronized void nProgramStoreBegin(int in, int out) {
+    native int  rsnProgramStoreCreate(int con, boolean r, boolean g, boolean b, boolean a,
+                                      boolean depthMask, boolean dither,
+                                      int srcMode, int dstMode, int depthFunc);
+    synchronized int nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
+                                         boolean depthMask, boolean dither,
+                                         int srcMode, int dstMode, int depthFunc) {
         validate();
-        rsnProgramStoreBegin(mContext, in, out);
-    }
-    native void rsnProgramStoreDepthFunc(int con, int func);
-    synchronized void nProgramStoreDepthFunc(int func) {
-        validate();
-        rsnProgramStoreDepthFunc(mContext, func);
-    }
-    native void rsnProgramStoreDepthMask(int con, boolean enable);
-    synchronized void nProgramStoreDepthMask(boolean enable) {
-        validate();
-        rsnProgramStoreDepthMask(mContext, enable);
-    }
-    native void rsnProgramStoreColorMask(int con, boolean r, boolean g, boolean b, boolean a);
-    synchronized void nProgramStoreColorMask(boolean r, boolean g, boolean b, boolean a) {
-        validate();
-        rsnProgramStoreColorMask(mContext, r, g, b, a);
-    }
-    native void rsnProgramStoreBlendFunc(int con, int src, int dst);
-    synchronized void nProgramStoreBlendFunc(int src, int dst) {
-        validate();
-        rsnProgramStoreBlendFunc(mContext, src, dst);
-    }
-    native void rsnProgramStoreDither(int con, boolean enable);
-    synchronized void nProgramStoreDither(boolean enable) {
-        validate();
-        rsnProgramStoreDither(mContext, enable);
-    }
-    native int  rsnProgramStoreCreate(int con);
-    synchronized int nProgramStoreCreate() {
-        validate();
-        return rsnProgramStoreCreate(mContext);
+        return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode,
+                                     dstMode, depthFunc);
     }
 
-    native int  rsnProgramRasterCreate(int con, boolean pointSmooth, boolean lineSmooth, boolean pointSprite);
-    synchronized int nProgramRasterCreate(boolean pointSmooth, boolean lineSmooth, boolean pointSprite) {
+    native int  rsnProgramRasterCreate(int con, boolean pointSmooth, boolean lineSmooth,
+                                       boolean pointSprite, float lineWidth, int cullMode);
+    synchronized int nProgramRasterCreate(boolean pointSmooth, boolean lineSmooth,
+                                          boolean pointSprite, float lineWidth, int cullMode) {
         validate();
-        return rsnProgramRasterCreate(mContext, pointSmooth, lineSmooth, pointSprite);
-    }
-    native void rsnProgramRasterSetLineWidth(int con, int pr, float v);
-    synchronized void nProgramRasterSetLineWidth(int pr, float v) {
-        validate();
-        rsnProgramRasterSetLineWidth(mContext, pr, v);
-    }
-    native void rsnProgramRasterSetCullMode(int con, int pr, int mode);
-    synchronized void nProgramRasterSetCullMode(int pr, int mode) {
-        validate();
-        rsnProgramRasterSetCullMode(mContext, pr, mode);
+        return rsnProgramRasterCreate(mContext, pointSmooth, lineSmooth, pointSprite, lineWidth,
+                                      cullMode);
     }
 
     native void rsnProgramBindConstants(int con, int pv, int slot, int mID);
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index c7f4809..12c5940 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -897,53 +897,17 @@
 
 // ---------------------------------------------------------------------------
 
-static void
-nProgramStoreBegin(JNIEnv *_env, jobject _this, RsContext con, jint in, jint out)
-{
-    LOG_API("nProgramStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
-    rsProgramStoreBegin(con, (RsElement)in, (RsElement)out);
-}
-
-static void
-nProgramStoreDepthFunc(JNIEnv *_env, jobject _this, RsContext con, jint func)
-{
-    LOG_API("nProgramStoreDepthFunc, con(%p), func(%i)", con, func);
-    rsProgramStoreDepthFunc(con, (RsDepthFunc)func);
-}
-
-static void
-nProgramStoreDepthMask(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
-{
-    LOG_API("nProgramStoreDepthMask, con(%p), enable(%i)", con, enable);
-    rsProgramStoreDepthMask(con, enable);
-}
-
-static void
-nProgramStoreColorMask(JNIEnv *_env, jobject _this, RsContext con, jboolean r, jboolean g, jboolean b, jboolean a)
-{
-    LOG_API("nProgramStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
-    rsProgramStoreColorMask(con, r, g, b, a);
-}
-
-static void
-nProgramStoreBlendFunc(JNIEnv *_env, jobject _this, RsContext con, int src, int dst)
-{
-    LOG_API("nProgramStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
-    rsProgramStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
-}
-
-static void
-nProgramStoreDither(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
-{
-    LOG_API("nProgramStoreDither, con(%p), enable(%i)", con, enable);
-    rsProgramStoreDither(con, enable);
-}
-
 static jint
-nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con)
+nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con,
+                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
+                    jboolean depthMask, jboolean ditherEnable,
+                    jint srcFunc, jint destFunc,
+                    jint depthFunc)
 {
     LOG_API("nProgramStoreCreate, con(%p)", con);
-    return (jint)rsProgramStoreCreate(con);
+    return (jint)rsProgramStoreCreate(con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
+                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
 }
 
 // ---------------------------------------------------------------------------
@@ -1005,25 +969,12 @@
 // ---------------------------------------------------------------------------
 
 static jint
-nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite)
+nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSmooth,
+                     jboolean lineSmooth, jboolean pointSprite, jfloat lineWidth, jint cull)
 {
     LOG_API("nProgramRasterCreate, con(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)",
             con, pointSmooth, lineSmooth, pointSprite);
-    return (jint)rsProgramRasterCreate(con, pointSmooth, lineSmooth, pointSprite);
-}
-
-static void
-nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jfloat v)
-{
-    LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
-    rsProgramRasterSetLineWidth(con, (RsProgramRaster)vpr, v);
-}
-
-static void
-nProgramRasterSetCullMode(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jint v)
-{
-    LOG_API("nProgramRasterSetCullMode, con(%p), vpf(%p), value(%i)", con, (RsProgramRaster)vpr, v);
-    rsProgramRasterSetCullMode(con, (RsProgramRaster)vpr, (RsCullMode)v);
+    return (jint)rsProgramRasterCreate(con, pointSmooth, lineSmooth, pointSprite, lineWidth, (RsCullMode)cull);
 }
 
 
@@ -1270,24 +1221,14 @@
 
 {"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;[BI)I",  (void*)nScriptCCreate },
 
-{"rsnProgramStoreBegin",             "(III)V",                                (void*)nProgramStoreBegin },
-{"rsnProgramStoreDepthFunc",         "(II)V",                                 (void*)nProgramStoreDepthFunc },
-{"rsnProgramStoreDepthMask",         "(IZ)V",                                 (void*)nProgramStoreDepthMask },
-{"rsnProgramStoreColorMask",         "(IZZZZ)V",                              (void*)nProgramStoreColorMask },
-{"rsnProgramStoreBlendFunc",         "(III)V",                                (void*)nProgramStoreBlendFunc },
-{"rsnProgramStoreDither",            "(IZ)V",                                 (void*)nProgramStoreDither },
-{"rsnProgramStoreCreate",            "(I)I",                                  (void*)nProgramStoreCreate },
+{"rsnProgramStoreCreate",            "(IZZZZZZIII)I",                         (void*)nProgramStoreCreate },
 
 {"rsnProgramBindConstants",          "(IIII)V",                               (void*)nProgramBindConstants },
 {"rsnProgramBindTexture",            "(IIII)V",                               (void*)nProgramBindTexture },
 {"rsnProgramBindSampler",            "(IIII)V",                               (void*)nProgramBindSampler },
 
 {"rsnProgramFragmentCreate",         "(ILjava/lang/String;[I)I",              (void*)nProgramFragmentCreate },
-
-{"rsnProgramRasterCreate",           "(IZZZ)I",                               (void*)nProgramRasterCreate },
-{"rsnProgramRasterSetLineWidth",     "(IIF)V",                                (void*)nProgramRasterSetLineWidth },
-{"rsnProgramRasterSetCullMode",      "(III)V",                                (void*)nProgramRasterSetCullMode },
-
+{"rsnProgramRasterCreate",           "(IZZZFI)I",                             (void*)nProgramRasterCreate },
 {"rsnProgramVertexCreate",           "(ILjava/lang/String;[I)I",              (void*)nProgramVertexCreate },
 
 {"rsnContextBindRootScript",         "(II)V",                                 (void*)nContextBindRootScript },
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 6227f3e..35792dc 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -972,6 +972,14 @@
         uint32_t screenConfig;
     };
     
+    union {
+        struct {
+            uint16_t screenWidthDp;
+            uint16_t screenHeightDp;
+        };
+        uint32_t screenSizeDp;
+    };
+
     inline void copyFromDeviceNoSwap(const ResTable_config& o) {
         const size_t size = dtohl(o.size);
         if (size >= sizeof(ResTable_config)) {
@@ -992,6 +1000,8 @@
         screenHeight = dtohs(screenHeight);
         sdkVersion = dtohs(sdkVersion);
         minorVersion = dtohs(minorVersion);
+        screenWidthDp = dtohs(screenWidthDp);
+        screenHeightDp = dtohs(screenHeightDp);
     }
     
     inline void swapHtoD() {
@@ -1003,6 +1013,8 @@
         screenHeight = htods(screenHeight);
         sdkVersion = htods(sdkVersion);
         minorVersion = htods(minorVersion);
+        screenWidthDp = htods(screenWidthDp);
+        screenHeightDp = htods(screenHeightDp);
     }
     
     inline int compare(const ResTable_config& o) const {
@@ -1021,6 +1033,8 @@
         diff = (int32_t)(screenLayout - o.screenLayout);
         if (diff != 0) return diff;
         diff = (int32_t)(uiMode - o.uiMode);
+        if (diff != 0) return diff;
+        diff = (int32_t)(screenSizeDp - o.screenSizeDp);
         return (int)diff;
     }
     
@@ -1061,6 +1075,7 @@
         if (version != o.version) diffs |= CONFIG_VERSION;
         if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
         if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
+        if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
         return diffs;
     }
     
@@ -1105,6 +1120,18 @@
             }
         }
 
+        if (screenSizeDp || o.screenSizeDp) {
+            if (screenWidthDp != o.screenWidthDp) {
+                if (!screenWidthDp) return false;
+                if (!o.screenWidthDp) return true;
+            }
+
+            if (screenHeightDp != o.screenHeightDp) {
+                if (!screenHeightDp) return false;
+                if (!o.screenHeightDp) return true;
+            }
+        }
+
         if (orientation != o.orientation) {
             if (!orientation) return false;
             if (!o.orientation) return true;
@@ -1243,6 +1270,30 @@
                 }
             }
 
+            if (screenSizeDp || o.screenSizeDp) {
+                // Better is based on the sum of the difference between both
+                // width and height from the requested dimensions.  We are
+                // assuming the invalid configs (with smaller dimens) have
+                // already been filtered.  Note that if a particular dimension
+                // is unspecified, we will end up with a large value (the
+                // difference between 0 and the requested dimension), which is
+                // good since we will prefer a config that has specified a
+                // dimension value.
+                int myDelta = 0, otherDelta = 0;
+                if (requested->screenWidthDp) {
+                    myDelta += requested->screenWidthDp - screenWidthDp;
+                    otherDelta += requested->screenWidthDp - o.screenWidthDp;
+                }
+                if (requested->screenHeightDp) {
+                    myDelta += requested->screenHeightDp - screenHeightDp;
+                    otherDelta += requested->screenHeightDp - o.screenHeightDp;
+                }
+                //LOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
+                //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
+                //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
+                return (myDelta <= otherDelta);
+            }
+
             if ((orientation != o.orientation) && requested->orientation) {
                 return (orientation);
             }
@@ -1426,6 +1477,18 @@
                 return false;
             }
         }
+        if (screenSizeDp != 0) {
+            if (settings.screenWidthDp != 0 && screenWidthDp != 0
+                && screenWidthDp > settings.screenWidthDp) {
+                //LOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
+                return false;
+            }
+            if (settings.screenHeightDp != 0 && screenHeightDp != 0
+                && screenHeightDp > settings.screenHeightDp) {
+                //LOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
+                return false;
+            }
+        }
         if (screenType != 0) {
             if (settings.orientation != 0 && orientation != 0
                 && orientation != settings.orientation) {
@@ -1505,13 +1568,13 @@
     String8 toString() const {
         char buf[200];
         sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
-                "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d sz=%d long=%d "
+                "kbd=%d nav=%d input=%d ssz=%dx%d %ddp x %ddp sz=%d long=%d "
                 "ui=%d night=%d vers=%d.%d",
                 mcc, mnc,
                 language[0] ? language[0] : '-', language[1] ? language[1] : '-',
                 country[0] ? country[0] : '-', country[1] ? country[1] : '-',
                 orientation, touchscreen, density, keyboard, navigation, inputFlags,
-                screenWidth, screenHeight,
+                screenWidth, screenHeight, screenWidthDp, screenHeightDp,
                 screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG,
                 uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT,
                 sdkVersion, minorVersion);
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 9100693..3362c7d 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -116,7 +116,9 @@
 	rsType.cpp \
 	rsVertexArray.cpp \
 	driver/rsdBcc.cpp \
-	driver/rsdCore.cpp
+	driver/rsdCore.cpp \
+	driver/rsdProgramRaster.cpp \
+	driver/rsdProgramStore.cpp
 
 
 LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc
diff --git a/libs/rs/driver/rsdBcc.h b/libs/rs/driver/rsdBcc.h
index 6723a36..ae7a7af 100644
--- a/libs/rs/driver/rsdBcc.h
+++ b/libs/rs/driver/rsdBcc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 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.
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 6546110..00d62ba 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -16,6 +16,8 @@
 
 #include "rsdCore.h"
 #include "rsdBcc.h"
+#include "rsdProgramStore.h"
+#include "rsdProgramRaster.h"
 
 #include <malloc.h>
 #include "rsContext.h"
@@ -48,7 +50,21 @@
         rsdScriptSetGlobalBind,
         rsdScriptSetGlobalObj,
         rsdScriptDestroy
+    },
+
+
+    {
+        rsdProgramStoreInit,
+        rsdProgramStoreSetActive,
+        rsdProgramStoreDestroy
+    },
+
+    {
+        rsdProgramRasterInit,
+        rsdProgramRasterSetActive,
+        rsdProgramRasterDestroy
     }
+
 };
 
 
diff --git a/libs/rs/driver/rsdProgramRaster.cpp b/libs/rs/driver/rsdProgramRaster.cpp
new file mode 100644
index 0000000..65995be
--- /dev/null
+++ b/libs/rs/driver/rsdProgramRaster.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+#include "rsdCore.h"
+#include "rsdProgramStore.h"
+
+#include "rsContext.h"
+#include "rsProgramStore.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+
+using namespace android;
+using namespace android::renderscript;
+
+bool rsdProgramRasterInit(const Context *, const ProgramRaster *) {
+    return true;
+}
+
+void rsdProgramRasterSetActive(const Context *, const ProgramRaster *pr) {
+    switch (pr->mHal.state.cull) {
+        case RS_CULL_BACK:
+            glEnable(GL_CULL_FACE);
+            glCullFace(GL_BACK);
+            break;
+        case RS_CULL_FRONT:
+            glEnable(GL_CULL_FACE);
+            glCullFace(GL_FRONT);
+            break;
+        case RS_CULL_NONE:
+            glDisable(GL_CULL_FACE);
+            break;
+    }
+
+}
+
+void rsdProgramRasterDestroy(const Context *, const ProgramRaster *) {
+}
+
+
diff --git a/libs/rs/driver/rsdProgramRaster.h b/libs/rs/driver/rsdProgramRaster.h
new file mode 100644
index 0000000..20adaad
--- /dev/null
+++ b/libs/rs/driver/rsdProgramRaster.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifndef RSD_PROGRAM_RASTER_H
+#define RSD_PROGRAM_RASTER_H
+
+#include <rs_hal.h>
+
+
+bool rsdProgramRasterInit(const android::renderscript::Context *rsc,
+                         const android::renderscript::ProgramRaster *);
+void rsdProgramRasterSetActive(const android::renderscript::Context *rsc,
+                              const android::renderscript::ProgramRaster *);
+void rsdProgramRasterDestroy(const android::renderscript::Context *rsc,
+                            const android::renderscript::ProgramRaster *);
+
+
+#endif
diff --git a/libs/rs/driver/rsdProgramStore.cpp b/libs/rs/driver/rsdProgramStore.cpp
new file mode 100644
index 0000000..e591453
--- /dev/null
+++ b/libs/rs/driver/rsdProgramStore.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ */
+
+
+#include "rsdCore.h"
+#include "rsdProgramStore.h"
+
+#include "rsContext.h"
+#include "rsProgramStore.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+
+using namespace android;
+using namespace android::renderscript;
+
+struct DrvProgramStore {
+    GLenum blendSrc;
+    GLenum blendDst;
+    bool blendEnable;
+
+    GLenum depthFunc;
+    bool depthTestEnable;
+};
+
+bool rsdProgramStoreInit(const Context *rsc, const ProgramStore *ps) {
+    DrvProgramStore *drv = (DrvProgramStore *)calloc(1, sizeof(DrvProgramStore));
+    if (drv == NULL) {
+        return false;
+    }
+
+    ps->mHal.drv = drv;
+    drv->depthTestEnable = true;
+
+    switch (ps->mHal.state.depthFunc) {
+    case RS_DEPTH_FUNC_ALWAYS:
+        drv->depthTestEnable = false;
+        drv->depthFunc = GL_ALWAYS;
+        break;
+    case RS_DEPTH_FUNC_LESS:
+        drv->depthFunc = GL_LESS;
+        break;
+    case RS_DEPTH_FUNC_LEQUAL:
+        drv->depthFunc = GL_LEQUAL;
+        break;
+    case RS_DEPTH_FUNC_GREATER:
+        drv->depthFunc = GL_GREATER;
+        break;
+    case RS_DEPTH_FUNC_GEQUAL:
+        drv->depthFunc = GL_GEQUAL;
+        break;
+    case RS_DEPTH_FUNC_EQUAL:
+        drv->depthFunc = GL_EQUAL;
+        break;
+    case RS_DEPTH_FUNC_NOTEQUAL:
+        drv->depthFunc = GL_NOTEQUAL;
+        break;
+    default:
+        LOGE("Unknown depth function.");
+        goto error;
+    }
+
+
+
+    drv->blendEnable = true;
+    if ((ps->mHal.state.blendSrc == RS_BLEND_SRC_ONE) &&
+        (ps->mHal.state.blendDst == RS_BLEND_DST_ZERO)) {
+        drv->blendEnable = false;
+    }
+
+    switch (ps->mHal.state.blendSrc) {
+    case RS_BLEND_SRC_ZERO:
+        drv->blendSrc = GL_ZERO;
+        break;
+    case RS_BLEND_SRC_ONE:
+        drv->blendSrc = GL_ONE;
+        break;
+    case RS_BLEND_SRC_DST_COLOR:
+        drv->blendSrc = GL_DST_COLOR;
+        break;
+    case RS_BLEND_SRC_ONE_MINUS_DST_COLOR:
+        drv->blendSrc = GL_ONE_MINUS_DST_COLOR;
+        break;
+    case RS_BLEND_SRC_SRC_ALPHA:
+        drv->blendSrc = GL_SRC_ALPHA;
+        break;
+    case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA:
+        drv->blendSrc = GL_ONE_MINUS_SRC_ALPHA;
+        break;
+    case RS_BLEND_SRC_DST_ALPHA:
+        drv->blendSrc = GL_DST_ALPHA;
+        break;
+    case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA:
+        drv->blendSrc = GL_ONE_MINUS_DST_ALPHA;
+        break;
+    case RS_BLEND_SRC_SRC_ALPHA_SATURATE:
+        drv->blendSrc = GL_SRC_ALPHA_SATURATE;
+        break;
+    default:
+        LOGE("Unknown blend src mode.");
+        goto error;
+    }
+
+    switch (ps->mHal.state.blendDst) {
+    case RS_BLEND_DST_ZERO:
+        drv->blendDst = GL_ZERO;
+        break;
+    case RS_BLEND_DST_ONE:
+        drv->blendDst = GL_ONE;
+        break;
+    case RS_BLEND_DST_SRC_COLOR:
+        drv->blendDst = GL_SRC_COLOR;
+        break;
+    case RS_BLEND_DST_ONE_MINUS_SRC_COLOR:
+        drv->blendDst = GL_ONE_MINUS_SRC_COLOR;
+        break;
+    case RS_BLEND_DST_SRC_ALPHA:
+        drv->blendDst = GL_SRC_ALPHA;
+        break;
+    case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA:
+        drv->blendDst = GL_ONE_MINUS_SRC_ALPHA;
+        break;
+    case RS_BLEND_DST_DST_ALPHA:
+        drv->blendDst = GL_DST_ALPHA;
+        break;
+    case RS_BLEND_DST_ONE_MINUS_DST_ALPHA:
+        drv->blendDst = GL_ONE_MINUS_DST_ALPHA;
+        break;
+    default:
+        LOGE("Unknown blend dst mode.");
+        goto error;
+    }
+
+    return true;
+
+error:
+    free(drv);
+    ps->mHal.drv = NULL;
+    return false;
+}
+
+void rsdProgramStoreSetActive(const Context *rsc, const ProgramStore *ps) {
+    DrvProgramStore *drv = (DrvProgramStore *)ps->mHal.drv;
+
+    glColorMask(ps->mHal.state.colorRWriteEnable,
+                ps->mHal.state.colorGWriteEnable,
+                ps->mHal.state.colorBWriteEnable,
+                ps->mHal.state.colorAWriteEnable);
+
+    if (drv->blendEnable) {
+        glEnable(GL_BLEND);
+        glBlendFunc(drv->blendSrc, drv->blendDst);
+    } else {
+        glDisable(GL_BLEND);
+    }
+
+    if (rsc->mUserSurfaceConfig.depthMin > 0) {
+        glDepthMask(ps->mHal.state.depthWriteEnable);
+        if (drv->depthTestEnable || ps->mHal.state.depthWriteEnable) {
+            glEnable(GL_DEPTH_TEST);
+            glDepthFunc(drv->depthFunc);
+        } else {
+            glDisable(GL_DEPTH_TEST);
+        }
+    } else {
+        glDepthMask(false);
+        glDisable(GL_DEPTH_TEST);
+    }
+
+    /*
+    if (rsc->mUserSurfaceConfig.stencilMin > 0) {
+    } else {
+        glStencilMask(0);
+        glDisable(GL_STENCIL_TEST);
+    }
+    */
+
+    if (ps->mHal.state.ditherEnable) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
+    }
+}
+
+void rsdProgramStoreDestroy(const Context *rsc, const ProgramStore *ps) {
+    free(ps->mHal.drv);
+    ps->mHal.drv = NULL;
+}
+
+
diff --git a/libs/rs/driver/rsdProgramStore.h b/libs/rs/driver/rsdProgramStore.h
new file mode 100644
index 0000000..217a0ce
--- /dev/null
+++ b/libs/rs/driver/rsdProgramStore.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifndef RSD_PROGRAM_STORE_H
+#define RSD_PROGRAM_STORE_H
+
+#include <rs_hal.h>
+
+
+bool rsdProgramStoreInit(const android::renderscript::Context *rsc,
+                         const android::renderscript::ProgramStore *ps);
+void rsdProgramStoreSetActive(const android::renderscript::Context *rsc,
+                              const android::renderscript::ProgramStore *ps);
+void rsdProgramStoreDestroy(const android::renderscript::Context *rsc,
+                            const android::renderscript::ProgramStore *ps);
+
+
+#endif
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index bbb6200..a7f473c 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -251,36 +251,16 @@
 	}
 
 
-ProgramStoreBegin {
-	param RsElement in
-	param RsElement out
-	}
-
-ProgramStoreColorMask {
-	param bool r
-	param bool g
-	param bool b
-	param bool a
-	}
-
-ProgramStoreBlendFunc {
+ProgramStoreCreate {
+	param bool colorMaskR
+	param bool colorMaskG
+	param bool colorMaskB
+	param bool colorMaskA
+        param bool depthMask
+        param bool ditherEnable
 	param RsBlendSrcFunc srcFunc
 	param RsBlendDstFunc destFunc
-	}
-
-ProgramStoreDepthMask {
-	param bool enable
-}
-
-ProgramStoreDither {
-	param bool enable
-}
-
-ProgramStoreDepthFunc {
-	param RsDepthFunc func
-}
-
-ProgramStoreCreate {
+        param RsDepthFunc depthFunc
 	ret RsProgramStore
 	}
 
@@ -288,19 +268,11 @@
 	param bool pointSmooth
 	param bool lineSmooth
 	param bool pointSprite
+	param float lineWidth
+	param RsCullMode cull
 	ret RsProgramRaster
 }
 
-ProgramRasterSetLineWidth {
-	param RsProgramRaster pr
-	param float lw
-}
-
-ProgramRasterSetCullMode {
-	param RsProgramRaster pr
-	param RsCullMode mode
-}
-
 ProgramBindConstants {
 	param RsProgram vp
 	param uint32_t slot
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index d727ba1..c9a7060 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -405,16 +405,16 @@
         return false;
     }
 
-    mFragmentStore->setupGL2(this, &mStateFragmentStore);
+    mFragmentStore->setup(this, &mStateFragmentStore);
     mFragment->setupGL2(this, &mStateFragment, &mShaderCache);
-    mRaster->setupGL2(this, &mStateRaster);
+    mRaster->setup(this, &mStateRaster);
     mVertex->setupGL2(this, &mStateVertex, &mShaderCache);
     mFBOCache.setupGL2(this);
     return true;
 }
 
 void Context::setupProgramStore() {
-    mFragmentStore->setupGL2(this, &mStateFragmentStore);
+    mFragmentStore->setup(this, &mStateFragmentStore);
 }
 
 static bool getProp(const char *str) {
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 595c89a..c30b857 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -507,12 +507,13 @@
     mFontSampler.set(sampler);
     mFontShaderF->bindSampler(mRSC, 0, sampler);
 
-    ProgramStore *fontStore = new ProgramStore(mRSC);
+    ProgramStore *fontStore = new ProgramStore(mRSC, true, true, true, true,
+                                               false, false,
+                                               RS_BLEND_SRC_SRC_ALPHA,
+                                               RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
+                                               RS_DEPTH_FUNC_ALWAYS);
     mFontProgramStore.set(fontStore);
-    mFontProgramStore->setDepthFunc(RS_DEPTH_FUNC_ALWAYS);
-    mFontProgramStore->setBlendFunc(RS_BLEND_SRC_SRC_ALPHA, RS_BLEND_DST_ONE_MINUS_SRC_ALPHA);
-    mFontProgramStore->setDitherEnable(false);
-    mFontProgramStore->setDepthMask(false);
+    mFontProgramStore->init();
 }
 
 void FontState::initTextTexture() {
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
index ace1572..9617c4d 100644
--- a/libs/rs/rsProgramRaster.cpp
+++ b/libs/rs/rsProgramRaster.cpp
@@ -15,11 +15,6 @@
  */
 
 #include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#endif //ANDROID_RS_SERIALIZE
-
 #include "rsProgramRaster.h"
 
 using namespace android;
@@ -27,49 +22,33 @@
 
 
 ProgramRaster::ProgramRaster(Context *rsc, bool pointSmooth,
-                             bool lineSmooth, bool pointSprite)
+                             bool lineSmooth, bool pointSprite,
+                             float lineWidth, RsCullMode cull)
     : Program(rsc) {
 
-    mPointSmooth = pointSmooth;
-    mLineSmooth = lineSmooth;
-    mPointSprite = pointSprite;
-    mLineWidth = 1.0f;
-    mCull = RS_CULL_BACK;
+    memset(&mHal, 0, sizeof(mHal));
+
+    mHal.state.pointSmooth = pointSmooth;
+    mHal.state.lineSmooth = lineSmooth;
+    mHal.state.pointSprite = pointSprite;
+    mHal.state.lineWidth = lineWidth;
+    mHal.state.cull = cull;
+
+    rsc->mHal.funcs.raster.init(rsc, this);
 }
 
 ProgramRaster::~ProgramRaster() {
+    mRSC->mHal.funcs.raster.destroy(mRSC, this);
 }
 
-void ProgramRaster::setLineWidth(float s) {
-    mLineWidth = s;
-    mDirty = true;
-}
-
-void ProgramRaster::setCullMode(RsCullMode mode) {
-    mCull = mode;
-    mDirty = true;
-}
-
-void ProgramRaster::setupGL2(const Context *rsc, ProgramRasterState *state) {
+void ProgramRaster::setup(const Context *rsc, ProgramRasterState *state) {
     if (state->mLast.get() == this && !mDirty) {
         return;
     }
     state->mLast.set(this);
     mDirty = false;
 
-    switch (mCull) {
-        case RS_CULL_BACK:
-            glEnable(GL_CULL_FACE);
-            glCullFace(GL_BACK);
-            break;
-        case RS_CULL_FRONT:
-            glEnable(GL_CULL_FACE);
-            glCullFace(GL_FRONT);
-            break;
-        case RS_CULL_NONE:
-            glDisable(GL_CULL_FACE);
-            break;
-    }
+    rsc->mHal.funcs.raster.setActive(rsc, this);
 }
 
 void ProgramRaster::serialize(OStream *stream) const {
@@ -86,7 +65,7 @@
 }
 
 void ProgramRasterState::init(Context *rsc) {
-    ProgramRaster *pr = new ProgramRaster(rsc, false, false, false);
+    ProgramRaster *pr = new ProgramRaster(rsc, false, false, false, 1.f, RS_CULL_BACK);
     mDefault.set(pr);
 }
 
@@ -101,27 +80,15 @@
 RsProgramRaster rsi_ProgramRasterCreate(Context * rsc,
                                       bool pointSmooth,
                                       bool lineSmooth,
-                                      bool pointSprite) {
+                                      bool pointSprite,
+                                      float lineWidth,
+                                      RsCullMode cull) {
     ProgramRaster *pr = new ProgramRaster(rsc, pointSmooth,
-                                          lineSmooth, pointSprite);
+                                          lineSmooth, pointSprite, lineWidth, cull);
     pr->incUserRef();
     return pr;
 }
 
-void rsi_ProgramRasterSetLineWidth(Context * rsc,
-                                   RsProgramRaster vpr,
-                                   float s) {
-    ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
-    pr->setLineWidth(s);
-}
-
-void rsi_ProgramRasterSetCullMode(Context * rsc,
-                                  RsProgramRaster vpr,
-                                  RsCullMode mode) {
-    ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
-    pr->setCullMode(mode);
-}
-
 }
 }
 
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
index 7958af9..045a7c1 100644
--- a/libs/rs/rsProgramRaster.h
+++ b/libs/rs/rsProgramRaster.h
@@ -30,23 +30,31 @@
     ProgramRaster(Context *rsc,
                   bool pointSmooth,
                   bool lineSmooth,
-                  bool pointSprite);
+                  bool pointSprite,
+                  float lineWidth,
+                  RsCullMode cull);
     virtual ~ProgramRaster();
 
-    virtual void setupGL2(const Context *, ProgramRasterState *);
+    virtual void setup(const Context *, ProgramRasterState *);
     virtual void serialize(OStream *stream) const;
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_RASTER; }
     static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
 
-    void setLineWidth(float w);
-    void setCullMode(RsCullMode mode);
+    struct Hal {
+        mutable void *drv;
+
+        struct State {
+            bool pointSmooth;
+            bool lineSmooth;
+            bool pointSprite;
+            float lineWidth;
+            RsCullMode cull;
+        };
+        State state;
+    };
+    Hal mHal;
 
 protected:
-    bool mPointSmooth;
-    bool mLineSmooth;
-    bool mPointSprite;
-    float mLineWidth;
-    RsCullMode mCull;
 };
 
 class ProgramRasterState {
diff --git a/libs/rs/rsProgramStore.cpp b/libs/rs/rsProgramStore.cpp
index 09b759d..2ad65e9 100644
--- a/libs/rs/rsProgramStore.cpp
+++ b/libs/rs/rsProgramStore.cpp
@@ -15,82 +15,43 @@
  */
 
 #include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#endif //ANDROID_RS_SERIALIZE
-
 #include "rsProgramStore.h"
 
 using namespace android;
 using namespace android::renderscript;
 
 
-ProgramStore::ProgramStore(Context *rsc) : Program(rsc) {
-    mDitherEnable = true;
-    mBlendEnable = false;
-    mColorRWriteEnable = true;
-    mColorGWriteEnable = true;
-    mColorBWriteEnable = true;
-    mColorAWriteEnable = true;
-    mBlendSrc = GL_ONE;
-    mBlendDst = GL_ZERO;
+ProgramStore::ProgramStore(Context *rsc,
+                           bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+                           bool depthMask, bool ditherEnable,
+                           RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+                           RsDepthFunc depthFunc) : Program(rsc) {
+    memset(&mHal, 0, sizeof(mHal));
 
-    mDepthTestEnable = false;
-    mDepthWriteEnable = true;
-    mDepthFunc = GL_LESS;
+    mHal.state.ditherEnable = ditherEnable;
+
+    mHal.state.colorRWriteEnable = colorMaskR;
+    mHal.state.colorGWriteEnable = colorMaskG;
+    mHal.state.colorBWriteEnable = colorMaskB;
+    mHal.state.colorAWriteEnable = colorMaskA;
+    mHal.state.blendSrc = srcFunc;
+    mHal.state.blendDst = destFunc;
+
+    mHal.state.depthWriteEnable = depthMask;
+    mHal.state.depthFunc = depthFunc;
 }
 
 ProgramStore::~ProgramStore() {
+    mRSC->mHal.funcs.store.destroy(mRSC, this);
 }
 
-void ProgramStore::setupGL2(const Context *rsc, ProgramStoreState *state) {
+void ProgramStore::setup(const Context *rsc, ProgramStoreState *state) {
     if (state->mLast.get() == this) {
         return;
     }
     state->mLast.set(this);
 
-    glColorMask(mColorRWriteEnable,
-                mColorGWriteEnable,
-                mColorBWriteEnable,
-                mColorAWriteEnable);
-    if (mBlendEnable) {
-        glEnable(GL_BLEND);
-        glBlendFunc(mBlendSrc, mBlendDst);
-    } else {
-        glDisable(GL_BLEND);
-    }
-
-    //LOGE("pfs  %i, %i, %x", mDepthWriteEnable, mDepthTestEnable, mDepthFunc);
-
-    if (rsc->mUserSurfaceConfig.depthMin > 0) {
-        glDepthMask(mDepthWriteEnable);
-        if (mDepthTestEnable || mDepthWriteEnable) {
-            glEnable(GL_DEPTH_TEST);
-            glDepthFunc(mDepthFunc);
-        } else {
-            glDisable(GL_DEPTH_TEST);
-        }
-    } else {
-        glDepthMask(false);
-        glDisable(GL_DEPTH_TEST);
-    }
-
-    if (rsc->mUserSurfaceConfig.stencilMin > 0) {
-    } else {
-        glStencilMask(0);
-        glDisable(GL_STENCIL_TEST);
-    }
-
-    if (mDitherEnable) {
-        glEnable(GL_DITHER);
-    } else {
-        glDisable(GL_DITHER);
-    }
-}
-
-void ProgramStore::setDitherEnable(bool enable) {
-    mDitherEnable = enable;
+    rsc->mHal.funcs.store.setActive(rsc, this);
 }
 
 void ProgramStore::serialize(OStream *stream) const {
@@ -100,123 +61,24 @@
     return NULL;
 }
 
-void ProgramStore::setDepthFunc(RsDepthFunc func) {
-    mDepthTestEnable = true;
-
-    switch (func) {
-    case RS_DEPTH_FUNC_ALWAYS:
-        mDepthTestEnable = false;
-        mDepthFunc = GL_ALWAYS;
-        break;
-    case RS_DEPTH_FUNC_LESS:
-        mDepthFunc = GL_LESS;
-        break;
-    case RS_DEPTH_FUNC_LEQUAL:
-        mDepthFunc = GL_LEQUAL;
-        break;
-    case RS_DEPTH_FUNC_GREATER:
-        mDepthFunc = GL_GREATER;
-        break;
-    case RS_DEPTH_FUNC_GEQUAL:
-        mDepthFunc = GL_GEQUAL;
-        break;
-    case RS_DEPTH_FUNC_EQUAL:
-        mDepthFunc = GL_EQUAL;
-        break;
-    case RS_DEPTH_FUNC_NOTEQUAL:
-        mDepthFunc = GL_NOTEQUAL;
-        break;
-    }
-}
-
-void ProgramStore::setDepthMask(bool mask) {
-    mDepthWriteEnable = mask;
-}
-
-void ProgramStore::setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst) {
-    mBlendEnable = true;
-    if ((src == RS_BLEND_SRC_ONE) &&
-        (dst == RS_BLEND_DST_ZERO)) {
-        mBlendEnable = false;
-    }
-
-    switch (src) {
-    case RS_BLEND_SRC_ZERO:
-        mBlendSrc = GL_ZERO;
-        break;
-    case RS_BLEND_SRC_ONE:
-        mBlendSrc = GL_ONE;
-        break;
-    case RS_BLEND_SRC_DST_COLOR:
-        mBlendSrc = GL_DST_COLOR;
-        break;
-    case RS_BLEND_SRC_ONE_MINUS_DST_COLOR:
-        mBlendSrc = GL_ONE_MINUS_DST_COLOR;
-        break;
-    case RS_BLEND_SRC_SRC_ALPHA:
-        mBlendSrc = GL_SRC_ALPHA;
-        break;
-    case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA:
-        mBlendSrc = GL_ONE_MINUS_SRC_ALPHA;
-        break;
-    case RS_BLEND_SRC_DST_ALPHA:
-        mBlendSrc = GL_DST_ALPHA;
-        break;
-    case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA:
-        mBlendSrc = GL_ONE_MINUS_DST_ALPHA;
-        break;
-    case RS_BLEND_SRC_SRC_ALPHA_SATURATE:
-        mBlendSrc = GL_SRC_ALPHA_SATURATE;
-        break;
-    }
-
-    switch (dst) {
-    case RS_BLEND_DST_ZERO:
-        mBlendDst = GL_ZERO;
-        break;
-    case RS_BLEND_DST_ONE:
-        mBlendDst = GL_ONE;
-        break;
-    case RS_BLEND_DST_SRC_COLOR:
-        mBlendDst = GL_SRC_COLOR;
-        break;
-    case RS_BLEND_DST_ONE_MINUS_SRC_COLOR:
-        mBlendDst = GL_ONE_MINUS_SRC_COLOR;
-        break;
-    case RS_BLEND_DST_SRC_ALPHA:
-        mBlendDst = GL_SRC_ALPHA;
-        break;
-    case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA:
-        mBlendDst = GL_ONE_MINUS_SRC_ALPHA;
-        break;
-    case RS_BLEND_DST_DST_ALPHA:
-        mBlendDst = GL_DST_ALPHA;
-        break;
-    case RS_BLEND_DST_ONE_MINUS_DST_ALPHA:
-        mBlendDst = GL_ONE_MINUS_DST_ALPHA;
-        break;
-    }
-}
-
-void ProgramStore::setColorMask(bool r, bool g, bool b, bool a) {
-    mColorRWriteEnable = r;
-    mColorGWriteEnable = g;
-    mColorBWriteEnable = b;
-    mColorAWriteEnable = a;
+void ProgramStore::init() {
+    mRSC->mHal.funcs.store.init(mRSC, this);
 }
 
 ProgramStoreState::ProgramStoreState() {
-    mPFS = NULL;
 }
 
 ProgramStoreState::~ProgramStoreState() {
-    ObjectBase::checkDelete(mPFS);
-    mPFS = NULL;
 }
 
 void ProgramStoreState::init(Context *rsc) {
-    ProgramStore *pfs = new ProgramStore(rsc);
-    mDefault.set(pfs);
+    ProgramStore *ps = new ProgramStore(rsc,
+                                        true, true, true, true,
+                                        true, true,
+                                        RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
+                                        RS_DEPTH_FUNC_LESS);
+    ps->init();
+    mDefault.set(ps);
 }
 
 void ProgramStoreState::deinit(Context *rsc) {
@@ -224,40 +86,24 @@
     mLast.clear();
 }
 
+
 namespace android {
 namespace renderscript {
 
-void rsi_ProgramStoreBegin(Context * rsc, RsElement in, RsElement out) {
-    ObjectBase::checkDelete(rsc->mStateFragmentStore.mPFS);
-    rsc->mStateFragmentStore.mPFS = new ProgramStore(rsc);
-}
+RsProgramStore rsi_ProgramStoreCreate(Context *rsc,
+                                      bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+                                      bool depthMask, bool ditherEnable,
+                                      RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+                                      RsDepthFunc depthFunc) {
 
-void rsi_ProgramStoreDepthFunc(Context *rsc, RsDepthFunc func) {
-    rsc->mStateFragmentStore.mPFS->setDepthFunc(func);
-}
-
-void rsi_ProgramStoreDepthMask(Context *rsc, bool mask) {
-    rsc->mStateFragmentStore.mPFS->setDepthMask(mask);
-}
-
-void rsi_ProgramStoreColorMask(Context *rsc, bool r, bool g, bool b, bool a) {
-    rsc->mStateFragmentStore.mPFS->setColorMask(r, g, b, a);
-}
-
-void rsi_ProgramStoreBlendFunc(Context *rsc, RsBlendSrcFunc src, RsBlendDstFunc dst) {
-    rsc->mStateFragmentStore.mPFS->setBlendFunc(src, dst);
-}
-
-RsProgramStore rsi_ProgramStoreCreate(Context *rsc) {
-    ProgramStore *pfs = rsc->mStateFragmentStore.mPFS;
+    ProgramStore *pfs = new ProgramStore(rsc,
+                                         colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+                                         depthMask, ditherEnable,
+                                         srcFunc, destFunc, depthFunc);
+    pfs->init();
     pfs->incUserRef();
-    rsc->mStateFragmentStore.mPFS = 0;
     return pfs;
 }
 
-void rsi_ProgramStoreDither(Context *rsc, bool enable) {
-    rsc->mStateFragmentStore.mPFS->setDitherEnable(enable);
-}
-
 }
 }
diff --git a/libs/rs/rsProgramStore.h b/libs/rs/rsProgramStore.h
index f8eb7cf..bfe276d 100644
--- a/libs/rs/rsProgramStore.h
+++ b/libs/rs/rsProgramStore.h
@@ -28,39 +28,46 @@
 
 class ProgramStore : public Program {
 public:
-    ProgramStore(Context *);
+    ProgramStore(Context *,
+                 bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+                 bool depthMask, bool ditherEnable,
+                 RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+                 RsDepthFunc depthFunc);
     virtual ~ProgramStore();
 
-    virtual void setupGL2(const Context *, ProgramStoreState *);
-
-    void setDepthFunc(RsDepthFunc);
-    void setDepthMask(bool);
-
-    void setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst);
-    void setColorMask(bool, bool, bool, bool);
-
-    void setDitherEnable(bool);
+    virtual void setup(const Context *, ProgramStoreState *);
 
     virtual void serialize(OStream *stream) const;
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_STORE; }
     static ProgramStore *createFromStream(Context *rsc, IStream *stream);
 
+    void init();
+
+    struct Hal {
+        mutable void *drv;
+
+        struct State {
+            bool ditherEnable;
+
+            //bool blendEnable;
+            bool colorRWriteEnable;
+            bool colorGWriteEnable;
+            bool colorBWriteEnable;
+            bool colorAWriteEnable;
+            RsBlendSrcFunc blendSrc;
+            RsBlendDstFunc blendDst;
+
+            //bool depthTestEnable;
+            bool depthWriteEnable;
+            RsDepthFunc depthFunc;
+        };
+        State state;
+
+
+    };
+    Hal mHal;
+
 protected:
-    bool mDitherEnable;
-
-    bool mBlendEnable;
-    bool mColorRWriteEnable;
-    bool mColorGWriteEnable;
-    bool mColorBWriteEnable;
-    bool mColorAWriteEnable;
-    int32_t mBlendSrc;
-    int32_t mBlendDst;
-
-    bool mDepthTestEnable;
-    bool mDepthWriteEnable;
-    int32_t mDepthFunc;
-
-    bool mStencilTestEnable;
 };
 
 class ProgramStoreState {
@@ -72,9 +79,6 @@
 
     ObjectBaseRef<ProgramStore> mDefault;
     ObjectBaseRef<ProgramStore> mLast;
-
-
-    ProgramStore *mPFS;
 };
 
 }
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index d5c486b..8e95891 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -185,7 +185,7 @@
 
     //LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
 
-    rsc->mHal.funcs.script.scriptInit(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0, symbolLookup);
+    rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0, symbolLookup);
 
     mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
     mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index 17983ce..93d7476 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -29,7 +29,8 @@
 class Allocation;
 class Script;
 class ScriptC;
-
+class ProgramStore;
+class ProgramRaster;
 
 typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
 
@@ -50,13 +51,13 @@
 
 
     struct {
-        bool (*scriptInit)(const Context *rsc, ScriptC *s,
-                           char const *resName,
-                           char const *cacheDir,
-                           uint8_t const *bitcode,
-                           size_t bitcodeSize,
-                           uint32_t flags,
-                           RsHalSymbolLookupFunc lookupFunc);
+        bool (*init)(const Context *rsc, ScriptC *s,
+                     char const *resName,
+                     char const *cacheDir,
+                     uint8_t const *bitcode,
+                     size_t bitcodeSize,
+                     uint32_t flags,
+                     RsHalSymbolLookupFunc lookupFunc);
 
         void (*invokeFunction)(const Context *rsc, Script *s,
                                uint32_t slot,
@@ -87,6 +88,18 @@
     } script;
 
 
+    struct {
+        bool (*init)(const Context *rsc, const ProgramStore *ps);
+        void (*setActive)(const Context *rsc, const ProgramStore *ps);
+        void (*destroy)(const Context *rsc, const ProgramStore *ps);
+    } store;
+
+    struct {
+        bool (*init)(const Context *rsc, const ProgramRaster *ps);
+        void (*setActive)(const Context *rsc, const ProgramRaster *ps);
+        void (*destroy)(const Context *rsc, const ProgramRaster *ps);
+    } raster;
+
 
 } RsdHalFunctions;
 
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 7197ad7..ac9cdf9 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -2424,7 +2424,7 @@
 {
     mLock.lock();
     TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
-                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
                        params->mcc, params->mnc,
                        params->language[0] ? params->language[0] : '-',
                        params->language[1] ? params->language[1] : '-',
@@ -2437,7 +2437,9 @@
                        params->inputFlags,
                        params->navigation,
                        params->screenWidth,
-                       params->screenHeight));
+                       params->screenHeight,
+                       params->screenWidthDp,
+                       params->screenHeightDp));
     mParams = *params;
     for (size_t i=0; i<mPackageGroups.size(); i++) {
         TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
@@ -3758,8 +3760,10 @@
         ResTable_config thisConfig;
         thisConfig.copyFromDtoH(thisType->config);
 
-        TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c "
-                            "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n",
+        TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d "
+                            "lang:%c%c=%c%c cnt:%c%c=%c%c orien:%d=%d touch:%d=%d "
+                            "density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d "
+                            "wdp:%d=%d hdp:%d=%d\n",
                            entryIndex, typeIndex+1, dtohl(thisType->config.size),
                            thisConfig.mcc, thisConfig.mnc,
                            config ? config->mcc : 0, config ? config->mnc : 0,
@@ -3786,7 +3790,11 @@
                            thisConfig.screenWidth,
                            config ? config->screenWidth : 0,
                            thisConfig.screenHeight,
-                           config ? config->screenHeight : 0));
+                           config ? config->screenHeight : 0,
+                           thisConfig.screenWidthDp,
+                           config ? config->screenWidthDp : 0,
+                           thisConfig.screenHeightDp,
+                           config ? config->screenHeightDp : 0));
         
         // Check to make sure this one is valid for the current parameters.
         if (config && !thisConfig.match(*config)) {
@@ -4067,7 +4075,8 @@
                 ResTable_config thisConfig;
                 thisConfig.copyFromDtoH(type->config);
                 LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
-                     "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                     "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d "
+                     "wdp:%d hdp:%d\n",
                       type->id,
                       thisConfig.mcc, thisConfig.mnc,
                       thisConfig.language[0] ? thisConfig.language[0] : '-',
@@ -4081,7 +4090,9 @@
                       thisConfig.inputFlags,
                       thisConfig.navigation,
                       thisConfig.screenWidth,
-                      thisConfig.screenHeight));
+                      thisConfig.screenHeight,
+                      thisConfig.screenWidthDp,
+                      thisConfig.screenHeightDp));
             t->configs.add(type);
         } else {
             status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
@@ -4444,6 +4455,12 @@
                     if (type->config.screenHeight != 0) {
                         printf(" h=%d", dtohs(type->config.screenHeight));
                     }
+                    if (type->config.screenWidthDp != 0) {
+                        printf(" wdp=%d", dtohs(type->config.screenWidthDp));
+                    }
+                    if (type->config.screenHeightDp != 0) {
+                        printf(" hdp=%d", dtohs(type->config.screenHeightDp));
+                    }
                     if (type->config.sdkVersion != 0) {
                         printf(" sdk=%d", dtohs(type->config.sdkVersion));
                     }
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 5d9a3c5..27b37b7 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -441,19 +441,20 @@
 {
     jclass clazz = env->FindClass(kClassPathName);
     if (clazz == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaMetadataRetriever");
         return;
     }
 
     fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
     if (fields.context == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaMetadataRetriever.mNativeContext");
         return;
     }
 
-    fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
+    jclass bitmapClazz = env->FindClass("android/graphics/Bitmap");
+    if (bitmapClazz == NULL) {
+        return;
+    }
+    fields.bitmapClazz = (jclass) env->NewGlobalRef(bitmapClazz);
     if (fields.bitmapClazz == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/graphics/Bitmap");
         return;
     }
     fields.createBitmapMethod =
@@ -461,8 +462,6 @@
                     "(IILandroid/graphics/Bitmap$Config;)"
                     "Landroid/graphics/Bitmap;");
     if (fields.createBitmapMethod == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find Bitmap.createBitmap(int, int, Config)  method");
         return;
     }
     fields.createScaledBitmapMethod =
@@ -470,28 +469,25 @@
                     "(Landroid/graphics/Bitmap;IIZ)"
                     "Landroid/graphics/Bitmap;");
     if (fields.createScaledBitmapMethod == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find Bitmap.createScaledBitmap(Bitmap, int, int, boolean)  method");
         return;
     }
     fields.nativeBitmap = env->GetFieldID(fields.bitmapClazz, "mNativeBitmap", "I");
     if (fields.nativeBitmap == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find Bitmap.mNativeBitmap field");
+        return;
     }
 
-    fields.configClazz = env->FindClass("android/graphics/Bitmap$Config");
+    jclass configClazz = env->FindClass("android/graphics/Bitmap$Config");
+    if (configClazz == NULL) {
+        return;
+    }
+    fields.configClazz = (jclass) env->NewGlobalRef(configClazz);
     if (fields.configClazz == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                               "Can't find Bitmap$Config class");
         return;
     }
     fields.createConfigMethod =
             env->GetStaticMethodID(fields.configClazz, "nativeToConfig",
                     "(I)Landroid/graphics/Bitmap$Config;");
     if (fields.createConfigMethod == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find Bitmap$Config.nativeToConfig(int)  method");
         return;
     }
 }
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 27d1fc0..e00fa85 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -53,7 +53,6 @@
 // ----------------------------------------------------------------------------
 struct fields_t {
     jfieldID    synthProxyFieldJniData;
-    jclass      synthProxyClass;
     jmethodID   synthProxyMethodPost;
 };
 
@@ -1043,7 +1042,6 @@
         goto bail;
     }
 
-    javaTTSFields.synthProxyClass = clazz;
     javaTTSFields.synthProxyFieldJniData = NULL;
     javaTTSFields.synthProxyMethodPost = NULL;
 
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 915b679..a2d10df 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -937,7 +937,7 @@
                 evaluateTrafficStatsPolling();
                 mWifiStateMachine.enableRssiPolling(true);
                 if (mBackgroundScanSupported) {
-                    mWifiStateMachine.enableBackgroundScan(false);
+                    mWifiStateMachine.enableBackgroundScanCommand(false);
                 }
                 mWifiStateMachine.enableAllNetworks();
                 updateWifiState();
@@ -949,7 +949,7 @@
                 evaluateTrafficStatsPolling();
                 mWifiStateMachine.enableRssiPolling(false);
                 if (mBackgroundScanSupported) {
-                    mWifiStateMachine.enableBackgroundScan(true);
+                    mWifiStateMachine.enableBackgroundScanCommand(true);
                 }
                 /*
                  * Set a timer to put Wi-Fi to sleep, but only if the screen is off
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 79c4518..e2874f8 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5453,6 +5453,9 @@
         mDisplay.getMetrics(dm);
         CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
 
+        config.screenWidthDp = (int)(dm.widthPixels / dm.density);
+        config.screenHeightDp = (int)(dm.heightPixels / dm.density);
+
         if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
             // Note we only do this once because at this point we don't
             // expect the screen to change in this way at runtime, and want
diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp
index 6aeede2..00ee7e3 100644
--- a/services/jni/com_android_server_UsbService.cpp
+++ b/services/jni/com_android_server_UsbService.cpp
@@ -260,7 +260,7 @@
         return -1;
     }
 
-   clazz = env->FindClass("java/io/FileDescriptor");
+    clazz = env->FindClass("java/io/FileDescriptor");
     LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor");
     gFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
     gFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V");
@@ -268,7 +268,7 @@
     LOG_FATAL_IF(gFileDescriptorOffsets.mDescriptor == NULL,
                  "Unable to find descriptor field in java.io.FileDescriptor");
 
-   clazz = env->FindClass("android/os/ParcelFileDescriptor");
+    clazz = env->FindClass("android/os/ParcelFileDescriptor");
     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
     gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
     gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 2b2ec7b..a2271d9 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -156,6 +156,20 @@
         return 0;
     }
 
+    // screen dp width
+    if (getScreenWidthDpName(part.string(), &config)) {
+        *axis = AXIS_SCREENWIDTHDP;
+        *value = config.screenWidthDp;
+        return 0;
+    }
+
+    // screen dp height
+    if (getScreenHeightDpName(part.string(), &config)) {
+        *axis = AXIS_SCREENHEIGHTDP;
+        *value = config.screenHeightDp;
+        return 0;
+    }
+
     // orientation
     if (getOrientationName(part.string(), &config)) {
         *axis = AXIS_ORIENTATION;
@@ -243,7 +257,7 @@
 
     String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
     String8 touch, key, keysHidden, nav, navHidden, size, vers;
-    String8 uiModeType, uiModeNight;
+    String8 uiModeType, uiModeNight, widthdp, heightdp;
 
     const char *p = dir;
     const char *q;
@@ -354,6 +368,30 @@
         //printf("not screen layout long: %s\n", part.string());
     }
 
+    if (getScreenWidthDpName(part.string())) {
+        widthdp = part;
+
+        index++;
+        if (index == N) {
+            goto success;
+        }
+        part = parts[index];
+    } else {
+        //printf("not screen width dp: %s\n", part.string());
+    }
+
+    if (getScreenHeightDpName(part.string())) {
+        heightdp = part;
+
+        index++;
+        if (index == N) {
+            goto success;
+        }
+        part = parts[index];
+    } else {
+        //printf("not screen height dp: %s\n", part.string());
+    }
+
     // orientation
     if (getOrientationName(part.string())) {
         orient = part;
@@ -503,6 +541,8 @@
     this->locale = loc;
     this->screenLayoutSize = layoutsize;
     this->screenLayoutLong = layoutlong;
+    this->screenWidthDp = widthdp;
+    this->screenHeightDp = heightdp;
     this->orientation = orient;
     this->uiModeType = uiModeType;
     this->uiModeNight = uiModeNight;
@@ -534,6 +574,10 @@
     s += ",";
     s += screenLayoutLong;
     s += ",";
+    s += screenWidthDp;
+    s += ",";
+    s += screenHeightDp;
+    s += ",";
     s += this->orientation;
     s += ",";
     s += uiModeType;
@@ -582,6 +626,14 @@
         s += "-";
         s += screenLayoutLong;
     }
+    if (this->screenWidthDp != "") {
+        s += "-";
+        s += screenWidthDp;
+    }
+    if (this->screenHeightDp != "") {
+        s += "-";
+        s += screenHeightDp;
+    }
     if (this->orientation != "") {
         s += "-";
         s += orientation;
@@ -1039,8 +1091,7 @@
     return false;
 }
 
-bool AaptGroupEntry::getScreenSizeName(const char* name,
-                                       ResTable_config* out)
+bool AaptGroupEntry::getScreenSizeName(const char* name, ResTable_config* out)
 {
     if (strcmp(name, kWildcardName) == 0) {
         if (out) {
@@ -1075,8 +1126,53 @@
     return true;
 }
 
-bool AaptGroupEntry::getVersionName(const char* name,
-                                    ResTable_config* out)
+bool AaptGroupEntry::getScreenWidthDpName(const char* name, ResTable_config* out)
+{
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->screenWidthDp = out->SCREENWIDTH_ANY;
+        }
+        return true;
+    }
+
+    if (*name != 'w') return false;
+    name++;
+    const char* x = name;
+    while (*x >= '0' && *x <= '9') x++;
+    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+    String8 xName(name, x-name);
+
+    if (out) {
+        out->screenWidthDp = (uint16_t)atoi(xName.string());
+    }
+
+    return true;
+}
+
+bool AaptGroupEntry::getScreenHeightDpName(const char* name, ResTable_config* out)
+{
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->screenHeightDp = out->SCREENWIDTH_ANY;
+        }
+        return true;
+    }
+
+    if (*name != 'h') return false;
+    name++;
+    const char* x = name;
+    while (*x >= '0' && *x <= '9') x++;
+    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+    String8 xName(name, x-name);
+
+    if (out) {
+        out->screenHeightDp = (uint16_t)atoi(xName.string());
+    }
+
+    return true;
+}
+
+bool AaptGroupEntry::getVersionName(const char* name, ResTable_config* out)
 {
     if (strcmp(name, kWildcardName) == 0) {
         if (out) {
@@ -1112,6 +1208,8 @@
     if (v == 0) v = vendor.compare(o.vendor);
     if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize);
     if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong);
+    if (v == 0) v = screenWidthDp.compare(o.screenWidthDp);
+    if (v == 0) v = screenHeightDp.compare(o.screenHeightDp);
     if (v == 0) v = orientation.compare(o.orientation);
     if (v == 0) v = uiModeType.compare(o.uiModeType);
     if (v == 0) v = uiModeNight.compare(o.uiModeNight);
@@ -1135,6 +1233,8 @@
     getLocaleName(locale.string(), &params);
     getScreenLayoutSizeName(screenLayoutSize.string(), &params);
     getScreenLayoutLongName(screenLayoutLong.string(), &params);
+    getScreenWidthDpName(screenWidthDp.string(), &params);
+    getScreenHeightDpName(screenHeightDp.string(), &params);
     getOrientationName(orientation.string(), &params);
     getUiModeTypeName(uiModeType.string(), &params);
     getUiModeNightName(uiModeNight.string(), &params);
@@ -1149,7 +1249,10 @@
     
     // Fix up version number based on specified parameters.
     int minSdk = 0;
-    if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE)
+    if (params.screenWidthDp != ResTable_config::SCREENWIDTH_ANY
+            || params.screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
+        minSdk = SDK_ICS;
+    } else if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE)
                 != ResTable_config::UI_MODE_TYPE_ANY
             ||  (params.uiMode&ResTable_config::MASK_UI_MODE_NIGHT)
                 != ResTable_config::UI_MODE_NIGHT_ANY) {
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index eeb00c0..e5afd1b 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -42,6 +42,8 @@
     AXIS_NAVHIDDEN,
     AXIS_NAVIGATION,
     AXIS_SCREENSIZE,
+    AXIS_SCREENWIDTHDP,
+    AXIS_SCREENHEIGHTDP,
     AXIS_VERSION
 };
 
@@ -52,6 +54,7 @@
     SDK_ECLAIR_0_1 = 6,
     SDK_MR1 = 7,
     SDK_FROYO = 8,
+    SDK_ICS = 13,
 };
 
 /**
@@ -71,6 +74,8 @@
     String8 vendor;
     String8 screenLayoutSize;
     String8 screenLayoutLong;
+    String8 screenWidthDp;
+    String8 screenHeightDp;
     String8 orientation;
     String8 uiModeType;
     String8 uiModeNight;
@@ -102,6 +107,8 @@
     static bool getNavigationName(const char* name, ResTable_config* out = NULL);
     static bool getNavHiddenName(const char* name, ResTable_config* out = NULL);
     static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
+    static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL);
+    static bool getScreenHeightDpName(const char* name, ResTable_config* out = NULL);
     static bool getVersionName(const char* name, ResTable_config* out = NULL);
 
     int compare(const AaptGroupEntry& o) const;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 10815a1..3dcc093 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2607,6 +2607,12 @@
     if (!match(AXIS_SCREENSIZE, config.screenSize)) {
         return false;
     }
+    if (!match(AXIS_SCREENWIDTHDP, config.screenWidthDp)) {
+        return false;
+    }
+    if (!match(AXIS_SCREENHEIGHTDP, config.screenHeightDp)) {
+        return false;
+    }
     if (!match(AXIS_SCREENLAYOUTSIZE, config.screenLayout&ResTable_config::MASK_SCREENSIZE)) {
         return false;
     }
@@ -2803,7 +2809,7 @@
                 ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
 
                 NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
-                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
                       ti+1,
                       config.mcc, config.mnc,
                       config.language[0] ? config.language[0] : '-',
@@ -2818,7 +2824,9 @@
                       config.inputFlags,
                       config.navigation,
                       config.screenWidth,
-                      config.screenHeight));
+                      config.screenHeight,
+                      config.screenWidthDp,
+                      config.screenHeightDp));
                       
                 if (filterable && !filter.match(config)) {
                     continue;
@@ -2841,7 +2849,7 @@
                 tHeader->entriesStart = htodl(typeSize);
                 tHeader->config = config;
                 NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
-                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
                       ti+1,
                       tHeader->config.mcc, tHeader->config.mnc,
                       tHeader->config.language[0] ? tHeader->config.language[0] : '-',
@@ -2856,7 +2864,9 @@
                       tHeader->config.inputFlags,
                       tHeader->config.navigation,
                       tHeader->config.screenWidth,
-                      tHeader->config.screenHeight));
+                      tHeader->config.screenHeight,
+                      tHeader->config.screenWidthDp,
+                      tHeader->config.screenHeightDp));
                 tHeader->config.swapHtoD();
 
                 // Build the entries inside of this type.
@@ -3438,7 +3448,7 @@
     if (e == NULL) {
         if (config != NULL) {
             NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
-                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
                       sourcePos.file.string(), sourcePos.line,
                       config->mcc, config->mnc,
                       config->language[0] ? config->language[0] : '-',
@@ -3452,7 +3462,9 @@
                       config->inputFlags,
                       config->navigation,
                       config->screenWidth,
-                      config->screenHeight));
+                      config->screenHeight,
+                      config->screenWidthDp,
+                      config->screenHeightDp));
         } else {
             NOISY(printf("New entry at %s:%d: NULL config\n",
                       sourcePos.file.string(), sourcePos.line));
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 909605d..6e13d0f 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -171,5 +171,7 @@
      */
     public native static String waitForEvent();
 
-    public native static void enableBackgroundScan(boolean enable);
+    public native static void enableBackgroundScanCommand(boolean enable);
+
+    public native static void setScanIntervalCommand(int scanInterval);
 }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 4346b327..46c07a3 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -339,10 +339,20 @@
     private static final int POWER_MODE_AUTO = 0;
 
     /**
-     * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
-     * Settings.Secure value is not present.
+     * Default framework scan interval in milliseconds. This is used in the scenario in which
+     * wifi chipset does not support background scanning to set up a
+     * periodic wake up scan so that the device can connect to a new access
+     * point on the move. {@link Settings.Secure#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can
+     * override this.
      */
-    private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */
+    private final int mDefaultFrameworkScanIntervalMs;
+
+    /**
+     * Default supplicant scan interval in milliseconds.
+     * {@link Settings.Secure#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} can override this.
+     */
+    private final int mDefaultSupplicantScanIntervalMs;
+
 
     private static final int MIN_RSSI = -200;
     private static final int MAX_RSSI = 256;
@@ -472,6 +482,12 @@
         Intent scanIntent = new Intent(ACTION_START_SCAN, null);
         mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
 
+        mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_wifi_framework_scan_interval);
+
+        mDefaultSupplicantScanIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_wifi_supplicant_scan_interval);
+
         mContext.registerReceiver(
             new BroadcastReceiver() {
                 @Override
@@ -819,7 +835,7 @@
        sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
     }
 
-    public void enableBackgroundScan(boolean enabled) {
+    public void enableBackgroundScanCommand(boolean enabled) {
        sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0));
     }
 
@@ -1949,6 +1965,11 @@
             mIsScanMode = false;
             /* Wifi is available as long as we have a connection to supplicant */
             mNetworkInfo.setIsAvailable(true);
+            /* Set scan interval */
+            long supplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
+                    Settings.Secure.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
+                    mDefaultSupplicantScanIntervalMs);
+            WifiNative.setScanIntervalCommand((int)supplicantScanIntervalMs / 1000);
         }
         @Override
         public boolean processMessage(Message message) {
@@ -2800,17 +2821,21 @@
 
     class DisconnectedState extends HierarchicalState {
         private boolean mAlarmEnabled = false;
-        private long mScanIntervalMs;
+        /* This is set from the overlay config file or from a secure setting.
+         * A value of 0 disables scanning in the framework.
+         */
+        private long mFrameworkScanIntervalMs;
 
         private void setScanAlarm(boolean enabled) {
             if (enabled == mAlarmEnabled) return;
             if (enabled) {
-                mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
-                        System.currentTimeMillis() + mScanIntervalMs,
-                        mScanIntervalMs,
-                        mScanIntent);
-
-                mAlarmEnabled = true;
+                if (mFrameworkScanIntervalMs > 0) {
+                    mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
+                            System.currentTimeMillis() + mFrameworkScanIntervalMs,
+                            mFrameworkScanIntervalMs,
+                            mScanIntent);
+                    mAlarmEnabled = true;
+                }
             } else {
                 mAlarmManager.cancel(mScanIntent);
                 mAlarmEnabled = false;
@@ -2822,8 +2847,9 @@
             if (DBG) Log.d(TAG, getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
-            mScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
-                    Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
+            mFrameworkScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
+                    Settings.Secure.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
+                    mDefaultFrameworkScanIntervalMs);
             /*
              * We initiate background scanning if it is enabled, otherwise we
              * initiate an infrequent scan that wakes up the device to ensure
@@ -2837,7 +2863,7 @@
                  * cleared
                  */
                 if (!mScanResultIsPending) {
-                    WifiNative.enableBackgroundScan(true);
+                    WifiNative.enableBackgroundScanCommand(true);
                 }
             } else {
                 setScanAlarm(true);
@@ -2859,10 +2885,10 @@
                 case CMD_ENABLE_BACKGROUND_SCAN:
                     mEnableBackgroundScan = (message.arg1 == 1);
                     if (mEnableBackgroundScan) {
-                        WifiNative.enableBackgroundScan(true);
+                        WifiNative.enableBackgroundScanCommand(true);
                         setScanAlarm(false);
                     } else {
-                        WifiNative.enableBackgroundScan(false);
+                        WifiNative.enableBackgroundScanCommand(false);
                         setScanAlarm(true);
                     }
                     break;
@@ -2877,14 +2903,14 @@
                 case CMD_START_SCAN:
                     /* Disable background scan temporarily during a regular scan */
                     if (mEnableBackgroundScan) {
-                        WifiNative.enableBackgroundScan(false);
+                        WifiNative.enableBackgroundScanCommand(false);
                     }
                     /* Handled in parent state */
                     return NOT_HANDLED;
                 case SCAN_RESULTS_EVENT:
                     /* Re-enable background scan when a pending scan result is received */
                     if (mEnableBackgroundScan && mScanResultIsPending) {
-                        WifiNative.enableBackgroundScan(true);
+                        WifiNative.enableBackgroundScanCommand(true);
                     }
                     /* Handled in parent state */
                     return NOT_HANDLED;
@@ -2899,7 +2925,7 @@
         public void exit() {
             /* No need for a background scan upon exit from a disconnected state */
             if (mEnableBackgroundScan) {
-                WifiNative.enableBackgroundScan(false);
+                WifiNative.enableBackgroundScanCommand(false);
             }
             setScanAlarm(false);
         }