Merge "Improvement for issue 3489986: BT SCO volume" into honeycomb-mr1
diff --git a/api/current.xml b/api/current.xml
index 5bc2dd3..7eef62f 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -72665,6 +72665,17 @@
 <parameter name="message" type="java.lang.String">
 </parameter>
 </constructor>
+<field name="TYPE_ACQUIRE_DRM_INFO_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2008"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TYPE_NOT_SUPPORTED"
  type="int"
  transient="false"
@@ -73018,6 +73029,17 @@
  visibility="public"
 >
 </field>
+<field name="TYPE_RIGHTS_REMOVED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="6"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TYPE_WAIT_FOR_RIGHTS"
  type="int"
  transient="false"
@@ -94459,6 +94481,17 @@
  visibility="public"
 >
 </method>
+<method name="getSerial"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getUri"
  return="java.lang.String"
  abstract="false"
@@ -267042,7 +267075,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
index cc174d4..5e9ead0 100644
--- a/core/java/android/hardware/usb/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -33,18 +33,20 @@
     private final String mDescription;
     private final String mVersion;
     private final String mUri;
+    private final String mSerial;
 
     /**
      * UsbAccessory should only be instantiated by UsbService implementation
      * @hide
      */
     public UsbAccessory(String manufacturer, String model, String description,
-            String version, String uri) {
+            String version, String uri, String serial) {
         mManufacturer = manufacturer;
         mModel = model;
         mDescription = description;
         mVersion = version;
         mUri = uri;
+        mSerial = serial;
     }
 
     /**
@@ -57,6 +59,7 @@
         mDescription = strings[2];
         mVersion = strings[3];
         mUri = strings[4];
+        mSerial = strings[5];
     }
 
     /**
@@ -106,6 +109,17 @@
         return mUri;
     }
 
+    /**
+     * Returns the unique serial number for the accessory.
+     * This is an optional serial number that can be used to differentiate
+     * between individual accessories of the same model and manufacturer
+     *
+     * @return the unique serial number
+     */
+    public String getSerial() {
+        return mSerial;
+    }
+
     private static boolean compare(String s1, String s2) {
         if (s1 == null) return (s2 == null);
         return s1.equals(s2);
@@ -119,7 +133,8 @@
                     compare(mModel, accessory.getModel()) &&
                     compare(mDescription, accessory.getDescription()) &&
                     compare(mVersion, accessory.getVersion()) &&
-                    compare(mUri, accessory.getUri()));
+                    compare(mUri, accessory.getUri()) &&
+                    compare(mSerial, accessory.getSerial()));
         }
         return false;
     }
@@ -130,7 +145,8 @@
                 (mModel == null ? 0 : mModel.hashCode()) ^
                 (mDescription == null ? 0 : mDescription.hashCode()) ^
                 (mVersion == null ? 0 : mVersion.hashCode()) ^
-                (mUri == null ? 0 : mUri.hashCode()));
+                (mUri == null ? 0 : mUri.hashCode()) ^
+                (mSerial == null ? 0 : mSerial.hashCode()));
     }
 
     @Override
@@ -139,7 +155,8 @@
                             ", mModel=" + mModel +
                             ", mDescription=" + mDescription +
                             ", mVersion=" + mVersion +
-                            ", mUri=" + mUri + "]";
+                            ", mUri=" + mUri +
+                            ", mSerial=" + mSerial + "]";
     }
 
     public static final Parcelable.Creator<UsbAccessory> CREATOR =
@@ -150,7 +167,8 @@
             String description = in.readString();
             String version = in.readString();
             String uri = in.readString();
-            return new UsbAccessory(manufacturer, model, description, version, uri);
+            String serial = in.readString();
+            return new UsbAccessory(manufacturer, model, description, version, uri, serial);
         }
 
         public UsbAccessory[] newArray(int size) {
@@ -168,5 +186,6 @@
         parcel.writeString(mDescription);
         parcel.writeString(mVersion);
         parcel.writeString(mUri);
+        parcel.writeString(mSerial);
    }
 }
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index f16a7e4..2bf6c7b 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -24,8 +24,10 @@
 import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
+import android.widget.CheckBox;
 import android.widget.Checkable;
 import android.widget.TextView;
 
@@ -90,8 +92,16 @@
                     checkboxView.isEnabled()) {
                 mSendAccessibilityEventViewClickedType = false;
 
-                int eventType = AccessibilityEvent.TYPE_VIEW_CLICKED;
-                checkboxView.sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
+                // we send an event on behalf of the check box because in onBind the latter
+                // is detached from its parent and such views do not send accessibility events
+                AccessibilityEvent event = AccessibilityEvent.obtain(
+                        AccessibilityEvent.TYPE_VIEW_CLICKED);
+                event.setClassName(checkboxView.getClass().getName());
+                event.setPackageName(getContext().getPackageName());
+                event.setEnabled(checkboxView.isEnabled());
+                event.setContentDescription(checkboxView.getContentDescription());
+                event.setChecked(((Checkable) checkboxView).isChecked());
+                mAccessibilityManager.sendAccessibilityEvent(event);
             }
         }
 
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index fa5479b..14f2e9d 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -245,12 +245,13 @@
     private static native void nDestroyDisplayList(int displayList);
 
     @Override
-    public boolean drawDisplayList(DisplayList displayList, Rect dirty) {
+    public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
         return nDrawDisplayList(mRenderer,
-                ((GLES20DisplayList) displayList).mNativeDisplayList, dirty);
+                ((GLES20DisplayList) displayList).mNativeDisplayList, width, height, dirty);
     }
 
-    private static native boolean nDrawDisplayList(int renderer, int displayList, Rect dirty);
+    private static native boolean nDrawDisplayList(int renderer, int displayList,
+            int width, int height, Rect dirty);
 
     ///////////////////////////////////////////////////////////////////////////
     // Hardware layer
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index cb1003a..caa7b74 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -53,13 +53,15 @@
      * Draws the specified display list onto this canvas.
      * 
      * @param displayList The display list to replay.
+     * @param width The width of the display list.
+     * @param height The height of the display list.
      * @param dirty The dirty region to redraw in the next pass, matters only
      *        if this method returns true, can be null.
      * 
      * @return True if the content of the display list requires another
      *         drawing pass (invalidate()), false otherwise
      */
-    abstract boolean drawDisplayList(DisplayList displayList, Rect dirty);
+    abstract boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty);
 
     /**
      * Draws the specified layer onto this canvas.
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 0cf7ae6..8584bf2 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -608,7 +608,8 @@
 
                         DisplayList displayList = view.getDisplayList();
                         if (displayList != null) {
-                            if (canvas.drawDisplayList(displayList, mRedrawClip)) {
+                            if (canvas.drawDisplayList(displayList, view.getWidth(),
+                                    view.getHeight(), mRedrawClip)) {
                                 if (mRedrawClip.isEmpty() || view.getParent() == null) {
                                     view.invalidate();
                                 } else {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 32c9e27..5a96efd 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -59,7 +59,6 @@
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.View.MeasureSpec;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -4651,6 +4650,7 @@
      * @return True if the event was handled by the view, false otherwise.
      */
     public boolean dispatchGenericMotionEvent(MotionEvent event) {
+        //noinspection SimplifiableIfStatement
         if (mOnGenericMotionListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                 && mOnGenericMotionListener.onGenericMotion(this, event)) {
             return true;
@@ -9326,7 +9326,8 @@
         }
 
         final ScrollabilityCache scrollabilityCache = mScrollCache;
-        int length = scrollabilityCache.fadingEdgeLength;
+        final float fadeHeight = scrollabilityCache.fadingEdgeLength;        
+        int length = (int) fadeHeight;
 
         // clip the fade length if top and bottom fades overlap
         // overlapping fades produce odd-looking artifacts
@@ -9341,16 +9342,16 @@
 
         if (verticalEdges) {
             topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
-            drawTop = topFadeStrength > 0.0f;
+            drawTop = topFadeStrength * fadeHeight > 1.0f;
             bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
-            drawBottom = bottomFadeStrength > 0.0f;
+            drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
         }
 
         if (horizontalEdges) {
             leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
-            drawLeft = leftFadeStrength > 0.0f;
+            drawLeft = leftFadeStrength * fadeHeight > 1.0f;
             rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
-            drawRight = rightFadeStrength > 0.0f;
+            drawRight = rightFadeStrength * fadeHeight > 1.0f;
         }
 
         saveCount = canvas.getSaveCount();
@@ -9388,7 +9389,6 @@
         final Paint p = scrollabilityCache.paint;
         final Matrix matrix = scrollabilityCache.matrix;
         final Shader fade = scrollabilityCache.shader;
-        final float fadeHeight = scrollabilityCache.fadingEdgeLength;
 
         if (drawTop) {
             matrix.setScale(1, fadeHeight * topFadeStrength);
@@ -9438,6 +9438,7 @@
      *
      * @return The known solid color background for this view, or 0 if the color may vary
      */
+    @ViewDebug.ExportedProperty(category = "drawing")
     public int getSolidColor() {
         return 0;
     }
@@ -11644,6 +11645,7 @@
      * @return true if scrolling was clamped to an over-scroll boundary along either
      *          axis, false otherwise.
      */
+    @SuppressWarnings({"UnusedParameters"})
     protected boolean overScrollBy(int deltaX, int deltaY,
             int scrollX, int scrollY,
             int scrollRangeX, int scrollRangeY,
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f9692da..8dc86ac 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2585,7 +2585,7 @@
                     }
                 } else {
                     child.mPrivateFlags &= ~DIRTY_MASK;
-                    ((HardwareCanvas) canvas).drawDisplayList(displayList, null);
+                    ((HardwareCanvas) canvas).drawDisplayList(displayList, cr - cl, cb - ct, null);
                 }
             }
         } else if (cache != null) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4aa1f5e..1a574d5 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5384,7 +5384,8 @@
     private boolean shouldForwardTouchEvent() {
         return mFullScreenHolder != null || (mForwardTouchEvents
                 && !mSelectingText
-                && mPreventDefault != PREVENT_DEFAULT_IGNORE);
+                && mPreventDefault != PREVENT_DEFAULT_IGNORE
+                && mPreventDefault != PREVENT_DEFAULT_NO);
     }
 
     private boolean inFullScreenMode() {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index eca39fc..d39271e 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5226,6 +5226,7 @@
      *
      * @return The cache color hint
      */
+    @ViewDebug.ExportedProperty(category = "drawing")
     public int getCacheColorHint() {
         return mCacheColorHint;
     }
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 13a407f..f8c76f2 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -1066,7 +1066,10 @@
         public boolean onTouch(View v, MotionEvent event) {
             if (mListView.isEnabled() && mGestureDetector.onTouchEvent(event)) {
                 WeekView weekView = (WeekView) v;
-                weekView.getDayFromLocation(event.getX(), mTempDate);
+                // if we cannot find a day for the given location we are done
+                if (!weekView.getDayFromLocation(event.getX(), mTempDate)) {
+                    return true;
+                }
                 // it is possible that the touched day is outside the valid range
                 // we draw whole weeks but range end can fall not on the week end
                 if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
@@ -1271,21 +1274,23 @@
 
         /**
          * Calculates the day that the given x position is in, accounting for
-         * week number. Returns a Time referencing that day or null if
+         * week number.
          *
-         * @param x The x position of the touch eventy
+         * @param x The x position of the touch event.
+         * @return True if a day was found for the given location.
          */
-        public void getDayFromLocation(float x, Calendar outCalendar) {
+        public boolean getDayFromLocation(float x, Calendar outCalendar) {
             int dayStart = mShowWeekNumber ? mWidth / mNumCells : 0;
             if (x < dayStart || x > mWidth) {
                 outCalendar.clear();
-                return;
+                return false;
             }
             // Selection is (x - start) / (pixels/day) == (x -s) * day / pixels
             int dayPosition = (int) ((x - dayStart) * mDaysPerWeek
                     / (mWidth - dayStart));
             outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
             outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
+            return true;
         }
 
         @Override
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 586ba87..81d02ee 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -462,6 +462,7 @@
     private void ensureTabsExist() {
         if (mTabScrollView == null) {
             mTabScrollView = new HorizontalScrollView(getContext());
+            mTabScrollView.setHorizontalFadingEdgeEnabled(true);
             mTabLayout = new LinearLayout(getContext(), null,
                     com.android.internal.R.attr.actionBarTabBarStyle);
             mTabScrollView.addView(mTabLayout);
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 0ea8225..7fdad10 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -119,7 +119,7 @@
     const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
 
     SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0);
-    SkScalar*                   pos = NULL;
+    SkScalar* pos = NULL;
 
     if (posArray) {
         AutoJavaFloatArray autoPos(env, posArray, count);
@@ -164,7 +164,11 @@
         }
     } else {
         storedPositions[0] = 0.0f;
-        storedPositions[1] = 1.0f;
+        const jfloat step = 1.0f / (count - 1);
+        for (size_t i = 1; i < count - 1; i++) {
+            storedPositions[i] = step * i;
+        }
+        storedPositions[count - 1] = 1.0f;
     }
 
     SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors,
@@ -289,7 +293,11 @@
         }
     } else {
         storedPositions[0] = 0.0f;
-        storedPositions[1] = 1.0f;
+        const jfloat step = 1.0f / (count - 1);
+        for (size_t i = 1; i < count - 1; i++) {
+            storedPositions[i] = step * i;
+        }
+        storedPositions[count - 1] = 1.0f;
     }
 
     SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors,
@@ -384,7 +392,11 @@
         }
     } else {
         storedPositions[0] = 0.0f;
-        storedPositions[1] = 1.0f;
+        const jfloat step = 1.0f / (count - 1);
+        for (size_t i = 1; i < count - 1; i++) {
+            storedPositions[i] = step * i;
+        }
+        storedPositions[count - 1] = 1.0f;
     }
 
     SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, count,
diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp
index a5878a9..e0c900e 100644
--- a/core/jni/android_database_SQLiteDatabase.cpp
+++ b/core/jni/android_database_SQLiteDatabase.cpp
@@ -64,7 +64,7 @@
 
 static jfieldID offset_db_handle;
 static jmethodID method_custom_function_callback;
-static jclass string_class = NULL;
+static jclass string_class;
 static jint sSqliteSoftHeapLimit = 0;
 
 static char *createStr(const char *path, short extra) {
@@ -406,8 +406,6 @@
     jobject function = (jobject)sqlite3_user_data(context);
 
     // pack up the arguments into a string array
-    if (!string_class)
-        string_class = (jclass)env->NewGlobalRef(env->FindClass("java/lang/String"));
     jobjectArray strArray = env->NewObjectArray(argc, string_class, NULL);
     if (!strArray)
         goto done;
@@ -425,6 +423,7 @@
     }
 
     env->CallVoidMethod(function, method_custom_function_callback, strArray);
+    env->DeleteLocalRef(strArray);
 
 done:
     if (env->ExceptionCheck()) {
@@ -489,6 +488,12 @@
         return -1;
     }
 
+    string_class = (jclass)env->NewGlobalRef(env->FindClass("java/lang/String"));
+    if (string_class == NULL) {
+        LOGE("Can't find java/lang/String\n");
+        return -1;
+    }
+
     offset_db_handle = env->GetFieldID(clazz, "mNativeHandle", "I");
     if (offset_db_handle == NULL) {
         LOGE("Can't find SQLiteDatabase.mNativeHandle\n");
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a78f660..5116f09 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -498,9 +498,10 @@
 }
 
 static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
