Merge "Frameworks changes to enable File Reader and blob.slice APIs."
diff --git a/api/current.xml b/api/current.xml
index a01ed51..b72db98 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -201419,6 +201419,28 @@
  visibility="public"
 >
 </method>
+<method name="canZoomIn"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="canZoomOut"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="capturePicture"
  return="android.graphics.Picture"
  abstract="false"
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index ac2eb0d..7a7f8ed 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -38,7 +38,7 @@
 #include <ui/EGLUtils.h>
 
 #include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 
 #include <core/SkBitmap.h>
 #include <images/SkImageDecoder.h>
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index e34e776..886951b 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -25,6 +25,7 @@
 import android.database.SQLException;
 import android.database.sqlite.SQLiteDebug.DbStats;
 import android.os.Debug;
+import android.os.StatFs;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.text.TextUtils;
@@ -236,6 +237,12 @@
     /** Used to make temp table names unique */
     /* package */ int mTempTableSequence = 0;
 
+    /**
+     * The size, in bytes, of a block on "/data". This corresponds to the Unix
+     * statfs.f_bsize field. note that this field is lazily initialized.
+     */
+    private static int sBlockSize = 0;
+
     /** The path for the database file */
     private String mPath;
 
@@ -858,6 +865,15 @@
             errorHandler.onCorruption(sqliteDatabase);
             sqliteDatabase = new SQLiteDatabase(path, factory, flags);
         }
+
+        // set sqlite pagesize to mBlockSize
+        if (sBlockSize == 0) {
+            // TODO: "/data" should be a static final String constant somewhere. it is hardcoded
+            // in several places right now.
+            sBlockSize = new StatFs("/data").getBlockSize();
+        }
+        sqliteDatabase.setPageSize(sBlockSize);
+
         ActiveDatabases.getInstance().mActiveDatabases.add(
                 new WeakReference<SQLiteDatabase>(sqliteDatabase));
         return sqliteDatabase;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 46e1f89..54aa363 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -825,21 +825,81 @@
          */
         public static final String FLASH_MODE_TORCH = "torch";
 
-        // Values for scene mode settings.
+        /**
+         * Scene mode is off.
+         */
         public static final String SCENE_MODE_AUTO = "auto";
+
+        /**
+         * Take photos of fast moving objects. Same as {@link
+         * #SCENE_MODE_SPORTS}.
+         */
         public static final String SCENE_MODE_ACTION = "action";
+
+        /**
+         * Take people pictures.
+         */
         public static final String SCENE_MODE_PORTRAIT = "portrait";
+
+        /**
+         * Take pictures on distant objects.
+         */
         public static final String SCENE_MODE_LANDSCAPE = "landscape";
+
+        /**
+         * Take photos at night.
+         */
         public static final String SCENE_MODE_NIGHT = "night";
+
+        /**
+         * Take people pictures at night.
+         */
         public static final String SCENE_MODE_NIGHT_PORTRAIT = "night-portrait";
+
+        /**
+         * Take photos in a theater. Flash light is off.
+         */
         public static final String SCENE_MODE_THEATRE = "theatre";
+
+        /**
+         * Take pictures on the beach.
+         */
         public static final String SCENE_MODE_BEACH = "beach";
+
+        /**
+         * Take pictures on the snow.
+         */
         public static final String SCENE_MODE_SNOW = "snow";
+
+        /**
+         * Take sunset photos.
+         */
         public static final String SCENE_MODE_SUNSET = "sunset";
+
+        /**
+         * Avoid blurry pictures (for example, due to hand shake).
+         */
         public static final String SCENE_MODE_STEADYPHOTO = "steadyphoto";
+
+        /**
+         * For shooting firework displays.
+         */
         public static final String SCENE_MODE_FIREWORKS = "fireworks";
+
+        /**
+         * Take photos of fast moving objects. Same as {@link
+         * #SCENE_MODE_ACTION}.
+         */
         public static final String SCENE_MODE_SPORTS = "sports";
+
+        /**
+         * Take indoor low-light shot.
+         */
         public static final String SCENE_MODE_PARTY = "party";
+
+        /**
+         * Capture the naturally warm color of scenes lit by candles.
+         */
         public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
 
         /**
diff --git a/core/java/android/os/FileObserver.java b/core/java/android/os/FileObserver.java
index 7e99f38..667ce68 100644
--- a/core/java/android/os/FileObserver.java
+++ b/core/java/android/os/FileObserver.java
@@ -24,33 +24,52 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
+/**
+ * Monitors files (using <a href="http://en.wikipedia.org/wiki/Inotify">inotify</a>)
+ * to fire an event after files are accessed or changed by by any process on
+ * the device (including this one).  FileObserver is an abstract class;
+ * subclasses must implement the event handler {@link #onEvent(int, String)}.
+ *
+ * <p>Each FileObserver instance monitors a single file or directory.
+ * If a directory is monitored, events will be triggered for all files and
+ * subdirectories (recursively) inside the monitored directory.</p>
+ *
+ * <p>An event mask is used to specify which changes or actions to report.
+ * Event type constants are used to describe the possible changes in the
+ * event mask as well as what actually happened in event callbacks.</p>
+ *
+ * <p class="caution"><b>Warning</b>: If a FileObserver is garbage collected, it
+ * will stop sending events.  To ensure you keep receiving events, you must
+ * keep a reference to the FileObserver instance from some other live object.</p>
+ */
 public abstract class FileObserver {
-    /** File was accessed */
+    /** Event type: Data was read from a file */
     public static final int ACCESS = 0x00000001;
-    /** File was modified */
+    /** Event type: Data was written to a file */
     public static final int MODIFY = 0x00000002;
-    /** Metadata changed */
+    /** Event type: Metadata (permissions, owner, timestamp) was changed explicitly */
     public static final int ATTRIB = 0x00000004;
-    /** Writable file was closed */
+    /** Event type: Someone had a file or directory open for writing, and closed it */
     public static final int CLOSE_WRITE = 0x00000008;
-    /** Unwrittable file closed */
+    /** Event type: Someone had a file or directory open read-only, and closed it */
     public static final int CLOSE_NOWRITE = 0x00000010;
-    /** File was opened */
+    /** Event type: A file or directory was opened */
     public static final int OPEN = 0x00000020;
-    /** File was moved from X */
+    /** Event type: A file or subdirectory was moved from the monitored directory */
     public static final int MOVED_FROM = 0x00000040;
-    /** File was moved to Y */
+    /** Event type: A file or subdirectory was moved to the monitored directory */
     public static final int MOVED_TO = 0x00000080;
-    /** Subfile was created */
+    /** Event type: A new file or subdirectory was created under the monitored directory */
     public static final int CREATE = 0x00000100;
-    /** Subfile was deleted */
+    /** Event type: A file was deleted from the monitored directory */
     public static final int DELETE = 0x00000200;
-    /** Self was deleted */
+    /** Event type: The monitored file or directory was deleted; monitoring effectively stops */
     public static final int DELETE_SELF = 0x00000400;
-    /** Self was moved */
+    /** Event type: The monitored file or directory was moved; monitoring continues */
     public static final int MOVE_SELF = 0x00000800;
 
-    public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE 
+    /** Event mask: All valid event types, combined */
+    public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE
             | CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE
             | DELETE_SELF | MOVE_SELF;
 
@@ -128,10 +147,21 @@
     private Integer m_descriptor;
     private int m_mask;
 
+    /**
+     * Equivalent to FileObserver(path, FileObserver.ALL_EVENTS).
+     */
     public FileObserver(String path) {
         this(path, ALL_EVENTS);
     }
 
+    /**
+     * Create a new file observer for a certain file or directory.
+     * Monitoring does not start on creation!  You must call
+     * {@link #startWatching()} before you will receive events.
+     *
+     * @param path The file or directory to monitor
+     * @param mask The event or events (added together) to watch for
+     */
     public FileObserver(String path, int mask) {
         m_path = path;
         m_mask = mask;
@@ -142,12 +172,22 @@
         stopWatching();
     }
 
+    /**
+     * Start watching for events.  The monitored file or directory must exist at
+     * this time, or else no events will be reported (even if it appears later).
+     * If monitoring is already started, this call has no effect.
+     */
     public void startWatching() {
         if (m_descriptor < 0) {
             m_descriptor = s_observerThread.startWatching(m_path, m_mask, this);
         }
     }
 
+    /**
+     * Stop watching for events.  Some events may be in process, so events
+     * may continue to be reported even after this method completes.  If
+     * monitoring is already stopped, this call has no effect.
+     */
     public void stopWatching() {
         if (m_descriptor >= 0) {
             s_observerThread.stopWatching(m_descriptor);
@@ -155,5 +195,19 @@
         }
     }
 
+    /**
+     * The event handler, which must be implemented by subclasses.
+     *
+     * <p class="note">This method is invoked on a special FileObserver thread.
+     * It runs independently of any threads, so take care to use appropriate
+     * synchronization!  Consider using {@link Handler#post(Runnable)} to shift
+     * event handling work to the main thread to avoid concurrency problems.</p>
+     *
+     * <p>Event handlers must not throw exceptions.</p>
+     *
+     * @param event The type of event which happened
+     * @param path The path, relative to the main monitored file or directory,
+     *     of the file or directory which triggered the event
+     */
     public abstract void onEvent(int event, String path);
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 401b3a5..056d10c 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -234,7 +234,7 @@
  *
  * <p>The screen density of a device is based on the screen resolution. A screen with low density
  * has fewer available pixels per inch, where a screen with high density
- * has more — sometimes significantly more — pixels per inch. The density of a
+ * has more - sometimes significantly more - pixels per inch. The density of a
  * screen is important because, other things being equal, a UI element (such as a button) whose
  * height and width are defined in terms of screen pixels will appear larger on the lower density
  * screen and smaller on the higher density screen.
@@ -1892,7 +1892,7 @@
         msg.sendToTarget();
     }
 