-        jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList, jobject dirty) {
+        jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList,
+        jint width, jint height, jobject dirty) {
     android::uirenderer::Rect bounds;
-    bool redraw = renderer->drawDisplayList(displayList, bounds);
+    bool redraw = renderer->drawDisplayList(displayList, width, height, bounds);
     if (redraw && dirty != NULL) {
         env->CallVoidMethod(dirty, gRectClassInfo.set,
                 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
@@ -664,7 +665,7 @@
     { "nGetDisplayList",         "(I)I",       (void*) android_view_GLES20Canvas_getDisplayList },
     { "nDestroyDisplayList",     "(I)V",       (void*) android_view_GLES20Canvas_destroyDisplayList },
     { "nGetDisplayListRenderer", "(I)I",       (void*) android_view_GLES20Canvas_getDisplayListRenderer },
-    { "nDrawDisplayList",        "(IILandroid/graphics/Rect;)Z",
+    { "nDrawDisplayList",        "(IIIILandroid/graphics/Rect;)Z",
                                                (void*) android_view_GLES20Canvas_drawDisplayList },
 
     { "nInterrupt",              "(I)V",       (void*) android_view_GLES20Canvas_interrupt },
diff --git a/core/res/res/drawable-hdpi/ic_media_embed_play.png b/core/res/res/drawable-hdpi/ic_media_embed_play.png
index e67ec80..23ac7e4 100644
--- a/core/res/res/drawable-hdpi/ic_media_embed_play.png
+++ b/core/res/res/drawable-hdpi/ic_media_embed_play.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_ff.png b/core/res/res/drawable-hdpi/ic_media_ff.png
index b0dc05b..a892ba2 100644
--- a/core/res/res/drawable-hdpi/ic_media_ff.png
+++ b/core/res/res/drawable-hdpi/ic_media_ff.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_fullscreen.png b/core/res/res/drawable-hdpi/ic_media_fullscreen.png
index 3f26e45..0cdbf77 100644
--- a/core/res/res/drawable-hdpi/ic_media_fullscreen.png
+++ b/core/res/res/drawable-hdpi/ic_media_fullscreen.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_next.png b/core/res/res/drawable-hdpi/ic_media_next.png
index 2552f4e..2285670 100644
--- a/core/res/res/drawable-hdpi/ic_media_next.png
+++ b/core/res/res/drawable-hdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_pause.png b/core/res/res/drawable-hdpi/ic_media_pause.png
index d4670c2..ffb55cd 100644
--- a/core/res/res/drawable-hdpi/ic_media_pause.png
+++ b/core/res/res/drawable-hdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_play.png b/core/res/res/drawable-hdpi/ic_media_play.png
index e67ec80..e525bd2 100644
--- a/core/res/res/drawable-hdpi/ic_media_play.png
+++ b/core/res/res/drawable-hdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_previous.png b/core/res/res/drawable-hdpi/ic_media_previous.png
index 05eba71..3333711 100644
--- a/core/res/res/drawable-hdpi/ic_media_previous.png
+++ b/core/res/res/drawable-hdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_rew.png b/core/res/res/drawable-hdpi/ic_media_rew.png
index 88eed2e..b14e9b9 100644
--- a/core/res/res/drawable-hdpi/ic_media_rew.png
+++ b/core/res/res/drawable-hdpi/ic_media_rew.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_paste_bubble_disabled_holo.png b/core/res/res/drawable-hdpi/ic_paste_bubble_disabled_holo.png
new file mode 100644
index 0000000..42ac16b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_paste_bubble_disabled_holo.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_paste_bubble_holo_disabled.png b/core/res/res/drawable-hdpi/ic_paste_bubble_holo_disabled.png
deleted file mode 100644
index 15bd8b2..0000000
--- a/core/res/res/drawable-hdpi/ic_paste_bubble_holo_disabled.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb.png b/core/res/res/drawable-hdpi/stat_sys_adb.png
index 877e731..9c56e24 100755
--- a/core/res/res/drawable-hdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-hdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_embed_play.png b/core/res/res/drawable-mdpi/ic_media_embed_play.png
index 41cd65f..fc5d8c6 100644
--- a/core/res/res/drawable-mdpi/ic_media_embed_play.png
+++ b/core/res/res/drawable-mdpi/ic_media_embed_play.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_ff.png b/core/res/res/drawable-mdpi/ic_media_ff.png
index d99779d..892772e 100644
--- a/core/res/res/drawable-mdpi/ic_media_ff.png
+++ b/core/res/res/drawable-mdpi/ic_media_ff.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_fullscreen.png b/core/res/res/drawable-mdpi/ic_media_fullscreen.png
index 24fb6d6..1c60e15 100644
--- a/core/res/res/drawable-mdpi/ic_media_fullscreen.png
+++ b/core/res/res/drawable-mdpi/ic_media_fullscreen.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_next.png b/core/res/res/drawable-mdpi/ic_media_next.png
index cee4930..bbe311b 100644
--- a/core/res/res/drawable-mdpi/ic_media_next.png
+++ b/core/res/res/drawable-mdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_pause.png b/core/res/res/drawable-mdpi/ic_media_pause.png
index 9e8b675..e4e8d86 100644
--- a/core/res/res/drawable-mdpi/ic_media_pause.png
+++ b/core/res/res/drawable-mdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_play.png b/core/res/res/drawable-mdpi/ic_media_play.png
index 41cd65f..8eaf962 100644
--- a/core/res/res/drawable-mdpi/ic_media_play.png
+++ b/core/res/res/drawable-mdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_previous.png b/core/res/res/drawable-mdpi/ic_media_previous.png
index 1be95b4..e9abc7f 100644
--- a/core/res/res/drawable-mdpi/ic_media_previous.png
+++ b/core/res/res/drawable-mdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_rew.png b/core/res/res/drawable-mdpi/ic_media_rew.png
index 8311508..a5eb94a 100644
--- a/core/res/res/drawable-mdpi/ic_media_rew.png
+++ b/core/res/res/drawable-mdpi/ic_media_rew.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_paste_bubble_disabled_holo.png b/core/res/res/drawable-mdpi/ic_paste_bubble_disabled_holo.png
new file mode 100644
index 0000000..ce6bd86
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_paste_bubble_disabled_holo.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_paste_bubble_holo_disabled.png b/core/res/res/drawable-mdpi/ic_paste_bubble_holo_disabled.png
deleted file mode 100644
index e483e84..0000000
--- a/core/res/res/drawable-mdpi/ic_paste_bubble_holo_disabled.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb.png b/core/res/res/drawable-mdpi/stat_sys_adb.png
index e259ca5..1400bb3 100644
--- a/core/res/res/drawable-mdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-mdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
index b7413b3..62e3274 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
index 82e7a03..b7512fa 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
index 4b0ea21..bfc6f83 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
index e87591c..708ba90 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
index 14f69b1..0da1e9c 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
index 85329ca..2e93557 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
index 7e130d9..7aeaad6 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
index 050d1c0..cf46f32 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/expander_group_holo_dark.xml b/core/res/res/drawable/expander_group_holo_dark.xml
index 51a7290..2481dcb 100644
--- a/core/res/res/drawable/expander_group_holo_dark.xml
+++ b/core/res/res/drawable/expander_group_holo_dark.xml
@@ -17,7 +17,7 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:state_expanded="true"
-        android:drawable="@drawable/expander_open_holo_dark" />
-    <item
         android:drawable="@drawable/expander_close_holo_dark" />
+    <item
+        android:drawable="@drawable/expander_open_holo_dark" />
 </selector>
diff --git a/core/res/res/drawable/expander_group_holo_light.xml b/core/res/res/drawable/expander_group_holo_light.xml
index 0ce71a5..8006574 100644
--- a/core/res/res/drawable/expander_group_holo_light.xml
+++ b/core/res/res/drawable/expander_group_holo_light.xml
@@ -17,7 +17,7 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:state_expanded="true"
-        android:drawable="@drawable/expander_open_holo_light" />
-    <item
         android:drawable="@drawable/expander_close_holo_light" />
+    <item
+        android:drawable="@drawable/expander_open_holo_light" />
 </selector>
diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml
index c52b73f..face8b2 100644
--- a/core/res/res/layout/search_view.xml
+++ b/core/res/res/layout/search_view.xml
@@ -54,8 +54,8 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:layout_gravity="center_vertical"
-        android:layout_marginLeft="4dip"
-        android:layout_marginRight="4dip"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="16dip"
         android:layout_marginTop="4dip"
         android:layout_marginBottom="4dip"
         android:orientation="horizontal">
diff --git a/core/res/res/layout/text_edit_no_paste_window.xml b/core/res/res/layout/text_edit_no_paste_window.xml
index f804986..98b16e2 100644
--- a/core/res/res/layout/text_edit_no_paste_window.xml
+++ b/core/res/res/layout/text_edit_no_paste_window.xml
@@ -25,7 +25,7 @@
         android:paddingRight="16dip"
         android:paddingTop="8dip"
         android:paddingBottom="8dip"
-        android:drawableLeft="@android:drawable/ic_paste_bubble_holo_disabled"
+        android:drawableLeft="@android:drawable/ic_paste_bubble_disabled_holo"
         android:drawablePadding="8dip"
         android:gravity="center"
         android:textAppearance="?android:attr/textAppearanceMediumInverse"
diff --git a/core/res/res/layout/text_edit_side_no_paste_window.xml b/core/res/res/layout/text_edit_side_no_paste_window.xml
index 903bcb6..3eb41fb 100644
--- a/core/res/res/layout/text_edit_side_no_paste_window.xml
+++ b/core/res/res/layout/text_edit_side_no_paste_window.xml
@@ -25,7 +25,7 @@
         android:paddingRight="16dip"
         android:paddingTop="8dip"
         android:paddingBottom="8dip"
-        android:drawableLeft="@android:drawable/ic_paste_bubble_holo_disabled"
+        android:drawableLeft="@android:drawable/ic_paste_bubble_disabled_holo"
         android:drawablePadding="8dip"
         android:gravity="center"
         android:textAppearance="?android:attr/textAppearanceMediumInverse"
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 4c5f062..0eeda2b 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -668,7 +668,7 @@
     <string name="save_password_label" msgid="6860261758665825069">"Potwierdź"</string>
     <string name="double_tap_toast" msgid="1068216937244567247">"Wskazówka: dotknij dwukrotnie, aby powiÄ™kszyć lub pomniejszyć."</string>
     <string name="autofill_this_form" msgid="1272247532604569872">"Autouzupełnianie"</string>
-    <string name="setup_autofill" msgid="8154593408885654044">"Konfiguruj autouzupełnianie"</string>
+    <string name="setup_autofill" msgid="8154593408885654044">"Opcje autouzupełniania"</string>
     <string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
diff --git a/data/fonts/DroidSans-Bold.ttf b/data/fonts/DroidSans-Bold.ttf
index 7ac04b6..d065b64 100644
--- a/data/fonts/DroidSans-Bold.ttf
+++ b/data/fonts/DroidSans-Bold.ttf
Binary files differ
diff --git a/data/fonts/DroidSans.ttf b/data/fonts/DroidSans.ttf
index 767c63a..ad1efca 100644
--- a/data/fonts/DroidSans.ttf
+++ b/data/fonts/DroidSans.ttf
Binary files differ
diff --git a/data/fonts/DroidSansArabic.ttf b/data/fonts/DroidSansArabic.ttf
index 660e2a9..bdefaac 100644
--- a/data/fonts/DroidSansArabic.ttf
+++ b/data/fonts/DroidSansArabic.ttf
Binary files differ
diff --git a/data/fonts/DroidSansFallback.ttf b/data/fonts/DroidSansFallback.ttf
index 8c6fabe..ba9d76f 100644
--- a/data/fonts/DroidSansFallback.ttf
+++ b/data/fonts/DroidSansFallback.ttf
Binary files differ
diff --git a/data/fonts/DroidSansMono.ttf b/data/fonts/DroidSansMono.ttf
index 6e79dad..a007071 100644
--- a/data/fonts/DroidSansMono.ttf
+++ b/data/fonts/DroidSansMono.ttf
Binary files differ
diff --git a/data/fonts/DroidSerif-Bold.ttf b/data/fonts/DroidSerif-Bold.ttf
index 85d6c6b..838d255 100644
--- a/data/fonts/DroidSerif-Bold.ttf
+++ b/data/fonts/DroidSerif-Bold.ttf
Binary files differ
diff --git a/data/fonts/DroidSerif-BoldItalic.ttf b/data/fonts/DroidSerif-BoldItalic.ttf
index 9d8e798..0b1601f 100644
--- a/data/fonts/DroidSerif-BoldItalic.ttf
+++ b/data/fonts/DroidSerif-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/DroidSerif-Italic.ttf b/data/fonts/DroidSerif-Italic.ttf
index 6acc86d..2972809 100644
--- a/data/fonts/DroidSerif-Italic.ttf
+++ b/data/fonts/DroidSerif-Italic.ttf
Binary files differ
diff --git a/data/fonts/DroidSerif-Regular.ttf b/data/fonts/DroidSerif-Regular.ttf
index 8c1c2c4..5b4fe81 100644
--- a/data/fonts/DroidSerif-Regular.ttf
+++ b/data/fonts/DroidSerif-Regular.ttf
Binary files differ
diff --git a/docs/html/guide/practices/optimizing-for-3.0.jd b/docs/html/guide/practices/optimizing-for-3.0.jd
index a22e69a..5cd519b 100644
--- a/docs/html/guide/practices/optimizing-for-3.0.jd
+++ b/docs/html/guide/practices/optimizing-for-3.0.jd
@@ -5,20 +5,32 @@
 <div id="qv">
 <h2>In this document</h2>
 <ol>
-<li><a href="#Setup">Set Up Your SDK with Android 3.0</a></li>
-<li><a href="#SearchableConfiguration">Optimize Your App for Tablets and Similar Devices</a></li>
-<li><a href="#SearchableActivity">Upgrade or Develop a New App for Tablets and Similar
-Devices</a></li>
+<li><a href="#Setup">Setting Up Your SDK with Android 3.0</a></li>
+<li><a href="#Optimizing">Optimizing Your App for Tablets</a></li>
+<li><a href="#Upgrading">Upgrading or Developing a New App for Tablets</a></li>
+<li><a href="#ManagingAppDist">Managing App Distribution Based on Screen Configuration</a>
+  <ol>
+    <li><a href="#FilteringTabletApps">Filtering a tablet app from mobile devices</a></li>
+    <li><a href="#FilteringMobileApps">Filtering a mobile device app from tablets</a></li>
+  </ol>
+</li>
+<li><a href="#Issues">Other Issues</a>
+  <ol>
+    <li><a href="#Landscape">Adding support for landscape screens</a></li>
+    <li><a href="#Telephony">Using telephony or other variable features</a></li>
+  </ol>
+</li>
 </ol>
 
 </div>
 </div>
 
-<p>If you're developing an Android application, Android 3.0 introduces several features that allow
+<p>Android 3.0 introduces several features that allow
 you to enhance your user's experience on tablets and similar devices. Any application you've already
 published is compatible with devices running Android 3.0, by default, because Android applications
-are forward-compatible. However, there are some simple changes you should make to optimize your
-application for tablet-type devices.</p>
+are forward-compatible. However, new tablet devices running Android 3.0 are now available to the
+public and provide users a new Android experience on a larger screen, so you should make sure
+your application looks and works great on the new platform and new device form-factors.</p>
 
 <p>This document shows how you can optimize your existing application for Android 3.0 and
 maintain compatibility with older versions or upgrade your application completely with new APIs.</p>
@@ -27,18 +39,28 @@
 <p><b>To get started:</b></p>
 
 <ol>
-  <li><a href="#Setup">Set up your SDK with Android 3.0</a>.</li>
-  <li>Then choose to either optimize or upgrade:
+  <li><a href="#Setup">Set up your SDK with Android 3.0</a>.
+    <p>Install the Android 3.0 platform, new tools, and set up a new AVD.</p></li>
+  <li>Choose to either optimize or upgrade:
     <ol type="a">
-      <li><a href="#Optimize">Optimize Your App for Tablets and Similar Devices</a>.
-        <p>When you have an existing application and want to maintain compatibility with
-older versions of Android.</p>
+      <li><a href="#Optimizing">Optimize your app for tablets and similar devices</a>.
+        <p>Read this section if you have an existing application and want to
+maintain compatibility with older versions of Android. All you need to do is update your
+manifest file to declare support for Android 3.0, test your application on the new platform, and
+add extra resources to support extra large screens, as appropriate.</p>
       </li>
-      <li><a href="#Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</a>.
-        <p>When you want to upgrade your application to use APIs introduced in Android 3.0 or
-    create a new application targeted to tablets and similar devices.</p></li>
+      <li><a href="#Upgrading">Upgrade or develop a new app for tablets and similar devices</a>.
+        <p>Read this section if you want to upgrade your application to use APIs introduced in
+Android 3.0 or create a new application targeted to tablets and similar devices. Compared to
+upgrading to previous versions of Android, there's nothing different about upgrading to Android 3.0.
+This section introduces some of the key features and APIs you should use to make an
+application that's fully enhanced for tablets.</p></li>
     </ol>
   </li>
+  <li>Consider whether you need to <a href="#ManagingAppDist">manage the distribution of your
+application based on screen configuration</a>.</li>
+  <li>Then review some <a href="#Issue">other issues</a> you might encounter when developing
+for tablets and similar devices.</li>
 </ol>
 
 
@@ -66,14 +88,16 @@
   <p>Set the target to "Android 3.0" and the skin to "WXGA" (the default skin).</p></li>
 </ol>
 
+<p>The best way to test your application on Android 3.0 is to use real hardware running Android 3.0,
+such as the <a href="http://www.motorola.com/staticfiles/Consumers/XOOM/index.html">Motorola
+Xoom</a>. Of course, you can also use the Android emulator on your development machine, but because
+the Android emulator must simulate the ARM instruction set on your computer and the WXGA screen is
+significantly larger than a typical virtual device, emulator performance is much slower than a real
+device.</p>
 
 <h3>About emulator performance</h3>
 
-<p>Because the Android emulator must simulate the ARM instruction set on your computer
-and the WXGA screen is significantly larger than a typical virtual device, emulator performance is
-much slower than a real device.</p>
-
-<p>In particular, initializing the emulator can be slow and can take several minutes, depending on
+<p>Initializing the emulator can be slow and can take several minutes, depending on
 your hardware. When the emulator is booting, there is limited user feedback, so please be patient
 and wait until you see the home screen (or lock screen) appear. </p>
 
@@ -82,9 +106,10 @@
 Also see the tip below for information about using a snapshot to drastically reduce startup time
 after the first initialization. </p>
 
-<p>We're working hard to resolve the performance issues and it will improve in future tools
-releases. For the time being, the emulator is still best way to evaluate your application's
-appearance and functionality on Android 3.0 without a real device.</p>
+<p>General performance in the emulator is also slow. We're working hard to resolve the performance
+issues and it will improve in future tools releases. If you don't yet have a real device running
+Android 3.0, the emulator is still best way to evaluate your application's appearance and
+functionality on Android 3.0.</p>
 
 <p class="note"><strong>Tip:</strong> To improve the startup time for the emulator, enable snapshots
 for the AVD when you create it with the SDK and AVD Manager (there's a checkbox in the AVD creator
@@ -97,7 +122,7 @@
 
 
 
-<h2 id="Optimize">Optimize Your Application for Tablets and Similar Devices</h2>
+<h2 id="Optimizing">Optimizing Your App for Tablets</h2>
 
 <p>If you've already developed an application for an earlier version of Android, there are a few
 things you can do to optimize it for a tablet-style experience on Android 3.0 without changing the
@@ -142,21 +167,24 @@
 </pre>
     <p>By targeting the Android 3.0 platform, the system automatically applies the holographic theme
 to each activity when your application runs on an Android 3.0 device. The holographic theme
-provides a new design for widgets, such as buttons and text boxes, and restyles other
-visual elements. This is the standard theme in applications built for Android 3.0, so your
-application will look more at home by enabling the theme.</p>
-    <p>Additionally, the holographic theme enables the <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> in your activities when running on an
-Android 3.0 device. The Action Bar replaces the traditional title bar at the top of the activity
-window and provides the user access to the activity's Options Menu.</p>
+provides a new design for widgets, such as buttons and text boxes, and new styles for other
+visual elements. This is the standard theme for applications built for Android 3.0, so your
+application will look and feel consistent with the system and other applications when it is
+enabled.</p>
+    <p>Additionally, when an activity uses the holographic theme, the system enables the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> for the activity. The Action Bar
+replaces the traditional title bar at the top of the activity window and provides the user access to
+the activity's Options Menu.</p>
       </li>
-      <li>Continue to build your application against the minimum version specified by <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>,
-but install it on the Android 3.0 AVD. Repeat your tests to be sure that your user interface works
-well with the holographic theme.
+      <li>Build your application against the same version of the Android platform you have been
+using previously (such as the version declared in your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>),
+but install it on the Android 3.0 AVD. (You should not build against Android 3.0 unless you are
+using new APIs.) Repeat your tests to be sure that your user interface works well with the
+holographic theme.
         <p class="note"><strong>Note:</strong> If you have applied other themes directly to your
 activities, they will override the inherited holographic theme. To resolve this, you can use
-the <a href="{@docRoot}guide/topics/resources/providing-resources.html#VersionQualifier">system
+the <a href="{@docRoot}guide/topics/resources/providing-resources.html#VersionQualifier">platform
 version qualifier</a> to provide an alternative theme for Android 3.0 devices that's based on the
 holographic theme. For more information, read how to <a
 href="{@docRoot}guide/topics/ui/themes.html#SelectATheme">select a theme based on platform
@@ -177,15 +205,24 @@
 (wide), so you should be sure that your activities offer a layout that's optimized for a wide
 viewing area. <p>You can specify landscape resources with the <code>land</code> resource
 qualifier, but if you want alternative resources for an extra large landscape screen, you
-should use both <code>xlarge</code> and <code>land</code> qualifiers. For example, {@code
+should use both the <code>xlarge</code> and <code>land</code> qualifiers. For example, {@code
 res/layout-xlarge-land/}. The order of the qualifier names is important; see <a
 href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
 Providing Alternative Resources</a> for more information.</p></li>
-      <li>Button position: Consider whether the position of the most common buttons in your UI are
-easily accessible while holding a tablet with two hands.</li>
+      <li>Button position and size: Consider whether the position and size of the most common
+buttons in your UI make them easily accessible while holding a tablet with two hands. In some
+cases, you might need to resize buttons, especially if they use {@code "wrap_content"}
+as the width value. To enlarge the buttons, if necessary, you should either: add
+extra padding to the button; specify dimension values with {@code dp} units; or use {@code
+android:layout_weight} when the button is in a <a
+href="{@docRoot}guide/topics/ui/layout-objects.html#linearlayout">linear layout</a>. Use your
+best judgment of proportions for each screen size&mdash;you don't want the buttons to be too big,
+either.</li>
       <li>Font sizes: Be sure your application uses {@code sp} units when setting font
-sizes. This alone should ensure a readable experience on tablet-style devices. In some cases,
-however, you might want to consider larger font sizes for <code>xlarge</code> configurations.</li>
+sizes. This alone should ensure a readable experience on tablet-style devices, because it is a
+scale-independent pixel unit, which will resize as appropriate for the current screen configuration.
+In some cases, however, you still might want to consider larger font sizes for <code>xlarge</code>
+configurations.</li>
     </ul>
     <p>In general, always be sure that your application follows the <a
 href="{@docRoot}guide/practices/screens_support.html#screen-independence">Best Practices
@@ -197,7 +234,29 @@
 
 
 
-<h2 id="Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</h2>
+
+<h2 id="Upgrading">Upgrading or Developing a New App for Tablets</h2>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+  <h3>Use new APIs and remain backward-compatible</h3>
+<p>It is possible for you to upgrade your application with some new
+APIs <em>and</em> remain compatible with older versions of Android. Usually, this requires that you
+use techniques such as reflection to check for the availability of certain APIs at runtime. However,
+to help you add features from Android 3.0 without requiring you to change your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
+or build target, we're providing a static library called the "Android Compatibility package"
+(downloadable from the AVD and SDK Manager).</p>
+<p>This library includes APIs for <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">fragments</a>, <a
+href="{@docRoot}guide/topics/fundamentals/loaders.html">loaders</a>, and some updated classes. By
+simply adding this library to your Android project, you can use these APIs in your application and
+remain compatible with Android 1.6. For more information, see the blog post, <a
+href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">Fragments for
+All</a>.</p>
+</div>
+</div>
+
 
 <p>If you want to develop an application that's fully enhanced for tablet-type devices running
 Android 3.0, then you need to use new APIs in Android 3.0. This section introduces some of
@@ -206,9 +265,11 @@
 
 <h3>Declare the minimum system version</h3>
 
-<p>The first thing to do when you create a project for Android 3.0 is set your manifest's <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
-to {@code "11"}. For example:</p>
+<p>The first thing to do when you upgrade or create a project for Android 3.0 is set your manifest's
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+android:minSdkVersion}</a> to {@code "11"}. This declares that your application uses APIs available
+in Android 3.0 and greater, so it should not be available to devices running an older version of
+Android. For example:</p>
 
 <pre>
 &lt;manifest ... >
@@ -218,9 +279,11 @@
     &lt;application>
 &lt;/manifest>
 </pre>
-   
-<p>By targeting the Android 3.0 platform, the system automatically applies the new holographic theme
-to each of your activities.</p>
+
+<p>Not only is this necessary in order to declare the minimum API level your application requires,
+but it enables the new holographic theme to each of your activities. The holographic theme is the
+standard theme for the Android 3.0 system and all applications designed for it. It includes new
+designs for the system widgets and overall appearance.</p>
 
 <p>Additionally, the holographic theme enables the Action Bar for each activity.</p>
 
@@ -229,13 +292,14 @@
 
 <p>The Action Bar is a widget for activities that replaces the traditional title bar at the top of
 the screen. By default, the Action Bar includes the application logo on the left side, followed by
-the activity title, and any available items from the Options Menu on the right side.</p>
+the activity title, and access to items from the Options Menu in a drop-down list on the right
+side.</p>
 
-<p>You can enable items from your activity's Options Menu to appear directly in the Action Bar as
-"action items" by adding {@code showAsAction="ifRoom"} to specific items in your <a
+<p>You can enable items from the Options Menu to appear directly in the Action Bar as
+"action items" by adding {@code showAsAction="ifRoom"} to specific menu items in your <a
 href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. You can also add
 navigation features to the Action Bar, such as tabs, and use the application icon to navigate to
-your application's "home" activity or "up" the activity hierarchy.</p>
+your application's "home" activity or to navigate "up" the application's activity hierarchy.</p>
 
 <p>For more information, read <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the
 Action Bar</a>.</p>
@@ -244,11 +308,12 @@
 
 <h3>Divide your activities into fragments</h3>
 
-<p>A fragment represents a behavior or a portion of user interface in an activity. You can combine
-multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple
-activities. You can think of a fragment as a modular section of an activity, which has its own
-lifecycle, receives its own input events, and which you can add or remove while the activity is
-running.</p>
+<p>A fragment represents a behavior or a portion of user interface in an activity. You can think of
+a fragment as a modular section of an activity, which has its own lifecycle, receives its own input
+events, and which you can add or remove while the activity is running. Fragments are an optional
+component for your activities that allow you to build a multi-pane UI and reuse them in multiple
+activities. If you're building an application for tablets, we recommend that you use fragments to
+create activities that offer a more dynamic and flexible user interface.</p>
 
 <p>For example, a news application can use one fragment to show a list of articles on the left and
 another fragment to display an article on the right&mdash;both fragments appear in one activity,
@@ -262,8 +327,8 @@
 
 <h3>Use new animation APIs for transitions</h3>
 
-<p>An all new flexible animation framework allows you to animate arbitrary properties of any object
-(View, Drawable, Fragment, Object, or anything else). You can define several animation aspects
+<p>An all-new animation framework allows you to animate arbitrary properties of any object
+(such as a View, Drawable, Fragment, or anything else). You can define several animation aspects
 (such as duration, repeat, interpolation, and more) for an object's int, float, and hexadecimal
 color values, by default. That is, when an object has a property field for one of these types, you
 can change its value over time to affect an animation.</p>
@@ -279,8 +344,9 @@
 
 <h3>Enable hardware acceleration</h3>
 
-<p>You can now enable the OpenGL renderer for your application by setting {@code
-android:hardwareAccelerated="true"} in your manifest's <a
+<p>Android 3.0 adds a hardware-accelerated OpenGL renderer that gives a performance boost to most 2D
+graphics operations. You can enable hardware-accelerated rendering in your application by setting
+{@code android:hardwareAccelerated="true"} in your manifest's <a
 href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
 element or for individual <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
 &lt;activity&gt;}</a> elements. Hardware acceleration results in smoother animations, smoother
@@ -314,48 +380,16 @@
 href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform</a> document.</p>
 
 
-<h3>Publish your app for extra large screens</h3>
-
-<p>You should also decide whether your application is <em>only</em> for
-tablet-type devices (specifically, <em>xlarge</em> devices) or for all types of screen sizes.</p>
-
-<p>If you want your application to be available to all screen sizes (for example, for all
-phones and tablets), there's nothing you need to do. By default, an application with <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
-android:minSdkVersion}</a> set to {@code "4"} or higher will resize to fit any screen size.</p>
-
-<p>If your application is <em>only</em> for <em>xlarge</em> screens, include the <a
-href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
-&lt;supports-screens&gt;}</a> element in your manifest and declare that the application supports
-only <em>xlarge</em> screens, by declaring all other sizes {@code "false"}. For example:</p>
-
-<pre>
-&lt;manifest ... >
-    ...
-    &lt;supports-screens android:smallScreens="false"
-                      android:normalScreens="false"
-                      android:largeScreens="false"
-                      android:xlargeScreens="true" /&gt;
-    &lt;application ... >
-        ...
-    &lt;application>
-&lt;/manifest>
-</pre>
-
-<p>With this declaration, you indicate that your application does not support any screen size except
-extra large. External services such as Android Market may then use this information to filter your
-application from devices that do not have an extra large screen.</p>
-
-
 
 <h3>Look at some samples</h3>
 
-<p>Many of the new features and APIs that are described in the <a
-href="{@docRoot}sdk/android-3.0.html#api">Android 3.0 Platform Preview</a> also have accompanying
-samples that can help you understand how to use them. To get the samples, download them from the SDK
-repository using the Android SDK Manager. After downloading the samples ("Samples for SDK API 11"), 
-you can find them in <code>&lt;sdk_root&gt;/samples/android-11/</code>. The links below can help you
-find samples for the features you are interested in:</p>
+<p>Many of the new features and APIs that are described above and in the <a
+href="{@docRoot}sdk/android-3.0.html#api">Android 3.0 Platform</a> document also have accompanying
+samples that allow you to preview the effects and can help you understand how to use them. To get
+the samples, download them from the SDK repository <a href="{@docRoot}sdk/adding-components.html"
+>using the Android SDK and AVD Manager</a>. After downloading the samples ("Samples for SDK API
+11"), you can find them in <code>&lt;sdk_root&gt;/samples/android-11/</code>. The following list
+provides links to the browsable source code for some of the samples:</p>
 
 <ul>
   <li><a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a>:
@@ -395,3 +429,248 @@
 graphics.</li>
 </ul>
 
+
+
+<h2 id="ManagingAppDist">Managing App Distribution Based on Screen Configuration</h2>
+
+<p>If your manifest file has either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
+or <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+android:targetSdkVersion}</a> set to {@code "4"} or higher, then the Android system will scale your
+application's layout and assets to fit the current device screen, whether the device screen is
+smaller or larger than the one for which you originally designed your application. As such, you
+should always test your application on real or <a
+href="{@docRoot}guide/developing/devices/index.html">virtual devices</a> with various screen sizes
+and densities.</p>
+
+<p>Although we recommend that you design your application to function properly on multiple
+configurations of screen size and density, you can instead choose to limit the distribution of your
+application to certain types of screens, such as only tablets or only mobile devices. To do so, you
+can add elements to your Android manifest file that enable filtering based on screen configuration
+by external services such as Android Market.</p>
+
+<p>However, before you decide to restrict your application to certain screen configurations, you
+should understand the techniques for <a
+href="{@docRoot}guide/practices/screens_support.html">supporting multiple screens</a> and employ
+them to the best of your ability. By supporting multiple screens, your application can be made
+available to the greatest number of users with different devices.</p>
+
+
+<h3 id="FilteringTabletApps">Filtering a tablet application from mobile devices</h3>
+
+<p>If the system scaling adversely affects your application UI when scaling your application down
+for smaller screens, you should add <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">alternative
+layouts</a> for smaller screens to adjust your layout. However, sometimes your layout still might
+not fit a smaller screen or you've explicitly designed your application only for tablets and other
+large devices. In this case, you can manage the availability of your application to smaller screens
+by using the <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+&lt;supports-screens>}</a> manifest element.</p>
+
+<p>For example, if you want your application to be available only to extra large
+screens, you can declare the element in your manifest like this:</p>
+
+<pre>
+&lt;manifest ... >
+    ...
+    &lt;supports-screens android:smallScreens="false"
+                      android:normalScreens="false"
+                      android:largeScreens="false"
+                      android:xlargeScreens="true" /&gt;
+    &lt;application ... >
+        ...
+    &lt;application>
+&lt;/manifest>
+</pre>
+
+<p>External services such as Android Market read this manifest element and use it to ensure that
+your application is available only to devices with an extra large screen.</p>
+
+<p class="note"><strong>Note:</strong> If you use the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+&lt;supports-screens>}</a> element for the reverse scenario (when your application is not compatible
+with <em>larger</em> screens) and set the larger screen size attributes to {@code "false"}, then
+external services such as Android Market <strong>do not</strong> apply filtering. Your application
+will still be available to larger screens, but when it runs, it will not fill the screen&mdash;the
+system will draw it in a "postage stamp" window that's the same relative size as the screen size
+that your application does support. If you want to prevent your application from being downloaded on
+larger screens, see the following section.</p>
+
+
+<h3 id="FilteringMobileApps">Filtering a mobile device application from tablets</h3>
+
+<p>Because Android automatically scales applications to fit larger screens, you shouldn't
+need to filter your application from larger screens. However, you might discover that your
+application can't scale up or perhaps you've decided to publish two versions of your application
+that each deliver different features for different screen configurations, so you don't want
+larger devices to download the version designed for smaller screens. In such a case, you can
+use the <a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code
+&lt;compatible-screens>}</a> element to manage the distribution of your application based on the
+combination of screen size and density. External services such as
+Android Market uses this information to apply filtering to your application, so that only devices
+that have a screen configuration with which you declare compatibility can download your
+application.</p>
+
+<p>The <a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code
+&lt;compatible-screens>}</a> element must contain one or more {@code &lt;screen&gt;} elements,
+which each specify a screen configuration with which your application is compatible, using both
+the {@code android:screenSize} and {@code android:screenDensity} attributes. Each {@code
+&lt;screen&gt;} element <strong>must include both attributes</strong> to specify an individual
+screen configuration&mdash;if either attribute is missing, then the element is invalid
+(external services such as Android Market will ignore it).</p>
+
+<p>For example, if your application is compatible with only small and normal screens, regardless
+of screen density, then you must specify eight different {@code &lt;screen&gt;} elements,
+because each screen size has four density configurations. You must declare each one of
+these; any combination of size and density that you do <em>not</em> specify is considered a screen
+configuration with which your application is <em>not</em> compatible. Here's what the manifest
+entry looks like if your application is compatible with only small and normal screens:</p>
+
+<pre>
+&lt;manifest ... >
+    ...
+    &lt;compatible-screens>
+        &lt;!-- all small size screens -->
+        &lt;screen android:screenSize="small" android:screenDensity="ldpi" />
+        &lt;screen android:screenSize="small" android:screenDensity="mdpi" />
+        &lt;screen android:screenSize="small" android:screenDensity="hdpi" />
+        &lt;screen android:screenSize="small" android:screenDensity="xhdpi" />
+        &lt;!-- all normal size screens -->
+        &lt;screen android:screenSize="normal" android:screenDensity="ldpi" />
+        &lt;screen android:screenSize="normal" android:screenDensity="mdpi" />
+        &lt;screen android:screenSize="normal" android:screenDensity="hdpi" />
+        &lt;screen android:screenSize="normal" android:screenDensity="xhdpi" />
+    &lt;/compatible-screens>
+    &lt;application ... >
+        ...
+    &lt;application>
+&lt;/manifest>
+</pre>
+
+<p class="note"><strong>Note:</strong> Although you can also use the <a
+href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code
+&lt;compatible-screens>}</a> element for the reverse scenario (when your application is not
+compatible with smaller screens), it's easier if you instead use the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+&lt;supports-screens>}</a> as discussed in the previous section, because it doesn't require you
+to specify each screen density your application supports.</p>
+
+<p>Remember, you should strive to make your application available to as many devices as possible by
+applying all necessary techniques for <a
+href="{@docRoot}guide/practices/screens_support.html">supporting multiple screens</a>. You should
+then use the <a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code
+&lt;compatible-screens>}</a> element to filter your application from certain devices only when you
+cannot offer compatibility on all screen configurations or you have decided to provide
+multiple versions of your application, each for a different set of screen configurations.</p>
+
+
+
+<h2 id="Issues">Other Issues</h2>
+
+<p>Whether you decide to optimize or upgrade your application for tablet-type devices, you
+should be aware that the functionality and availability of your application on new devices
+might be affected by the following issues:</p>
+
+<ul>
+  <li><a href="#Landscape">Tablets are often designed for use in the landscape orientation</a>
+  <p>Tablets and similar devices often have a screen that uses the landscape orientation
+by default. If your application assumes a portrait orientation or locks into portrait
+orientation, you should update your application to support landscape.</p></li>
+  <li><a href="#Telephony">Not all devices have telephony or other features</a>
+  <p>If your application declares the {@code "android.hardware.telephony"} feature in the manifest,
+then it will not be available to devices that do not offer telephony (such as tablets), based on
+Android Market filtering. If your application can function properly without telephony, you should
+update your application to gracefully disable the telephony features when not available on a
+device.</p></li>
+</ul>
+
+
+<h3 id="Landscape">Adding support for landscape screens</h3>
+
+<p>Although tablets can rotate to operate in any orientation, they are often designed for
+landscape orientation and that is how most users will use them. So, you should ensure that your
+application can function in landscape. Even if you want to avoid rotating the screen while your
+application is running, you should not assume that portrait is the device's default orientation. You
+should either ensure that your layout is usable in both portrait and landscape orientations or
+provide an <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources" 
+>alternative layout resource</a> for landscape orientation.</p>
+
+<p>If you believe your application or game provides its best experience when the screen is tall,
+consider that tablets and similar devices have a screen that's as tall or taller in landscape
+orientation than a phone in portrait orientation. With that in mind, you might be able to add a
+landscape design that adds padding or extra landscape scenery on the left and right sides, so
+the primary screen space still remains taller than it is wide.</p>
+
+<p>Ideally, your application should handle all orientation changes instead of locking into one
+orientation. When the user rotates the screen, the system restarts the current activity by calling
+{@link android.app.Activity#onDestroy onDestroy()} and {@link android.app.Activity#onCreate
+onCreate()}) in immediate succession. You should design your activity to account for these changes
+in the lifecycle, so the activity can save and restore its state. You can learn about the
+necessary lifecycle callback methods and how to save and restore the activity state in the <a
+href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activities</a>
+document. If your activity state is more complex and cannot retain it using the normal
+lifecycle callback methods, you can use alternative techniques described in <a
+href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>.</p>
+
+<p>In the worst-case scenario, however, you can avoid orientation changes by using the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#screen">{@code
+android:screenOrientation}</a> attribute in the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+element. Instead of locking the orientation in landscape or portrait, however, you should
+specify a value of {@code "nosensor"}. This way, your activity uses whatever orientation the
+device specifies as its natural orientation and the screen will not rotate. You should still
+avoid using the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#screen">{@code
+android:screenOrientation}</a> attribute, but because it's sometimes necessary to lock the
+screen into one orientation, it's best if you do so in a way that uses the device's natural
+orientation instead of assuming one specific orientation.</p>
+
+<p>If your application uses the orientation sensors, such as the accelerometer (with the {@link
+android.hardware.SensorManager} APIs), also be aware that the landscape screen can also cause
+problems, due to false assumptions about which orientation is the natural position. For more
+information about how you should properly handle rotation changes when using the orientation
+sensors, read the blog post, <a
+href="http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html">One
+Screen Turn Deserves Another</a>.</p>
+
+
+
+<h3 id="Telephony">Using telephony or other variable features</h3>
+
+<p>Tablets and similar devices might not include support for telephony, so they can't make
+traditional phone calls or handle SMS. Some devices might also omit
+other hardware features, such as Bluetooth. If your application uses these features, then your
+manifest file probably already includes (or should include) a declaration of the feature with the <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code &lt;uses-feature&gt;}</a>
+element. Doing so prevents devices that do not declare support for the feature from downloading
+your applications. For example:</p>
+
+<pre>&lt;uses-feature android:name="android.hardware.telephony" /></pre>
+
+<p>By default, this declares that your application <em>requires</em> telephony features. So,
+external services such as Android Market use this information to filter your application from
+devices that do not offer telephony.</p>
+
+<p>If, however, your application uses, but does not require the feature, you should
+add to this element, {@code android:required="false"}. For example:</p>
+
+<pre>&lt;uses-feature android:name="android.hardware.telephony" android:required="false" /></pre>
+
+<p>This indicates that your application uses the feature, but is still functional if the feature is
+not available. So, it should still be available to devices that don't provide telephony hardware
+(or telephony features), such as tablets.</p>
+
+<p>Then in your application code, you must gracefully disable the features that use telephony
+when it's not available. You can check whether the feature is available using {@link
+android.content.pm.PackageManager#hasSystemFeature PackageManager.hasSystemFeature()}. For
+example:</p>
+
+<pre>
+PackageManager pm = getPackageManager();
+boolean hasTelephony = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+</pre>
+
+<p>For more information about these
+issues and how to future-proof your application for different hardware, read the blog post <a
+href="http://android-developers.blogspot.com/2010/10/five-steps-to-future-hardware-happiness.html">
+The Five Steps to Future Hardware Happiness</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/manifest/compatible-screens-element.jd b/docs/html/guide/topics/manifest/compatible-screens-element.jd
index 8669874..5c89869 100644
--- a/docs/html/guide/topics/manifest/compatible-screens-element.jd
+++ b/docs/html/guide/topics/manifest/compatible-screens-element.jd
@@ -101,6 +101,38 @@
     </dd>
   </dl>
 </dd>
+
+<dt>example</dt>
+<dd>
+<p>If your application is compatible with only small and normal screens, regardless
+of screen density, then you must specify eight different {@code &lt;screen&gt;} elements,
+because each screen size has four different density configurations. You must declare each one of
+these; any combination of size and density that you do <em>not</em> specify is considered a screen
+configuration with which your application is <em>not</em> compatible. Here's what the manifest
+entry looks like if your application is compatible with only small and normal screens:</p>
+
+<pre>
+&lt;manifest ... >
+    ...
+    &lt;compatible-screens>
+        &lt;!-- all small size screens -->
+        &lt;screen android:screenSize="small" android:screenDensity="ldpi" />
+        &lt;screen android:screenSize="small" android:screenDensity="mdpi" />
+        &lt;screen android:screenSize="small" android:screenDensity="hdpi" />
+        &lt;screen android:screenSize="small" android:screenDensity="xhdpi" />
+        &lt;!-- all normal size screens -->
+        &lt;screen android:screenSize="normal" android:screenDensity="ldpi" />
+        &lt;screen android:screenSize="normal" android:screenDensity="mdpi" />
+        &lt;screen android:screenSize="normal" android:screenDensity="hdpi" />
+        &lt;screen android:screenSize="normal" android:screenDensity="xhdpi" />
+    &lt;/compatible-screens>
+    &lt;application ... >
+        ...
+    &lt;application>
+&lt;/manifest>
+</pre>
+</dd>
+
 <dt>introduced in:</dt>
 <dd>API Level 9</dd>
 <dt>see also:</dt>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 60030f0..1583dee 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -596,7 +596,7 @@
     </tr>
 -->
     <tr id="VersionQualifier">