-    private static int pinLoc(int x, int viewMax, int docMax) {
+    static int pinLoc(int x, int viewMax, int docMax) {
 //        Log.d(LOGTAG, "-- pinLoc " + x + " " + viewMax + " " + docMax);
         if (docMax < viewMax) {   // the doc has room on the sides for "blank"
             // pin the short document to the top/left of the screen
@@ -2248,7 +2248,7 @@
         if (mDrawHistory) {
             return mHistoryWidth;
         } else if (mHorizontalScrollBarMode == SCROLLBAR_ALWAYSOFF
-                && mZoomManager.isZoomedOut()) {
+                && !mZoomManager.canZoomOut()) {
             // only honor the scrollbar mode when it is at minimum zoom level
             return computeHorizontalScrollExtent();
         } else {
@@ -2262,7 +2262,7 @@
         if (mDrawHistory) {
             return mHistoryHeight;
         } else if (mVerticalScrollBarMode == SCROLLBAR_ALWAYSOFF
-                && mZoomManager.isZoomedOut()) {
+                && !mZoomManager.canZoomOut()) {
             // only honor the scrollbar mode when it is at minimum zoom level
             return computeVerticalScrollExtent();
         } else {
@@ -3283,17 +3283,12 @@
             }
         }
         if (animateZoom) {
-            float zoomScale;
-            int interval = (int) (SystemClock.uptimeMillis() - mZoomManager.mZoomStart);
-            if (interval < mZoomManager.ZOOM_ANIMATION_LENGTH) {
-                float ratio = (float) interval / mZoomManager.ZOOM_ANIMATION_LENGTH;
-                zoomScale = 1.0f / (mZoomManager.mInvInitialZoomScale
-                        + (mZoomManager.mInvFinalZoomScale - mZoomManager.mInvInitialZoomScale) * ratio);
+            final float[] zoomValues = mZoomManager.animateZoom();
+            final boolean isStillAnimating = mZoomManager.isZoomAnimating();
+
+            if (isStillAnimating) {
                 invalidate();
             } else {
-                zoomScale = mZoomManager.mZoomScale;
-                // set mZoomScale to be 0 as we have done animation
-                mZoomManager.mZoomScale = 0;
                 WebViewCore.resumeUpdatePicture(mWebViewCore);
                 // call invalidate() again to draw with the final filters
                 invalidate();
@@ -3307,24 +3302,11 @@
                     }
                 }
             }
-            // calculate the intermediate scroll position. As we need to use
-            // zoomScale, we can't use pinLocX/Y directly. Copy the logic here.
-            float scale = zoomScale * mZoomManager.mInvInitialZoomScale;
-            int tx = Math.round(scale * (mZoomManager.mInitialScrollX + mZoomManager.mZoomCenterX)
-                    - mZoomManager.mZoomCenterX);
-            tx = -pinLoc(tx, getViewWidth(), Math.round(mContentWidth
-                    * zoomScale)) + mScrollX;
-            int titleHeight = getTitleHeight();
-            int ty = Math.round(scale
-                    * (mZoomManager.mInitialScrollY + mZoomManager.mZoomCenterY - titleHeight)
-                    - (mZoomManager.mZoomCenterY - titleHeight));
-            ty = -(ty <= titleHeight ? Math.max(ty, 0) : pinLoc(ty
-                    - titleHeight, getViewHeight(), Math.round(mContentHeight
-                    * zoomScale)) + titleHeight) + mScrollY;
-            canvas.translate(tx, ty);
-            canvas.scale(zoomScale, zoomScale);
-            if (inEditingMode() && !mNeedToAdjustWebTextView
-                    && mZoomManager.isZoomAnimating()) {
+
+            canvas.translate(zoomValues[0], zoomValues[1]);
+            canvas.scale(zoomValues[2], zoomValues[2]);
+
+            if (inEditingMode() && !mNeedToAdjustWebTextView && isStillAnimating) {
                 // The WebTextView is up.  Keep track of this so we can adjust
                 // its size and placement when we finish zooming
                 mNeedToAdjustWebTextView = true;
@@ -4511,7 +4493,7 @@
                 mAnchorY = viewToContentY((int) mZoomManager.mZoomCenterY + mScrollY);
                 // don't reflow when zoom in; when zoom out, do reflow if the
                 // new scale is almost minimum scale;
-                boolean reflowNow = mZoomManager.isZoomedOut()
+                boolean reflowNow = !mZoomManager.canZoomOut()
                         || (mZoomManager.mActualScale <= 0.8 * mZoomManager.mTextWrapScale);
                 // force zoom after mPreviewZoomOnly is set to false so that the
                 // new view size will be passed to the WebKit
@@ -5019,7 +5001,10 @@
                                 break;
                             }
                         } else {
-                            if (mTouchMode == TOUCH_INIT_MODE) {
+                            // only trigger double tap if the WebView is
+                            // scalable
+                            if (mTouchMode == TOUCH_INIT_MODE
+                                    && (canZoomIn() || canZoomOut())) {
                                 mPrivateHandler.sendEmptyMessageDelayed(
                                         RELEASE_SINGLE_TAP, ViewConfiguration
                                                 .getDoubleTapTimeout());
@@ -5575,6 +5560,20 @@
     }
 
     /**
+     * @return TRUE if the WebView can be zoomed in.
+     */
+    public boolean canZoomIn() {
+        return mZoomManager.canZoomIn();
+    }
+
+    /**
+     * @return TRUE if the WebView can be zoomed out.
+     */
+    public boolean canZoomOut() {
+        return mZoomManager.canZoomOut();
+    }
+
+    /**
      * Perform zoom in in the webview
      * @return TRUE if zoom in succeeds. FALSE if no zoom changes.
      */
@@ -5796,7 +5795,7 @@
             float zoomCenterY = (oldScreenY * scale - newScreenY * actualScale)
                     / (scale - actualScale);
             mZoomManager.setZoomCenter(zoomCenterX, zoomCenterY);
-            mZoomManager.animateZoom(scale, false);
+            mZoomManager.startZoomAnimation(scale, false);
         }
     }
 
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index af521be..f39e178 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -16,7 +16,9 @@
 
 package android.webkit;
 
+import android.graphics.Canvas;
 import android.os.SystemClock;
+import android.util.Log;
 import android.view.View;
 
 class ZoomManager {
@@ -53,8 +55,9 @@
     // the last zoom scale.
     boolean mInZoomOverview = false;
 
-    // These keep track of the center point of the zoom.  They are used to
-    // determine the point around which we should zoom.
+    // These keep track of the center point of the zoom and they are used to
+    // determine the point around which we should zoom. They are stored in view
+    // coordinates.
     float mZoomCenterX;
     float mZoomCenterY;
 
@@ -75,13 +78,19 @@
     // the current computed zoom scale and its inverse.
     float mActualScale;
     float mInvActualScale;
-    // if this is non-zero, it is used on drawing rather than mActualScale
-    float mZoomScale;
-    float mInvInitialZoomScale;
-    float mInvFinalZoomScale;
-    int mInitialScrollX;
-    int mInitialScrollY;
-    long mZoomStart;
+    
+    /*
+     * The following member variables are only to be used for animating zoom. If
+     * mZoomScale is non-zero then we are in the middle of a zoom animation. The
+     * other variables are used as a cache (e.g. inverse) or as a way to store
+     * the state of the view prior to animating (e.g. initial scroll coords).
+     */
+    private float mZoomScale;
+    private float mInvInitialZoomScale;
+    private float mInvFinalZoomScale;
+    private int mInitialScrollX;
+    private int mInitialScrollY;
+    private long mZoomStart;
     static final int ZOOM_ANIMATION_LENGTH = 500;
 
     public ZoomManager(WebView webView, CallbackProxy callbackProxy) {
@@ -129,12 +138,12 @@
         return exceedsMinScaleIncrement(scale, mActualScale);
     }
 
-    public boolean isZoomedOut() {
-        return mActualScale - mMinZoomScale <= MINIMUM_SCALE_INCREMENT;
+    public boolean canZoomIn() {
+        return mMaxZoomScale - mActualScale > MINIMUM_SCALE_INCREMENT;
     }
 
-    public boolean isZoomAnimating() {
-        return mZoomScale != 0;
+    public boolean canZoomOut() {
+        return mActualScale - mMinZoomScale > MINIMUM_SCALE_INCREMENT;
     }
 
     public boolean zoomIn() {
@@ -156,7 +165,7 @@
         int anchorX = mWebView.viewToContentX((int) mZoomCenterX + mWebView.getScrollX());
         int anchorY = mWebView.viewToContentY((int) mZoomCenterY + mWebView.getScrollY());
         mWebView.setViewSizeAnchor(anchorX, anchorY);
-        return animateZoom(mActualScale * zoomMultiplier, true);
+        return startZoomAnimation(mActualScale * zoomMultiplier, true);
     }
 
     public void zoomToOverview() {
@@ -166,15 +175,20 @@
         if (scrollY < mWebView.getTitleHeight()) {
             mWebView.updateScrollCoordinates(mWebView.getScrollX(), 0);
         }
-        animateZoom((float) mWebView.getViewWidth() / mZoomOverviewWidth, true);
+        startZoomAnimation((float) mWebView.getViewWidth() / mZoomOverviewWidth, true);
     }
 
     public void zoomToDefaultLevel(boolean reflowText) {
         mInZoomOverview = false;
-        animateZoom(mDefaultScale, reflowText);
+        startZoomAnimation(mDefaultScale, reflowText);
     }
 
-    public boolean animateZoom(float scale, boolean reflowText) {
+    /**
+     * Initiates an animated zoom of the WebView.
+     *
+     * @return true if the new scale triggered an animation and false otherwise.
+     */
+    public boolean startZoomAnimation(float scale, boolean reflowText) {
         float oldScale = mActualScale;
         mInitialScrollX = mWebView.getScrollX();
         mInitialScrollY = mWebView.getScrollY();
@@ -200,6 +214,61 @@
         }
     }
 
+    /**
+     * Computes and returns the relevant data needed by the WebView's drawing
+     * model to animate a zoom.
+     *
+     * This method is to be called when a zoom animation is occurring. The
+     * animation begins by calling startZoomAnimation(...).  The caller can
+     * check to see if the animation has completed by calling isZoomAnimating().
+     *
+     * @return an array containing the values needed to animate the drawing
+     * surface.
+     * [0] = delta for the new scrollX position
+     * [1] = delta for the new scrollY position
+     * [2] = current zoom scale
+     */
+    public float[] animateZoom() {
+        if (mZoomScale == 0) {
+            Log.w(LOGTAG, "A WebView is attempting to animate a zoom when no " +
+                    "zoom is in progress");
+            float[] result = {0, 0, mActualScale};
+            return result;
+        }
+
+        float zoomScale;
+        int interval = (int) (SystemClock.uptimeMillis() - mZoomStart);
+        if (interval < ZOOM_ANIMATION_LENGTH) {
+            float ratio = (float) interval / ZOOM_ANIMATION_LENGTH;
+            zoomScale = 1.0f / (mInvInitialZoomScale
+                    + (mInvFinalZoomScale - mInvInitialZoomScale) * ratio);
+        } else {
+            zoomScale = mZoomScale;
+            // set mZoomScale to be 0 as we have finished animating
+            mZoomScale = 0;
+        }
+        // calculate the intermediate scroll position. Since we need to use
+        // zoomScale, we can't use the WebView's pinLocX/Y functions directly.
+        float scale = zoomScale * mInvInitialZoomScale;
+        int tx = Math.round(scale * (mInitialScrollX + mZoomCenterX) - mZoomCenterX);
+        tx = -WebView.pinLoc(tx, mWebView.getViewWidth(), Math.round(mWebView.getContentWidth()
+                * zoomScale)) + mWebView.getScrollX();
+        int titleHeight = mWebView.getTitleHeight();
+        int ty = Math.round(scale
+                * (mInitialScrollY + mZoomCenterY - titleHeight)
+                - (mZoomCenterY - titleHeight));
+        ty = -(ty <= titleHeight ? Math.max(ty, 0) : WebView.pinLoc(ty
+                - titleHeight, mWebView.getViewHeight(), Math.round(mWebView.getContentHeight()
+                * zoomScale)) + titleHeight) + mWebView.getScrollY();
+
+        float[] result = {tx, ty, zoomScale};
+        return result;
+    }
+
+    public boolean isZoomAnimating() {
+        return mZoomScale != 0;
+    }
+
     public void refreshZoomScale(boolean reflowText) {
         setZoomScale(mActualScale, reflowText, true);
     }
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 61af22d..5ef7b31 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1470,6 +1470,8 @@
     <string name="lockscreen_pattern_correct">Correct!</string>
     <!-- On the unlock pattern screen, shown when the user enters the wrong lock pattern and must try again. -->
     <string name="lockscreen_pattern_wrong">Sorry, try again</string>
+    <!-- On the unlock password screen, shown when the user enters the wrong lock password and must try again. -->
+    <string name="lockscreen_password_wrong">Sorry, try again</string>
 
     <!-- When the lock screen is showing and the phone plugged in, and the battery
          is not fully charged, show the current charge %.  -->
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index c77e7b7..6638bef 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -50,7 +50,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="460" height="250"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.1,35.6,28.1,0.2,0.4,35.6&chl=
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.1,27.6,26.8,0.1,0.3,45.1&chl=
 Android%201.1|Android%201.5|Android%201.6|Android%202.0|Android%202.0.1|Android%202.1&chco=c4df9b,
 6fad0c" />
 
@@ -60,12 +60,12 @@
   <th>Percent of Devices</th>
 </tr>
 <tr><td>Android 1.1</td><td>0.1%</td></tr>
-<tr><td>Android 1.5</td><td>34.1%</td></tr>
-<tr><td>Android 1.6</td><td>28.0%</td></tr>
-<tr><td>Android 2.0</td><td>0.2%</td></tr>
-<tr><td>Android 2.0.1</td><td>0.4%</td></tr>
-<tr><td>Android 2.1</td><td>37.2%</td></tr>
+<tr><td>Android 1.5</td><td>27.6%</td></tr>
+<tr><td>Android 1.6</td><td>26.8%</td></tr>
+<tr><td>Android 2.0</td><td>0.1%</td></tr>
+<tr><td>Android 2.0.1</td><td>0.3%</td></tr>
+<tr><td>Android 2.1</td><td>45.1%</td></tr>
 </table>
-<p><em>Data collected during two weeks ending on May 17, 2010</em></p>
+<p><em>Data collected during two weeks ending on June 1, 2010</em></p>
 </div>
 
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index 4ce7596..5da217b 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -49,7 +49,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="460" height="250"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.0,63.9,35.1&chl=Small%20/%20ldpi|
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.0,61.6,37.4&chl=Small%20/%20ldpi|
 Normal%20/%20mdpi|Normal%20/%20hdpi&chco=c4df9b,6fad0c" />
 
 <table>
@@ -66,8 +66,8 @@
 </tr> 
 <tr><th scope="row">Normal</th> 
 <td></td> 
-<td class='cent hi'>63.7%</td> 
-<td class='cent hi'>35.3%</td> 
+<td class='cent hi'>61.3%</td> 
+<td class='cent hi'>37.7%</td> 
 </tr> 
 <tr><th scope="row">Large</th> 
 <td></td> 
@@ -76,6 +76,6 @@
 </tr> 
 </table>
 
-<p><em>Data collected during two weeks ending on May 17, 2010</em></p>
+<p><em>Data collected during two weeks ending on June 1, 2010</em></p>
 </div>
 
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index 107c604..52689b6 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -29,7 +29,7 @@
           </a></li>
       <li><a href="<?cs var:toroot ?>resources/dashboard/screens.html">
             <span class="en">Screen Sizes &amp; Densities</span>
-          </a> <span class="new">new!</span></li>
+          </a></li>
     </ul>
   </li><?cs
   /if
diff --git a/docs/html/shareables/adl/2Q10_Business_Overview.pdf b/docs/html/shareables/adl/2010Q2_Business_Overview.pdf
similarity index 100%
rename from docs/html/shareables/adl/2Q10_Business_Overview.pdf
rename to docs/html/shareables/adl/2010Q2_Business_Overview.pdf
Binary files differ
diff --git a/docs/html/shareables/adl/2Q10_Market_Overview.pdf b/docs/html/shareables/adl/2010Q2_Market_Overview.pdf
similarity index 100%
rename from docs/html/shareables/adl/2Q10_Market_Overview.pdf
rename to docs/html/shareables/adl/2010Q2_Market_Overview.pdf
Binary files differ
diff --git a/docs/html/shareables/adl/2Q10_SDK_Overview.pdf b/docs/html/shareables/adl/2010Q2_SDK_Overview.pdf
similarity index 100%
rename from docs/html/shareables/adl/2Q10_SDK_Overview.pdf
rename to docs/html/shareables/adl/2010Q2_SDK_Overview.pdf
Binary files differ
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index f801794..974a36e 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -91,109 +91,109 @@
         }
     }
 
-    public static Element USER_U8(RenderScript rs) {
-        if(rs.mElement_USER_U8 == null) {
-            rs.mElement_USER_U8 = createUser(rs, DataType.UNSIGNED_8);
+    public static Element U8(RenderScript rs) {
+        if(rs.mElement_U8 == null) {
+            rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
         }
-        return rs.mElement_USER_U8;
+        return rs.mElement_U8;
     }
 
-    public static Element USER_I8(RenderScript rs) {
-        if(rs.mElement_USER_I8 == null) {
-            rs.mElement_USER_I8 = createUser(rs, DataType.SIGNED_8);
+    public static Element I8(RenderScript rs) {
+        if(rs.mElement_I8 == null) {
+            rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
         }
-        return rs.mElement_USER_I8;
+        return rs.mElement_I8;
     }
 
-    public static Element USER_U32(RenderScript rs) {
-        if(rs.mElement_USER_U32 == null) {
-            rs.mElement_USER_U32 = createUser(rs, DataType.UNSIGNED_32);
+    public static Element U32(RenderScript rs) {
+        if(rs.mElement_U32 == null) {
+            rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
         }
-        return rs.mElement_USER_U32;
+        return rs.mElement_U32;
     }
 
-    public static Element USER_I32(RenderScript rs) {
-        if(rs.mElement_USER_I32 == null) {
-            rs.mElement_USER_I32 = createUser(rs, DataType.SIGNED_32);
+    public static Element I32(RenderScript rs) {
+        if(rs.mElement_I32 == null) {
+            rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
         }
-        return rs.mElement_USER_I32;
+        return rs.mElement_I32;
     }
 
-    public static Element USER_F32(RenderScript rs) {
-        if(rs.mElement_USER_F32 == null) {
-            rs.mElement_USER_F32 = createUser(rs, DataType.FLOAT_32);
+    public static Element F32(RenderScript rs) {
+        if(rs.mElement_F32 == null) {
+            rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
         }
-        return rs.mElement_USER_F32;
+        return rs.mElement_F32;
     }
 
-    public static Element USER_ELEMENT(RenderScript rs) {
-        if(rs.mElement_USER_ELEMENT == null) {
-            rs.mElement_USER_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
+    public static Element ELEMENT(RenderScript rs) {
+        if(rs.mElement_ELEMENT == null) {
+            rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
         }
-        return rs.mElement_USER_ELEMENT;
+        return rs.mElement_ELEMENT;
     }
 
-    public static Element USER_TYPE(RenderScript rs) {
-        if(rs.mElement_USER_TYPE == null) {
-            rs.mElement_USER_TYPE = createUser(rs, DataType.RS_TYPE);
+    public static Element TYPE(RenderScript rs) {
+        if(rs.mElement_TYPE == null) {
+            rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
         }
-        return rs.mElement_USER_TYPE;
+        return rs.mElement_TYPE;
     }
 
-    public static Element USER_ALLOCATION(RenderScript rs) {
-        if(rs.mElement_USER_ALLOCATION == null) {
-            rs.mElement_USER_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
+    public static Element ALLOCATION(RenderScript rs) {
+        if(rs.mElement_ALLOCATION == null) {
+            rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
         }
-        return rs.mElement_USER_ALLOCATION;
+        return rs.mElement_ALLOCATION;
     }
 
-    public static Element USER_SAMPLER(RenderScript rs) {
-        if(rs.mElement_USER_SAMPLER == null) {
-            rs.mElement_USER_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
+    public static Element SAMPLER(RenderScript rs) {
+        if(rs.mElement_SAMPLER == null) {
+            rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
         }
-        return rs.mElement_USER_SAMPLER;
+        return rs.mElement_SAMPLER;
     }
 
-    public static Element USER_SCRIPT(RenderScript rs) {
-        if(rs.mElement_USER_SCRIPT == null) {
-            rs.mElement_USER_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
+    public static Element SCRIPT(RenderScript rs) {
+        if(rs.mElement_SCRIPT == null) {
+            rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
         }
-        return rs.mElement_USER_SCRIPT;
+        return rs.mElement_SCRIPT;
     }
 
-    public static Element USER_MESH(RenderScript rs) {
-        if(rs.mElement_USER_MESH == null) {
-            rs.mElement_USER_MESH = createUser(rs, DataType.RS_MESH);
+    public static Element MESH(RenderScript rs) {
+        if(rs.mElement_MESH == null) {
+            rs.mElement_MESH = createUser(rs, DataType.RS_MESH);
         }
-        return rs.mElement_USER_MESH;
+        return rs.mElement_MESH;
     }
 
-    public static Element USER_PROGRAM_FRAGMENT(RenderScript rs) {
-        if(rs.mElement_USER_PROGRAM_FRAGMENT == null) {
-            rs.mElement_USER_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT);
+    public static Element PROGRAM_FRAGMENT(RenderScript rs) {
+        if(rs.mElement_PROGRAM_FRAGMENT == null) {
+            rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT);
         }
-        return rs.mElement_USER_PROGRAM_FRAGMENT;
+        return rs.mElement_PROGRAM_FRAGMENT;
     }
 
-    public static Element USER_PROGRAM_VERTEX(RenderScript rs) {
-        if(rs.mElement_USER_PROGRAM_VERTEX == null) {
-            rs.mElement_USER_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX);
+    public static Element PROGRAM_VERTEX(RenderScript rs) {
+        if(rs.mElement_PROGRAM_VERTEX == null) {
+            rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX);
         }
-        return rs.mElement_USER_PROGRAM_VERTEX;
+        return rs.mElement_PROGRAM_VERTEX;
     }
 
-    public static Element USER_PROGRAM_RASTER(RenderScript rs) {
-        if(rs.mElement_USER_PROGRAM_RASTER == null) {
-            rs.mElement_USER_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER);
+    public static Element PROGRAM_RASTER(RenderScript rs) {
+        if(rs.mElement_PROGRAM_RASTER == null) {
+            rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER);
         }
-        return rs.mElement_USER_PROGRAM_RASTER;
+        return rs.mElement_PROGRAM_RASTER;
     }
 
-    public static Element USER_PROGRAM_STORE(RenderScript rs) {
-        if(rs.mElement_USER_PROGRAM_STORE == null) {
-            rs.mElement_USER_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE);
+    public static Element PROGRAM_STORE(RenderScript rs) {
+        if(rs.mElement_PROGRAM_STORE == null) {
+            rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE);
         }
-        return rs.mElement_USER_PROGRAM_STORE;
+        return rs.mElement_PROGRAM_STORE;
     }
 
 
@@ -246,47 +246,34 @@
         return rs.mElement_INDEX_16;
     }
 
-    public static Element ATTRIB_POSITION_2(RenderScript rs) {
-        if(rs.mElement_POSITION_2 == null) {
-            rs.mElement_POSITION_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 2);
+    public static Element F32_2(RenderScript rs) {
+        if(rs.mElement_FLOAT_2 == null) {
+            rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
         }
-        return rs.mElement_POSITION_2;
+        return rs.mElement_FLOAT_2;
     }
 
-    public static Element ATTRIB_POSITION_3(RenderScript rs) {
-        if(rs.mElement_POSITION_3 == null) {
-            rs.mElement_POSITION_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 3);
+    public static Element F32_3(RenderScript rs) {
+        if(rs.mElement_FLOAT_3 == null) {
+            rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
         }
-        return rs.mElement_POSITION_3;
+        return rs.mElement_FLOAT_3;
     }
 
-    public static Element ATTRIB_TEXTURE_2(RenderScript rs) {
-        if(rs.mElement_TEXTURE_2 == null) {
-            rs.mElement_TEXTURE_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.TEXTURE, 2);
+    public static Element F32_4(RenderScript rs) {
+        if(rs.mElement_FLOAT_4 == null) {
+            rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
         }
-        return rs.mElement_TEXTURE_2;
+        return rs.mElement_FLOAT_4;
     }
 
-    public static Element ATTRIB_NORMAL_3(RenderScript rs) {
-        if(rs.mElement_NORMAL_3 == null) {
-            rs.mElement_NORMAL_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.NORMAL, 3);
+    public static Element U8_4(RenderScript rs) {
+        if(rs.mElement_UCHAR_4 == null) {
+            rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
         }
-        return rs.mElement_NORMAL_3;
+        return rs.mElement_UCHAR_4;
     }
 
-    public static Element ATTRIB_COLOR_U8_4(RenderScript rs) {
-        if(rs.mElement_COLOR_U8_4 == null) {
-            rs.mElement_COLOR_U8_4 = createAttrib(rs, DataType.UNSIGNED_8, DataKind.COLOR, 4);
-        }
-        return rs.mElement_COLOR_U8_4;
-    }
-
-    public static Element ATTRIB_COLOR_F32_4(RenderScript rs) {
-        if(rs.mElement_COLOR_F32_4 == null) {
-            rs.mElement_COLOR_F32_4 = createAttrib(rs, DataType.FLOAT_32, DataKind.COLOR, 4);
-        }
-        return rs.mElement_COLOR_F32_4;
-    }
 
     Element(RenderScript rs, Element[] e, String[] n) {
         super(rs);
@@ -331,55 +318,6 @@
         return new Element(rs, DataType.UNSIGNED_16, DataKind.INDEX, false, 1);
     }
 
-    public static Element createAttrib(RenderScript rs, DataType dt, DataKind dk, int size) {
-        if (!(dt == DataType.FLOAT_32 ||
-              dt == DataType.UNSIGNED_8 ||
-              dt == DataType.UNSIGNED_16 ||
-              dt == DataType.UNSIGNED_32 ||
-              dt == DataType.SIGNED_8 ||
-              dt == DataType.SIGNED_16 ||
-              dt == DataType.SIGNED_32)) {
-            throw new IllegalArgumentException("Unsupported DataType");
-        }
-
-        if (!(dk == DataKind.COLOR ||
-              dk == DataKind.POSITION ||
-              dk == DataKind.TEXTURE ||
-              dk == DataKind.NORMAL ||
-              dk == DataKind.POINT_SIZE ||
-              dk == DataKind.USER)) {
-            throw new IllegalArgumentException("Unsupported DataKind");
-        }
-
-        if (dk == DataKind.COLOR &&
-            ((dt != DataType.FLOAT_32 && dt != DataType.UNSIGNED_8) ||
-             size < 3 || size > 4)) {
-            throw new IllegalArgumentException("Bad combo");
-        }
-        if (dk == DataKind.POSITION && (size < 1 || size > 4)) {
-            throw new IllegalArgumentException("Bad combo");
-        }
-        if (dk == DataKind.TEXTURE &&
-            (dt != DataType.FLOAT_32 || size < 1 || size > 4)) {
-            throw new IllegalArgumentException("Bad combo");
-        }
-        if (dk == DataKind.NORMAL &&
-            (dt != DataType.FLOAT_32 || size != 3)) {
-            throw new IllegalArgumentException("Bad combo");
-        }
-        if (dk == DataKind.POINT_SIZE &&
-            (dt != DataType.FLOAT_32 || size != 1)) {
-            throw new IllegalArgumentException("Bad combo");
-        }
-
-        boolean norm = false;
-        if (dk == DataKind.COLOR && dt == DataType.UNSIGNED_8) {
-            norm = true;
-        }
-
-        return new Element(rs, dt, dk, norm, size);
-    }
-
     public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
         if (!(dk == DataKind.PIXEL_L ||
               dk == DataKind.PIXEL_A ||
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index acc58bc..eda849e 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -192,24 +192,24 @@
     @SuppressWarnings({"FieldCanBeLocal"})
     protected MessageThread mMessageThread;
 
-    Element mElement_USER_U8;
-    Element mElement_USER_I8;
-    Element mElement_USER_U16;
-    Element mElement_USER_I16;
-    Element mElement_USER_U32;
-    Element mElement_USER_I32;
-    Element mElement_USER_F32;
+    Element mElement_U8;
+    Element mElement_I8;
+    Element mElement_U16;
+    Element mElement_I16;
+    Element mElement_U32;
+    Element mElement_I32;
+    Element mElement_F32;
 
-    Element mElement_USER_ELEMENT;
-    Element mElement_USER_TYPE;
-    Element mElement_USER_ALLOCATION;
-    Element mElement_USER_SAMPLER;
-    Element mElement_USER_SCRIPT;
-    Element mElement_USER_MESH;
-    Element mElement_USER_PROGRAM_FRAGMENT;
-    Element mElement_USER_PROGRAM_VERTEX;
-    Element mElement_USER_PROGRAM_RASTER;
-    Element mElement_USER_PROGRAM_STORE;
+    Element mElement_ELEMENT;
+    Element mElement_TYPE;
+    Element mElement_ALLOCATION;
+    Element mElement_SAMPLER;
+    Element mElement_SCRIPT;
+    Element mElement_MESH;
+    Element mElement_PROGRAM_FRAGMENT;
+    Element mElement_PROGRAM_VERTEX;
+    Element mElement_PROGRAM_RASTER;
+    Element mElement_PROGRAM_STORE;
 
     Element mElement_A_8;
     Element mElement_RGB_565;
@@ -219,12 +219,10 @@
     Element mElement_RGBA_8888;
 
     Element mElement_INDEX_16;
-    Element mElement_POSITION_2;
-    Element mElement_POSITION_3;
-    Element mElement_TEXTURE_2;
-    Element mElement_NORMAL_3;
-    Element mElement_COLOR_U8_4;
-    Element mElement_COLOR_F32_4;
+    Element mElement_FLOAT_2;
+    Element mElement_FLOAT_3;
+    Element mElement_FLOAT_4;
+    Element mElement_UCHAR_4;
 
     Sampler mSampler_CLAMP_NEAREST;
     Sampler mSampler_CLAMP_LINEAR;
diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java
index 4a217a9..fc011b5 100644
--- a/graphics/java/android/renderscript/SimpleMesh.java
+++ b/graphics/java/android/renderscript/SimpleMesh.java
@@ -313,30 +313,20 @@
         public SimpleMesh create() {
             Element.Builder b = new Element.Builder(mRS);
             int floatCount = mVtxSize;
-            b.add(Element.createAttrib(mRS,
+            b.add(Element.createVector(mRS,
                                        Element.DataType.FLOAT_32,
-                                       Element.DataKind.POSITION,
                                        mVtxSize), "position");
             if ((mFlags & COLOR) != 0) {
                 floatCount += 4;
-                b.add(Element.createAttrib(mRS,
-                                           Element.DataType.FLOAT_32,
-                                           Element.DataKind.COLOR,
-                                           4), "color");
+                b.add(Element.F32_4(mRS), "color");
             }
             if ((mFlags & TEXTURE_0) != 0) {
                 floatCount += 2;
-                b.add(Element.createAttrib(mRS,
-                                           Element.DataType.FLOAT_32,
-                                           Element.DataKind.TEXTURE,
-                                           2), "texture");
+                b.add(Element.F32_2(mRS), "texture0");
             }
             if ((mFlags & NORMAL) != 0) {
                 floatCount += 3;
-                b.add(Element.createAttrib(mRS,
-                                           Element.DataType.FLOAT_32,
-                                           Element.DataKind.NORMAL,
-                                           3), "normal");
+                b.add(Element.F32_3(mRS), "normal");
             }
             mElement = b.create();
 
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index b859e78..dcce25e 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -136,9 +136,7 @@
 public:
     SharedClient();
     ~SharedClient();
-
     status_t validate(size_t token) const;
-    uint32_t getIdentity(size_t token) const;
 
 private:
     friend class SharedBufferBase;
@@ -160,6 +158,7 @@
             int32_t identity);
     ~SharedBufferBase();
     status_t getStatus() const;
+    int32_t getIdentity() const;
     size_t getFrontBuffer() const;
     String8 dump(char const* prefix) const;
 
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index 18e7950..ddbe03d 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -53,10 +53,24 @@
 public: 
     DECLARE_META_INTERFACE(Surface);
 
+    /*
+     * requests a new buffer for the given index. If w, h, or format are
+     * null the buffer is created with the parameters assigned to the
+     * surface it is bound to. Otherwise the buffer's parameters are
+     * set to those specified.
+     */
     virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
             uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
+
+    /*
+     * sets the number of buffers dequeuable for this surface.
+     */
     virtual status_t setBufferCount(int bufferCount) = 0;
     
+    // ------------------------------------------------------------------------
+    // Deprecated...
+    // ------------------------------------------------------------------------
+
     class BufferHeap {
     public:
         enum {
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index d1e7785..3271cfd 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -27,7 +27,7 @@
 
 #include <ui/PixelFormat.h>
 
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -86,7 +86,7 @@
      * ACCESS_SURFACE_FLINGER permission
      */
 
-    virtual sp<ISurfaceFlingerClient> createConnection() = 0;
+    virtual sp<ISurfaceComposerClient> createConnection() = 0;
 
     /* retrieve the control block */
     virtual sp<IMemoryHeap> getCblk() const = 0;
diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
similarity index 86%
rename from include/surfaceflinger/ISurfaceFlingerClient.h
rename to include/surfaceflinger/ISurfaceComposerClient.h
index c96432f..b2a4766 100644
--- a/include/surfaceflinger/ISurfaceFlingerClient.h
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
-#define ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
+#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -26,7 +26,7 @@
 #include <binder/IInterface.h>
 
 #include <ui/PixelFormat.h>
-  
+
 #include <surfaceflinger/ISurface.h>
 
 namespace android {
@@ -42,10 +42,10 @@
 
 class layer_state_t;
 
-class ISurfaceFlingerClient : public IInterface
+class ISurfaceComposerClient : public IInterface
 {
-public: 
-    DECLARE_META_INTERFACE(SurfaceFlingerClient);
+public:
+    DECLARE_META_INTERFACE(SurfaceComposerClient);
 
     struct surface_data_t {
         int32_t             token;
@@ -56,21 +56,21 @@
         status_t readFromParcel(const Parcel& parcel);
         status_t writeToParcel(Parcel* parcel) const;
     };
-    
+
     virtual sp<IMemoryHeap> getControlBlock() const = 0;
 
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
      */
     virtual sp<ISurface> createSurface( surface_data_t* data,
-                                        int pid, 
+                                        int pid,
                                         const String8& name,
                                         DisplayID display,
                                         uint32_t w,
                                         uint32_t h,
                                         PixelFormat format,
                                         uint32_t flags) = 0;
-                                    
+
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
      */
@@ -84,7 +84,7 @@
 
 // ----------------------------------------------------------------------------
 
-class BnSurfaceFlingerClient : public BnInterface<ISurfaceFlingerClient>
+class BnSurfaceComposerClient : public BnInterface<ISurfaceComposerClient>
 {
 public:
     virtual status_t    onTransact( uint32_t code,
@@ -97,4 +97,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
+#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 33269cb..2957970 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -28,7 +28,7 @@
 #include <ui/egl/android_natives.h>
 
 #include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 
 #define ANDROID_VIEW_SURFACE_JNI_ID    "mNativeSurface"
 
@@ -108,7 +108,7 @@
     SurfaceControl(
             const sp<SurfaceComposerClient>& client,
             const sp<ISurface>& surface,
-            const ISurfaceFlingerClient::surface_data_t& data,
+            const ISurfaceComposerClient::surface_data_t& data,
             uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
 
     ~SurfaceControl();
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index 102aebc..8e28a81 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -149,7 +149,7 @@
                 // these don't need to be protected because they never change
                 // after assignment
                 status_t                    mStatus;
-                sp<ISurfaceFlingerClient>   mClient;
+                sp<ISurfaceComposerClient>  mClient;
 };
 
 // ---------------------------------------------------------------------------
@@ -161,7 +161,7 @@
     SharedClient*               mControl;
     sp<IMemoryHeap>             mControlMemory;
     sp<IBinder>                 mConnection;
-    sp<ISurfaceComposer>        mSignalServer;
+    sp<ISurfaceComposer>        mComposerService;
     void init(const sp<IBinder>& conn);
 public:
     explicit SurfaceClient(const sp<IBinder>& conn);
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index bc7626a8..3b975b4 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -54,11 +54,13 @@
  * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
  * and avoid to have a copy of them in each compilation units Singleton<TYPE>
  * is used.
+ * NOTE: we use a version of Mutex ctor that takes a parameter, because
+ * for some unknown reason using the default ctor doesn't emit the variable!
  */
 
-#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)             \
-    template class Singleton< TYPE >;                       \
-    template< class TYPE > Mutex Singleton< TYPE >::sLock;  \
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)                 \
+    template class Singleton< TYPE >;                           \
+    template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE);  \
     template<> TYPE* Singleton< TYPE >::sInstance(0);
 
 
diff --git a/libs/rs/java/Fountain/res/raw/fountain.rs b/libs/rs/java/Fountain/res/raw/fountain.rs
index 67f7ef5..fe2ca33 100644
--- a/libs/rs/java/Fountain/res/raw/fountain.rs
+++ b/libs/rs/java/Fountain/res/raw/fountain.rs
@@ -40,6 +40,18 @@
     return 1;
 }
 
+// Putting the overloadable attribute on this function breaks rendering
+// appears to be a bug.
+static uchar4 /*__attribute__((overloadable))*/ pack(float r, float g, float b)
+{
+    uchar4 c;
+    c.x = (uchar)(r * 255.f);
+    c.y = (uchar)(g * 255.f);
+    c.z = (uchar)(b * 255.f);
+    c.w = 255;
+    return c;
+}
+
 void addParticles(int rate, int x, int y)
 {
     //rsDebug("partColor", partColor);
@@ -51,7 +63,10 @@
     float rMax = ((float)rate) * 0.005f;
     int size = rsAllocationGetDimX(rsGetAllocation(point));
 
-    uchar4 c = rsPackColorTo8888(partColor.x, partColor.y, partColor.z);
+    //uchar4 c = rsPackColorTo8888(partColor.x, partColor.y, partColor.z);
+    uchar4 c = pack(partColor.x, partColor.y, partColor.z);
+    c.x = 255;
+    c.w = 255;
 
     //rsDebug("color ", ((int *)&c)[0]);
     Point_t * np = &point[newPart];
diff --git a/libs/rs/java/Fountain/res/raw/fountain_bc.bc b/libs/rs/java/Fountain/res/raw/fountain_bc.bc
index 7b2e88b..d223460 100644
--- a/libs/rs/java/Fountain/res/raw/fountain_bc.bc
+++ b/libs/rs/java/Fountain/res/raw/fountain_bc.bc
Binary files differ
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/ScriptField_Point.java b/libs/rs/java/Fountain/src/com/android/fountain/ScriptField_Point.java
index b091f39..91db2c6 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/ScriptField_Point.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/ScriptField_Point.java
@@ -30,9 +30,9 @@
         mItemArray = new Item[count];
 
         Element.Builder eb = new Element.Builder(rs);
-        eb.add(Element.createVector(rs, Element.DataType.FLOAT_32, 2), "delta");
-        eb.add(Element.createAttrib(rs, Element.DataType.FLOAT_32, Element.DataKind.POSITION, 2), "position");
-        eb.add(Element.createAttrib(rs, Element.DataType.UNSIGNED_8, Element.DataKind.COLOR, 4), "color");
+        eb.add(Element.F32_2(rs), "delta");
+        eb.add(Element.F32_2(rs), "position");
+        eb.add(Element.U8_4(rs), "color");
         mElement = eb.create();
 
         init(rs, count);
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index d4c29c8..d667c86 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -178,11 +178,11 @@
         }
         mShader.append(mUserShader);
     } else {
-        mShader.append("attribute vec4 ATTRIB_LegacyPosition;\n");
-        mShader.append("attribute vec4 ATTRIB_LegacyColor;\n");
-        mShader.append("attribute vec3 ATTRIB_LegacyNormal;\n");
-        mShader.append("attribute float ATTRIB_LegacyPointSize;\n");
-        mShader.append("attribute vec4 ATTRIB_LegacyTexture;\n");
+        mShader.append("attribute vec4 ATTRIB_position;\n");
+        mShader.append("attribute vec4 ATTRIB_color;\n");
+        mShader.append("attribute vec3 ATTRIB_normal;\n");
+        mShader.append("attribute float ATTRIB_pointSize;\n");
+        mShader.append("attribute vec4 ATTRIB_texture0;\n");
 
         for (uint32_t ct=0; ct < mUniformCount; ct++) {
             mShader.append("uniform mat4 ");
@@ -191,14 +191,14 @@
         }
 
         mShader.append("void main() {\n");
-        mShader.append("  gl_Position = UNI_MVP * ATTRIB_LegacyPosition;\n");
-        mShader.append("  gl_PointSize = ATTRIB_LegacyPointSize;\n");
+        mShader.append("  gl_Position = UNI_MVP * ATTRIB_position;\n");
+        mShader.append("  gl_PointSize = ATTRIB_pointSize;\n");
 
-        mShader.append("  varColor = ATTRIB_LegacyColor;\n");
+        mShader.append("  varColor = ATTRIB_color;\n");
         if (mTextureMatrixEnable) {
-            mShader.append("  varTex0 = UNI_TexMatrix * ATTRIB_LegacyTexture;\n");
+            mShader.append("  varTex0 = UNI_TexMatrix * ATTRIB_texture0;\n");
         } else {
-            mShader.append("  varTex0 = ATTRIB_LegacyTexture;\n");
+            mShader.append("  varTex0 = ATTRIB_texture0;\n");
         }
         //mShader.append("  pos.x = pos.x / 480.0;\n");
         //mShader.append("  pos.y = pos.y / 800.0;\n");
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 18f873e..8f650f8 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -131,12 +131,8 @@
 
     float vtx[] = { x1, y1, z1, x2, y2, z2 };
     VertexArray va;
-    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
-    if (rsc->checkVersion2_0()) {
-        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-    } else {
-        va.setupGL(rsc, &rsc->mStateVertexArray);
-    }
+    va.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
+    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
 
     glDrawArrays(GL_LINES, 0, 2);
 }
@@ -151,12 +147,8 @@
     float vtx[] = { x, y, z };
 
     VertexArray va;
-    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
-    if (rsc->checkVersion2_0()) {
-        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-    } else {
-        va.setupGL(rsc, &rsc->mStateVertexArray);
-    }
+    va.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
+    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
 
     glDrawArrays(GL_POINTS, 0, 1);
 }
@@ -185,14 +177,9 @@
     const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
 
     VertexArray va;
-    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
-    va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex);
-    if (rsc->checkVersion2_0()) {
-        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-    } else {
-        va.setupGL(rsc, &rsc->mStateVertexArray);
-    }
-
+    va.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
+    va.add(GL_FLOAT, 2, 8, false, (uint32_t)tex, "texture0");
+    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 }
diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp
index 0218dc5..504ffba 100644
--- a/libs/rs/rsShaderCache.cpp
+++ b/libs/rs/rsShaderCache.cpp
@@ -98,16 +98,11 @@
         glAttachShader(pgm, frag->getShaderID());
 
         if (!vtx->isUserProgram()) {
-            glBindAttribLocation(pgm, 0, "ATTRIB_LegacyPosition");
-            glBindAttribLocation(pgm, 1, "ATTRIB_LegacyColor");
-            glBindAttribLocation(pgm, 2, "ATTRIB_LegacyNormal");
-            glBindAttribLocation(pgm, 3, "ATTRIB_LegacyPointSize");
-            glBindAttribLocation(pgm, 4, "ATTRIB_LegacyTexture");
-            e->mVtxAttribSlots[RS_KIND_POSITION] = 0;
-            e->mVtxAttribSlots[RS_KIND_COLOR] = 1;
-            e->mVtxAttribSlots[RS_KIND_NORMAL] = 2;
-            e->mVtxAttribSlots[RS_KIND_POINT_SIZE] = 3;
-            e->mVtxAttribSlots[RS_KIND_TEXTURE] = 4;
+            glBindAttribLocation(pgm, 0, "ATTRIB_position");
+            glBindAttribLocation(pgm, 1, "ATTRIB_color");
+            glBindAttribLocation(pgm, 2, "ATTRIB_normal");
+            glBindAttribLocation(pgm, 3, "ATTRIB_pointSize");
+            glBindAttribLocation(pgm, 4, "ATTRIB_texture0");
         }
 
         //LOGE("e2 %x", glGetError());
diff --git a/libs/rs/rsSimpleMesh.cpp b/libs/rs/rsSimpleMesh.cpp
index 170b792..2dd082d 100644
--- a/libs/rs/rsSimpleMesh.cpp
+++ b/libs/rs/rsSimpleMesh.cpp
@@ -68,21 +68,12 @@
 
     rsc->checkError("SimpleMesh::renderRange 1");
     VertexArray va;
-    if (rsc->checkVersion2_0()) {
-        for (uint32_t ct=0; ct < mVertexTypeCount; ct++) {
-            mVertexBuffers[ct]->uploadCheck(rsc);
-            va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID());
-            mVertexTypes[ct]->enableGLVertexBuffer2(&va);
-        }
-        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
-    } else {
-        for (uint32_t ct=0; ct < mVertexTypeCount; ct++) {
-            mVertexBuffers[ct]->uploadCheck(rsc);
-            va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID());
-            mVertexTypes[ct]->enableGLVertexBuffer(&va);
-        }
-        va.setupGL(rsc, 0);
+    for (uint32_t ct=0; ct < mVertexTypeCount; ct++) {
+        mVertexBuffers[ct]->uploadCheck(rsc);
+        va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID());
+        mVertexTypes[ct]->enableGLVertexBuffer(&va);
     }
+    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
 
     rsc->checkError("SimpleMesh::renderRange 2");
     if (mIndexType.get()) {
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 8f99209..89e73b0 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -148,131 +148,22 @@
     for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
         const Component &c = getElement()->getField(ct)->getComponent();
 
-        switch(c.getKind()) {
-        case RS_KIND_USER:
-            mGL.mUser[userNum].size = c.getVectorSize();
-            mGL.mUser[userNum].offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mUser[userNum].type = c.getGLType();
-            mGL.mUser[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
-            mGL.mUser[userNum].name.setTo(getElement()->getFieldName(ct));
-            userNum ++;
-            break;
-
-        case RS_KIND_POSITION:
-            rsAssert(mGL.mVtx.size == 0);
-            mGL.mVtx.size = c.getVectorSize();
-            mGL.mVtx.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mVtx.type = c.getGLType();
-            mGL.mVtx.normalized = false;
-            mGL.mVtx.name.setTo("Position");
-            break;
-
-        case RS_KIND_COLOR:
-            rsAssert(mGL.mColor.size == 0);
-            mGL.mColor.size = c.getVectorSize();
-            mGL.mColor.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mColor.type = c.getGLType();
-            mGL.mColor.normalized = c.getType() != RS_TYPE_FLOAT_32;
-            mGL.mColor.name.setTo("Color");
-            break;
-
-        case RS_KIND_NORMAL:
-            rsAssert(mGL.mNorm.size == 0);
-            mGL.mNorm.size = c.getVectorSize();
-            mGL.mNorm.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mNorm.type = c.getGLType();
-            mGL.mNorm.normalized = false;
-            mGL.mNorm.name.setTo("Normal");
-            break;
-
-        case RS_KIND_TEXTURE:
-            rsAssert(mGL.mTex.size == 0);
-            mGL.mTex.size = c.getVectorSize();
-            mGL.mTex.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mTex.type = c.getGLType();
-            mGL.mTex.normalized = false;
-            mGL.mTex.name.setTo("Texture");
-            break;
-
-        case RS_KIND_POINT_SIZE:
-            rsAssert(!mGL.mPointSize.size);
-            mGL.mPointSize.size = c.getVectorSize();
-            mGL.mPointSize.offset = mElement->getFieldOffsetBytes(ct);
-            mGL.mPointSize.type = c.getGLType();
-            mGL.mPointSize.normalized = false;
-            mGL.mPointSize.name.setTo("PointSize");
-        break;
-
-        default:
-            break;
-        }
+        mAttribs[userNum].size = c.getVectorSize();
+        mAttribs[userNum].offset = mElement->getFieldOffsetBytes(ct);
+        mAttribs[userNum].type = c.getGLType();
+        mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
+        mAttribs[userNum].name.setTo(getElement()->getFieldName(ct));
+        userNum ++;
     }
 }
 
+
 void Type::enableGLVertexBuffer(VertexArray *va) const
 {
-    // Note: We are only going to enable buffers and never disable them
-    // here.  The reason is more than one Allocation may be used as a vertex
-    // source.  So we cannot disable arrays that may have been in use by
-    // another allocation.
-
-    uint32_t stride = mElement->getSizeBytes();
-    if (mGL.mVtx.size) {
-        va->addLegacy(mGL.mVtx.type,
-                      mGL.mVtx.size,
-                      stride,
-                      RS_KIND_POSITION,
-                      false,
-                      mGL.mVtx.offset);
-    }
-
-    if (mGL.mNorm.size) {
-        va->addLegacy(mGL.mNorm.type,
-                     3,
-                     stride,
-                     RS_KIND_NORMAL,
-                     false,
-                     mGL.mNorm.offset);
-    }
-
-    if (mGL.mColor.size) {
-        va->addLegacy(mGL.mColor.type,
-                     mGL.mColor.size,
-                     stride,
-                     RS_KIND_COLOR,
-                     true,
-                     mGL.mColor.offset);
-    }
-
-    if (mGL.mTex.size) {
-        va->addLegacy(mGL.mTex.type,
-                     mGL.mTex.size,
-                     stride,
-                     RS_KIND_TEXTURE,
-                     false,
-                     mGL.mTex.offset);
-    }
-
-    if (mGL.mPointSize.size) {
-        va->addLegacy(mGL.mPointSize.type,
-                     1,
-                     stride,
-                     RS_KIND_POINT_SIZE,
-                     false,
-                     mGL.mPointSize.offset);
-    }
-
-}
-
-void Type::enableGLVertexBuffer2(VertexArray *va) const
-{
-    // Do legacy buffers
-    enableGLVertexBuffer(va);
-
     uint32_t stride = mElement->getSizeBytes();
     for (uint32_t ct=0; ct < RS_MAX_ATTRIBS; ct++) {
-        if (mGL.mUser[ct].size) {
-            va->addUser(mGL.mUser[ct], stride);
+        if (mAttribs[ct].size) {
+            va->add(mAttribs[ct], stride);
         }
     }
 }
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 664f343..f598f64 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -71,7 +71,6 @@
     void compute();
 
     void enableGLVertexBuffer(class VertexArray *) const;
-    void enableGLVertexBuffer2(class VertexArray *) const;
 
     void dumpLOGV(const char *prefix) const;
     virtual void serialize(OStream *stream) const;
@@ -115,15 +114,7 @@
     LOD *mLODs;
     uint32_t mLODCount;
 
-    struct GLState_t {
-        VertexArray::Attrib mUser[RS_MAX_ATTRIBS];
-        VertexArray::Attrib mVtx;
-        VertexArray::Attrib mNorm;
-        VertexArray::Attrib mColor;
-        VertexArray::Attrib mTex;
-        VertexArray::Attrib mPointSize;
-    };
-    GLState_t mGL;
+    VertexArray::Attrib mAttribs[RS_MAX_ATTRIBS];
     void makeGLComponents();
 
 private:
diff --git a/libs/rs/rsVertexArray.cpp b/libs/rs/rsVertexArray.cpp
index b42d1c4..425b584 100644
--- a/libs/rs/rsVertexArray.cpp
+++ b/libs/rs/rsVertexArray.cpp
@@ -60,7 +60,6 @@
     size = a.size;
     stride = a.stride;
     normalized = a.normalized;
-    kind = RS_KIND_USER;
     name.setTo(a.name);
 }
 
@@ -80,17 +79,16 @@
     mAttribs[n].clear();
 }
 
-void VertexArray::addUser(const Attrib &a, uint32_t stride)
+void VertexArray::add(const Attrib &a, uint32_t stride)
 {
     rsAssert(mCount < RS_MAX_ATTRIBS);
     mAttribs[mCount].set(a);
     mAttribs[mCount].buffer = mActiveBuffer;
     mAttribs[mCount].stride = stride;
-    mAttribs[mCount].kind = RS_KIND_USER;
     mCount ++;
 }
 
-void VertexArray::addLegacy(uint32_t type, uint32_t size, uint32_t stride, RsDataKind kind, bool normalized, uint32_t offset)
+void VertexArray::add(uint32_t type, uint32_t size, uint32_t stride, bool normalized, uint32_t offset, const char *name)
 {
     rsAssert(mCount < RS_MAX_ATTRIBS);
     mAttribs[mCount].clear();
@@ -100,96 +98,25 @@
     mAttribs[mCount].normalized = normalized;
     mAttribs[mCount].buffer = mActiveBuffer;
     mAttribs[mCount].stride = stride;
-    mAttribs[mCount].kind = kind;
+    mAttribs[mCount].name.setTo(name);
     mCount ++;
 }
 
 void VertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
-    LOGE("va %i: slot=%i name=%s buf=%i  size=%i  type=0x%x  kind=%i  stride=0x%x  norm=%i  offset=0x%x", idx, slot,
+    LOGE("va %i: slot=%i name=%s buf=%i  size=%i  type=0x%x  stride=0x%x  norm=%i  offset=0x%x", idx, slot,
          mAttribs[idx].name.string(),
          mAttribs[idx].buffer,
          mAttribs[idx].size,
          mAttribs[idx].type,
-         mAttribs[idx].kind,
          mAttribs[idx].stride,
          mAttribs[idx].normalized,
          mAttribs[idx].offset);
 }
 
-void VertexArray::setupGL(const Context *rsc, class VertexArrayState *state) const
-{
-    glClientActiveTexture(GL_TEXTURE0);
-    glDisableClientState(GL_NORMAL_ARRAY);
-    glDisableClientState(GL_COLOR_ARRAY);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-#ifndef ANDROID_RS_BUILD_FOR_HOST // GLES only
-    glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
-    for (uint32_t ct=0; ct < mCount; ct++) {
-        switch(mAttribs[ct].kind) {
-        case RS_KIND_POSITION:
-            //logAttrib(POSITION);
-            glEnableClientState(GL_VERTEX_ARRAY);
-            glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
-            glVertexPointer(mAttribs[ct].size,
-                            mAttribs[ct].type,
-                            mAttribs[ct].stride,
-                            (void *)mAttribs[ct].offset);
-            break;
-
-        case RS_KIND_NORMAL:
-            //logAttrib(NORMAL);
-            glEnableClientState(GL_NORMAL_ARRAY);
-            rsAssert(mAttribs[ct].size == 3);
-            glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
-            glNormalPointer(mAttribs[ct].type,
-                            mAttribs[ct].stride,
-                            (void *)mAttribs[ct].offset);
-            break;
-
-        case RS_KIND_COLOR:
-            //logAttrib(COLOR);
-            glEnableClientState(GL_COLOR_ARRAY);
-            glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
-            glColorPointer(mAttribs[ct].size,
-                           mAttribs[ct].type,
-                           mAttribs[ct].stride,
-                           (void *)mAttribs[ct].offset);
-            break;
-
-        case RS_KIND_TEXTURE:
-            //logAttrib(TEXTURE);
-            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-            glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
-            glTexCoordPointer(mAttribs[ct].size,
-                              mAttribs[ct].type,
-                              mAttribs[ct].stride,
-                              (void *)mAttribs[ct].offset);
-            break;
-#ifndef ANDROID_RS_BUILD_FOR_HOST // GLES only
-        case RS_KIND_POINT_SIZE:
-            //logAttrib(POINT_SIZE);
-            glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
-            glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
-            glPointSizePointerOES(mAttribs[ct].type,
-                                  mAttribs[ct].stride,
-                                  (void *)mAttribs[ct].offset);
-            break;
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
-        default:
-            rsAssert(0);
-        }
-    }
-
-    rsc->checkError("VertexArray::setupGL");
-}
-
 void VertexArray::setupGL2(const Context *rsc, class VertexArrayState *state, ShaderCache *sc) const
 {
     rsc->checkError("VertexArray::setupGL2 start");
-    for (uint32_t ct=1; ct <= state->mLastEnableCount; ct++) {
+    for (uint32_t ct=1; ct <= 0xf/*state->mLastEnableCount*/; ct++) {
         glDisableVertexAttribArray(ct);
     }
 
@@ -199,16 +126,24 @@
         if (sc->isUserVertexProgram()) {
             slot = sc->vtxAttribSlot(ct);
         } else {
-            if (mAttribs[ct].kind == RS_KIND_USER) {
+            if (mAttribs[ct].name == "position") {
+                slot = 0;
+            } else if (mAttribs[ct].name == "color") {
+                slot = 1;
+            } else if (mAttribs[ct].name == "normal") {
+                slot = 2;
+            } else if (mAttribs[ct].name == "pointSize") {
+                slot = 3;
+            } else if (mAttribs[ct].name == "texture0") {
+                slot = 4;
+            } else {
                 continue;
             }
-            slot = sc->vtxAttribSlot(mAttribs[ct].kind);
         }
 
-        //logAttrib(ct, slot);
+        logAttrib(ct, slot);
         glEnableVertexAttribArray(slot);
         glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
-
         glVertexAttribPointer(slot,
                               mAttribs[ct].size,
                               mAttribs[ct].type,
diff --git a/libs/rs/rsVertexArray.h b/libs/rs/rsVertexArray.h
index 3904cb6..e5b51d7 100644
--- a/libs/rs/rsVertexArray.h
+++ b/libs/rs/rsVertexArray.h
@@ -43,7 +43,6 @@
         uint32_t stride;
         bool normalized;
         String8 name;
-        RsDataKind kind;
 
         Attrib();
         void set(const Attrib &);
@@ -53,8 +52,9 @@
 
     void clearAll();
     void setActiveBuffer(uint32_t id) {mActiveBuffer = id;}
-    void addUser(const Attrib &, uint32_t stride);
-    void addLegacy(uint32_t type, uint32_t size, uint32_t stride, RsDataKind kind, bool normalized, uint32_t offset);
+    void add(const Attrib &, uint32_t stride);
+    //void addLegacy(uint32_t type, uint32_t size, uint32_t stride, bool normalized, uint32_t offset);
+    void add(uint32_t type, uint32_t size, uint32_t stride, bool normalized, uint32_t offset, const char *name);
 
     void setupGL(const Context *rsc, class VertexArrayState *) const;
     void setupGL2(const Context *rsc, class VertexArrayState *, ShaderCache *) const;
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
new file mode 100644
index 0000000..c0ba4af
--- /dev/null
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -0,0 +1,61 @@
+#ifndef __RS_CORE_RSH__
+#define __RS_CORE_RSH__
+
+//uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b);
+//uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a);
+
+static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b)
+{
+    uchar4 c;
+    c.x = (uchar)(r * 255.f);
+    c.y = (uchar)(g * 255.f);
+    c.z = (uchar)(b * 255.f);
+    c.w = 255;
+    return c;
+}
+
+static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a)
+{
+    uchar4 c;
+    c.x = (uchar)(r * 255.f);
+    c.y = (uchar)(g * 255.f);
+    c.z = (uchar)(b * 255.f);
+    c.w = (uchar)(a * 255.f);
+    return c;
+}
+
+
+/*
+static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color)
+{
+    color *= 255.f;
+    uchar4 c = {color.x, color.y, color.z, 255};
+    return c;
+}
+
+static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color)
+{
+    color *= 255.f;
+    uchar4 c = {color.x, color.y, color.z, color.w};
+    return c;
+}
+
+static float4 rsUnpackColor8888(uchar4 c)
+{
+    float4 ret = {
+        c.x * (1.f / 255.f),
+        c.y * (1.f / 255.f),
+        c.z * (1.f / 255.f),
+        c.w * (1.f / 255.f),
+    };
+    return ret;
+}
+
+extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float r, float g, float b);
+extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float3);
+extern float4 rsUnpackColor565(uchar4);
+*/
+
+
+#endif
+
diff --git a/libs/rs/scriptc/rs_math.rsh b/libs/rs/scriptc/rs_math.rsh
index 91c4303..a26491f 100644
--- a/libs/rs/scriptc/rs_math.rsh
+++ b/libs/rs/scriptc/rs_math.rsh
@@ -1,4 +1,6 @@
 #include "rs_cl.rsh"
+#include "rs_core.rsh"
+
 
 
 // Allocations
@@ -11,18 +13,6 @@
 
 
 
-// Color conversion
-extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b);
-extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a);
-extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3);
-extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4);
-extern float4 rsUnpackColor8888(uchar4);
-
-extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float r, float g, float b);
-extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float3);
-extern float4 rsUnpackColor565(uchar4);
-
-
 // Debugging
 extern void __attribute__((overloadable))rsDebug(const char *, float);
 extern void __attribute__((overloadable))rsDebug(const char *, float2);
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index 185bb83..2ac81e5 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -68,32 +68,6 @@
 typedef int int16 __attribute__((ext_vector_type(16)));
 
 
-// RS_KIND_POSITION
-typedef float rs_position1;
-typedef float2 rs_position2;
-typedef float3 rs_position3;
-typedef float4 rs_position4;
-
-// RS_KIND_COLOR
-typedef float3 rs_color3f;
-typedef float4 rs_color4f;
-typedef uchar4 rs_color4u;
-
-// RS_KIND_NORMAL
-typedef float3 rs_normal;
-
-// RS_KIND_POINT_SIZE
-typedef float rs_point_size;
-
-// RS_KIND_TEXTURE
-typedef float rs_texture_coord1;
-typedef float2 rs_texture_coord2;
-typedef float3 rs_texture_coord3;
-typedef float4 rs_texture_coord4;
-
-// RS_KIND_INDEX
-typedef ushort rs_index;
-
 typedef struct {
     float m[16];
 } rs_matrix4x4;
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 76733a9..7ab74b4 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -379,33 +379,21 @@
     
     glEnable(GL_TEXTURE_2D);
 
+    GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
     if (UNLIKELY(s.alpha < 0xFF)) {
-        // We have an alpha-modulation. We need to modulate all
-        // texture components by alpha because we're always using 
-        // premultiplied alpha.
-        
-        // If the texture doesn't have an alpha channel we can
-        // use REPLACE and switch to non premultiplied alpha
-        // blending (SRCA/ONE_MINUS_SRCA).
-        
-        GLenum env, src;
-        if (needsBlending()) {
-            env = GL_MODULATE;
-            src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
-        } else {
-            env = GL_REPLACE;
-            src = GL_SRC_ALPHA;
-        }
         const GLfloat alpha = s.alpha * (1.0f/255.0f);
-        glColor4f(alpha, alpha, alpha, alpha);
+        if (mPremultipliedAlpha) {
+            glColor4f(alpha, alpha, alpha, alpha);
+        } else {
+            glColor4f(1, 1, 1, alpha);
+        }
         glEnable(GL_BLEND);
         glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     } else {
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         glColor4f(1, 1, 1, 1);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         if (needsBlending()) {
-            GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
             glEnable(GL_BLEND);
             glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
         } else {
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index a78424e..2e2f2df 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -29,7 +29,7 @@
 #include <ui/Region.h>
 #include <ui/Overlay.h>
 
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 #include <private/surfaceflinger/SharedBufferStack.h>
 #include <private/surfaceflinger/LayerState.h>
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 5a6893f..fff0853 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -225,7 +225,7 @@
     return mServerHeap;
 }
 
-sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
+sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
 {
     Mutex::Autolock _l(mStateLock);
     uint32_t token = mTokens.acquire();
@@ -1230,7 +1230,7 @@
 }
 
 sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
-        const String8& name, ISurfaceFlingerClient::surface_data_t* params,
+        const String8& name, ISurfaceComposerClient::surface_data_t* params,
         DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
 {
@@ -1740,7 +1740,7 @@
 }
 
 sp<ISurface> BClient::createSurface(
-        ISurfaceFlingerClient::surface_data_t* params, int pid,
+        ISurfaceComposerClient::surface_data_t* params, int pid,
         const String8& name,
         DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 2558324..d8fe98c 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -32,7 +32,7 @@
 
 #include <ui/PixelFormat.h>
 #include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 
 #include "Barrier.h"
 #include "Layer.h"
@@ -158,7 +158,7 @@
     virtual status_t dump(int fd, const Vector<String16>& args);
 
     // ISurfaceComposer interface
-    virtual sp<ISurfaceFlingerClient>   createConnection();
+    virtual sp<ISurfaceComposerClient>  createConnection();
     virtual sp<IMemoryHeap>             getCblk() const;
     virtual void                        bootFinished();
     virtual void                        openGlobalTransaction();
@@ -189,7 +189,7 @@
     friend class LayerDim;
 
     sp<ISurface> createSurface(ClientID client, int pid, const String8& name,
-            ISurfaceFlingerClient::surface_data_t* params,
+            ISurfaceComposerClient::surface_data_t* params,
             DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
             uint32_t flags);
 
@@ -393,14 +393,14 @@
 
 // ---------------------------------------------------------------------------
 
-class BClient : public BnSurfaceFlingerClient
+class BClient : public BnSurfaceComposerClient
 {
 public:
     BClient(SurfaceFlinger *flinger, ClientID cid,
             const sp<IMemoryHeap>& cblk);
     ~BClient();
 
-    // ISurfaceFlingerClient interface
+    // ISurfaceComposerClient interface
     virtual sp<IMemoryHeap> getControlBlock() const;
 
     virtual sp<ISurface> createSurface(
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
index fe85b34..ce3c71a 100644
--- a/libs/surfaceflinger_client/Android.mk
+++ b/libs/surfaceflinger_client/Android.mk
@@ -4,7 +4,7 @@
 LOCAL_SRC_FILES:= \
 	ISurfaceComposer.cpp \
 	ISurface.cpp \
-	ISurfaceFlingerClient.cpp \
+	ISurfaceComposerClient.cpp \
 	LayerState.cpp \
 	SharedBufferStack.cpp \
 	Surface.cpp \
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index b6f4e24..50495c1 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -46,13 +46,13 @@
     {
     }
 
-    virtual sp<ISurfaceFlingerClient> createConnection()
+    virtual sp<ISurfaceComposerClient> createConnection()
     {
         uint32_t n;
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
-        return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
+        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
     }
 
     virtual sp<IMemoryHeap> getCblk() const
diff --git a/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
similarity index 83%
rename from libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
rename to libs/surfaceflinger_client/ISurfaceComposerClient.cpp
index def96d7..67c7df81 100644
--- a/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
@@ -30,7 +30,7 @@
 #include <ui/Rect.h>
 
 #include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 #include <private/surfaceflinger/LayerState.h>
 
 // ---------------------------------------------------------------------------
@@ -56,18 +56,18 @@
     SET_STATE
 };
 
-class BpSurfaceFlingerClient : public BpInterface<ISurfaceFlingerClient>
+class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
 {
 public:
-    BpSurfaceFlingerClient(const sp<IBinder>& impl)
-        : BpInterface<ISurfaceFlingerClient>(impl)
+    BpSurfaceComposerClient(const sp<IBinder>& impl)
+        : BpInterface<ISurfaceComposerClient>(impl)
     {
     }
 
     virtual sp<IMemoryHeap> getControlBlock() const
     {
         Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
         remote()->transact(GET_CBLK, data, &reply);
         return interface_cast<IMemoryHeap>(reply.readStrongBinder());
     }
@@ -82,7 +82,7 @@
                                         uint32_t flags)
     {
         Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
         data.writeInt32(pid);
         data.writeString8(name);
         data.writeInt32(display);
@@ -94,11 +94,11 @@
         params->readFromParcel(reply);
         return interface_cast<ISurface>(reply.readStrongBinder());
     }
-                                    
+
     virtual status_t destroySurface(SurfaceID sid)
     {
         Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
         data.writeInt32(sid);
         remote()->transact(DESTROY_SURFACE, data, &reply);
         return reply.readInt32();
@@ -107,7 +107,7 @@
     virtual status_t setState(int32_t count, const layer_state_t* states)
     {
         Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
         data.writeInt32(count);
         for (int i=0 ; i<count ; i++)
             states[i].write(data);
@@ -116,18 +116,18 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient");
+IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
 
 // ----------------------------------------------------------------------
 
-status_t BnSurfaceFlingerClient::onTransact(
+status_t BnSurfaceComposerClient::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
     // codes that don't require permission check
 
     switch(code) {
         case GET_CBLK: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
             sp<IMemoryHeap> ctl(getControlBlock());
             reply->writeStrongBinder(ctl->asBinder());
             return NO_ERROR;
@@ -135,7 +135,7 @@
     }
 
     // these must be checked
-     
+
      IPCThreadState* ipc = IPCThreadState::self();
      const int pid = ipc->getCallingPid();
      const int uid = ipc->getCallingUid();
@@ -150,10 +150,10 @@
              return PERMISSION_DENIED;
          }
      }
-   
+
      switch(code) {
         case CREATE_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
             surface_data_t params;
             int32_t pid = data.readInt32();
             String8 name = data.readString8();
@@ -169,12 +169,12 @@
             return NO_ERROR;
         } break;
         case DESTROY_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
             reply->writeInt32( destroySurface( data.readInt32() ) );
             return NO_ERROR;
         } break;
         case SET_STATE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
             int32_t count = data.readInt32();
             layer_state_t* states = new layer_state_t[count];
             for (int i=0 ; i<count ; i++)
@@ -191,7 +191,7 @@
 
 // ----------------------------------------------------------------------
 
-status_t ISurfaceFlingerClient::surface_data_t::readFromParcel(const Parcel& parcel)
+status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& parcel)
 {
     token    = parcel.readInt32();
     identity = parcel.readInt32();
@@ -201,7 +201,7 @@
     return NO_ERROR;
 }
 
-status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) const
+status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) const
 {
     parcel->writeInt32(token);
     parcel->writeInt32(identity);
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 2577dc0..8d03145 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -49,10 +49,6 @@
     return surfaces[i].status;
 }
 
-uint32_t SharedClient::getIdentity(size_t token) const {
-    return uint32_t(surfaces[token].identity);
-}
-
 // ----------------------------------------------------------------------------
 
 
@@ -161,6 +157,12 @@
     return stack.status;
 }
 
+int32_t SharedBufferBase::getIdentity() const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.identity;
+}
+
 size_t SharedBufferBase::getFrontBuffer() const
 {
     SharedBufferStack& stack( *mSharedStack );
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 35a4e8b..ac4b198 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -104,7 +104,7 @@
 SurfaceControl::SurfaceControl(
         const sp<SurfaceComposerClient>& client, 
         const sp<ISurface>& surface,
-        const ISurfaceFlingerClient::surface_data_t& data,
+        const ISurfaceComposerClient::surface_data_t& data,
         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
     : mClient(client), mSurface(surface),
       mToken(data.token), mIdentity(data.identity),
@@ -278,7 +278,6 @@
 //  Surface
 // ============================================================================
 
-
 Surface::Surface(const sp<SurfaceControl>& surface)
     : mSurface(surface->mSurface),
       mToken(surface->mToken), mIdentity(surface->mIdentity),
@@ -369,7 +368,7 @@
         LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
         return NO_INIT;
     }
-    return NO_ERROR;
+    return cblk->validate(mToken);
 }
 
 bool Surface::isValid() {
@@ -386,9 +385,7 @@
     }
 
     // verify the identity of this surface
-    SharedClient const* cblk = mClient->getSharedClient();
-
-    uint32_t identity = cblk->getIdentity(mToken);
+    uint32_t identity = mSharedBufferClient->getIdentity();
 
     // this is a bit of a (temporary) special case, identity==0 means that
     // no operation are allowed from the client (eg: dequeue/queue), this
@@ -406,7 +403,7 @@
     }
 
     // check the surface didn't become invalid
-    status_t err = cblk->validate(mToken);
+    status_t err = mSharedBufferClient->getStatus();
     if (err != NO_ERROR) {
         LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
                 mToken, mIdentity, err, strerror(-err));
diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
index 8d39c85..0670d20 100644
--- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
@@ -31,7 +31,7 @@
 #include <ui/DisplayInfo.h>
 
 #include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
@@ -42,18 +42,14 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-class Composer : public Singleton<Composer>
+class ComposerService : public Singleton<ComposerService>
 {
     // these are constants
     sp<ISurfaceComposer> mComposerService;
     sp<IMemoryHeap> mServerCblkMemory;
     surface_flinger_cblk_t volatile* mServerCblk;
 
-    Mutex mLock;
-    SortedVector< wp<SurfaceComposerClient> > mActiveConnections;
-    SortedVector<sp<SurfaceComposerClient> > mOpenTransactions;
-
-    Composer() : Singleton<Composer>() {
+    ComposerService() : Singleton<ComposerService>() {
         const String16 name("SurfaceFlinger");
         while (getService(name, &mComposerService) != NO_ERROR) {
             usleep(250000);
@@ -63,6 +59,39 @@
                 mServerCblkMemory->getBase());
     }
 
+    friend class Singleton<ComposerService>;
+
+public:
+    static sp<ISurfaceComposer> getComposerService() {
+        return ComposerService::getInstance().mComposerService;
+    }
+    static surface_flinger_cblk_t const volatile * getControlBlock() {
+        return ComposerService::getInstance().mServerCblk;
+    }
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
+
+
+static inline sp<ISurfaceComposer> getComposerService() {
+    return ComposerService::getComposerService();
+}
+
+static inline surface_flinger_cblk_t const volatile * get_cblk() {
+    return ComposerService::getControlBlock();
+}
+
+// ---------------------------------------------------------------------------
+
+class Composer : public Singleton<Composer>
+{
+    Mutex mLock;
+    SortedVector< wp<SurfaceComposerClient> > mActiveConnections;
+    SortedVector<sp<SurfaceComposerClient> > mOpenTransactions;
+
+    Composer() : Singleton<Composer>() {
+    }
+
     void addClientImpl(const sp<SurfaceComposerClient>& client) {
         Mutex::Autolock _l(mLock);
         mActiveConnections.add(client);
@@ -102,7 +131,7 @@
             mOpenTransactions.clear();
         mLock.unlock();
 
-        sp<ISurfaceComposer> sm(mComposerService);
+        sp<ISurfaceComposer> sm(getComposerService());
         sm->openGlobalTransaction();
             const size_t N = clients.size();
             for (size_t i=0; i<N; i++) {
@@ -114,12 +143,6 @@
     friend class Singleton<Composer>;
 
 public:
-    static sp<ISurfaceComposer> getComposerService() {
-        return Composer::getInstance().mComposerService;
-    }
-    static surface_flinger_cblk_t const volatile * getControlBlock() {
-        return Composer::getInstance().mServerCblk;
-    }
     static void addClient(const sp<SurfaceComposerClient>& client) {
         Composer::getInstance().addClientImpl(client);
     }
@@ -136,14 +159,6 @@
 
 ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
 
-static inline sp<ISurfaceComposer> getComposerService() {
-    return Composer::getComposerService();
-}
-
-static inline surface_flinger_cblk_t const volatile * get_cblk() {
-    return Composer::getControlBlock();
-}
-
 // ---------------------------------------------------------------------------
 
 static inline int compare_type( const layer_state_t& lhs,
@@ -162,7 +177,7 @@
 {
     sp<ISurfaceComposer> sm(getComposerService());
     if (sm != 0) {
-        sp<ISurfaceFlingerClient> conn = sm->createConnection();
+        sp<ISurfaceComposerClient> conn = sm->createConnection();
         if (conn != 0) {
             mClient = conn;
             Composer::addClient(this);
@@ -199,7 +214,7 @@
 void SurfaceComposerClient::dispose()
 {
     // this can be called more than once.
-    sp<ISurfaceFlingerClient> client;
+    sp<ISurfaceComposerClient> client;
     Mutex::Autolock _lm(mLock);
     if (mClient != 0) {
         Composer::removeClient(this);
@@ -296,7 +311,7 @@
 {
     sp<SurfaceControl> result;
     if (mStatus == NO_ERROR) {
-        ISurfaceFlingerClient::surface_data_t data;
+        ISurfaceComposerClient::surface_data_t data;
         sp<ISurface> surface = mClient->createSurface(&data, pid, name,
                 display, w, h, format, flags);
         if (surface != 0) {
@@ -558,8 +573,8 @@
 }
 void SurfaceClient::init(const sp<IBinder>& conn)
 {
-    mSignalServer = getComposerService();
-    sp<ISurfaceFlingerClient> sf(interface_cast<ISurfaceFlingerClient>(conn));
+    mComposerService = getComposerService();
+    sp<ISurfaceComposerClient> sf(interface_cast<ISurfaceComposerClient>(conn));
     if (sf != 0) {
         mConnection = conn;
         mControlMemory = sf->getControlBlock();
@@ -574,7 +589,7 @@
     return mControl;
 }
 void SurfaceClient::signalServer() const {
-    mSignalServer->signal();
+    mComposerService->signal();
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index ba1fd9c..35e4af3 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -122,11 +122,20 @@
 status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
         uint32_t reqUsage)
 {
-    if (format == PIXEL_FORMAT_RGBX_8888)
-        format = PIXEL_FORMAT_RGBA_8888;
-
     GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
     status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
+
+    if (err<0 && format == PIXEL_FORMAT_RGBX_8888) {
+        /*
+         * There is currently a bug with some gralloc implementations
+         * not supporting RGBX_8888. In this case, we revert to using RGBA_8888
+         * which is not exactly the same, as GL_REPLACE will yield a different
+         * result.
+         */
+        format = PIXEL_FORMAT_RGBA_8888;
+        err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
+    }
+
     if (err == NO_ERROR) {
         this->width  = w;
         this->height = h;
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 8d15013..f00fad8 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -40,6 +40,7 @@
         ShoutcastSource.cpp       \
         StagefrightMediaScanner.cpp \
         StagefrightMetadataRetriever.cpp \
+        ThrottledSource.cpp       \
         TimeSource.cpp            \
         TimedEventQueue.cpp       \
         WAVExtractor.cpp          \
diff --git a/media/libstagefright/ThrottledSource.cpp b/media/libstagefright/ThrottledSource.cpp
new file mode 100644
index 0000000..4711f7c6
--- /dev/null
+++ b/media/libstagefright/ThrottledSource.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 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 "include/ThrottledSource.h"
+
+#include <media/stagefright/MediaDebug.h>
+
+namespace android {
+
+static int64_t getNowUs() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+
+    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
+}
+
+ThrottledSource::ThrottledSource(
+        const sp<DataSource> &source,
+        int32_t bandwidthLimitBytesPerSecond)
+    : mSource(source),
+      mBandwidthLimitBytesPerSecond(bandwidthLimitBytesPerSecond),
+      mStartTimeUs(-1),
+      mTotalTransferred(0) {
+    CHECK(mBandwidthLimitBytesPerSecond > 0);
+}
+
+status_t ThrottledSource::initCheck() const {
+    return mSource->initCheck();
+}
+
+ssize_t ThrottledSource::readAt(off_t offset, void *data, size_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    ssize_t n = mSource->readAt(offset, data, size);
+
+    if (n <= 0) {
+        return n;
+    }
+
+    mTotalTransferred += n;
+
+    int64_t nowUs = getNowUs();
+
+    if (mStartTimeUs < 0) {
+        mStartTimeUs = nowUs;
+    }
+
+    // How long would it have taken to transfer everything we ever
+    // transferred given the limited bandwidth.
+    int64_t durationUs =
+        mTotalTransferred * 1000000ll / mBandwidthLimitBytesPerSecond;
+
+    int64_t whenUs = mStartTimeUs + durationUs;
+
+    if (whenUs > nowUs) {
+        usleep(whenUs - nowUs);
+    }
+
+    return n;
+}
+
+status_t ThrottledSource::getSize(off_t *size) {
+    return mSource->getSize(size);
+}
+
+uint32_t ThrottledSource::flags() {
+    return mSource->flags();
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/include/ThrottledSource.h b/media/libstagefright/include/ThrottledSource.h
new file mode 100644
index 0000000..88164b3
--- /dev/null
+++ b/media/libstagefright/include/ThrottledSource.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 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 THROTTLED_SOURCE_H_
+
+#define THROTTLED_SOURCE_H_
+
+#include <media/stagefright/DataSource.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct ThrottledSource : public DataSource {
+    ThrottledSource(
+            const sp<DataSource> &source,
+            int32_t bandwidthLimitBytesPerSecond);
+
+    virtual status_t initCheck() const;
+
+    virtual ssize_t readAt(off_t offset, void *data, size_t size);
+
+    virtual status_t getSize(off_t *size);
+    virtual uint32_t flags();
+
+private:
+    Mutex mLock;
+
+    sp<DataSource> mSource;
+    int32_t mBandwidthLimitBytesPerSecond;
+    int64_t mStartTimeUs;
+    size_t mTotalTransferred;
+
+    ThrottledSource(const ThrottledSource &);
+    ThrottledSource &operator=(const ThrottledSource &);
+};
+
+}  // namespace android
+
+#endif  // THROTTLED_SOURCE_H_
diff --git a/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 8fdff92..60cd56c 100644
--- a/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -53,6 +53,8 @@
     private final KeyguardUpdateMonitor mUpdateMonitor;
     private final KeyguardScreenCallback mCallback;
 
+    private boolean mIsAlpha;
+
     private EditText mPasswordEntry;
     private Button mEmergencyCallButton;
     private LockPatternUtils mLockPatternUtils;
@@ -87,7 +89,7 @@
         }
 
         final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality();
-        final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
+        mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
                 || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
                 || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
 
@@ -100,7 +102,7 @@
         mTitle = (TextView) findViewById(R.id.enter_password_label);
 
         mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this);
-        mKeyboardHelper.setKeyboardMode(isAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
+        mKeyboardHelper.setKeyboardMode(mIsAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
                 : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
 
         mKeyboardView.setVisibility(mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
@@ -109,7 +111,7 @@
 
         // This allows keyboards with overlapping qwerty/numeric keys to choose just the
         // numeric keys.
-        if (isAlpha) {
+        if (mIsAlpha) {
             mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
         } else {
             mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
@@ -140,6 +142,7 @@
     public void onResume() {
         // start fresh
         mPasswordEntry.setText("");
+        resetStatusInfo();
         mPasswordEntry.requestFocus();
         mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
 
@@ -176,6 +179,9 @@
                 long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
                 handleAttemptLockout(deadline);
             }
+            mTitle.setText(R.string.lockscreen_password_wrong);
+        } else if (entry.length() > 0) {
+            mTitle.setText(R.string.lockscreen_password_wrong);
         }
         mPasswordEntry.setText("");
     }
@@ -199,16 +205,8 @@
             @Override
             public void onFinish() {
                 mPasswordEntry.setEnabled(true);
-                final int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
-                final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
-                        || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
-                        || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
-                if(isAlpha) {
-                    mTitle.setText(R.string.keyguard_password_enter_password_code);
-                } else {
-                    mTitle.setText(R.string.keyguard_password_enter_pin_password_code);
-                }
                 mKeyboardView.setEnabled(true);
+                resetStatusInfo();
             }
         }.start();
     }
@@ -274,4 +272,12 @@
 
     }
 
+    private void resetStatusInfo() {
+        if(mIsAlpha) {
+            mTitle.setText(R.string.keyguard_password_enter_password_code);
+        } else {
+            mTitle.setText(R.string.keyguard_password_enter_pin_password_code);
+        }
+    }
+
 }
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 6ceeb95..6c2f1b2 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -642,10 +642,21 @@
     }
 
     private boolean doGetShareMethodAvailable(String method) {
-        ArrayList<String> rsp = mConnector.doCommand("share status " + method);
+        ArrayList<String> rsp;
+        try {
+            rsp = mConnector.doCommand("share status " + method);
+        } catch (NativeDaemonConnectorException ex) {
+            Slog.e(TAG, "Failed to determine whether share method " + method + " is available.");
+            return false;
+        }
 
         for (String line : rsp) {
-            String []tok = line.split(" ");
+            String[] tok = line.split(" ");
+            if (tok.length < 3) {
+                Slog.e(TAG, "Malformed response to share status " + method);
+                return false;
+            }
+
             int code;
             try {
                 code = Integer.parseInt(tok[0]);
@@ -770,10 +781,22 @@
 
     private boolean doGetVolumeShared(String path, String method) {
         String cmd = String.format("volume shared %s %s", path, method);
-        ArrayList<String> rsp = mConnector.doCommand(cmd);
+        ArrayList<String> rsp;
+
+        try {
+            rsp = mConnector.doCommand(cmd);
+        } catch (NativeDaemonConnectorException ex) {
+            Slog.e(TAG, "Failed to read response to volume shared " + path + " " + method);
+            return false;
+        }
 
         for (String line : rsp) {
-            String []tok = line.split(" ");
+            String[] tok = line.split(" ");
+            if (tok.length < 3) {
+                Slog.e(TAG, "Malformed response to volume shared " + path + " " + method + " command");
+                return false;
+            }
+
             int code;
             try {
                 code = Integer.parseInt(tok[0]);
@@ -782,9 +805,7 @@
                 return false;
             }
             if (code == VoldResponseCode.ShareEnabledResult) {
-                if (tok[2].equals("enabled"))
-                    return true;
-                return false;
+                return "enabled".equals(tok[2]);
             } else {
                 Slog.e(TAG, String.format("Unexpected response code %d", code));
                 return false;
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 08d7ce6..c452590 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -128,12 +128,11 @@
                                     Slog.e(TAG, String.format(
                                             "Error handling '%s'", event), ex);
                                 }
-                            } else {
-                                try {
-                                    mResponseQueue.put(event);
-                                } catch (InterruptedException ex) {
-                                    Slog.e(TAG, "Failed to put response onto queue", ex);
-                                }
+                            }
+                            try {
+                                mResponseQueue.put(event);
+                            } catch (InterruptedException ex) {
+                                Slog.e(TAG, "Failed to put response onto queue", ex);
                             }
                         } catch (NumberFormatException nfe) {
                             Slog.w(TAG, String.format("Bad msg (%s)", event));
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index cbbc7be..c156150 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -35,6 +35,7 @@
 import android.util.Log;
 import android.util.Slog;
 import java.util.ArrayList;
+import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
 import android.provider.Settings;
 import android.content.ContentResolver;
@@ -226,44 +227,61 @@
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
 
-        return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult);
+        try {
+            return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Cannot communicate with native daemon to list interfaces");
+        }
     }
 
     public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException {
-        String rsp = mConnector.doCommand("interface getcfg " + iface).get(0);
+        String rsp;
+        try {
+            rsp = mConnector.doCommand("interface getcfg " + iface).get(0);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Cannot communicate with native daemon to get interface config");
+        }
         Slog.d(TAG, String.format("rsp <%s>", rsp));
 
         // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz [flag1 flag2 flag3]
         StringTokenizer st = new StringTokenizer(rsp);
 
+        InterfaceConfiguration cfg;
         try {
-            int code = Integer.parseInt(st.nextToken(" "));
-            if (code != NetdResponseCode.InterfaceGetCfgResult) {
+            try {
+                int code = Integer.parseInt(st.nextToken(" "));
+                if (code != NetdResponseCode.InterfaceGetCfgResult) {
+                    throw new IllegalStateException(
+                        String.format("Expected code %d, but got %d",
+                                NetdResponseCode.InterfaceGetCfgResult, code));
+                }
+            } catch (NumberFormatException nfe) {
                 throw new IllegalStateException(
-                    String.format("Expected code %d, but got %d",
-                            NetdResponseCode.InterfaceGetCfgResult, code));
+                        String.format("Invalid response from daemon (%s)", rsp));
             }
-        } catch (NumberFormatException nfe) {
+
+            cfg = new InterfaceConfiguration();
+            cfg.hwAddr = st.nextToken(" ");
+            try {
+                cfg.ipAddr = stringToIpAddr(st.nextToken(" "));
+            } catch (UnknownHostException uhe) {
+                Slog.e(TAG, "Failed to parse ipaddr", uhe);
+                cfg.ipAddr = 0;
+            }
+
+            try {
+                cfg.netmask = stringToIpAddr(st.nextToken(" "));
+            } catch (UnknownHostException uhe) {
+                Slog.e(TAG, "Failed to parse netmask", uhe);
+                cfg.netmask = 0;
+            }
+            cfg.interfaceFlags = st.nextToken("]").trim() +"]";
+        } catch (NoSuchElementException nsee) {
             throw new IllegalStateException(
                     String.format("Invalid response from daemon (%s)", rsp));
         }
-
-        InterfaceConfiguration cfg = new InterfaceConfiguration();
-        cfg.hwAddr = st.nextToken(" ");
-        try {
-            cfg.ipAddr = stringToIpAddr(st.nextToken(" "));
-        } catch (UnknownHostException uhe) {
-            Slog.e(TAG, "Failed to parse ipaddr", uhe);
-            cfg.ipAddr = 0;
-        }
-
-        try {
-            cfg.netmask = stringToIpAddr(st.nextToken(" "));
-        } catch (UnknownHostException uhe) {
-            Slog.e(TAG, "Failed to parse netmask", uhe);
-            cfg.netmask = 0;
-        }
-        cfg.interfaceFlags = st.nextToken("]").trim() +"]";
         Slog.d(TAG, String.format("flags <%s>", cfg.interfaceFlags));
         return cfg;
     }
@@ -272,7 +290,12 @@
             String iface, InterfaceConfiguration cfg) throws IllegalStateException {
         String cmd = String.format("interface setcfg %s %s %s %s", iface,
                 intToIpString(cfg.ipAddr), intToIpString(cfg.netmask), cfg.interfaceFlags);
-        mConnector.doCommand(cmd);
+        try {
+            mConnector.doCommand(cmd);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate with native daemon to interface setcfg");
+        }
     }
 
     public void shutdown() {
@@ -289,20 +312,25 @@
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
 
-        ArrayList<String> rsp = mConnector.doCommand("ipfwd status");
+        ArrayList<String> rsp;
+        try {
+            rsp = mConnector.doCommand("ipfwd status");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate with native daemon to ipfwd status");
+        }
 
         for (String line : rsp) {
-            String []tok = line.split(" ");
+            String[] tok = line.split(" ");
+            if (tok.length < 3) {
+                Slog.e(TAG, "Malformed response from native daemon: " + line);
+                return false;
+            }
+
             int code = Integer.parseInt(tok[0]);
             if (code == NetdResponseCode.IpFwdStatusResult) {
                 // 211 Forwarding <enabled/disabled>
-                if (tok.length !=2) {
-                    throw new IllegalStateException(
-                            String.format("Malformatted list entry '%s'", line));
-                }
-                if (tok[2].equals("enabled"))
-                    return true;
-                return false;
+                return "enabled".equals(tok[2]);
             } else {
                 throw new IllegalStateException(String.format("Unexpected response code %d", code));
             }
@@ -326,29 +354,45 @@
         for (String d : dhcpRange) {
             cmd += " " + d;
         }
-        mConnector.doCommand(cmd);
+
+        try {
+            mConnector.doCommand(cmd);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Unable to communicate to native daemon");
+        }
     }
 
     public void stopTethering() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand("tether stop");
+        try {
+            mConnector.doCommand("tether stop");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Unable to communicate to native daemon to stop tether");
+        }
     }
 
     public boolean isTetheringStarted() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
 
-        ArrayList<String> rsp = mConnector.doCommand("tether status");
+        ArrayList<String> rsp;
+        try {
+            rsp = mConnector.doCommand("tether status");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon to get tether status");
+        }
 
         for (String line : rsp) {
-            String []tok = line.split(" ");
+            String[] tok = line.split(" ");
+            if (tok.length < 3) {
+                throw new IllegalStateException("Malformed response for tether status: " + line);
+            }
             int code = Integer.parseInt(tok[0]);
             if (code == NetdResponseCode.TetherStatusResult) {
                 // XXX: Tethering services <started/stopped> <TBD>...
-                if (tok[2].equals("started"))
-                    return true;
-                return false;
+                return "started".equals(tok[2]);
             } else {
                 throw new IllegalStateException(String.format("Unexpected response code %d", code));
             }
@@ -359,20 +403,35 @@
     public void tetherInterface(String iface) throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand("tether interface add " + iface);
+        try {
+            mConnector.doCommand("tether interface add " + iface);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for adding tether interface");
+        }
     }
 
     public void untetherInterface(String iface) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand("tether interface remove " + iface);
+        try {
+            mConnector.doCommand("tether interface remove " + iface);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for removing tether interface");
+        }
     }
 
     public String[] listTetheredInterfaces() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
-        return mConnector.doListCommand(
-                "tether interface list", NetdResponseCode.TetherInterfaceListResult);
+        try {
+            return mConnector.doListCommand(
+                    "tether interface list", NetdResponseCode.TetherInterfaceListResult);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for listing tether interfaces");
+        }
     }
 
     public void setDnsForwarders(String[] dns) throws IllegalStateException {
@@ -383,7 +442,12 @@
             for (String s : dns) {
                 cmd += " " + InetAddress.getByName(s).getHostAddress();
             }
-            mConnector.doCommand(cmd);
+            try {
+                mConnector.doCommand(cmd);
+            } catch (NativeDaemonConnectorException e) {
+                throw new IllegalStateException(
+                        "Unable to communicate to native daemon for setting tether dns");
+            }
         } catch (UnknownHostException e) {
             throw new IllegalStateException("Error resolving dns name", e);
         }
@@ -392,30 +456,50 @@
     public String[] getDnsForwarders() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
-        return mConnector.doListCommand(
-                "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult);
+        try {
+            return mConnector.doListCommand(
+                    "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for listing tether dns");
+        }
     }
 
     public void enableNat(String internalInterface, String externalInterface)
             throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand(
-                String.format("nat enable %s %s", internalInterface, externalInterface));
+        try {
+            mConnector.doCommand(
+                    String.format("nat enable %s %s", internalInterface, externalInterface));
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for enabling NAT interface");
+        }
     }
 
     public void disableNat(String internalInterface, String externalInterface)
             throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand(
-                String.format("nat disable %s %s", internalInterface, externalInterface));
+        try {
+            mConnector.doCommand(
+                    String.format("nat disable %s %s", internalInterface, externalInterface));
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for disabling NAT interface");
+        }
     }
 
     public String[] listTtys() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
-        return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult);
+        try {
+            return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate to native daemon for listing TTYs");
+        }
     }
 
     public void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr,
@@ -430,31 +514,52 @@
                     InetAddress.getByName(dns2Addr).getHostAddress()));
         } catch (UnknownHostException e) {
             throw new IllegalStateException("Error resolving addr", e);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Error communicating to native daemon to attach pppd", e);
         }
     }
 
     public void detachPppd(String tty) throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand(String.format("pppd detach %s", tty));
+        try {
+            mConnector.doCommand(String.format("pppd detach %s", tty));
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Error communicating to native daemon to detach pppd", e);
+        }
     }
 
     public void startUsbRNDIS() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand("usb startrndis");
+        try {
+            mConnector.doCommand("usb startrndis");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Error communicating to native daemon for starting RNDIS", e);
+        }
     }
 
     public void stopUsbRNDIS() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand("usb stoprndis");
+        try {
+            mConnector.doCommand("usb stoprndis");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Error communicating to native daemon", e);
+        }
     }
 
     public boolean isUsbRNDISStarted() throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
-        ArrayList<String> rsp = mConnector.doCommand("usb rndisstatus");
+        ArrayList<String> rsp;
+        try {
+            rsp = mConnector.doCommand("usb rndisstatus");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Error communicating to native daemon to check RNDIS status", e);
+        }
 
         for (String line : rsp) {
             String []tok = line.split(" ");
@@ -476,31 +581,35 @@
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
-        mConnector.doCommand(String.format("softap stop " + wlanIface));
-        mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP"));
-        mConnector.doCommand(String.format("softap start " + wlanIface));
-        if (wifiConfig == null) {
-            mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
-        } else {
-            /**
-             * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8]
-             * argv1 - wlan interface
-             * argv2 - softap interface
-             * argv3 - SSID
-             * argv4 - Security
-             * argv5 - Key
-             * argv6 - Channel
-             * argv7 - Preamble
-             * argv8 - Max SCB
-             */
-            String str = String.format("softap set " + wlanIface + " " + softapIface +
-                                       " %s %s %s", convertQuotedString(wifiConfig.SSID),
-                                       wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
-                                       "wpa2-psk" : "open",
-                                       convertQuotedString(wifiConfig.preSharedKey));
-            mConnector.doCommand(str);
+        try {
+            mConnector.doCommand(String.format("softap stop " + wlanIface));
+            mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP"));
+            mConnector.doCommand(String.format("softap start " + wlanIface));
+            if (wifiConfig == null) {
+                mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
+            } else {
+                /**
+                 * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8]
+                 * argv1 - wlan interface
+                 * argv2 - softap interface
+                 * argv3 - SSID
+                 * argv4 - Security
+                 * argv5 - Key
+                 * argv6 - Channel
+                 * argv7 - Preamble
+                 * argv8 - Max SCB
+                 */
+                String str = String.format("softap set " + wlanIface + " " + softapIface +
+                                           " %s %s %s", convertQuotedString(wifiConfig.SSID),
+                                           wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
+                                           "wpa2-psk" : "open",
+                                           convertQuotedString(wifiConfig.preSharedKey));
+                mConnector.doCommand(str);
+            }
+            mConnector.doCommand(String.format("softap startap"));
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Error communicating to native daemon to start softap", e);
         }
-        mConnector.doCommand(String.format("softap startap"));
     }
 
     private String convertQuotedString(String s) {
@@ -516,7 +625,12 @@
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
-        mConnector.doCommand("softap stopap");
+        try {
+            mConnector.doCommand("softap stopap");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Error communicating to native daemon to stop soft AP",
+                    e);
+        }
     }
 
     public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface)
@@ -525,15 +639,19 @@
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
         mContext.enforceCallingOrSelfPermission(
             android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
-        if (wifiConfig == null) {
-            mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
-        } else {
-            String str = String.format("softap set " + wlanIface + " " + softapIface +
-                                       " %s %s %s", convertQuotedString(wifiConfig.SSID),
-                                       wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
-                                       "wpa2-psk" : "open",
-                                       convertQuotedString(wifiConfig.preSharedKey));
-            mConnector.doCommand(str);
+        try {
+            if (wifiConfig == null) {
+                mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
+            } else {
+                String str = String.format("softap set " + wlanIface + " " + softapIface
+                        + " %s %s %s", convertQuotedString(wifiConfig.SSID),
+                        wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? "wpa2-psk" : "open",
+                        convertQuotedString(wifiConfig.preSharedKey));
+                mConnector.doCommand(str);
+            }
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Error communicating to native daemon to set soft AP",
+                    e);
         }
     }
 
@@ -541,9 +659,22 @@
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
         try {
-            String rsp = mConnector.doCommand(
-                    String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0);
-            String []tok = rsp.split(" ");
+            String rsp;
+            try {
+                rsp = mConnector.doCommand(
+                        String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0);
+            } catch (NativeDaemonConnectorException e1) {
+                Slog.e(TAG, "Error communicating with native daemon", e1);
+                return -1;
+            }
+
+            String[] tok = rsp.split(" ");
+            if (tok.length < 2) {
+                Slog.e(TAG, String.format("Malformed response for reading %s interface",
+                        (rx ? "rx" : "tx")));
+                return -1;
+            }
+
             int code;
             try {
                 code = Integer.parseInt(tok[0]);
@@ -575,17 +706,34 @@
     public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
-        mConnector.doCommand(String.format(
-                "interface setthrottle %s %d %d", iface, rxKbps, txKbps));
+        try {
+            mConnector.doCommand(String.format(
+                    "interface setthrottle %s %d %d", iface, rxKbps, txKbps));
+        } catch (NativeDaemonConnectorException e) {
+            Slog.e(TAG, "Error communicating with native daemon to set throttle", e);
+        }
     }
 
     private int getInterfaceThrottle(String iface, boolean rx) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
         try {
-            String rsp = mConnector.doCommand(
-                    String.format("interface getthrottle %s %s", iface,(rx ? "rx" : "tx"))).get(0);
-            String []tok = rsp.split(" ");
+            String rsp;
+            try {
+                rsp = mConnector.doCommand(
+                        String.format("interface getthrottle %s %s", iface,
+                                (rx ? "rx" : "tx"))).get(0);
+            } catch (NativeDaemonConnectorException e) {
+                Slog.e(TAG, "Error communicating with native daemon to getthrottle", e);
+                return -1;
+            }
+
+            String[] tok = rsp.split(" ");
+            if (tok.length < 2) {
+                Slog.e(TAG, "Malformed response to getthrottle command");
+                return -1;
+            }
+
             int code;
             try {
                 code = Integer.parseInt(tok[0]);
diff --git a/test-runner/src/android/test/ServiceTestCase.java b/test-runner/src/android/test/ServiceTestCase.java
index fcb9d55..d9262f6 100644
--- a/test-runner/src/android/test/ServiceTestCase.java
+++ b/test-runner/src/android/test/ServiceTestCase.java
@@ -147,9 +147,6 @@
      * @param intent The Intent as if supplied to {@link android.content.Context#startService}.
      */
     protected void startService(Intent intent) {
-        assertFalse(mServiceStarted);
-        assertFalse(mServiceBound);
-        
         if (!mServiceAttached) {
             setupService();
         }
@@ -159,7 +156,7 @@
             mService.onCreate();
             mServiceCreated = true;
         }
-        mService.onStart(intent, mServiceId);
+        mService.onStartCommand(intent, 0, mServiceId);
         
         mServiceStarted = true;
     }
@@ -183,9 +180,6 @@
      * @return Return an IBinder for making further calls into the Service.
      */
     protected IBinder bindService(Intent intent) {
-        assertFalse(mServiceStarted);
-        assertFalse(mServiceBound);
-        
         if (!mServiceAttached) {
             setupService();
         }