-      <td>System Version (API Level)</td>
+      <td>Platform Version (API Level)</td>
       <td>Examples:<br/>
         <code>v3</code><br/>
         <code>v4</code><br/>
@@ -609,7 +609,7 @@
 href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a> document for more information
 about these values.</p>
         <p class="caution"><strong>Caution:</strong> Android 1.5 and 1.6 only match resources
-with this qualifier when it exactly matches the system version. See the section below about <a
+with this qualifier when it exactly matches the platform version. See the section below about <a
 href="#KnownIssues">Known Issues</a> for more information.</p>
       </td>
     </tr>
@@ -975,7 +975,7 @@
 
 <p>The correct behavior is for the system to match resources marked with a <a
 href="#VersionQualifier">version qualifier</a> equal
-to or less than the system version on the device, but on Android 1.5 and 1.6, (API Level 3 and 4),
+to or less than the platform version on the device, but on Android 1.5 and 1.6, (API Level 3 and 4),
 there is a bug that causes the system to match resources marked with the version qualifier
 only when it exactly matches the version on the device.</p>
 
diff --git a/docs/html/index.jd b/docs/html/index.jd
index f1bb59f..7fcd7b6 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -13,7 +13,7 @@
                             <!-- total max width is 520px -->
                                   <img src="{@docRoot}assets/images/home/GDC2011.png" alt="Android at GDC 2011" width="203px" style="padding-left:22px;padding-bottom:28px;padding-top:22px;"/>
                                   <div id="announcement" style="width:275px">
-    <p>Android will be at the <a href="http://www.gdconf.com/">2011 Game Developers Conference</a> in San Francisco, from March 1st to 4th. We're looking forward to seeing you there!</p>
+    <p>Thanks to everyone who visited us at the <a href="http://www.gdconf.com/">Game Developers Conference</a> in San Francisco. We're looking forward to seeing your games running on Android!</p>
     <p><a href="http://android-developers.blogspot.com/2011/02/heading-for-gdc.html">Learn more &raquo;</a></p>
                                 </div> <!-- end annoucement -->
                             </div> <!-- end annoucement-block -->
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index d745cea..73d7fc1 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,7 +52,7 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="460"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:3.9,6.3,31.4,57.6,0.8&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:3.0,4.8,29.0,61.3,0.7,1.0,0.2&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0&chco=c4df9b,6fad0c" />
 
 <table>
 <tr>
@@ -60,14 +60,16 @@
   <th>API Level</th>
   <th>Distribution</th>
 </tr>
-<tr><td>Android 1.5</td><td>3</td><td>3.9%</td></tr> 
-<tr><td>Android 1.6</td><td>4</td><td>6.3%</td></tr> 
-<tr><td>Android 2.1</td><td>7</td><td>31.4%</td></tr> 
-<tr><td>Android 2.2</td><td>8</td><td>57.6%</td></tr> 
-<tr><td>Android 2.3</td><td>9</td><td>0.8%</td></tr> 
+<tr><td>Android 1.5</td><td>3</td><td>3.0%</td></tr> 
+<tr><td>Android 1.6</td><td>4</td><td>4.8%</td></tr> 
+<tr><td>Android 2.1</td><td>7</td><td>29.0%</td></tr> 
+<tr><td>Android 2.2</td><td>8</td><td>61.3%</td></tr> 
+<tr><td>Android 2.3</td><td>9</td><td>0.7%</td></tr> 
+<tr><td>Android 2.3.3</td><td>10</td><td>1.0%</td></tr> 
+<tr><td>Android 3.0</td><td>11</td><td>0.2%</td></tr> 
 </table>
 
-<p><em>Data collected during two weeks ending on February 2, 2011</em></p>
+<p><em>Data collected during two weeks ending on March 15, 2011</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -96,9 +98,9 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C10/15%7C11/01%7C11/15%7C12/01%7C12/15%7C01/01%7C01/15%7C02/01%7C1%3A%7C2010%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.8,99.7,99.8,99.9,99.9,99.9,100.0,99.9,99.8,99.7,99.6,99.4,99.1|84.3,86.5,87.9,89.2,90.2,91.1,92.0,92.7,93.4,94.1,94.8,95.1,95.2|64.0,68.1,70.3,72.1,73.8,75.3,77.4,79.6,82.2,84.4,86.8,87.8,88.9|4.3,11.3,27.8,32.1,33.4,34.5,37.1,40.5,44.3,47.7,51.4,53.8,57.5&chm=tAndroid 1.5,7caa36,0,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid 1.6,5b831d,1,0,15,,t::-5|b,aadb5e,1,2,0|tAndroid 2.1,38540b,2,0,15,,t::-5|b,91da1e,2,3,0|tAndroid 2.2,131d02,3,1,15,,t::-5|B,6fad0c,3,4,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2&chco=add274,94d134,73ad18,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C09/15%7C10/01%7C10/15%7C11/01%7C11/15%7C12/01%7C12/15%7C01/01%7C01/15%7C02/01%7C02/15%7C03/01%7C03/15%7C1%3A%7C2010%7C%7C%7C%7C%7C%7C%7C2011%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.9,99.9,99.9,100.0,99.9,99.8,99.7,100.0,99.9,99.9,99.9,100.0,99.8|89.2,90.2,91.1,92.0,92.7,93.4,94.1,95.2,95.6,96.0,96.3,96.7,96.8|72.1,73.8,75.3,77.4,79.6,82.2,84.4,87.2,88.3,89.7,90.5,91.5,92.0|32.1,33.4,34.5,37.1,40.5,44.3,47.7,51.8,54.3,58.3,59.7,61.5,63.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.4,0.6,0.7,0.8,1.1,1.7|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0&chm=tAndroid 1.5,7caa36,0,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid 1.6,689326,1,0,15,,t::-5|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
 
-<p><em>Last historical dataset collected during two weeks ending on February 2, 2011</em></p>
+<p><em>Last historical dataset collected during two weeks ending on March 15, 2011</em></p>
 
 
 </div><!-- end dashboard-panel -->
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 97717fe..ece9d4a 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
 page.title=ADT Plugin for Eclipse
-adt.zip.version=10.0.0
-adt.zip.download=ADT-10.0.0.zip
-adt.zip.bytes=4243777
-adt.zip.checksum=bf88bff62bc45c3b6d062e2beed67765
+adt.zip.version=10.0.1
+adt.zip.download=ADT-10.0.1.zip
+adt.zip.bytes=5096182
+adt.zip.checksum=e26a77db08377bdd2e62edeb9a3e3701
 
 @jd:body
 
@@ -33,7 +33,7 @@
 <p>ADT extends the capabilities of Eclipse to let you quickly set up new Android
 projects, create an application UI, add components based on the Android
 Framework API, debug your applications using the Android SDK tools, and even
-export signed (or unsigned) APKs in order to distribute your application.</p>
+export signed (or unsigned) {@code .apk} files in order to distribute your application.</p>
 
 <p>Developing in Eclipse with ADT is highly recommended and is the fastest way
 to get started. With the guided project setup it provides, as well as tools
@@ -100,6 +100,36 @@
   <a href="#" onclick="return toggleDiv(this)">
         <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
 width="9px" />
+ADT 10.0.1</a> <em>(March 2011)</em>
+  <div class="toggleme">
+
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd>ADT 10.0.1 is designed for use with SDK Tools r10. If you haven't
+already installed SDK Tools r10 into your SDK, use the Android SDK and AVD Manager to do
+so.</dd>
+
+<dt>General notes:</dt>
+<dd>
+  <ul>
+    <li>Temporary work-around to resolve the rare cases in which the layout editor will
+not open.</li>
+    <li>Fix issue in which ADT 10.0.0 would install on Eclipse 3.4 and lower, even though ADT
+requires Eclipse 3.5 or higher (as of 10.0.0).</li>
+  </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+
+
+<div class="toggleable closed">
+  <a href="#" onclick="return toggleDiv(this)">
+        <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
 ADT 10.0.0</a> <em>(February 2011)</em>
   <div class="toggleme">
 
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index a1c26db..6b9a5ce 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -129,7 +129,7 @@
       <span style="display:none" class="zh-TW"></span>
       </h2>
     <ul>
-      <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 10.0.0
+      <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 10.0.1
       <span style="display:none" class="de"></span>
       <span style="display:none" class="es"></span>
       <span style="display:none" class="fr"></span>
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
index 3e02093..c0bff0e 100644
--- a/drm/common/DrmSupportInfo.cpp
+++ b/drm/common/DrmSupportInfo.cpp
@@ -45,7 +45,7 @@
     for (unsigned int i = 0; i < mMimeTypeVector.size(); i++) {
         const String8 item = mMimeTypeVector.itemAt(i);
 
-        if (String8("") != mimeType && item.find(mimeType) != -1) {
+        if (!strcasecmp(item.string(), mimeType.string())) {
             return true;
         }
     }
@@ -56,7 +56,7 @@
     for (unsigned int i = 0; i < mFileSuffixVector.size(); i++) {
         const String8 item = mFileSuffixVector.itemAt(i);
 
-        if (item.find(fileType) != -1) {
+        if (!strcasecmp(item.string(), fileType.string())) {
             return true;
         }
     }
diff --git a/drm/drmserver/Android.mk b/drm/drmserver/Android.mk
index 5df2ff8..f94f9a3 100644
--- a/drm/drmserver/Android.mk
+++ b/drm/drmserver/Android.mk
@@ -19,8 +19,7 @@
 LOCAL_SRC_FILES:= \
     main_drmserver.cpp \
     DrmManager.cpp \
-    DrmManagerService.cpp \
-    StringTokenizer.cpp
+    DrmManagerService.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libutils \
diff --git a/drm/drmserver/StringTokenizer.cpp b/drm/drmserver/StringTokenizer.cpp
deleted file mode 100644
index 2130a00..0000000
--- a/drm/drmserver/StringTokenizer.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 "StringTokenizer.h"
-
-using namespace android;
-
-StringTokenizer::StringTokenizer(const String8& string, const String8& delimiter) {
-    splitString(string, delimiter);
-}
-
-void StringTokenizer::splitString(const String8& string, const String8& delimiter) {
-    for (unsigned int i = 0; i < string.length(); i++) {
-        unsigned int position = string.find(delimiter.string(), i);
-        if (string.length() != position) {
-            String8 token(string.string()+i, position-i);
-            if (token.length()) {
-                mStringTokenizerVector.push(token);
-                i = position + delimiter.length() - 1;
-            }
-        } else {
-            mStringTokenizerVector.push(String8(string.string()+i, string.length()-i));
-            break;
-        }
-    }
-}
-
-StringTokenizer::Iterator StringTokenizer::iterator() {
-    return Iterator(this);
-}
-
-StringTokenizer::Iterator::Iterator(const StringTokenizer::Iterator& iterator) :
-    mStringTokenizer(iterator.mStringTokenizer),
-    mIndex(iterator.mIndex) {
-}
-
-StringTokenizer::Iterator& StringTokenizer::Iterator::operator=(
-            const StringTokenizer::Iterator& iterator) {
-    mStringTokenizer = iterator.mStringTokenizer;
-    mIndex = iterator.mIndex;
-    return *this;
-}
-
-bool StringTokenizer::Iterator::hasNext() {
-    return mIndex < mStringTokenizer->mStringTokenizerVector.size();
-}
-
-String8& StringTokenizer::Iterator::next() {
-    String8& value = mStringTokenizer->mStringTokenizerVector.editItemAt(mIndex);
-    mIndex++;
-    return value;
-}
-
diff --git a/drm/java/android/drm/DrmErrorEvent.java b/drm/java/android/drm/DrmErrorEvent.java
index 20fd8aa..90adb47f 100644
--- a/drm/java/android/drm/DrmErrorEvent.java
+++ b/drm/java/android/drm/DrmErrorEvent.java
@@ -53,6 +53,10 @@
      * associated with all DRM schemes.
      */
     public static final int TYPE_REMOVE_ALL_RIGHTS_FAILED = 2007;
+    /**
+     * TYPE_ACQUIRE_DRM_INFO_FAILED, when failed to acquire DrmInfo.
+     */
+    public static final int TYPE_ACQUIRE_DRM_INFO_FAILED = 2008;
 
     /**
      * constructor to create DrmErrorEvent object with given parameters
diff --git a/drm/java/android/drm/DrmInfoEvent.java b/drm/java/android/drm/DrmInfoEvent.java
index a778e06..72f37ea 100644
--- a/drm/java/android/drm/DrmInfoEvent.java
+++ b/drm/java/android/drm/DrmInfoEvent.java
@@ -45,6 +45,10 @@
      * already done for the given account.
      */
     public static final int TYPE_ACCOUNT_ALREADY_REGISTERED = 5;
+    /**
+     * TYPE_RIGHTS_REMOVED, when the rights has been removed.
+     */
+    public static final int TYPE_RIGHTS_REMOVED = 6;
 
     /**
      * constructor to create DrmInfoEvent object with given parameters
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 782ffdb..aa56159 100644
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -181,7 +181,7 @@
         }
 
         public void handleMessage(Message msg) {
-            DrmInfoEvent event = null;
+            DrmInfoEvent info = null;
             DrmErrorEvent error = null;
 
             switch (msg.what) {
@@ -197,11 +197,15 @@
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
-                    event = new DrmInfoEvent(uniqueId, infoType, message);
+                    info = new DrmInfoEvent(uniqueId, infoType, message);
                     break;
                 }
-                case DrmInfoEvent.TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT: {
-                    event = new DrmInfoEvent(uniqueId, infoType, message);
+                case DrmInfoEvent.TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT:
+                case DrmInfoEvent.TYPE_RIGHTS_INSTALLED:
+                case DrmInfoEvent.TYPE_WAIT_FOR_RIGHTS:
+                case DrmInfoEvent.TYPE_ACCOUNT_ALREADY_REGISTERED:
+                case DrmInfoEvent.TYPE_RIGHTS_REMOVED: {
+                    info = new DrmInfoEvent(uniqueId, infoType, message);
                     break;
                 }
                 default:
@@ -209,8 +213,8 @@
                     break;
                 }
 
-                if (null != mOnInfoListener && null != event) {
-                    mOnInfoListener.onInfo(DrmManagerClient.this, event);
+                if (null != mOnInfoListener && null != info) {
+                    mOnInfoListener.onInfo(DrmManagerClient.this, info);
                 }
                 if (null != mOnErrorListener && null != error) {
                     mOnErrorListener.onError(DrmManagerClient.this, error);
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
index 9ad195f..8029138 100644
--- a/drm/libdrmframework/include/PlugInManager.h
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -230,11 +230,9 @@
      */
     bool isPlugIn(const struct dirent* pEntry) const {
         String8 sName(pEntry->d_name);
-        int extentionPos = sName.size() - String8(PLUGIN_EXTENSION).size();
-        if (extentionPos < 0) {
-            return false;
-        }
-        return extentionPos == (int)sName.find(PLUGIN_EXTENSION);
+        String8 extension(sName.getPathExtension());
+        // Note that the plug-in extension must exactly match case
+        return extension == String8(PLUGIN_EXTENSION);
     }
 
     /**
diff --git a/drm/libdrmframework/include/StringTokenizer.h b/drm/libdrmframework/include/StringTokenizer.h
deleted file mode 100644
index 70e7558..0000000
--- a/drm/libdrmframework/include/StringTokenizer.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 __STRING_TOKENIZER_H__
-#define __STRING_TOKENIZER_H__
-
-#include <drm/drm_framework_common.h>
-
-namespace android {
-
-/**
- * This is an utility class for String manipulation.
- *
- */
-class StringTokenizer {
-public:
-    /**
-     * Iterator for string tokens
-     */
-    class Iterator {
-        friend class StringTokenizer;
-    private:
-        Iterator(StringTokenizer* StringTokenizer)
-         : mStringTokenizer(StringTokenizer), mIndex(0) {}
-
-    public:
-        Iterator(const Iterator& iterator);
-        Iterator& operator=(const Iterator& iterator);
-        virtual ~Iterator() {}
-
-    public:
-        bool hasNext();
-        String8& next();
-
-    private:
-        StringTokenizer* mStringTokenizer;
-        unsigned int mIndex;
-    };
-
-public:
-    /**
-     * Constructor for StringTokenizer
-     *
-     * @param[in] string Complete string data
-     * @param[in] delimeter Delimeter used to split the string
-     */
-    StringTokenizer(const String8& string, const String8& delimeter);
-
-    /**
-     * Destructor for StringTokenizer
-     */
-    ~StringTokenizer() {}
-
-private:
-    /**
-     * Splits the string according to the delimeter
-     */
-    void splitString(const String8& string, const String8& delimeter);
-
-public:
-    /**
-     * Returns Iterator object to walk through the split string values
-     *
-     * @return Iterator object
-     */
-    Iterator iterator();
-
-private:
-    Vector<String8> mStringTokenizerVector;
-};
-
-};
-#endif /* __STRING_TOKENIZER_H__ */
-
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index 78ff97b..acc5bd8 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -42,7 +42,7 @@
     *                  floats long
     */
     public Matrix2f(float[] dataArray) {
-        mMat = new float[2];
+        mMat = new float[4];
         System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
     }
 
diff --git a/include/drm/DrmInfoEvent.h b/include/drm/DrmInfoEvent.h
index 7b409ff..add33d3 100644
--- a/include/drm/DrmInfoEvent.h
+++ b/include/drm/DrmInfoEvent.h
@@ -43,6 +43,8 @@
     //! TYPE_ACCOUNT_ALREADY_REGISTERED, when registration has been
     //! already done for the given account.
     static const int TYPE_ACCOUNT_ALREADY_REGISTERED = 5;
+    //! TYPE_RIGHTS_REMOVED, when the rights has been removed.
+    static const int TYPE_RIGHTS_REMOVED = 6;
 
     /**
      * The following constant values should be in sync with DrmErrorEvent.java
@@ -61,6 +63,11 @@
     static const int TYPE_NO_INTERNET_CONNECTION = 2005;
     //! TYPE_PROCESS_DRM_INFO_FAILED, when failed to process DrmInfo.
     static const int TYPE_PROCESS_DRM_INFO_FAILED = 2006;
+    //! TYPE_REMOVE_ALL_RIGHTS_FAILED, when failed to remove all the rights objects
+    //! associated with all DRM schemes.
+    static const int TYPE_REMOVE_ALL_RIGHTS_FAILED = 2007;
+    //! TYPE_ACQUIRE_DRM_INFO_FAILED, when failed to acquire DrmInfo.
+    static const int TYPE_ACQUIRE_DRM_INFO_FAILED = 2008;
 
 public:
     /**
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 4cdece9..7992105 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -33,6 +33,8 @@
 public:
     SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);
 
+    sp<ISurfaceTexture> getISurfaceTexture() const;
+
 private:
 
     // can't be copied
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 0ac34d0..0fc1ddf 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -110,6 +110,14 @@
      * conjunction with this query.
      */
     NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+
+    /* Get the concrete type of a ANativeWindow.  See below for the list of
+     * possible return values.
+     *
+     * This query should not be used outside the Android framework and will
+     * likely be removed in the near future.
+     */
+    NATIVE_WINDOW_CONCRETE_TYPE,
 };
 
 /* valid operations for the (*perform)() hook */
@@ -142,6 +150,13 @@
     NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
 };
 
+/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */
+enum {
+    NATIVE_WINDOW_FRAMEBUFFER,                  // FramebufferNativeWindow
+    NATIVE_WINDOW_SURFACE,                      // Surface
+    NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT,       // SurfaceTextureClient
+};
+
 struct ANativeWindow 
 {
 #ifdef __cplusplus
diff --git a/include/utils/String8.h b/include/utils/String8.h
index 6b49ff5..4163697 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -165,8 +165,8 @@
     String8 walkPath(String8* outRemains = NULL) const;
 
     /*
-     * Return the filename extension.  This is the last '.' and up to
-     * four characters that follow it.  The '.' is included in case we
+     * Return the filename extension.  This is the last '.' and any number
+     * of characters that follow it.  The '.' is included in case we
      * decide to expand our definition of what constitutes an extension.
      *
      * "/tmp/foo/bar.c" --> ".c"
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 3bed959..5c6d71b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -283,11 +283,42 @@
     sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
     float tx, ty, sx, sy;
     if (!mCurrentCrop.isEmpty()) {
-        tx = float(mCurrentCrop.left) / float(buf->getWidth());
-        ty = float(buf->getHeight() - mCurrentCrop.bottom) /
-                float(buf->getHeight());
-        sx = float(mCurrentCrop.width()) / float(buf->getWidth());
-        sy = float(mCurrentCrop.height()) / float(buf->getHeight());
+        // In order to prevent bilinear sampling at the of the crop rectangle we
+        // may need to shrink it by 2 texels in each direction.  Normally this
+        // would just need to take 1/2 a texel off each end, but because the
+        // chroma channels will likely be subsampled we need to chop off a whole
+        // texel.  This will cause artifacts if someone does nearest sampling
+        // with 1:1 pixel:texel ratio, but it's impossible to simultaneously
+        // accomodate the bilinear and nearest sampling uses.
+        //
+        // If nearest sampling turns out to be a desirable usage of these
+        // textures then we could add the ability to switch a SurfaceTexture to
+        // nearest-mode.  Preferably, however, the image producers (video
+        // decoder, camera, etc.) would simply not use a crop rectangle (or at
+        // least not tell the framework about it) so that the GPU can do the
+        // correct edge behavior.
+        int xshrink = 0, yshrink = 0;
+        if (mCurrentCrop.left > 0) {
+            tx = float(mCurrentCrop.left + 1) / float(buf->getWidth());
+            xshrink++;
+        } else {
+            tx = 0.0f;
+        }
+        if (mCurrentCrop.right < buf->getWidth()) {
+            xshrink++;
+        }
+        if (mCurrentCrop.bottom < buf->getHeight()) {
+            ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) /
+                    float(buf->getHeight());
+            yshrink++;
+        } else {
+            ty = 0.0f;
+        }
+        if (mCurrentCrop.top > 0) {
+            yshrink++;
+        }
+        sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth());
+        sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight());
     } else {
         tx = 0.0f;
         ty = 0.0f;
@@ -298,7 +329,7 @@
         sx, 0, 0, 0,
         0, sy, 0, 0,
         0, 0, 1, 0,
-        sx*tx, sy*ty, 0, 1,
+        tx, ty, 0, 1,
     };
 
     float mtxBeforeFlipV[16];
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index a40fac9..7f1d9cb 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -40,6 +40,10 @@
     mAllocator = mSurfaceTexture->getAllocator();
 }
 
+sp<ISurfaceTexture> SurfaceTextureClient::getISurfaceTexture() const {
+    return mSurfaceTexture;
+}
+
 int SurfaceTextureClient::setSwapInterval(ANativeWindow* window, int interval) {
     SurfaceTextureClient* c = getSelf(window);
     return c->setSwapInterval(interval);
@@ -160,6 +164,9 @@
         // SurfaceTextureClient currently never queues frames to SurfaceFlinger.
         *value = 0;
         return NO_ERROR;
+    case NATIVE_WINDOW_CONCRETE_TYPE:
+        *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
+        return NO_ERROR;
     }
     return BAD_VALUE;
 }
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index 1dd8885..7516299 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -4,39 +4,37 @@
 
 ifneq ($(TARGET_SIMULATOR),true)
 
-# Build the unit tests.
-test_src_files := \
-    SurfaceTextureClient_test.cpp \
+LOCAL_MODULE := SurfaceTexture_test
 
-shared_libraries := \
-	libcutils \
-	libutils \
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+    SurfaceTextureClient_test.cpp \
+    SurfaceTexture_test.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+	libEGL \
+	libGLESv2 \
+	libandroid \
 	libbinder \
+	libcutils \
 	libgui \
 	libstlport \
+	libsurfaceflinger_client \
+	libui \
+	libutils \
 
-static_libraries := \
+LOCAL_STATIC_LIBRARIES := \
 	libgtest \
 	libgtest_main \
 
-c_includes := \
+LOCAL_C_INCLUDES := \
     bionic \
     bionic/libstdc++/include \
     external/gtest/include \
     external/stlport/stlport \
 
-module_tags := tests
-
-$(foreach file,$(test_src_files), \
-    $(eval include $(CLEAR_VARS)) \
-    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
-    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
-    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
-    $(eval LOCAL_SRC_FILES := $(file)) \
-    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
-    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
-    $(eval include $(BUILD_EXECUTABLE)) \
-)
+include $(BUILD_EXECUTABLE)
 
 # Build the manual test programs.
 include $(call all-subdir-makefiles)
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 0f140ff..94b05bc 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#include <gui/SurfaceTextureClient.h>
+#include <EGL/egl.h>
 #include <gtest/gtest.h>
+#include <gui/SurfaceTextureClient.h>
 
 namespace android {
 
@@ -35,6 +36,11 @@
     sp<SurfaceTextureClient> mSTC;
 };
 
+TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
+    sp<ISurfaceTexture> ist(mSTC->getISurfaceTexture());
+    ASSERT_TRUE(ist != NULL);
+}
+
 TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
     sp<ANativeWindow> anw(mSTC);
     int result = -123;
@@ -44,4 +50,54 @@
     EXPECT_EQ(0, result);
 }
 
+TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
+    sp<ANativeWindow> anw(mSTC);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
+}
+
+TEST_F(SurfaceTextureClientTest, ANativeWindowLockFails) {
+    sp<ANativeWindow> anw(mSTC);
+    ANativeWindow_Buffer buf;
+    ASSERT_EQ(BAD_VALUE, ANativeWindow_lock(anw.get(), &buf, NULL));
+}
+
+TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceFails) {
+    sp<ANativeWindow> anw(mSTC);
+
+    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_DISPLAY, dpy);
+
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EXPECT_TRUE(eglInitialize(dpy, &majorVersion, &minorVersion));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EGLConfig myConfig = {0};
+    EGLint numConfigs = 0;
+    EGLint configAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_RED_SIZE, 8,
+        EGL_GREEN_SIZE, 8,
+        EGL_BLUE_SIZE, 8,
+        EGL_ALPHA_SIZE, 8,
+        EGL_DEPTH_SIZE, 16,
+        EGL_STENCIL_SIZE, 8,
+        EGL_NONE };
+    EXPECT_TRUE(eglChooseConfig(dpy, configAttribs, &myConfig, 1,
+            &numConfigs));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, anw.get(),
+            NULL);
+    ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
+    ASSERT_EQ(EGL_BAD_NATIVE_WINDOW, eglGetError());
+
+    eglTerminate(dpy);
+}
+
 }
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
new file mode 100644
index 0000000..4184463
--- /dev/null
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -0,0 +1,621 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/String8.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+
+namespace android {
+
+class GLTest : public ::testing::Test {
+protected:
+
+    GLTest():
+            mEglDisplay(EGL_NO_DISPLAY),
+            mEglSurface(EGL_NO_SURFACE),
+            mEglContext(EGL_NO_CONTEXT) {
+    }
+
+    virtual void SetUp() {
+        EGLBoolean returnValue;
+
+        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
+
+        EGLint majorVersion;
+        EGLint minorVersion;
+        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        RecordProperty("EglVersionMajor", majorVersion);
+        RecordProperty("EglVersionMajor", minorVersion);
+
+        EGLConfig myConfig = {0};
+        EGLint numConfigs = 0;
+        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
+                1, &numConfigs));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
+        if (displaySecsEnv != NULL) {
+            mDisplaySecs = atoi(displaySecsEnv);
+            if (mDisplaySecs < 0) {
+                mDisplaySecs = 0;
+            }
+        } else {
+            mDisplaySecs = 0;
+        }
+
+        if (mDisplaySecs > 0) {
+            mComposerClient = new SurfaceComposerClient;
+            ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+            mSurfaceControl = mComposerClient->createSurface(getpid(),
+                    String8("Test Surface"), 0,
+                    getSurfaceWidth(), getSurfaceHeight(),
+                    PIXEL_FORMAT_RGB_888, 0);
+
+            ASSERT_TRUE(mSurfaceControl != NULL);
+            ASSERT_TRUE(mSurfaceControl->isValid());
+
+            ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
+            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
+            ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+            ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
+
+            sp<ANativeWindow> window = mSurfaceControl->getSurface();
+            mEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
+                    window.get(), NULL);
+        } else {
+            EGLint pbufferAttribs[] = {
+                EGL_WIDTH, getSurfaceWidth(),
+                EGL_HEIGHT, getSurfaceHeight(),
+                EGL_NONE };
+
+            mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig,
+                    pbufferAttribs);
+        }
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
+
+        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
+                getContextAttribs());
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
+
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        EGLint w, h;
+        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        RecordProperty("EglSurfaceWidth", w);
+        RecordProperty("EglSurfaceHeight", h);
+
+        glViewport(0, 0, w, h);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    }
+
+    virtual void TearDown() {
+        // Display the result 
+        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
+            eglSwapBuffers(mEglDisplay, mEglSurface);
+            sleep(mDisplaySecs);
+        }
+
+        if (mComposerClient != NULL) {
+            mComposerClient->dispose();
+        }
+        if (mEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mEglContext);
+        }
+        if (mEglSurface != EGL_NO_SURFACE) {
+            eglDestroySurface(mEglDisplay, mEglSurface);
+        }
+        if (mEglDisplay != EGL_NO_DISPLAY) {
+            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                    EGL_NO_CONTEXT);
+            eglTerminate(mEglDisplay);
+        }
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    }
+
+    virtual EGLint const* getConfigAttribs() {
+        static EGLint sDefaultConfigAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+            EGL_DEPTH_SIZE, 16,
+            EGL_STENCIL_SIZE, 8,
+            EGL_NONE };
+
+        return sDefaultConfigAttribs;
+    }
+
+    virtual EGLint const* getContextAttribs() {
+        static EGLint sDefaultContextAttribs[] = {
+            EGL_CONTEXT_CLIENT_VERSION, 2,
+            EGL_NONE };
+
+        return sDefaultContextAttribs;
+    }
+
+    virtual EGLint getSurfaceWidth() {
+        return 64;
+    }
+
+    virtual EGLint getSurfaceHeight() {
+        return 64;
+    }
+
+    void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
+        GLuint shader = glCreateShader(shaderType);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        if (shader) {
+            glShaderSource(shader, 1, &pSource, NULL);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            glCompileShader(shader);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            GLint compiled = 0;
+            glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            if (!compiled) {
+                GLint infoLen = 0;
+                glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+                ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+                if (infoLen) {
+                    char* buf = (char*) malloc(infoLen);
+                    if (buf) {
+                        glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                        printf("Shader compile log:\n%s\n", buf);
+                        free(buf);
+                        FAIL();
+                    }
+                } else {
+                    char* buf = (char*) malloc(0x1000);
+                    if (buf) {
+                        glGetShaderInfoLog(shader, 0x1000, NULL, buf);
+                        printf("Shader compile log:\n%s\n", buf);
+                        free(buf);
+                        FAIL();
+                    }
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+        ASSERT_TRUE(shader != 0);
+        *outShader = shader;
+    }
+
+    void createProgram(const char* pVertexSource, const char* pFragmentSource,
+            GLuint* outPgm) {
+        GLuint vertexShader, fragmentShader;
+        {
+            SCOPED_TRACE("compiling vertex shader");
+            loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
+            if (HasFatalFailure()) {
+                return;
+            }
+        }
+        {
+            SCOPED_TRACE("compiling fragment shader");
+            loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
+            if (HasFatalFailure()) {
+                return;
+            }
+        }
+
+        GLuint program = glCreateProgram();
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        if (program) {
+            glAttachShader(program, vertexShader);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            glAttachShader(program, fragmentShader);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            glLinkProgram(program);
+            GLint linkStatus = GL_FALSE;
+            glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+            if (linkStatus != GL_TRUE) {
+                GLint bufLength = 0;
+                glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+                if (bufLength) {
+                    char* buf = (char*) malloc(bufLength);
+                    if (buf) {
+                        glGetProgramInfoLog(program, bufLength, NULL, buf);
+                        printf("Program link log:\n%s\n", buf);
+                        free(buf);
+                        FAIL();
+                    }
+                }
+                glDeleteProgram(program);
+                program = 0;
+            }
+        }
+        glDeleteShader(vertexShader);
+        glDeleteShader(fragmentShader);
+        ASSERT_TRUE(program != 0);
+        *outPgm = program;
+    }
+
+    ::testing::AssertionResult checkPixel(int x, int y, int r,
+            int g, int b, int a) {
+        GLubyte pixel[4];
+        String8 msg;
+        glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+        GLenum err = glGetError();
+        if (err != GL_NO_ERROR) {
+            msg += String8::format("error reading pixel: %#x", err);
+            while ((err = glGetError()) != GL_NO_ERROR) {
+                msg += String8::format(", %#x", err);
+            }
+            fprintf(stderr, "pixel check failure: %s\n", msg.string());
+            return ::testing::AssertionFailure(
+                    ::testing::Message(msg.string()));
+        }
+        if (r >= 0 && GLubyte(r) != pixel[0]) {
+            msg += String8::format("r(%d isn't %d)", pixel[0], r);
+        }
+        if (g >= 0 && GLubyte(g) != pixel[1]) {
+            if (!msg.isEmpty()) {
+                msg += " ";
+            }
+            msg += String8::format("g(%d isn't %d)", pixel[1], g);
+        }
+        if (b >= 0 && GLubyte(b) != pixel[2]) {
+            if (!msg.isEmpty()) {
+                msg += " ";
+            }
+            msg += String8::format("b(%d isn't %d)", pixel[2], b);
+        }
+        if (a >= 0 && GLubyte(a) != pixel[3]) {
+            if (!msg.isEmpty()) {
+                msg += " ";
+            }
+            msg += String8::format("a(%d isn't %d)", pixel[3], a);
+        }
+        if (!msg.isEmpty()) {
+            fprintf(stderr, "pixel check failure: %s\n", msg.string());
+            return ::testing::AssertionFailure(
+                    ::testing::Message(msg.string()));
+        } else {
+            return ::testing::AssertionSuccess();
+        }
+    }
+
+    int mDisplaySecs;
+    sp<SurfaceComposerClient> mComposerClient;
+    sp<SurfaceControl> mSurfaceControl;
+
+    EGLDisplay mEglDisplay;
+    EGLSurface mEglSurface;
+    EGLContext mEglContext;
+};
+
+// XXX: Code above this point should live elsewhere
+
+class SurfaceTextureGLTest : public GLTest {
+protected:
+    static const GLint TEX_ID = 123;
+
+    virtual void SetUp() {
+        GLTest::SetUp();
+        mST = new SurfaceTexture(TEX_ID);
+        mSTC = new SurfaceTextureClient(mST);
+        mANW = mSTC;
+
+        const char vsrc[] =
+            "attribute vec4 vPosition;\n"
+            "varying vec2 texCoords;\n"
+            "uniform mat4 texMatrix;\n"
+            "void main() {\n"
+            "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
+            "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
+            "  gl_Position = vPosition;\n"
+            "}\n";
+
+        const char fsrc[] =
+            "#extension GL_OES_EGL_image_external : require\n"
+            "precision mediump float;\n"
+            "uniform samplerExternalOES texSampler;\n"
+            "varying vec2 texCoords;\n"
+            "void main() {\n"
+            "  gl_FragColor = texture2D(texSampler, texCoords);\n"
+            "}\n";
+
+        {
+            SCOPED_TRACE("creating shader program");
+            createProgram(vsrc, fsrc, &mPgm);
+            if (HasFatalFailure()) {
+                return;
+            }
+        }
+
+        mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        ASSERT_NE(-1, mPositionHandle);
+        mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        ASSERT_NE(-1, mTexSamplerHandle);
+        mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        ASSERT_NE(-1, mTexMatrixHandle);
+    }
+
+    // drawTexture draws the SurfaceTexture over the entire GL viewport.
+    void drawTexture() {
+        const GLfloat triangleVertices[] = {
+            -1.0f, 1.0f,
+            -1.0f, -1.0f,
+            1.0f, -1.0f,
+            1.0f, 1.0f,
+        };
+
+        glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glEnableVertexAttribArray(mPositionHandle);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        glUseProgram(mPgm);
+        glUniform1i(mTexSamplerHandle, 0);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        GLfloat texMatrix[16];
+        mST->getTransformMatrix(texMatrix);
+        glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
+
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    }
+
+    sp<SurfaceTexture> mST;
+    sp<SurfaceTextureClient> mSTC;
+    sp<ANativeWindow> mANW;
+
+    GLuint mPgm;
+    GLint mPositionHandle;
+    GLint mTexSamplerHandle;
+    GLint mTexMatrixHandle;
+};
+
+// Fill a YV12 buffer with a multi-colored checkerboard pattern
+void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
+    const int blockWidth = w > 16 ? w / 16 : 1;
+    const int blockHeight = h > 16 ? h / 16 : 1;
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            int parityX = (x / blockWidth) & 1;
+            int parityY = (y / blockHeight) & 1;
+            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+            if (x < w / 2 && y < h / 2) {
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+                if (x * 2 < w / 2 && y * 2 < h / 2) {
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
+                        intensity;
+                }
+            }
+        }
+    }
+}
+
+// Fill a YV12 buffer with red outside a given rectangle and green inside it.
+void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
+        const android_native_rect_t& rect) {
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            bool inside = rect.left <= x && x < rect.right &&
+                    rect.top <= y && y < rect.bottom;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
+            if (x < w / 2 && y < h / 2) {
+                bool inside = rect.left <= 2*x && 2*x < rect.right &&
+                        rect.top <= 2*y && 2*y < rect.bottom;
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
+                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
+                        inside ? 16 : 255;
+            }
+        }
+    }
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
+    const int yuvTexWidth = 64;
+    const int yuvTexHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillYV12Buffer(img, yuvTexWidth, yuvTexHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
+
+    EXPECT_TRUE(checkPixel(22, 44, 247,  70, 255, 255));
+    EXPECT_TRUE(checkPixel(45, 52, 209,  32, 235, 255));
+    EXPECT_TRUE(checkPixel(52, 51, 100, 255,  73, 255));
+    EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255));
+    EXPECT_TRUE(checkPixel(31,  9, 148,  71, 110, 255));
+    EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255));
+}
+
+// XXX: This test is disabled because it it currently broken on all devices to
+// which I have access.  Some of the checkPixel calls are not correct because
+// I just copied them from the npot test above and haven't bothered to figure
+// out the correct values.
+TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) {
+    const int yuvTexWidth = 64;
+    const int yuvTexHeight = 64;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillYV12Buffer(img, yuvTexWidth, yuvTexHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
+
+    EXPECT_TRUE(checkPixel(22, 19, 247,  70, 255, 255));
+    EXPECT_TRUE(checkPixel(45, 11, 209,  32, 235, 255));
+    EXPECT_TRUE(checkPixel(52, 12, 100, 255,  73, 255));
+    EXPECT_TRUE(checkPixel( 7, 32, 155,   0, 118, 255));
+    EXPECT_TRUE(checkPixel(31, 54, 148,  71, 110, 255));
+    EXPECT_TRUE(checkPixel(29, 28, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(36, 41, 155,  29,   0, 255));
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
+    const int yuvTexWidth = 64;
+    const int yuvTexHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_rect_t crops[] = {
+        {4, 6, 22, 36},
+        {0, 6, 22, 36},
+        {4, 0, 22, 36},
+        {4, 6, yuvTexWidth, 36},
+        {4, 6, 22, yuvTexHeight},
+    };
+
+    for (int i = 0; i < 5; i++) {
+        const android_native_rect_t& crop(crops[i]);
+        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", crop.left,
+                crop.top, crop.right, crop.bottom).string());
+
+        ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
+
+        android_native_buffer_t* anb;
+        ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+        ASSERT_TRUE(anb != NULL);
+
+        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+        uint8_t* img = NULL;
+        buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+        fillYV12BufferRect(img, yuvTexWidth, yuvTexHeight, buf->getStride(), crop);
+        buf->unlock();
+        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+        mST->updateTexImage();
+
+        glClearColor(0.2, 0.2, 0.2, 0.2);
+        glClear(GL_COLOR_BUFFER_BIT);
+
+        drawTexture();
+
+        EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
+
+        EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
+    }
+}
+
+}
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 737fa02..868290b 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -285,9 +285,12 @@
             break;
             case DrawDisplayList: {
                 DisplayList* displayList = getDisplayList();
-                DISPLAY_LIST_LOGD("%s%s %p, %d", (char*) indent, OP_NAMES[op],
-                    displayList, level + 1);
-                needsInvalidate |= renderer.drawDisplayList(displayList, dirty, level + 1);
+                uint32_t width = getUInt();
+                uint32_t height = getUInt();
+                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
+                    displayList, width, height, level + 1);
+                needsInvalidate |= renderer.drawDisplayList(displayList, width, height,
+                        dirty, level + 1);
             }
             break;
             case DrawLayer: {
@@ -674,11 +677,13 @@
     return OpenGLRenderer::clipRect(left, top, right, bottom, op);
 }
 
-bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level) {
+bool DisplayListRenderer::drawDisplayList(DisplayList* displayList,
+        uint32_t width, uint32_t height, Rect& dirty, uint32_t level) {
     // dirty is an out parameter and should not be recorded,
     // it matters only when replaying the display list
     addOp(DisplayList::DrawDisplayList);
     addDisplayList(displayList);
+    addSize(width, height);
     return false;
 }
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index f24545d..6fc315c 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -144,6 +144,10 @@
         return mReader.readInt();
     }
 
+    inline uint32_t getUInt() {
+        return mReader.readU32();
+    }
+
     SkMatrix* getMatrix() {
         return (SkMatrix*) getInt();
     }
@@ -238,7 +242,8 @@
 
     bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
 
-    bool drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level = 0);
+    bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+            Rect& dirty, uint32_t level = 0);
     void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
     void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
     void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
@@ -323,6 +328,11 @@
         mWriter.writeInt(value);
     }
 
+    inline void addSize(uint32_t w, uint32_t h) {
+        mWriter.writeInt(w);
+        mWriter.writeInt(h);
+    }
+
     void addInts(const int32_t* values, uint32_t count) {
         mWriter.writeInt(count);
         for (uint32_t i = 0; i < count; i++) {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index b1eb164..f92e20b 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -92,7 +92,11 @@
 
 void LayerRenderer::generateMesh() {
 #if RENDER_LAYERS_AS_REGIONS
+#if RENDER_LAYERS_RECT_AS_RECT
     if (mLayer->region.isRect() || mLayer->region.isEmpty()) {
+#else
+    if (mLayer->region.isEmpty()) {
+#endif
         if (mLayer->mesh) {
             delete mLayer->mesh;
             delete mLayer->meshIndices;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 1f65201..e01e072 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -403,22 +403,23 @@
 
     // Window coordinates of the layer
     Rect bounds(left, top, right, bottom);
-    if (fboLayer) {
-        // Clear the previous layer regions before we change the viewport
-        clearLayerRegions();
-    } else {
+    if (!fboLayer) {
         mSnapshot->transform->mapRect(bounds);
 
         // Layers only make sense if they are in the framebuffer's bounds
-        bounds.intersect(*snapshot->clipRect);
+        if (bounds.intersect(*snapshot->clipRect)) {
+            // We cannot work with sub-pixels in this case
+            bounds.snapToPixelBoundaries();
 
-        // We cannot work with sub-pixels in this case
-        bounds.snapToPixelBoundaries();
-
-        // When the layer is not an FBO, we may use glCopyTexImage so we
-        // need to make sure the layer does not extend outside the bounds
-        // of the framebuffer
-        bounds.intersect(snapshot->previous->viewport);
+            // When the layer is not an FBO, we may use glCopyTexImage so we
+            // need to make sure the layer does not extend outside the bounds
+            // of the framebuffer
+            if (!bounds.intersect(snapshot->previous->viewport)) {
+                bounds.setEmpty();
+            }
+        } else {
+            bounds.setEmpty();
+        }
     }
 
     if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize ||
@@ -464,8 +465,14 @@
                 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
                         snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
             }
-            // Enqueue the buffer coordinates to clear the corresponding region later
-            mLayers.push(new Rect(bounds));
+
+            // Clear the framebuffer where the layer will draw
+            glScissor(bounds.left, mSnapshot->height - bounds.bottom,
+                    bounds.getWidth(), bounds.getHeight());
+            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+            glClear(GL_COLOR_BUFFER_BIT);
+
+            dirtyClip();
         }
     }
 
@@ -629,11 +636,13 @@
 
 void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
 #if RENDER_LAYERS_AS_REGIONS
+#if RENDER_LAYERS_RECT_AS_RECT
     if (layer->region.isRect()) {
         composeLayerRect(layer, rect);
         layer->region.clear();
         return;
     }
+#endif
 
     if (!layer->region.isEmpty()) {
         size_t count;
@@ -760,31 +769,6 @@
 #endif
 }
 
-void OpenGLRenderer::clearLayerRegions() {
-    if (mLayers.size() == 0 || mSnapshot->isIgnored()) return;
-
-    Rect clipRect(*mSnapshot->clipRect);
-    clipRect.snapToPixelBoundaries();
-
-    for (uint32_t i = 0; i < mLayers.size(); i++) {
-        Rect* bounds = mLayers.itemAt(i);
-        if (clipRect.intersects(*bounds)) {
-            // Clear the framebuffer where the layer will draw
-            glScissor(bounds->left, mSnapshot->height - bounds->bottom,
-                    bounds->getWidth(), bounds->getHeight());
-            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-            glClear(GL_COLOR_BUFFER_BIT);
-
-            // Restore the clip
-            dirtyClip();
-        }
-
-        delete bounds;
-    }
-
-    mLayers.clear();
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Transforms
 ///////////////////////////////////////////////////////////////////////////////
@@ -870,7 +854,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::setupDraw() {
-    clearLayerRegions();
     if (mDirtyClip) {
         setScissorFromClip();
     }
@@ -1064,12 +1047,18 @@
 // Drawing
 ///////////////////////////////////////////////////////////////////////////////
 
-bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level) {
+bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+        Rect& dirty, uint32_t level) {
+    if (quickReject(0.0f, 0.0f, width, height)) {
+        return false;
+    }
+
     // All the usual checks and setup operations (quickReject, setupDraw, etc.)
     // will be performed by the display list itself
     if (displayList) {
         return displayList->replay(*this, dirty, level);
     }
+
     return false;
 }
 
@@ -1659,10 +1648,14 @@
 
 #if RENDER_LAYERS_AS_REGIONS
     if (!layer->region.isEmpty()) {
+#if RENDER_LAYERS_RECT_AS_RECT
         if (layer->region.isRect()) {
             const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
             composeLayerRect(layer, r);
         } else if (layer->mesh) {
+#else
+        if (layer->mesh) {
+#endif
             const float a = alpha / 255.0f;
             const Rect& rect = layer->layer;
 
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 9d86388..7362473 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -96,7 +96,8 @@
     bool quickReject(float left, float top, float right, float bottom);
     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
 
-    virtual bool drawDisplayList(DisplayList* displayList, Rect& dirty, uint32_t level = 0);
+    virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+            Rect& dirty, uint32_t level = 0);
     virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
     virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
     virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
@@ -247,12 +248,6 @@
     void composeLayerRect(Layer* layer, const Rect& rect, bool swap = false);
 
     /**
-     * Clears all the regions corresponding to the current list of layers.
-     * This method MUST be invoked before any drawing operation.
-     */
-    void clearLayerRegions();
-
-    /**
      * Mark the layer as dirty at the specified coordinates. The coordinates
      * are transformed with the supplied matrix.
      */
@@ -499,9 +494,6 @@
     // Various caches
     Caches& mCaches;
 
-    // List of rectangles to clear due to calls to saveLayer()
-    Vector<Rect*> mLayers;
-
     // Indentity matrix
     const mat4 mIdentity;
 
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 3acd18a..ead5b92 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -231,9 +231,11 @@
      * Logs the specified message followed by the key identifying this program.
      */
     void log(const char* message) const {
+#if DEBUG_PROGRAMS
         programid k = key();
         PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32),
                 uint32_t(k & 0xffffffff));
+#endif
     }
 
 private:
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 2d8b6f3..1aef99b 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -27,6 +27,8 @@
 
 // If turned on, layers drawn inside FBOs are optimized with regions
 #define RENDER_LAYERS_AS_REGIONS 1
+// If turned on, layers that map to a single rect are drawn as a rect
+#define RENDER_LAYERS_RECT_AS_RECT 0
 
 /**
  * Debug level for app developers.
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 7c64184..23230a6 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -961,43 +961,43 @@
     { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_toClientBlocking2, false },
 
     // matrix
-    { "_Z20rsMatrixLoadIdentityP12rs_matrix4x4", (void *)&SC_MatrixLoadIdentity_4x4, false },
-    { "_Z20rsMatrixLoadIdentityP12rs_matrix3x3", (void *)&SC_MatrixLoadIdentity_3x3, false },
-    { "_Z20rsMatrixLoadIdentityP12rs_matrix2x2", (void *)&SC_MatrixLoadIdentity_2x2, false },
+    { "_Z20rsMatrixLoadIdentityP12rs_matrix4x4", (void *)&SC_MatrixLoadIdentity_4x4, true },
+    { "_Z20rsMatrixLoadIdentityP12rs_matrix3x3", (void *)&SC_MatrixLoadIdentity_3x3, true },
+    { "_Z20rsMatrixLoadIdentityP12rs_matrix2x2", (void *)&SC_MatrixLoadIdentity_2x2, true },
 
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PKf", (void *)&SC_MatrixLoad_4x4_f, false },
-    { "_Z12rsMatrixLoadP12rs_matrix3x3PKf", (void *)&SC_MatrixLoad_3x3_f, false },
-    { "_Z12rsMatrixLoadP12rs_matrix2x2PKf", (void *)&SC_MatrixLoad_2x2_f, false },
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PKf", (void *)&SC_MatrixLoad_4x4_f, true },
+    { "_Z12rsMatrixLoadP12rs_matrix3x3PKf", (void *)&SC_MatrixLoad_3x3_f, true },
+    { "_Z12rsMatrixLoadP12rs_matrix2x2PKf", (void *)&SC_MatrixLoad_2x2_f, true },
 
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PKS_", (void *)&SC_MatrixLoad_4x4_4x4, false },
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix3x3", (void *)&SC_MatrixLoad_4x4_3x3, false },
-    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix2x2", (void *)&SC_MatrixLoad_4x4_2x2, false },
-    { "_Z12rsMatrixLoadP12rs_matrix3x3PKS_", (void *)&SC_MatrixLoad_3x3_3x3, false },
-    { "_Z12rsMatrixLoadP12rs_matrix2x2PKS_", (void *)&SC_MatrixLoad_2x2_2x2, false },
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PKS_", (void *)&SC_MatrixLoad_4x4_4x4, true },
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix3x3", (void *)&SC_MatrixLoad_4x4_3x3, true },
+    { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix2x2", (void *)&SC_MatrixLoad_4x4_2x2, true },
+    { "_Z12rsMatrixLoadP12rs_matrix3x3PKS_", (void *)&SC_MatrixLoad_3x3_3x3, true },
+    { "_Z12rsMatrixLoadP12rs_matrix2x2PKS_", (void *)&SC_MatrixLoad_2x2_2x2, true },
 
-    { "_Z18rsMatrixLoadRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadRotate, false },
-    { "_Z17rsMatrixLoadScaleP12rs_matrix4x4fff", (void *)&SC_MatrixLoadScale, false },
-    { "_Z21rsMatrixLoadTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixLoadTranslate, false },
-    { "_Z14rsMatrixRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixRotate, false },
-    { "_Z13rsMatrixScaleP12rs_matrix4x4fff", (void *)&SC_MatrixScale, false },
-    { "_Z17rsMatrixTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixTranslate, false },
+    { "_Z18rsMatrixLoadRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadRotate, true },
+    { "_Z17rsMatrixLoadScaleP12rs_matrix4x4fff", (void *)&SC_MatrixLoadScale, true },
+    { "_Z21rsMatrixLoadTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixLoadTranslate, true },
+    { "_Z14rsMatrixRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixRotate, true },
+    { "_Z13rsMatrixScaleP12rs_matrix4x4fff", (void *)&SC_MatrixScale, true },
+    { "_Z17rsMatrixTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixTranslate, true },
 
-    { "_Z20rsMatrixLoadMultiplyP12rs_matrix4x4PKS_S2_", (void *)&SC_MatrixLoadMultiply_4x4_4x4_4x4, false },
-    { "_Z16rsMatrixMultiplyP12rs_matrix4x4PKS_", (void *)&SC_MatrixMultiply_4x4_4x4, false },
-    { "_Z20rsMatrixLoadMultiplyP12rs_matrix3x3PKS_S2_", (void *)&SC_MatrixLoadMultiply_3x3_3x3_3x3, false },
-    { "_Z16rsMatrixMultiplyP12rs_matrix3x3PKS_", (void *)&SC_MatrixMultiply_3x3_3x3, false },
-    { "_Z20rsMatrixLoadMultiplyP12rs_matrix2x2PKS_S2_", (void *)&SC_MatrixLoadMultiply_2x2_2x2_2x2, false },
-    { "_Z16rsMatrixMultiplyP12rs_matrix2x2PKS_", (void *)&SC_MatrixMultiply_2x2_2x2, false },
+    { "_Z20rsMatrixLoadMultiplyP12rs_matrix4x4PKS_S2_", (void *)&SC_MatrixLoadMultiply_4x4_4x4_4x4, true },
+    { "_Z16rsMatrixMultiplyP12rs_matrix4x4PKS_", (void *)&SC_MatrixMultiply_4x4_4x4, true },
+    { "_Z20rsMatrixLoadMultiplyP12rs_matrix3x3PKS_S2_", (void *)&SC_MatrixLoadMultiply_3x3_3x3_3x3, true },
+    { "_Z16rsMatrixMultiplyP12rs_matrix3x3PKS_", (void *)&SC_MatrixMultiply_3x3_3x3, true },
+    { "_Z20rsMatrixLoadMultiplyP12rs_matrix2x2PKS_S2_", (void *)&SC_MatrixLoadMultiply_2x2_2x2_2x2, true },
+    { "_Z16rsMatrixMultiplyP12rs_matrix2x2PKS_", (void *)&SC_MatrixMultiply_2x2_2x2, true },
 
-    { "_Z17rsMatrixLoadOrthoP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadOrtho, false },
-    { "_Z19rsMatrixLoadFrustumP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadFrustum, false },
-    { "_Z23rsMatrixLoadPerspectiveP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadPerspective, false },
+    { "_Z17rsMatrixLoadOrthoP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadOrtho, true },
+    { "_Z19rsMatrixLoadFrustumP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadFrustum, true },
+    { "_Z23rsMatrixLoadPerspectiveP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadPerspective, true },
 
-    { "_Z15rsMatrixInverseP12rs_matrix4x4", (void *)&SC_MatrixInverse_4x4, false },
-    { "_Z24rsMatrixInverseTransposeP12rs_matrix4x4", (void *)&SC_MatrixInverseTranspose_4x4, false },
-    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_4x4, false },
-    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_3x3, false },
-    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_2x2, false },
+    { "_Z15rsMatrixInverseP12rs_matrix4x4", (void *)&SC_MatrixInverse_4x4, true },
+    { "_Z24rsMatrixInverseTransposeP12rs_matrix4x4", (void *)&SC_MatrixInverseTranspose_4x4, true },
+    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_4x4, true },
+    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_3x3, true },
+    { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_2x2, true },
 
     { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach, false },
     //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2, true },
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index afabbf4..21d509a 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -712,11 +712,15 @@
     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
         *value = MIN_UNDEQUEUED_BUFFERS;
         return NO_ERROR;
-    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
         sp<ISurfaceComposer> sf(ComposerService::getComposerService());
         *value = sf->authenticateSurface(mSurface) ? 1 : 0;
         return NO_ERROR;
     }
+    case NATIVE_WINDOW_CONCRETE_TYPE:
+        *value = NATIVE_WINDOW_SURFACE;
+        return NO_ERROR;
+    }
     return BAD_VALUE;
 }
 
diff --git a/libs/surfaceflinger_client/tests/Surface_test.cpp b/libs/surfaceflinger_client/tests/Surface_test.cpp
index 74ebf4e..fd07479 100644
--- a/libs/surfaceflinger_client/tests/Surface_test.cpp
+++ b/libs/surfaceflinger_client/tests/Surface_test.cpp
@@ -130,4 +130,12 @@
     ASSERT_TRUE(heap != NULL);
 }
 
+TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
+    sp<ANativeWindow> anw(mSurface);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(NATIVE_WINDOW_SURFACE, result);
+}
+
 }
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 0702d49..dc223f9 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -286,6 +286,9 @@
         case NATIVE_WINDOW_FORMAT:
             *value = fb->format;
             return NO_ERROR;
+        case NATIVE_WINDOW_CONCRETE_TYPE:
+            *value = NATIVE_WINDOW_FRAMEBUFFER;
+            return NO_ERROR;
     }
     *value = 0;
     return BAD_VALUE;
diff --git a/libs/usb/src/com/android/future/usb/UsbAccessory.java b/libs/usb/src/com/android/future/usb/UsbAccessory.java
index 3d0707f..0f965d7 100644
--- a/libs/usb/src/com/android/future/usb/UsbAccessory.java
+++ b/libs/usb/src/com/android/future/usb/UsbAccessory.java
@@ -19,13 +19,14 @@
 /**
  * A class representing a USB accessory.
  */
-public final class UsbAccessory {
+public class UsbAccessory {
 
     private final String mManufacturer;
     private final String mModel;
     private final String mDescription;
     private final String mVersion;
     private final String mUri;
+    private final String mSerial;
 
     /* package */ UsbAccessory(android.hardware.usb.UsbAccessory accessory) {
         mManufacturer = accessory.getManufacturer();
@@ -33,6 +34,7 @@
         mDescription = accessory.getDescription();
         mVersion = accessory.getVersion();
         mUri = accessory.getUri();
+        mSerial = accessory.getSerial();
     }
 
     /**
@@ -82,6 +84,17 @@
         return mUri;
     }
 
+    /**
+     * Returns the unique serial number for the accessory.
+     * This is an optional serial number that can be used to differentiate
+     * between individual accessories of the same model and manufacturer
+     *
+     * @return the unique serial number
+     */
+    public String getSerial() {
+        return mSerial;
+    }
+
     private static boolean compare(String s1, String s2) {
         if (s1 == null) return (s2 == null);
         return s1.equals(s2);
@@ -95,7 +108,8 @@
                     compare(mModel, accessory.getModel()) &&
                     compare(mDescription, accessory.getDescription()) &&
                     compare(mVersion, accessory.getVersion()) &&
-                    compare(mUri, accessory.getUri()));
+                    compare(mUri, accessory.getUri()) &&
+                    compare(mSerial, accessory.getSerial()));
         }
         return false;
     }
@@ -106,7 +120,8 @@
                 (mModel == null ? 0 : mModel.hashCode()) ^
                 (mDescription == null ? 0 : mDescription.hashCode()) ^
                 (mVersion == null ? 0 : mVersion.hashCode()) ^
-                (mUri == null ? 0 : mUri.hashCode()));
+                (mUri == null ? 0 : mUri.hashCode()) ^
+                (mSerial == null ? 0 : mSerial.hashCode()));
     }
 
     @Override
@@ -115,6 +130,7 @@
                             ", mModel=" + mModel +
                             ", mDescription=" + mDescription +
                             ", mVersion=" + mVersion +
-                            ", mUri=" + mUri + "]";
+                            ", mUri=" + mUri +
+                            ", mSerial=" + mSerial + "]";
     }
 }
diff --git a/libs/usb/src/com/android/future/usb/UsbManager.java b/libs/usb/src/com/android/future/usb/UsbManager.java
index 840e1e3..d424b63 100644
--- a/libs/usb/src/com/android/future/usb/UsbManager.java
+++ b/libs/usb/src/com/android/future/usb/UsbManager.java
@@ -130,7 +130,8 @@
         try {
             return mService.openAccessory(new android.hardware.usb.UsbAccessory(
                     accessory.getManufacturer(),accessory.getModel(),
-                    accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
+                    accessory.getDescription(), accessory.getVersion(),
+                    accessory.getUri(), accessory.getSerial()));
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in openAccessory" , e);
             return null;
@@ -150,7 +151,8 @@
         try {
             return mService.hasAccessoryPermission(new android.hardware.usb.UsbAccessory(
                     accessory.getManufacturer(),accessory.getModel(),
-                    accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
+                    accessory.getDescription(), accessory.getVersion(),
+                    accessory.getUri(), accessory.getSerial()));
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in hasPermission", e);
             return false;
@@ -174,7 +176,8 @@
         try {
             mService.requestAccessoryPermission(new android.hardware.usb.UsbAccessory(
                     accessory.getManufacturer(),accessory.getModel(),
-                    accessory.getDescription(), accessory.getVersion(), accessory.getUri()),
+                    accessory.getDescription(), accessory.getVersion(),
+                    accessory.getUri(), accessory.getSerial()),
                     mContext.getPackageName(), pi);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in requestPermission", e);
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index d555961..77b8424 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -21,7 +21,7 @@
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
-LOCAL_PACKAGE_NAME := AccessoryChatGB
+LOCAL_PACKAGE_NAME := AccessoryChat
 
 LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory
 
diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
index d6093ae..802b715 100644
--- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml
+++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
@@ -17,10 +17,10 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.accessorychat">
 
-    <application>
+    <application android:label="Accessory Chat">
         <uses-library android:name="com.android.future.usb.accessory" />
 
-        <activity android:name="AccessoryChat" android:label="Accessory Chat GB">
+        <activity android:name="AccessoryChat" android:label="Accessory Chat">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
index 3c0de69..85b52dd 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
+++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
@@ -24,6 +24,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <pthread.h>
+#include <time.h>
 
 #include <usbhost/usbhost.h>
 #include <linux/usb/f_accessory.h>
@@ -65,9 +66,20 @@
     return NULL;
 }
 
+static void milli_sleep(int millis) {
+    struct timespec tm;
+
+    tm.tv_sec = 0;
+    tm.tv_nsec = millis * 1000000;
+    nanosleep(&tm, NULL);
+}
+
 static void send_string(struct usb_device *device, int index, const char* string) {
     int ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
             ACCESSORY_SEND_STRING, 0, index, (void *)string, strlen(string) + 1, 0);
+
+    // some devices can't handle back-to-back requests, so delay a bit
+    milli_sleep(10);
 }
 
 static int usb_device_added(const char *devname, void* client_data) {
@@ -143,9 +155,10 @@
 
             send_string(device, ACCESSORY_STRING_MANUFACTURER, "Google, Inc.");
             send_string(device, ACCESSORY_STRING_MODEL, "AccessoryChat");
-            send_string(device, ACCESSORY_STRING_DESCRIPTION, "Sample Program");
+            send_string(device, ACCESSORY_STRING_DESCRIPTION, "Accessory Chat");
             send_string(device, ACCESSORY_STRING_VERSION, "1.0");
             send_string(device, ACCESSORY_STRING_URI, "http://www.android.com");
+            send_string(device, ACCESSORY_STRING_SERIAL, "1234567890");
 
             ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
                     ACCESSORY_START, 0, 0, 0, 0, 0);
diff --git a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
index f9a5bf4..c3f4fa3 100644
--- a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
+++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
@@ -135,7 +135,8 @@
     }
 
     private void openAccessory(UsbAccessory accessory) {
-       mFileDescriptor = mUsbManager.openAccessory(accessory);
+        Log.d(TAG, "openAccessory: " + accessory);
+        mFileDescriptor = mUsbManager.openAccessory(accessory);
         if (mFileDescriptor != null) {
             FileDescriptor fd = mFileDescriptor.getFileDescriptor();
             mInputStream = new FileInputStream(fd);
diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java
index 7069b23..2de82f2 100755
--- a/media/java/android/media/videoeditor/AudioTrack.java
+++ b/media/java/android/media/videoeditor/AudioTrack.java
@@ -49,7 +49,6 @@
     private final int mAudioType;
     private final int mAudioBitrate;
     private final int mAudioSamplingFrequency;
-
     /**
      *  Ducking variables
      */
@@ -127,11 +126,17 @@
                int duckThreshold, int duckedTrackVolume,
             String audioWaveformFilename) throws IOException {
         Properties properties = null;
+
         File file = new File(filename);
         if (!file.exists()) {
             throw new IOException(filename + " not found ! ");
         }
 
+        /*Compare file_size with 2GB*/
+        if (VideoEditor.MAX_SUPPORTED_FILE_SIZE <= file.length()) {
+            throw new IllegalArgumentException("File size is more than 2GB");
+        }
+
         if (editor instanceof VideoEditorImpl) {
             mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
         } else {
diff --git a/media/java/android/media/videoeditor/MediaItem.java b/media/java/android/media/videoeditor/MediaItem.java
index dfe0bae..8c4841f 100755
--- a/media/java/android/media/videoeditor/MediaItem.java
+++ b/media/java/android/media/videoeditor/MediaItem.java
@@ -131,6 +131,15 @@
         if (filename == null) {
             throw new IllegalArgumentException("MediaItem : filename is null");
         }
+        File file = new File(filename);
+        if (!file.exists()) {
+            throw new IOException(filename + " not found ! ");
+        }
+
+        /*Compare file_size with 2GB*/
+        if (VideoEditor.MAX_SUPPORTED_FILE_SIZE <= file.length()) {
+            throw new IllegalArgumentException("File size is more than 2GB");
+        }
         mUniqueId = mediaItemId;
         mFilename = filename;
         mRenderingMode = renderingMode;
diff --git a/media/java/android/media/videoeditor/VideoEditor.java b/media/java/android/media/videoeditor/VideoEditor.java
index 122dc8d..59e4540 100755
--- a/media/java/android/media/videoeditor/VideoEditor.java
+++ b/media/java/android/media/videoeditor/VideoEditor.java
@@ -68,6 +68,11 @@
     public final static int DURATION_OF_STORYBOARD = -1;
 
     /**
+     *  Maximum supported file size
+     */
+    public static final long MAX_SUPPORTED_FILE_SIZE = 2147483648L;
+
+    /**
      * This listener interface is used by the VideoEditor to emit preview
      * progress notifications. This callback should be invoked after the number
      * of frames specified by
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index 7e1f73a..78557ee 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -119,7 +119,6 @@
     private static final String ATTR_OVERLAY_FRAME_HEIGHT = "overlay_frame_height";
     private static final String ATTR_OVERLAY_RESIZED_RGB_FRAME_WIDTH = "resized_RGBframe_width";
     private static final String ATTR_OVERLAY_RESIZED_RGB_FRAME_HEIGHT = "resized_RGBframe_height";
-
     private static final int ENGINE_ACCESS_MAX_TIMEOUT_MS = 500;
     /*
      *  Instance variables
@@ -437,6 +436,12 @@
                 throw new IllegalArgumentException(message);
             }
         }
+        computeTimelineDuration();
+        final long audioBitrate = MediaArtistNativeHelper.Bitrate.BR_96_KBPS;
+        final long fileSize = (mDurationMs * (bitrate + audioBitrate)) / 8000;
+        if (MAX_SUPPORTED_FILE_SIZE <= fileSize) {
+            throw new IllegalStateException("Export Size is more than 2GB");
+        }
 
         boolean semAcquireDone = false;
         try {
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index 219cd19..ae1993d 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -74,6 +74,12 @@
 
 int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
         ARect* inOutDirtyBounds) {
+    int type = -1;
+    if (window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &type) != 0 ||
+            type != NATIVE_WINDOW_SURFACE) {
+        return BAD_VALUE;
+    }
+
     Region dirtyRegion;
     Region* dirtyParam = NULL;
     if (inOutDirtyBounds != NULL) {
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3d5a4d1..f4a1650 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -1094,6 +1094,16 @@
         EGLConfig iConfig = dp->configs[intptr_t(config)].config;
         EGLint format;
 
+        // for now fail if the window is not a Surface.
+        int type = -1;
+        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
+        if ((anw->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &type) != 0) ||
+                (type == NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT)) {
+            LOGE("native window is a SurfaceTextureClient (currently "
+                    "unsupported)");
+            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+        }
+
         // set the native window's buffers format to match this config
         if (cnx->egl.eglGetConfigAttrib(iDpy,
                 iConfig, EGL_NATIVE_VISUAL_ID, &format)) {
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 21f77e3..337593f 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -390,6 +390,9 @@
     // No-installation limit for internal flash: 10% or less space available
     private static final double LOW_NAND_FLASH_TRESHOLD = 0.1;
 
+    // No-installation limit for internal flash: 150MB or less space available
+    private static final long NAND_MIN_FREE_SPACE = (1024L * 1024L * 150L);
+
     // SD-to-internal app size threshold: currently set to 1 MB
     private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024);
     private static final int ERR_LOC = -1;
@@ -451,7 +454,8 @@
         String status = Environment.getExternalStorageState();
         long availSDSize = -1;
         boolean mediaAvailable = false;
-        if (!Environment.isExternalStorageEmulated() && status.equals(Environment.MEDIA_MOUNTED)) {
+        final boolean mediaEmulated = Environment.isExternalStorageEmulated();
+        if (!mediaEmulated && status.equals(Environment.MEDIA_MOUNTED)) {
             StatFs sdStats = new StatFs(
                     Environment.getExternalStorageDirectory().getPath());
             availSDSize = (long)sdStats.getAvailableBlocks() *
@@ -474,7 +478,7 @@
         // For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now.
         long reqInternalSize = 0;
         boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
-        boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalSize);
+        boolean intAvailOk = (reqInstallSize + reqInternalSize) < (availInternalSize - NAND_MIN_FREE_SPACE);
         boolean fitsOnSd = false;
         if (mediaAvailable && (reqInstallSize < availSDSize)) {
             // If we do not have an internal size requirement
@@ -485,7 +489,7 @@
                 fitsOnSd = true;
             }
         }
-        boolean fitsOnInt = intThresholdOk && intAvailOk;
+        boolean fitsOnInt = intThresholdOk || intAvailOk;
         if (checkInt) {
             // Check for internal memory availability
             if (fitsOnInt) {
@@ -506,7 +510,7 @@
                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
             }
         }
-        if ((checkExt || checkBoth) && !mediaAvailable) {
+        if (!mediaEmulated && (checkExt || checkBoth) && !mediaAvailable) {
             return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
         }
         return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_dnd.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_dnd.png
new file mode 100644
index 0000000..eb783df
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notification_dnd.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
index 6d4da7f..3f88968 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
Binary files differ
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8998674..b4eea6e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -129,7 +129,7 @@
     <string name="usb_accessory_confirm_prompt">Open %1$s when this USB accessory is connected?</string>
 
     <!-- Prompt for the USB accessory URI dialog [CHAR LIMIT=80] -->
-    <string name="usb_accessory_uri_prompt">Additional information for this device may be found at: %1$s</string>
+    <string name="usb_accessory_uri_prompt">Additional information for this USB accessory may be found at: %1$s</string>
 
     <!-- Title for USB accessory dialog.  Used when the name of the accessory cannot be determined.  [CHAR LIMIT=50] -->
     <string name="title_usb_accessory">USB accessory</string>
@@ -137,7 +137,10 @@
     <!-- View button label for USB dialogs.  [CHAR LIMIT=15] -->
     <string name="label_view">View</string>
 
-    <!-- Ignore button label for USB dialogs.  [CHAR LIMIT=15] -->
-    <string name="label_ignore">Ignore</string>
+    <!-- Checkbox label for USB device dialogs.  [CHAR LIMIT=50] -->
+    <string name="always_use_device">Use by default for this USB device</string>
+
+    <!-- Checkbox label for USB accessory dialogs.  [CHAR LIMIT=50] -->
+    <string name="always_use_accessory">Use by default for this USB accessory</string>
 
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
index eefb1c6..5007cf4 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
@@ -76,7 +76,7 @@
         }
         ap.mMessage = getString(R.string.usb_accessory_uri_prompt, mUri);
         ap.mPositiveButtonText = getString(R.string.label_view);
-        ap.mNegativeButtonText = getString(R.string.label_ignore);
+        ap.mNegativeButtonText = getString(android.R.string.cancel);
         ap.mPositiveButtonListener = this;
         ap.mNegativeButtonListener = this;
 
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
index 4e6f81f..030a261 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
@@ -80,8 +80,8 @@
             ap.mMessage = getString(R.string.usb_device_confirm_prompt, appName);
             mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
         }
-        ap.mPositiveButtonText = getString(com.android.internal.R.string.ok);
-        ap.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
+        ap.mPositiveButtonText = getString(android.R.string.ok);
+        ap.mNegativeButtonText = getString(android.R.string.cancel);
         ap.mPositiveButtonListener = this;
         ap.mNegativeButtonListener = this;
 
@@ -90,7 +90,11 @@
                 Context.LAYOUT_INFLATER_SERVICE);
         ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
         mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
-        mAlwaysUse.setText(com.android.internal.R.string.alwaysUse);
+        if (mDevice == null) {
+            mAlwaysUse.setText(R.string.always_use_accessory);
+        } else {
+            mAlwaysUse.setText(R.string.always_use_device);
+        }
         mAlwaysUse.setOnCheckedChangeListener(this);
         mClearDefaultHint = (TextView)ap.mView.findViewById(
                                                     com.android.internal.R.id.clearDefaultHint);
@@ -100,6 +104,14 @@
 
     }
 
+    @Override
+    protected void onDestroy() {
+        if (mDisconnectedReceiver != null) {
+            unregisterReceiver(mDisconnectedReceiver);
+        }
+        super.onDestroy();
+    }
+
     public void onClick(DialogInterface dialog, int which) {
         if (which == AlertDialog.BUTTON_POSITIVE) {
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
index 27cce6d..c384f50 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -91,8 +91,8 @@
             ap.mMessage = getString(R.string.usb_device_permission_prompt, appName);
             mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
         }
-        ap.mPositiveButtonText = getString(com.android.internal.R.string.ok);
-        ap.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
+        ap.mPositiveButtonText = getString(android.R.string.ok);
+        ap.mNegativeButtonText = getString(android.R.string.cancel);
         ap.mPositiveButtonListener = this;
         ap.mNegativeButtonListener = this;
 
@@ -101,7 +101,11 @@
                 Context.LAYOUT_INFLATER_SERVICE);
         ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
         mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
-        mAlwaysUse.setText(com.android.internal.R.string.alwaysUse);
+        if (mDevice == null) {
+            mAlwaysUse.setText(R.string.always_use_accessory);
+        } else {
+            mAlwaysUse.setText(R.string.always_use_device);
+        }
         mAlwaysUse.setOnCheckedChangeListener(this);
         mClearDefaultHint = (TextView)ap.mView.findViewById(
                                                     com.android.internal.R.id.clearDefaultHint);
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
index 7c63820..f61ecb1 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
@@ -31,6 +31,9 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
+import android.widget.CheckBox;
+
+import com.android.systemui.R;
 
 import java.util.ArrayList;
 
@@ -58,6 +61,15 @@
         super.onCreate(savedInstanceState, target, title, null, rList,
                 true /* Set alwaysUseOption to true to enable "always use this app" checkbox. */ );
 
+        CheckBox alwaysUse = (CheckBox)findViewById(com.android.internal.R.id.alwaysUse);
+        if (alwaysUse != null) {
+            if (mDevice == null) {
+                alwaysUse.setText(R.string.always_use_accessory);
+            } else {
+                alwaysUse.setText(R.string.always_use_device);
+            }
+        }
+
         mDevice = (UsbDevice)target.getParcelableExtra(UsbManager.EXTRA_DEVICE);
         if (mDevice != null) {
             mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 9c9d406..1455764 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -60,7 +60,6 @@
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.provider.Settings.SettingNotFoundException;
@@ -315,7 +314,6 @@
 
     int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
     int mImeWindowVis;
-    long mOldSystemSettingsVersion;
 
     AlertDialog.Builder mDialogBuilder;
     AlertDialog mSwitchingDialog;
@@ -490,8 +488,6 @@
                 handleMessage(msg);
             }
         });
-        // Initialize the system settings version to undefined.
-        mOldSystemSettingsVersion = -1;
 
         (new MyPackageMonitor()).register(mContext, true);
 
@@ -1012,15 +1008,7 @@
         }
     }
 
-    // TODO: Investigate and fix why are settings changes getting processed before the settings seq
-    // number is updated?
-    // TODO: Change this stuff to not rely on modifying settings for normal user interactions.
     void updateFromSettingsLocked() {
-        long newSystemSettingsVersion = getSystemSettingsVersion();
-        // This is a workaround to avoid a situation that old cached value in Settings.Secure
-        // will be handled.
-        if (newSystemSettingsVersion == mOldSystemSettingsVersion) return;
-
         // We are assuming that whoever is changing DEFAULT_INPUT_METHOD and
         // ENABLED_INPUT_METHODS is taking care of keeping them correctly in
         // sync, so we will never have a DEFAULT_INPUT_METHOD that is not
@@ -1989,7 +1977,6 @@
 
     private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId,
             boolean setSubtypeOnly) {
-        mOldSystemSettingsVersion = getSystemSettingsVersion();
         // Update the history of InputMethod and Subtype
         saveCurrentInputMethodAndSubtypeToHistory();
 
@@ -2239,10 +2226,6 @@
         }
     }
 
-    private static long getSystemSettingsVersion() {
-        return SystemProperties.getLong(Settings.Secure.SYS_PROP_SETTING_VERSION, 0);
-    }
-
     /**
      * @return Return the current subtype of this input method.
      */
diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp
index c66f181..816f76f 100644
--- a/services/jni/com_android_server_UsbService.cpp
+++ b/services/jni/com_android_server_UsbService.cpp
@@ -193,13 +193,14 @@
         return NULL;
     }
     jclass stringClass = env->FindClass("java/lang/String");
-    jobjectArray strArray = env->NewObjectArray(5, stringClass, NULL);
+    jobjectArray strArray = env->NewObjectArray(6, stringClass, NULL);
     if (!strArray) goto out;
     set_accessory_string(env, fd, ACCESSORY_GET_STRING_MANUFACTURER, strArray, 0);
     set_accessory_string(env, fd, ACCESSORY_GET_STRING_MODEL, strArray, 1);
     set_accessory_string(env, fd, ACCESSORY_GET_STRING_DESCRIPTION, strArray, 2);
     set_accessory_string(env, fd, ACCESSORY_GET_STRING_VERSION, strArray, 3);
     set_accessory_string(env, fd, ACCESSORY_GET_STRING_URI, strArray, 4);
+    set_accessory_string(env, fd, ACCESSORY_GET_STRING_SERIAL, strArray, 5);
 
 out:
     close(fd);
diff --git a/tests/HwAccelerationTest/res/drawable/gradient.xml b/tests/HwAccelerationTest/res/drawable/gradient.xml
new file mode 100644
index 0000000..756db0b
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable/gradient.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:startColor="#FF707070"
+        android:endColor="#FF0C0C0C"
+        android:angle="270" />
+</shape>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java
index f8422f4..90db818 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/GradientsActivity.java
@@ -193,6 +193,7 @@
         private final float mDrawWidth;
         private final float mDrawHeight;
         private final LinearGradient mGradient;
+        private final LinearGradient mGradientStops;
         private final Matrix mMatrix;
 
         ShadersView(Context c) {
@@ -202,6 +203,9 @@
             mDrawHeight = 200;
 
             mGradient = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
+            mGradientStops = new LinearGradient(0, 0, 0, 1,
+                    new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF }, null, Shader.TileMode.CLAMP);
+
             mMatrix = new Matrix();
 
             mPaint = new Paint();
@@ -255,6 +259,19 @@
             mGradient.setLocalMatrix(mMatrix);
             canvas.drawRect(left, top, left + mDrawWidth, bottom, mPaint);
 
+            right = left + mDrawWidth;
+            left = 40.0f;
+            top = bottom + 20.0f;
+            bottom = top + 50.0f;
+
+            mPaint.setShader(mGradientStops);
+
+            mMatrix.setScale(1, mDrawWidth);
+            mMatrix.postRotate(90);
+            mMatrix.postTranslate(right, top);
+            mGradientStops.setLocalMatrix(mMatrix);
+            canvas.drawRect(left, top, right, bottom, mPaint);
+            
             canvas.restore();
         }
     }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
index 763169a..535f865 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
@@ -79,7 +79,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         
-        getWindow().setBackgroundDrawable(getResources().getDrawable(R.drawable.default_wallpaper));
+        getWindow().setBackgroundDrawable(getResources().getDrawable(R.drawable.gradient));
         setContentView(R.layout.list_activity);
 
         ListAdapter adapter = new SimpleListAdapter(this);