Merge change Iefd4a388 into eclair

* changes:
  Suppress flaky test AppCacheTest#testFreeApplicationCacheSomeFiles
diff --git a/api/current.xml b/api/current.xml
index b4161ae..3abd38b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -6389,6 +6389,72 @@
  visibility="public"
 >
 </field>
+<field name="quickContactBadgeStyleSmallWindowLarge"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843443"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleSmallWindowMedium"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843442"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleSmallWindowSmall"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843441"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleWindowLarge"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843440"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleWindowMedium"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843439"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleWindowSmall"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843438"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="radioButtonStyle"
  type="int"
  transient="false"
@@ -158042,6 +158108,17 @@
  visibility="public"
 >
 </method>
+<method name="isOpaque"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isPaddingOffsetRequired"
  return="boolean"
  abstract="false"
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 697ac76..8faef59ba 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -96,6 +96,10 @@
     
     // The extra key used in an intent to the speech recognizer for in-app voice search.
     private static final String EXTRA_CALLING_PACKAGE = "calling_package";
+    
+    // The string used for privateImeOptions to identify to the IME that it should not show
+    // a microphone button since one already exists in the search dialog.
+    private static final String IME_OPTION_NO_MICROPHONE = "nm";
 
     private static final int SEARCH_PLATE_LEFT_PADDING_GLOBAL = 12;
     private static final int SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL = 7;
@@ -543,6 +547,14 @@
             mSearchAutoComplete.setInputType(inputType);
             mSearchAutoCompleteImeOptions = mSearchable.getImeOptions();
             mSearchAutoComplete.setImeOptions(mSearchAutoCompleteImeOptions);
+            
+            // If the search dialog is going to show a voice search button, then don't let
+            // the soft keyboard display a microphone button if it would have otherwise.
+            if (mSearchable.getVoiceSearchEnabled()) {
+                mSearchAutoComplete.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE);
+            } else {
+                mSearchAutoComplete.setPrivateImeOptions(null);
+            }
         }
     }
     
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 3265ac4..7f5a1e7 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -330,8 +330,8 @@
  * you'll need to update your searchable activity (or other activities) to receive the intents
  * as you've defined them.</li>
  * <li>Implement a Content Provider that provides suggestions.  If you already have one, and it 
- * has access to your suggestions data.  If not, you'll have to create one.
- * You'll also provide information about your Content Provider in your 
+ * has access to your suggestions data, you can use that provider. If not, you'll have to create 
+ * one. You'll also provide information about your Content Provider in your 
  * package's <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest</a>.</li>
  * <li>Update your searchable activity's XML configuration file.  There are two categories of
  * information used for suggestions:
@@ -1181,7 +1181,7 @@
  *     Bundle appData = new Bundle();
  *     appData.put...();
  *     appData.put...();
- *     startSearch(null, false, appData);
+ *     startSearch(null, false, appData, false);
  *     return true;
  * }</pre> 
  *
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 00ab7de..1c0ed36 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -54,7 +54,7 @@
     // Use the current SDK version code.  If we are a development build,
     // also allow the previous SDK version + 1.
     private static final int sSdkVersion = Build.VERSION.SDK_INT
-            + ("REL".equals(Build.VERSION.CODENAME) ? 1 : 0);
+            + ("REL".equals(Build.VERSION.CODENAME) ? 0 : 1);
     private static final Object mSync = new Object();
     private static Resources mSystem = null;
     
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 0ce2f7b..f5fed4f 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -46,13 +46,21 @@
 
     /** A constant describing a gyroscope sensor type */
     public static final int TYPE_GYROSCOPE      = 4;
-    /** A constant describing a light sensor type */
+    /**
+     * A constant describing an light sensor type.
+     * See {@link android.hardware.SensorEvent SensorEvent}
+     * for more details.
+     */
     public static final int TYPE_LIGHT          = 5;
     /** A constant describing a pressure sensor type */
     public static final int TYPE_PRESSURE       = 6;
     /** A constant describing a temperature sensor type */
     public static final int TYPE_TEMPERATURE    = 7;
-    /** A constant describing a proximity sensor type */
+    /**
+     * A constant describing an proximity sensor type.
+     * See {@link android.hardware.SensorEvent SensorEvent}
+     * for more details.
+     */
     public static final int TYPE_PROXIMITY      = 8;
 
     
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index cf939c5..32d5691 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -115,8 +115,19 @@
      * <p>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD Sensor.TYPE_MAGNETIC_FIELD}:<p>
      *  All values are in micro-Tesla (uT) and measure the ambient magnetic
      *  field in the X, Y and Z axis.
-     *  
-     */    
+     *
+     * <p>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:<p>
+     *
+     *  <p>values[0]: Ambient light level in SI lux units
+     *
+     * <p>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:<p>
+     *
+     *  <p>values[0]: Proximity sensor distance measured in centimeters
+     *
+     *  <p> Note that some proximity sensors only support a binary "close" or "far" measurement.
+     *   In this case, the sensor should report its maxRange value in the "far" state and a value
+     *   less than maxRange in the "near" state.
+     */
     public final float[] values;
 
     /**
diff --git a/core/java/android/os/PerformanceCollector.java b/core/java/android/os/PerformanceCollector.java
index 4ca1f32..be1cf6d 100644
--- a/core/java/android/os/PerformanceCollector.java
+++ b/core/java/android/os/PerformanceCollector.java
@@ -107,6 +107,36 @@
          * @see PerformanceCollector#stopTiming(String)
          */
         public void writeStopTiming(Bundle results);
+
+        /**
+         * Callback invoked as last action in
+         * {@link PerformanceCollector#addMeasurement(String, long)} for
+         * reporting an integer type measurement.
+         *
+         * @param label short description of the metric that was measured
+         * @param value long value of the measurement
+         */
+        public void writeMeasurement(String label, long value);
+
+        /**
+         * Callback invoked as last action in
+         * {@link PerformanceCollector#addMeasurement(String, float)} for
+         * reporting a float type measurement.
+         *
+         * @param label short description of the metric that was measured
+         * @param value float value of the measurement
+         */
+        public void writeMeasurement(String label, float value);
+
+        /**
+         * Callback invoked as last action in
+         * {@link PerformanceCollector#addMeasurement(String, String)} for
+         * reporting a string field.
+         *
+         * @param label short description of the metric that was measured
+         * @param value string summary of the measurement
+         */
+        public void writeMeasurement(String label, String value);
     }
 
     /**
@@ -385,6 +415,39 @@
         return mPerfMeasurement;
     }
 
+    /**
+     * Add an integer type measurement to the collector.
+     *
+     * @param label short description of the metric that was measured
+     * @param value long value of the measurement
+     */
+    public void addMeasurement(String label, long value) {
+        if (mPerfWriter != null)
+            mPerfWriter.writeMeasurement(label, value);
+    }
+
+    /**
+     * Add a float type measurement to the collector.
+     *
+     * @param label short description of the metric that was measured
+     * @param value float value of the measurement
+     */
+    public void addMeasurement(String label, float value) {
+        if (mPerfWriter != null)
+            mPerfWriter.writeMeasurement(label, value);
+    }
+
+    /**
+     * Add a string field to the collector.
+     *
+     * @param label short description of the metric that was measured
+     * @param value string summary of the measurement
+     */
+    public void addMeasurement(String label, String value) {
+        if (mPerfWriter != null)
+            mPerfWriter.writeMeasurement(label, value);
+    }
+
     /*
      * Starts tracking memory usage, binder transactions, and real & cpu timing.
      */
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index c4711f8..9638262 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -313,6 +313,8 @@
 
     private boolean mIsCallLogComposer = false;
 
+    private boolean mNeedPhotoForVCard = true;
+
     private static final String[] sContactsProjection = new String[] {
         Contacts._ID,
     };
@@ -332,17 +334,17 @@
     private static final String FLAG_TIMEZONE_UTC = "Z";
 
     public VCardComposer(Context context) {
-        this(context, VCardConfig.VCARD_TYPE_DEFAULT, true, false);
+        this(context, VCardConfig.VCARD_TYPE_DEFAULT, true, false, true);
     }
 
     public VCardComposer(Context context, String vcardTypeStr,
             boolean careHandlerErrors) {
         this(context, VCardConfig.getVCardTypeFromString(vcardTypeStr),
-                careHandlerErrors, false);
+                careHandlerErrors, false, true);
     }
 
     public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
-        this(context, vcardType, careHandlerErrors, false);
+        this(context, vcardType, careHandlerErrors, false, true);
     }
 
     /**
@@ -351,11 +353,12 @@
      * @param isCallLogComposer true if this composer is for creating Call Log vCard.
      */
     public VCardComposer(Context context, int vcardType, boolean careHandlerErrors,
-            boolean isCallLogComposer) {
+            boolean isCallLogComposer, boolean needPhotoInVCard) {
         mContext = context;
         mVCardType = vcardType;
         mCareHandlerErrors = careHandlerErrors;
         mIsCallLogComposer = isCallLogComposer;
+        mNeedPhotoForVCard = needPhotoInVCard;
         mContentResolver = context.getContentResolver();
 
         mIsV30 = VCardConfig.isV30(vcardType);
@@ -679,7 +682,9 @@
         appendWebsites(builder, contentValuesListMap);
         appendBirthday(builder, contentValuesListMap);
         appendOrganizations(builder, contentValuesListMap);
-        appendPhotos(builder, contentValuesListMap);
+        if (mNeedPhotoForVCard) {
+            appendPhotos(builder, contentValuesListMap);
+        }
         appendNotes(builder, contentValuesListMap);
         // TODO: GroupMembership
 
diff --git a/core/java/android/util/AttributeSet.java b/core/java/android/util/AttributeSet.java
index 01a7ad4..82592b9 100644
--- a/core/java/android/util/AttributeSet.java
+++ b/core/java/android/util/AttributeSet.java
@@ -34,13 +34,13 @@
  * <p>This interface provides an efficient mechanism for retrieving
  * data from compiled XML files, which can be retrieved for a particular
  * XmlPullParser through {@link Xml#asAttributeSet
- * Xml.getAttributeSet()}.  Normally this will return an implementation
+ * Xml.asAttributeSet()}.  Normally this will return an implementation
  * of the interface that works on top of a generic XmlPullParser, however it
  * is more useful in conjunction with compiled XML resources:
  * 
  * <pre>
  * XmlPullParser parser = resources.getXml(myResouce);
- * AttributeSet attributes = Xml.getAttributeSet(parser);</pre>
+ * AttributeSet attributes = Xml.asAttributeSet(parser);</pre>
  * 
  * <p>The implementation returned here, unlike using
  * the implementation on top of a generic XmlPullParser,
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 74f01cc..2628eb4 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -69,7 +69,7 @@
      * Density Independent Pixel unit, where one DIP is one pixel on an
      * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 
      * providing the baseline of the system's display. Thus on a 160dpi screen 
-     * this density value will be 1; on a 106 dpi screen it would be .75; etc.
+     * this density value will be 1; on a 120 dpi screen it would be .75; etc.
      *  
      * <p>This value does not exactly follow the real screen size (as given by 
      * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index eb3e523..ef306fe 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4956,8 +4956,6 @@
      * invalidate/draw passes.
      *
      * @return True if this View is guaranteed to be fully opaque, false otherwise.
-     *
-     * @hide Pending API council approval
      */
     @ViewDebug.ExportedProperty
     public boolean isOpaque() {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bf3d26e..596fd98 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3964,8 +3964,7 @@
                     mHighlightPath = new Path();
 
                 if (selStart == selEnd) {
-                    if ((SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK)
-                        < BLINK) {
+                    if ((SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
                         if (mHighlightPathBogus) {
                             mHighlightPath.reset();
                             mLayout.getCursorPath(selStart, mHighlightPath, mText);
@@ -5344,21 +5343,24 @@
              * will happen at measure).
              */
             makeNewLayout(want, hintWant, UNKNOWN_BORING, UNKNOWN_BORING,
-                          mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(), false);
+                          mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(),
+                          false);
 
-            // In a fixed-height view, so use our new text layout.
-            if (mLayoutParams.height != LayoutParams.WRAP_CONTENT &&
-                mLayoutParams.height != LayoutParams.FILL_PARENT) {
-                invalidate();
-                return;
-            }
-
-            // Dynamic height, but height has stayed the same,
-            // so use our new text layout.
-            if (mLayout.getHeight() == oldht &&
-                (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
-                invalidate();
-                return;
+            if (mEllipsize != TextUtils.TruncateAt.MARQUEE) {
+                // In a fixed-height view, so use our new text layout.
+                if (mLayoutParams.height != LayoutParams.WRAP_CONTENT &&
+                    mLayoutParams.height != LayoutParams.FILL_PARENT) {
+                    invalidate();
+                    return;
+                }
+    
+                // Dynamic height, but height has stayed the same,
+                // so use our new text layout.
+                if (mLayout.getHeight() == oldht &&
+                    (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
+                    invalidate();
+                    return;
+                }
             }
 
             // We lose: the height has changed and we have a dynamic height.
diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp
index 0f8dff1..455449e 100644
--- a/core/jni/android/graphics/MaskFilter.cpp
+++ b/core/jni/android/graphics/MaskFilter.cpp
@@ -1,6 +1,7 @@
 #include "GraphicsJNI.h"
 #include "SkMaskFilter.h"
 #include "SkBlurMaskFilter.h"
+#include "SkTableMaskFilter.h"
 
 #include <jni.h>
 
@@ -39,6 +40,19 @@
         ThrowIAE_IfNull(env, filter);
         return filter;
     }
+
+    static SkMaskFilter* createTable(JNIEnv* env, jobject, jbyteArray jtable) {
+        AutoJavaByteArray autoTable(env, jtable, 256);
+        return new SkTableMaskFilter((const uint8_t*)autoTable.ptr());
+    }
+
+    static SkMaskFilter* createClipTable(JNIEnv* env, jobject, int min, int max) {
+        return SkTableMaskFilter::CreateClip(min, max);
+    }
+
+    static SkMaskFilter* createGammaTable(JNIEnv* env, jobject, float gamma) {
+        return SkTableMaskFilter::CreateGamma(gamma);
+    }
 };
 
 static JNINativeMethod gMaskFilterMethods[] = {
@@ -53,6 +67,12 @@
     { "nativeConstructor",  "([FFFF)I", (void*)SkMaskFilterGlue::createEmboss    }
 };
 
+static JNINativeMethod gTableMaskFilterMethods[] = {
+    { "nativeNewTable", "([B)I", (void*)SkMaskFilterGlue::createTable    },
+    { "nativeNewClip",  "(II)I", (void*)SkMaskFilterGlue::createClipTable    },
+    { "nativeNewGamma", "(F)I", (void*)SkMaskFilterGlue::createGammaTable    }
+};
+
 #include <android_runtime/AndroidRuntime.h>
 
 #define REG(env, name, array)                                                                       \
@@ -67,6 +87,7 @@
     REG(env, "android/graphics/MaskFilter", gMaskFilterMethods);
     REG(env, "android/graphics/BlurMaskFilter", gBlurMaskFilterMethods);
     REG(env, "android/graphics/EmbossMaskFilter", gEmbossMaskFilterMethods);
+    REG(env, "android/graphics/TableMaskFilter", gTableMaskFilterMethods);
     
     return 0;
 }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bd6e7b4..9058221 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -71,11 +71,6 @@
          the slider can be opened (for example, in a pocket or purse). -->
     <bool name="config_bypass_keyguard_if_slider_open">true</bool>
     
-    <!-- Flag indicating whether the device supports automatic brightness mode in hardware.
-         WARNING - DO NOT USE THIS FEATURE
-         Hardware auto brightness support is deprecated and will be removed in the next release. -->
-    <bool name="config_hardware_automatic_brightness_available">false</bool>
-
     <!-- Flag indicating whether the we should enable the automatic brightness in Settings.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 52e32002..a0b56101 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1194,4 +1194,12 @@
   <public type="drawable" name="screen_background_dark_transparent" />
   <public type="drawable" name="screen_background_light_transparent" />
   <public type="drawable" name="stat_notify_sdcard_prepare" />
+  
+  <public type="attr" name="quickContactBadgeStyleWindowSmall" />
+  <public type="attr" name="quickContactBadgeStyleWindowMedium" />
+  <public type="attr" name="quickContactBadgeStyleWindowLarge" />
+  <public type="attr" name="quickContactBadgeStyleSmallWindowSmall" />
+  <public type="attr" name="quickContactBadgeStyleSmallWindowMedium" />
+  <public type="attr" name="quickContactBadgeStyleSmallWindowLarge" />
+  
 </resources>
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index 0830032..cebd2d4 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -18,7 +18,7 @@
     </ol>
   </li>
   <li><a href="#provisional">Using a Provisional API Level</a></li>
-  <li><a href="#filtering">Filtering the Reference Documentation by API Level</a></li>
+  <li><a href="#filtering">Filtering the Documentation</a></li>
 </ol>
 
   <h2>See also</h2>
diff --git a/docs/html/guide/practices/design/responsiveness.jd b/docs/html/guide/practices/design/responsiveness.jd
index ecd743d..1d5a235 100644
--- a/docs/html/guide/practices/design/responsiveness.jd
+++ b/docs/html/guide/practices/design/responsiveness.jd
@@ -80,7 +80,7 @@
 event timeout. These same practices should be followed for any other threads
 that display UI, as they are also subject to the same timeouts.</p>
 
-<p>The specific constraint on IntentReciever execution time emphasizes what
+<p>The specific constraint on IntentReceiver execution time emphasizes what
 they were meant to do: small, discrete amounts of work in the background such
 as saving a setting or registering a Notification. So as with other methods
 called in the main thread, applications should avoid potentially long-running
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index 5f0a278..e5a1b5e2 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -847,118 +847,118 @@
 <tr>
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_alarmclock.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_alarmclock.png" alt="Android asset" />
   <div class="caption">Alarm Clock</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_browser.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_browser.png" alt="Android asset" />
   <div class="caption">Browser</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_calculator.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_calculator.png" alt="Android asset" />
   <div class="caption">Calculator</div></td>
 	
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_calendar.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_calendar.png" alt="Android asset" />
   <div class="caption">Calendar</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_video_camera.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_video_camera.png" alt="Android asset" />
   <div class="caption">Camcorder</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_camera.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_camera.png" alt="Android asset" />
   <div class="caption">Camera</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_contacts.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_contacts.png" alt="Android asset" />
   <div class="caption">Contacts</div></td>
 
 </tr>
 <tr>
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_phone_dialer.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_phone_dialer.png" alt="Android asset" />
   <div class="caption">Dialer</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_email_generic.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_email_generic.png" alt="Android asset" />
   <div class="caption">Email</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_gallery.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_gallery.png" alt="Android asset" />
   <div class="caption">Gallery</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_generic_application.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_generic_application.png" alt="Android asset" />
   <div class="caption">Generic application</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_email.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_email.png" alt="Android asset" />
   <div class="caption">Gmail</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_google_talk.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_google_talk.png" alt="Android asset" />
   <div class="caption">Google Talk</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_IM.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_IM.png" alt="Android asset" />
   <div class="caption">IM</div></td>
 
 </tr>
 <tr>
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_maps.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_maps.png" alt="Android asset" />
   <div class="caption">Maps</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_marketplace.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_marketplace.png" alt="Android asset" />
   <div class="caption">Market </div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_sms_mms.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_sms_mms.png" alt="Android asset" />
   <div class="caption">Messaging </div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_musicplayer_2.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_musicplayer_2.png" alt="Android asset" />
   <div class="caption">Music</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_settings.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_settings.png" alt="Android asset" />
   <div class="caption">Settings</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_voicedial.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_voicedial.png" alt="Android asset" />
   <div class="caption">Voice Dialer</div></td>
 
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_voicesearch.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_voicesearch.png" alt="Android asset" />
   <div class="caption">Voice Search</div></td>
 
 </tr>
 <tr>
 
 <td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_youtube.png" alt="Android asset" />
+  <img src="{@docRoot}images/icon_design/ic_launcher_youtube.png" alt="Android asset" />
   <div class="caption">YouTube</div></td>
 </tr>
 </table>
diff --git a/docs/html/guide/publishing/versioning.jd b/docs/html/guide/publishing/versioning.jd
index 8d8b304..0bec658 100644
--- a/docs/html/guide/publishing/versioning.jd
+++ b/docs/html/guide/publishing/versioning.jd
@@ -165,4 +165,4 @@
 <p>For more information, see the <a
 href="{@docRoot}guide/developing/manifest/uses-sdk-element.html"><code>&lt;uses-
 sdk&gt;</code></a> manifest element documentation and the <a
-href="{@docRoot}guide/appendix/api-levels.htmll">API Levels</a> document.</p>
+href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document.</p>
diff --git a/docs/html/sdk/1.5_r3/upgrading.jd b/docs/html/sdk/1.5_r3/upgrading.jd
index c79b656..f853d25 100644
--- a/docs/html/sdk/1.5_r3/upgrading.jd
+++ b/docs/html/sdk/1.5_r3/upgrading.jd
@@ -187,7 +187,7 @@
 
 <p>If you encounter problems, ensure your ADT is fully uninstalled and then
 follow the guide to 
-<a href="installingplugin">Installing the ADT Plugin
+<a href="installing.html#installingplugin">Installing the ADT Plugin
 for Eclipse</a>.</p>
 
 <h3 id="updateEclipsePrefs">Update your Eclipse SDK Preferences</h3>
diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd
index 66c6bdc..edc77e8 100644
--- a/docs/html/sdk/installing.jd
+++ b/docs/html/sdk/installing.jd
@@ -360,7 +360,7 @@
 </ul>
 
 
-<h2 id="troubleshooting">Installation Troubleshooting</h2>
+<h2 id="troubleshooting">Troubleshooting</h2>
 
 <h3>Ubuntu Linux Notes</h3>
 
diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java
new file mode 100644
index 0000000..a8a7ff0
--- /dev/null
+++ b/graphics/java/android/graphics/TableMaskFilter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+/**
+ * @hide
+ */
+public class TableMaskFilter extends MaskFilter {
+
+    public TableMaskFilter(byte[] table) {
+        if (table.length < 256) {
+            throw new RuntimeException("table.length must be >= 256");
+        }
+        native_instance = nativeNewTable(table);
+    }
+    
+    private TableMaskFilter(int ni) {
+        native_instance = ni;
+    }
+    
+    public static TableMaskFilter CreateClipTable(int min, int max) {
+        return new TableMaskFilter(nativeNewClip(min, max));
+    }
+    
+    public static TableMaskFilter CreateGammaTable(float gamma) {
+        return new TableMaskFilter(nativeNewGamma(gamma));
+    }
+
+    private static native int nativeNewTable(byte[] table);
+    private static native int nativeNewClip(int min, int max);
+    private static native int nativeNewGamma(float gamma);
+}
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 53466cc..1bc03ac 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -80,6 +80,9 @@
      */
     public void surfaceDestroyed(SurfaceHolder holder) {
         // Surface will be destroyed when we return
+        if (mRS != null) {
+            mRS.contextSetSurface(null);
+        }
         //Log.v(RenderScript.LOG_TAG, "surfaceDestroyed");
     }
 
@@ -88,6 +91,9 @@
      * not normally called or subclassed by clients of RSSurfaceView.
      */
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        if (mRS != null) {
+            mRS.contextSetSurface(holder.getSurface());
+        }
         //Log.v(RenderScript.LOG_TAG, "surfaceChanged");
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 1f2ea38..f1e5af1 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -64,6 +64,7 @@
     native void nDeviceSetConfig(int dev, int param, int value);
     native int  nContextCreate(int dev, Surface sur, int ver, boolean useDepth);
     native void nContextDestroy(int con);
+    native void nContextSetSurface(Surface sur);
 
     native void nContextBindRootScript(int script);
     native void nContextBindSampler(int sampler, int slot);
@@ -276,6 +277,11 @@
         mMessageThread.start();
     }
 
+    public void contextSetSurface(Surface sur) {
+        mSurface = sur;
+        nContextSetSurface(mSurface);
+    }
+
     public void destroy() {
         nContextDeinitToClient();
         mMessageThread.mRun = false;
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index fa3baa20..f3dda41 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -171,6 +171,24 @@
 }
 
 static void
+nContextSetSurface(JNIEnv *_env, jobject _this, jobject wnd)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextSetSurface, con(%p), surface(%p)", con, (Surface *)wnd);
+
+    Surface * window = NULL;
+    if (wnd == NULL) {
+
+    } else {
+        jclass surface_class = _env->FindClass("android/view/Surface");
+        jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I");
+        window = (Surface*)_env->GetIntField(wnd, surfaceFieldID);
+    }
+
+    rsContextSetSurface(con, window);
+}
+
+static void
 nContextDestroy(JNIEnv *_env, jobject _this, jint con)
 {
     LOG_API("nContextDestroy, con(%p)", (RsContext)con);
@@ -1328,6 +1346,7 @@
 {"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
 {"nDeviceSetConfig",               "(III)V",                               (void*)nDeviceSetConfig },
 {"nContextCreate",                 "(ILandroid/view/Surface;IZ)I",         (void*)nContextCreate },
+{"nContextSetSurface",             "(Landroid/view/Surface;)V",            (void*)nContextSetSurface },
 {"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
 {"nContextPause",                  "()V",                                  (void*)nContextPause },
 {"nContextResume",                 "()V",                                  (void*)nContextResume },
diff --git a/include/binder/MemoryHeapBase.h b/include/binder/MemoryHeapBase.h
index 435540e..d793c24 100644
--- a/include/binder/MemoryHeapBase.h
+++ b/include/binder/MemoryHeapBase.h
@@ -35,7 +35,8 @@
         MAP_ONCE = IMemoryHeap::MAP_ONCE,
         // memory won't be mapped locally, but will be mapped in the remote
         // process.
-        DONT_MAP_LOCALLY = 0x00000100
+        DONT_MAP_LOCALLY = 0x00000100,
+        NO_CACHING = 0x00000200
     };
 
     /* 
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index a7c8a0a..e066177 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -257,11 +257,12 @@
         DEVICE_IN_WIRED_HEADSET = 0x100000,
         DEVICE_IN_AUX_DIGITAL = 0x200000,
         DEVICE_IN_VOICE_CALL = 0x400000,
+        DEVICE_IN_BACK_MIC = 0x800000,
         DEVICE_IN_DEFAULT = 0x80000000,
 
         DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC |
                 DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL |
-                DEVICE_IN_VOICE_CALL| DEVICE_IN_DEFAULT)
+                DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT)
     };
 
     // device connection states used for setDeviceConnectionState()
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 13316a9..8c7392b 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -41,7 +41,9 @@
     AUDIO_SOURCE_VOICE_UPLINK = 2,
     AUDIO_SOURCE_VOICE_DOWNLINK = 3,
     AUDIO_SOURCE_VOICE_CALL = 4,
-    AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_CALL,
+    AUDIO_SOURCE_CAMCORDER = 5,
+    AUDIO_SOURCE_VOICE_RECOGNITION = 6,
+    AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_RECOGNITION,
 
     AUDIO_SOURCE_LIST_END  // must be last - used to validate audio source type
 };
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index 67c2dd8..26cde38 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -32,6 +32,8 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
+struct android_native_buffer_t;
+
 namespace android {
 
 const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10;
@@ -602,7 +604,7 @@
     copybit_device_t*       blitEngine;
     int32_t                 minScale;
     int32_t                 maxScale;
-    buffer_handle_t         drawSurfaceBuffer;
+    android_native_buffer_t* drawSurfaceBuffer;
 };
 
 struct ogles_context_t {
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 2172536..b9c491be 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -93,6 +93,8 @@
     
     void setIndex(int index);
     int getIndex() const;
+    void setVerticalStride(uint32_t vstride);
+    uint32_t getVerticalStride() const;
 
 protected:
     GraphicBuffer(const Parcel& reply);
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 17ccad6..49145e8 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -1272,7 +1272,7 @@
 
             if (version || o.version) {
                 if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
-                    return (sdkVersion);
+                    return (sdkVersion > o.sdkVersion);
                 }
 
                 if ((minorVersion != o.minorVersion) &&
@@ -1384,7 +1384,7 @@
         }
         if (version != 0) {
             if (settings.sdkVersion != 0 && sdkVersion != 0
-                && sdkVersion != settings.sdkVersion) {
+                && sdkVersion > settings.sdkVersion) {
                 return false;
             }
             if (settings.minorVersion != 0 && minorVersion != 0
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 0960c81..9c0c850 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1162,7 +1162,7 @@
 
 bool AudioFlinger::MixerThread::threadLoop()
 {
-    uint32_t sleepTime = 0;
+    uint32_t sleepTime = 1000;
     uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
     int16_t* curBuf = mMixBuffer;
     Vector< sp<Track> > tracksToRemove;
@@ -1224,6 +1224,7 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    sleepTime = 1000;
                     continue;
                 }
             }
@@ -1591,7 +1592,7 @@
 
 bool AudioFlinger::DirectOutputThread::threadLoop()
 {
-    uint32_t sleepTime = 0;
+    uint32_t sleepTime = 1000;
     uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
     sp<Track> trackToRemove;
     sp<Track> activeTrack;
@@ -1643,6 +1644,7 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    sleepTime = 1000;
                     continue;
                 }
             }
@@ -1879,7 +1881,7 @@
 
 bool AudioFlinger::DuplicatingThread::threadLoop()
 {
-    uint32_t sleepTime = 0;
+    uint32_t sleepTime = 1000;
     uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
     int16_t* curBuf = mMixBuffer;
     Vector< sp<Track> > tracksToRemove;
@@ -1940,6 +1942,7 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    sleepTime = 1000;
                     continue;
                 }
             }
diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.cpp b/libs/audioflinger/AudioPolicyManagerGeneric.cpp
index 6323859..8cfc204 100644
--- a/libs/audioflinger/AudioPolicyManagerGeneric.cpp
+++ b/libs/audioflinger/AudioPolicyManagerGeneric.cpp
@@ -459,6 +459,61 @@
     return NO_ERROR;
 }
 
+status_t AudioPolicyManagerGeneric::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+
+    snprintf(buffer, SIZE, "\nOutputs dump:\n");
+    write(fd, buffer, strlen(buffer));
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
+        write(fd, buffer, strlen(buffer));
+        mOutputs.valueAt(i)->dump(fd);
+    }
+
+    snprintf(buffer, SIZE, "\nInputs dump:\n");
+    write(fd, buffer, strlen(buffer));
+    for (size_t i = 0; i < mInputs.size(); i++) {
+        snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
+        write(fd, buffer, strlen(buffer));
+        mInputs.valueAt(i)->dump(fd);
+    }
+
+    snprintf(buffer, SIZE, "\nStreams dump:\n");
+    write(fd, buffer, strlen(buffer));
+    snprintf(buffer, SIZE, " Stream  Index Min  Index Max  Index Cur  Mute Count  Can be muted\n");
+    write(fd, buffer, strlen(buffer));
+    for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
+        snprintf(buffer, SIZE, " %02d", i);
+        mStreams[i].dump(buffer + 3, SIZE);
+        write(fd, buffer, strlen(buffer));
+    }
+
+    return NO_ERROR;
+}
+
 // ----------------------------------------------------------------------------
 // AudioPolicyManagerGeneric
 // ----------------------------------------------------------------------------
@@ -815,6 +870,35 @@
     return refcount;
 }
 
+status_t AudioPolicyManagerGeneric::AudioOutputDescriptor::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Stream refCount\n");
+    result.append(buffer);
+    for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
+        snprintf(buffer, SIZE, " %02d     %d\n", i, mRefCount[i]);
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+
+    return NO_ERROR;
+}
+
 // --- AudioInputDescriptor class implementation
 
 AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor()
@@ -823,4 +907,39 @@
 {
 }
 
+status_t AudioPolicyManagerGeneric::AudioInputDescriptor::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+
+    return NO_ERROR;
+}
+
+// --- StreamDescriptor class implementation
+
+void AudioPolicyManagerGeneric::StreamDescriptor::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "      %02d         %02d         %02d         %02d          %d\n",
+            mIndexMin,
+            mIndexMax,
+            mIndexCur,
+            mMuteCount,
+            mCanBeMuted);
+}
+
 }; // namespace android
diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.h b/libs/audioflinger/AudioPolicyManagerGeneric.h
index d904520..4997cdf 100644
--- a/libs/audioflinger/AudioPolicyManagerGeneric.h
+++ b/libs/audioflinger/AudioPolicyManagerGeneric.h
@@ -76,6 +76,8 @@
         virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index);
         virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);
 
+        virtual status_t dump(int fd);
+
 private:
 
         enum routing_strategy {
@@ -93,6 +95,7 @@
         public:
             AudioOutputDescriptor();
 
+            status_t    dump(int fd);
 
             uint32_t device();
             void changeRefCount(AudioSystem::stream_type, int delta);
@@ -115,6 +118,8 @@
         public:
             AudioInputDescriptor();
 
+            status_t    dump(int fd);
+
             uint32_t mSamplingRate;                     //
             uint32_t mFormat;                           // input configuration
             uint32_t mChannels;                         //
@@ -130,6 +135,8 @@
             StreamDescriptor()
             :   mIndexMin(0), mIndexMax(1), mIndexCur(1), mMuteCount(0), mCanBeMuted(true) {}
 
+            void dump(char* buffer, size_t size);
+
             int mIndexMin;      // min volume index
             int mIndexMax;      // max volume index
             int mIndexCur;      // current volume index
diff --git a/libs/audioflinger/AudioPolicyService.cpp b/libs/audioflinger/AudioPolicyService.cpp
index f71c99c..9723697 100644
--- a/libs/audioflinger/AudioPolicyService.cpp
+++ b/libs/audioflinger/AudioPolicyService.cpp
@@ -43,6 +43,12 @@
 
 namespace android {
 
+static const char* kDeadlockedString = "AudioPolicyService may be deadlocked\n";
+static const char* kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
+
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleep = 20000;
+
 static bool checkPermission() {
 #ifndef HAVE_ANDROID_OS
     return true;
@@ -335,17 +341,65 @@
     LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
 }
 
+static bool tryLock(Mutex& mutex)
+{
+    bool locked = false;
+    for (int i = 0; i < kDumpLockRetries; ++i) {
+        if (mutex.tryLock() == NO_ERROR) {
+            locked = true;
+            break;
+        }
+        usleep(kDumpLockSleep);
+    }
+    return locked;
+}
+
+status_t AudioPolicyService::dumpInternals(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
+    result.append(buffer);
+
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
 status_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
 {
     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        dumpPermissionDenial(fd, args);
+        dumpPermissionDenial(fd);
     } else {
+        bool locked = tryLock(mLock);
+        if (!locked) {
+            String8 result(kDeadlockedString);
+            write(fd, result.string(), result.size());
+        }
 
+        dumpInternals(fd);
+        if (mAudioCommandThread != NULL) {
+            mAudioCommandThread->dump(fd);
+        }
+        if (mTonePlaybackThread != NULL) {
+            mTonePlaybackThread->dump(fd);
+        }
+
+        if (mpPolicyManager) {
+            mpPolicyManager->dump(fd);
+        }
+
+        if (locked) mLock.unlock();
     }
     return NO_ERROR;
 }
 
-status_t AudioPolicyService::dumpPermissionDenial(int fd, const Vector<String16>& args)
+status_t AudioPolicyService::dumpPermissionDenial(int fd)
 {
     const size_t SIZE = 256;
     char buffer[SIZE];
@@ -609,6 +663,36 @@
     return false;
 }
 
+status_t AudioPolicyService::AudioCommandThread::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+
+    bool locked = tryLock(mLock);
+    if (!locked) {
+        String8 result2(kCmdDeadlockedString);
+        write(fd, result2.string(), result2.size());
+    }
+
+    snprintf(buffer, SIZE, "- Commands:\n");
+    result = String8(buffer);
+    result.append("   Command Time        Status  Wait pParam\n");
+    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
+        mAudioCommands[i]->dump(buffer, SIZE);
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+
+    if (locked) mLock.unlock();
+
+    return NO_ERROR;
+}
+
 void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
 {
     AudioCommand *command = new AudioCommand();
@@ -808,4 +892,15 @@
     requestExitAndWait();
 }
 
+void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "   %02d      %06d.%03d  %03d     %01u    %p\n",
+            mCommand,
+            (int)ns2s(mTime),
+            (int)ns2ms(mTime)%1000,
+            mStatus,
+            mWaitStatus,
+            mParam);
+}
+
 }; // namespace android
diff --git a/libs/audioflinger/AudioPolicyService.h b/libs/audioflinger/AudioPolicyService.h
index 11a1214..7c1bb85 100644
--- a/libs/audioflinger/AudioPolicyService.h
+++ b/libs/audioflinger/AudioPolicyService.h
@@ -111,6 +111,8 @@
                         AudioPolicyService();
     virtual             ~AudioPolicyService();
 
+            status_t dumpInternals(int fd);
+
     // Thread used for tone playback and to send audio config commands to audio flinger
     // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because startTone()
     // and stopTone() are normally called with mLock locked and requesting a tone start or stop will cause
@@ -133,6 +135,8 @@
         AudioCommandThread ();
         virtual             ~AudioCommandThread();
 
+                    status_t    dump(int fd);
+
         // Thread virtuals
         virtual     void        onFirstRef();
         virtual     bool        threadLoop();
@@ -149,6 +153,8 @@
         // descriptor for requested tone playback event
         class AudioCommand {
         public:
+            void dump(char* buffer, size_t size);
+
             int mCommand;   // START_TONE, STOP_TONE ...
             nsecs_t mTime;  // time stamp
             Condition mCond; // condition for status return
@@ -188,7 +194,7 @@
     };
 
     // Internal dump utilities.
-    status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
+    status_t dumpPermissionDenial(int fd);
 
 
     Mutex   mLock;      // prevents concurrent access to AudioPolicy manager functions changing device
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index c371a23..86c3df6 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "IPCThreadState"
+
 #include <binder/IPCThreadState.h>
 
 #include <binder/Binder.h>
 #include <binder/BpBinder.h>
+#include <cutils/sched_policy.h>
 #include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/TextOutput.h>
@@ -418,7 +421,32 @@
                 alog << "Processing top-level Command: "
                     << getReturnString(cmd) << endl;
             }
+
+            bool isTainted = false;
+
+            {
+                SchedPolicy policy;
+                get_sched_policy(getpid(), &policy);
+
+                if (policy == SP_BACKGROUND) {
+                    isTainted = true;
+                }
+            }
+
             result = executeCommand(cmd);
+
+            // Make sure that after executing the commands that we put the thread back into the
+            // default cgroup.
+            {
+                int pid = getpid();
+                SchedPolicy policy;
+                get_sched_policy(pid, &policy);
+
+                if (!isTainted && policy == SP_BACKGROUND) {
+                    LOGW("*** THREAD %p (PID %p) was left in SP_BACKGROUND with a priority of %d\n",
+                        (void*)pthread_self(), pid, getpriority(PRIO_PROCESS, pid));
+                }
+            }
         }
         
         // Let this thread exit the thread pool if it is no longer
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 5df078f..624f7eb 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -67,7 +67,11 @@
     : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
       mDevice(0), mNeedUnmap(false)
 {
-    int fd = open(device, O_RDWR);
+    int open_flags = O_RDWR;
+    if (flags & NO_CACHING)
+        open_flags |= O_SYNC;
+
+    int fd = open(device, open_flags);
     LOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
     if (fd >= 0) {
         const size_t pagesize = getpagesize();
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
index 3806a42..c660947 100644
--- a/libs/binder/MemoryHeapPmem.cpp
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -132,7 +132,7 @@
     char const * const device = pmemHeap->getDevice();
 #if HAVE_ANDROID_OS
     if (device) {
-        int fd = open(device, O_RDWR);
+        int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
         LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
         if (fd >= 0) {
             int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index a393e2f..865e435 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -36,6 +36,10 @@
 ContextResume {
 	}
 
+ContextSetSurface {
+	param void *sur
+	}
+
 AssignName {
 	param void *obj
 	param const char *name
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index b7d1297..38cec64 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -52,6 +52,19 @@
 
 Allocation::~Allocation()
 {
+    free(mPtr);
+    mPtr = NULL;
+
+    if (mBufferID) {
+        // Causes a SW crash....
+        //LOGV(" mBufferID %i", mBufferID);
+        //glDeleteBuffers(1, &mBufferID);
+        //mBufferID = 0;
+    }
+    if (mTextureID) {
+        glDeleteTextures(1, &mTextureID);
+        mTextureID = 0;
+    }
 }
 
 void Allocation::setCpuWritable(bool)
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index eb388af..3e4cc36 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -85,17 +85,6 @@
     }
     //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
 
-    if (mWndSurface) {
-        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
-    } else {
-        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig,
-             android_createDisplaySurface(),
-             NULL);
-    }
-    checkEglError("eglCreateWindowSurface");
-    if (mEGL.mSurface == EGL_NO_SURFACE) {
-        LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
-    }
 
     mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL);
     checkEglError("eglCreateContext");
@@ -104,10 +93,10 @@
     }
     gGLContextCount++;
 
-    EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
-    checkEglError("eglCreateContext", ret);
-    if (mEGL.mContext == EGL_NO_CONTEXT) {
-        LOGE("eglCreateContext returned EGL_NO_CONTEXT");
+    if (mWndSurface) {
+        setSurface(mWndSurface);
+    } else {
+        setSurface((Surface *)android_createDisplaySurface());
     }
 
     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
@@ -134,12 +123,7 @@
 
 void Context::deinitEGL()
 {
-    EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    checkEglError("eglCreateContext", ret);
-    if (mEGL.mContext == EGL_NO_CONTEXT) {
-        LOGE("eglCreateContext returned EGL_NO_CONTEXT");
-    }
-
+    setSurface(NULL);
     eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
     checkEglError("eglDestroyContext");
 
@@ -311,6 +295,7 @@
      while (!rsc->mExit) {
          mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
          mDraw &= (rsc->mRootScript.get() != NULL);
+         mDraw &= (rsc->mWndSurface != NULL);
 
          if (mDraw) {
              mDraw = rsc->runRootScript() && !rsc->mPaused;
@@ -342,6 +327,9 @@
      rsc->mStateFragmentStore.deinit(rsc);
      ObjectBase::zeroAllUserRef(rsc);
 
+     rsc->mObjDestroy.mNeedToEmpty = true;
+     rsc->objDestroyOOBRun();
+
      glClearColor(0,0,0,0);
      glClear(GL_COLOR_BUFFER_BIT);
      eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
@@ -350,7 +338,6 @@
      rsc->deinitEGL();
      pthread_mutex_unlock(&gInitMutex);
 
-     rsc->objDestroyOOBRun();
      LOGV("RS Thread exited");
      return NULL;
 }
@@ -421,6 +408,7 @@
 
     mIO.shutdown();
     int status = pthread_join(mThreadId, &res);
+    mObjDestroy.mNeedToEmpty = true;
     objDestroyOOBRun();
 
     // Global structure cleanup.
@@ -431,12 +419,39 @@
         if (!gThreadTLSKeyCount) {
             pthread_key_delete(gThreadTLSKey);
         }
+        mDev = NULL;
     }
     pthread_mutex_unlock(&gInitMutex);
 
     objDestroyOOBDestroy();
 }
 
+void Context::setSurface(Surface *sur)
+{
+    EGLBoolean ret;
+    if (mEGL.mSurface != NULL) {
+        ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        checkEglError("eglMakeCurrent", ret);
+
+        ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+        checkEglError("eglDestroySurface", ret);
+
+        mEGL.mSurface = NULL;
+    }
+
+    mWndSurface = sur;
+    if (mWndSurface != NULL) {
+        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
+        checkEglError("eglCreateWindowSurface");
+        if (mEGL.mSurface == EGL_NO_SURFACE) {
+            LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
+        }
+
+        ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
+        checkEglError("eglMakeCurrent", ret);
+    }
+}
+
 void Context::pause()
 {
     mPaused = true;
@@ -752,6 +767,11 @@
     rsc->resume();
 }
 
+void rsi_ContextSetSurface(Context *rsc, void *sur)
+{
+    rsc->setSurface((Surface *)sur);
+}
+
 }
 }
 
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index c80fd5a..bffc55b 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -94,6 +94,7 @@
 
     void pause();
     void resume();
+    void setSurface(Surface *sur);
 
     void assignName(ObjectBase *obj, const char *name, uint32_t len);
     void removeName(ObjectBase *obj);
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 0008ea4..b7d67cc 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -39,6 +39,7 @@
     rsAssert(!mUserRefCount);
     rsAssert(!mSysRefCount);
     remove();
+    delete[] mName;
 }
 
 void ObjectBase::dumpLOGV(const char *op) const
@@ -112,12 +113,7 @@
 
 void ObjectBase::setName(const char *name)
 {
-    delete mName;
-    mName = NULL;
-    if (name) {
-        mName = new char[strlen(name) +1];
-        strcpy(mName, name);
-    }
+    setName(name, strlen(name));
 }
 
 void ObjectBase::setName(const char *name, uint32_t len)
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 8aa4542..bc40854 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -54,7 +54,7 @@
         ObjectBaseRef<ProgramRaster> mRaster;
         ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
         InvokeFunc_t mInvokables[MAX_SCRIPT_BANKS];
-        const char * mScriptText;
+        char * mScriptText;
         uint32_t mScriptTextLength;
     };
     Enviroment_t mEnviroment;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 9da7766..073d98b 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -46,6 +46,8 @@
     if (mAccScript) {
         accDeleteScript(mAccScript);
     }
+    free(mEnviroment.mScriptText);
+    mEnviroment.mScriptText = NULL;
 }
 
 void ScriptC::setupScript()
@@ -404,7 +406,11 @@
 void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
 {
     ScriptCState *ss = &rsc->mScriptC;
-    ss->mScript->mEnviroment.mScriptText = text;
+
+    char *t = (char *)malloc(len + 1);
+    memcpy(t, text, len);
+    t[len] = 0;
+    ss->mScript->mEnviroment.mScriptText = t;
     ss->mScript->mEnviroment.mScriptTextLength = len;
 }
 
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index ae124b4..69afc18 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -41,10 +41,6 @@
     virtual ~ScriptC();
 
     struct Program_t {
-        const char * mScriptText;
-        uint32_t mScriptTextLength;
-
-
         int mVersionMajor;
         int mVersionMinor;
 
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index 744f2e9..5fd7904 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -40,9 +40,10 @@
 
 LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client, int32_t i)
-: LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
-mRefreshCache(true), mCacheAge(0), mTextureName(-1U), 
-mWidthScale(1.0f), mHeightScale(1.0f)
+    : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+          mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
+          mWidthScale(1.0f), mHeightScale(1.0f),
+          mBlurFormat(GGL_PIXEL_FORMAT_RGB_565)
 {
 }
 
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 6590503..a36304c 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -33,14 +33,13 @@
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
 
-#include "gralloc_priv.h"   // needed for msm / copybit
-
 namespace android {
 
 // ---------------------------------------------------------------------------
 
 const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
 const char* const LayerBuffer::typeID = "LayerBuffer";
+gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
 
 // ---------------------------------------------------------------------------
 
@@ -60,6 +59,16 @@
     LayerBaseClient::onFirstRef();
     mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(),
             const_cast<LayerBuffer *>(this));
+
+    hw_module_t const* module = (hw_module_t const*)sGrallocModule;
+    if (!module) {
+        // NOTE: technically there is a race here, but it shouldn't
+        // cause any problem since hw_get_module() always returns
+        // the same value.
+        if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
+            sGrallocModule = (gralloc_module_t const *)module;
+        }
+    }
 }
 
 sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
@@ -243,30 +252,36 @@
     : mBufferHeap(buffers)
 {
     NativeBuffer& src(mNativeBuffer);
-    
-    src.crop.l = 0;
-    src.crop.t = 0;
-    src.crop.r = buffers.w;
-    src.crop.b = buffers.h;
-    
-    src.img.w       = buffers.hor_stride ?: buffers.w;
-    src.img.h       = buffers.ver_stride ?: buffers.h;
-    src.img.format  = buffers.format;
-    src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
+    src.img.handle = 0;
 
-    // FIXME: gross hack, we should never access private_handle_t from here,
-    // but this is needed by msm drivers
-    private_handle_t* hnd = new private_handle_t(
-            buffers.heap->heapID(), buffers.heap->getSize(), 0);
-    hnd->offset = offset;
-    src.img.handle = hnd;
+    gralloc_module_t const * module = LayerBuffer::getGrallocModule();
+    if (module && module->perform) {
+        int err = module->perform(module,
+                GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
+                buffers.heap->heapID(), buffers.heap->getSize(),
+                offset, buffers.heap->base(),
+                &src.img.handle);
+
+        if (err == NO_ERROR) {
+            src.crop.l = 0;
+            src.crop.t = 0;
+            src.crop.r = buffers.w;
+            src.crop.b = buffers.h;
+
+            src.img.w       = buffers.hor_stride ?: buffers.w;
+            src.img.h       = buffers.ver_stride ?: buffers.h;
+            src.img.format  = buffers.format;
+            src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
+        }
+    }
 }
 
 LayerBuffer::Buffer::~Buffer()
 {
     NativeBuffer& src(mNativeBuffer);
-    if (src.img.handle)
-        delete (private_handle_t*)src.img.handle;
+    if (src.img.handle) {
+        native_handle_delete(src.img.handle);
+    }
 }
 
 // ============================================================================
@@ -429,6 +444,8 @@
                 GraphicBuffer::USAGE_HW_TEXTURE,
                 src.img.w, src.img.handle, false);
 
+        graphicBuffer->setVerticalStride(src.img.h);
+
         err = mLayer.initializeEglImage(graphicBuffer, &mTexture);
     }
 #endif
@@ -437,9 +454,7 @@
     }
 
     if (err != NO_ERROR) {
-        // OpenGL fall-back
-        GLuint w = 0;
-        GLuint h = 0;
+        // slower fallback
         GGLSurface t;
         t.version = sizeof(GGLSurface);
         t.width  = src.crop.r;
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 438b711..47482f4 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -91,6 +91,11 @@
         copybit_rect_t    crop;
     };
 
+    static gralloc_module_t const* sGrallocModule;
+    static gralloc_module_t const* getGrallocModule() {
+        return sGrallocModule;
+    }
+
     class Buffer : public LightRefBase<Buffer> {
     public:
         Buffer(const ISurface::BufferHeap& buffers, ssize_t offset);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index efe2d78..6a5c8a9 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -226,6 +226,14 @@
     return mIndex;
 }
 
+void GraphicBuffer::setVerticalStride(uint32_t vstride) {
+    mVStride = vstride;
+}
+
+uint32_t GraphicBuffer::getVerticalStride() const {
+    return mVStride;
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 9bb00c6..0b42cf6 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -135,6 +135,12 @@
 
         /** Voice call uplink + downlink audio source */
         public static final int VOICE_CALL = 4;
+
+        /** @hide Microphone audio source with same orientation as camera */
+        public static final int CAMCORDER = 5;
+
+        /** @hide Microphone audio source tuned for voice recognition */
+        public static final int VOICE_RECOGNITION = 6;
     }
 
     /**
@@ -274,7 +280,7 @@
      * Gets the maximum value for audio sources.
      * @see android.media.MediaRecorder.AudioSource
      */
-    public static final int getAudioSourceMax() { return AudioSource.VOICE_CALL; }
+    public static final int getAudioSourceMax() { return AudioSource.VOICE_RECOGNITION; }
 
     /**
      * Sets the video source to be used for recording. If this method is not
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9d2c779..0b75a2b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1509,6 +1509,7 @@
 {
     LOGV("pause");
     if (mTrack) mTrack->pause();
+    lastWriteTime = 0;
 }
 
 void MediaPlayerService::AudioOutput::close()
diff --git a/media/libstagefright/omx/QComHardwareRenderer.cpp b/media/libstagefright/omx/QComHardwareRenderer.cpp
index 7dc368f..c65d1f3 100644
--- a/media/libstagefright/omx/QComHardwareRenderer.cpp
+++ b/media/libstagefright/omx/QComHardwareRenderer.cpp
@@ -126,7 +126,8 @@
 
     master->setDevice("/dev/pmem");
 
-    mMemoryHeap = new MemoryHeapPmem(master, 0);
+    uint32_t heap_flags = master->getFlags() & MemoryHeapBase::NO_CACHING;
+    mMemoryHeap = new MemoryHeapPmem(master, heap_flags);
     mMemoryHeap->slap();
 
     ISurface::BufferHeap bufferHeap(
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
index fa0986a..e66e560 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
@@ -226,7 +226,8 @@
      * Test case 1: Take a picture and verify all the callback
      * functions are called properly.
      */
-    @LargeTest
+    // TODO: add this back to LargeTest once bug 2141755 is fixed
+    // @LargeTest
     public void testTakePicture() throws Exception {  
         synchronized (lock) {
             initializeMessageLooper();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
index d2809c1..ddf5e0b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
@@ -83,7 +83,8 @@
         assertMediaPlaybackActivityHandles("audio/*");
     }
 
-    @MediumTest
+    // TODO: temporarily remove from medium suite because it hangs whole suite 
+    // @MediumTest
     // Checks the MediaPlaybackActivity handles application/itunes. Some servers
     // set the Content-type header to application/iTunes (with capital T, but
     // the download manager downcasts it) for their MP3 podcasts. This is non
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
index 9927edaa..8750098 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
@@ -22,6 +22,7 @@
 import java.io.FileOutputStream;
 import android.test.AndroidTestCase;
 import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.MediaProfileReader;
 import android.test.suitebuilder.annotation.*;
 
 /**
@@ -38,10 +39,19 @@
     public static void testAlbumArt() throws Exception {
         Log.v(TAG, "testAlbumArt starts.");
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+        MediaProfileReader reader = new MediaProfileReader();
+        boolean supportWMA = reader.getWMAEnable();
+        boolean supportWMV = reader.getWMVEnable();
         retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
         for (int i = 0, n = MediaNames.ALBUMART_TEST_FILES.length; i < n; ++i) {
             try {
                 Log.v(TAG, "File " + i + ": " + MediaNames.ALBUMART_TEST_FILES[i]);
+                if ((MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+                    (MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+                   ) {
+                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
+                    continue;
+                }
                 retriever.setDataSource(MediaNames.ALBUMART_TEST_FILES[i]);
                 byte[] albumArt = retriever.extractAlbumArt();
 
@@ -64,11 +74,20 @@
     @LargeTest
     public static void testThumbnailCapture() throws Exception {
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+        MediaProfileReader reader = new MediaProfileReader();
+        boolean supportWMA = reader.getWMAEnable();
+        boolean supportWMV = reader.getWMVEnable();
         Log.v(TAG, "Thumbnail processing starts");
         long startedAt = System.currentTimeMillis();
         for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) {
             try {
                 Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
+                if ((MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+                    (MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+                   ) {
+                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
+                    continue;
+                }
                 retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
                 Bitmap bitmap = retriever.captureFrame();
                 assertTrue(bitmap != null);
@@ -91,10 +110,20 @@
     
     @LargeTest
     public static void testMetadataRetrieval() throws Exception {
+        MediaProfileReader reader = new MediaProfileReader();
+        boolean supportWMA = reader.getWMAEnable();
+        boolean supportWMV = reader.getWMVEnable();
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
         retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
         for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) {
             try {
+                Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
+                if ((MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+                    (MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+                   ) {
+                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
+                    continue;
+                }
                 retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
                 extractAllSupportedMetadataValues(retriever);
             } catch(Exception e) {
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 4b9e59b..1bef859 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -46,13 +46,24 @@
 
 static void textureToCopyBitImage(
         const GGLSurface* surface, int32_t opFormat, 
-        buffer_handle_t buffer, copybit_image_t* img) 
+        android_native_buffer_t* buffer, copybit_image_t* img)
 {
+    uint32_t vstride = 0;
+    if (opFormat == COPYBIT_FORMAT_YCbCr_422_SP ||
+            opFormat == COPYBIT_FORMAT_YCbCr_420_SP) {
+        // NOTE: this static_cast is really not safe b/c we can't know for
+        // sure the buffer passed is of the right type.
+        // However, since we do this only for YUV formats, we should be safe
+        // since only SurfaceFlinger makes use of them.
+        GraphicBuffer* graphicBuffer = static_cast<GraphicBuffer*>(buffer);
+        vstride = graphicBuffer->getVerticalStride();
+    }
+
     img->w      = surface->stride;
-    img->h      = surface->height;
+    img->h      = vstride ? vstride : surface->height;
     img->format = opFormat;
     img->base   = surface->data;
-    img->handle = (native_handle_t *)buffer;
+    img->handle = (native_handle_t *)buffer->handle;
 }
 
 struct clipRectRegion : public copybit_region_t {
@@ -74,6 +85,7 @@
     static int iterate_done(copybit_region_t const *, copybit_rect_t*) {
         return 0;
     }
+public:
     copybit_rect_t r;
 };
 
@@ -278,8 +290,8 @@
 
     copybit_device_t* copybit = c->copybits.blitEngine;
     copybit_image_t src;
-    buffer_handle_t source_hnd = textureObject->buffer->handle;
-    textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src);
+    textureToCopyBitImage(&textureObject->surface, opFormat,
+            textureObject->buffer, &src);
     copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
 
     /*
@@ -359,8 +371,8 @@
     }
 
     copybit_image_t dst;
-    buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer;
-    textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst);
+    textureToCopyBitImage(&cbSurface, cbSurface.format,
+            c->copybits.drawSurfaceBuffer, &dst);
     copybit_rect_t drect = {x, y, x+w, y+h};
 
 
@@ -421,6 +433,20 @@
                 (enables & GGL_ENABLE_DITHER) ?
                         COPYBIT_ENABLE : COPYBIT_DISABLE);
         clipRectRegion it(c);
+
+        LOGD_IF(0,
+             "dst={%d, %d, %d, %p, %p}, "
+             "src={%d, %d, %d, %p, %p}, "
+             "drect={%d,%d,%d,%d}, "
+             "srect={%d,%d,%d,%d}, "
+             "it={%d,%d,%d,%d}, " ,
+             dst.w, dst.h, dst.format, dst.base, dst.handle,
+             src.w, src.h, src.format, src.base, src.handle,
+             drect.l, drect.t, drect.r, drect.b,
+             srect.l, srect.t, srect.r, srect.b,
+             it.r.l, it.r.t, it.r.r, it.r.b
+        );
+
         err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
     }
     if (err != NO_ERROR) {
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index d04900e..80ddc02 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -651,7 +651,7 @@
         if (supportedCopybitsDestinationFormat(buffer.format)) {
             buffer_handle_t handle = this->buffer->handle;
             if (handle != NULL) {
-                gl->copybits.drawSurfaceBuffer = handle;
+                gl->copybits.drawSurfaceBuffer = this->buffer;
             }
         }
     }
diff --git a/opengl/libagl/matrix.cpp b/opengl/libagl/matrix.cpp
index 21ef50e..3c50977 100644
--- a/opengl/libagl/matrix.cpp
+++ b/opengl/libagl/matrix.cpp
@@ -741,20 +741,19 @@
 
 void point4__mvui(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
     // this used for transforming light positions back to object space.
-    // Lights have 3 components positions, so w is always 1.
-    // however, it is used as a switch for directional lights, so we need
+    // w is used as a switch for directional lights, so we need
     // to preserve it.
     const GLfixed* const m = mx->matrix.m;
     const GLfixed rx = rhs->x;
     const GLfixed ry = rhs->y;
     const GLfixed rz = rhs->z;
-    lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); 
-    lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
-    lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
-    lhs->w = rhs->w;
+    const GLfixed rw = rhs->w;
+    lhs->x = mla4(rx, m[ 0], ry, m[ 4], rz, m[ 8], rw, m[12]);
+    lhs->y = mla4(rx, m[ 1], ry, m[ 5], rz, m[ 9], rw, m[13]);
+    lhs->z = mla4(rx, m[ 2], ry, m[ 6], rz, m[10], rw, m[14]);
+    lhs->w = rw;
 }
 
-
 void point2__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
     lhs->z = 0;
     lhs->w = 0x10000;
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3efb678..c22c21b 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -1641,8 +1641,13 @@
         if (dp == 0) {
             return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
         }
-        // since we don't have a way to know which implementation to call,
-        // we're calling all of them
+
+        /* Since we don't have a way to know which implementation to call,
+         * we're calling all of them. If at least one of the implementation
+         * succeeded, this is a success.
+         */
+
+        EGLint currentError = eglGetError();
 
         EGLImageKHR implImages[IMPL_NUM_IMPLEMENTATIONS];
         bool success = false;
@@ -1659,9 +1664,24 @@
                 }
             }
         }
-        if (!success)
+
+        if (!success) {
+            // failure, if there was an error when we entered this function,
+            // the error flag must not be updated.
+            // Otherwise, the error is whatever happened in the implementation
+            // that faulted.
+            if (currentError != EGL_SUCCESS) {
+                setError(currentError, EGL_NO_IMAGE_KHR);
+            }
             return EGL_NO_IMAGE_KHR;
-        
+        } else {
+            // In case of success, we need to clear all error flags
+            // (especially those caused by the implementation that didn't
+            // succeed). TODO: we could avoid this if we knew this was
+            // a "full" success (all implementation succeeded).
+            eglGetError();
+        }
+
         egl_image_t* result = new egl_image_t(dpy, ctx);
         memcpy(result->images, implImages, sizeof(implImages));
         return (EGLImageKHR)result;
diff --git a/opengl/tests/linetex/linetex.cpp b/opengl/tests/linetex/linetex.cpp
index 992a10c..6842940 100644
--- a/opengl/tests/linetex/linetex.cpp
+++ b/opengl/tests/linetex/linetex.cpp
@@ -68,7 +68,7 @@
      
      glBindTexture(GL_TEXTURE_2D, 0);
      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
      glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -77,7 +77,9 @@
      glEnable(GL_TEXTURE_2D);
      glColor4f(1,1,1,1);
 
-     const uint16_t t16[64] = { 0xFFFF, 0xF800, 0x07E0, 0x001F };
+
+     // default pack-alignment is 4
+     const uint16_t t16[64] = { 0xFFFF, 0, 0xF800, 0, 0x07E0, 0, 0x001F, 0 };
 
      const GLfloat vertices[4][2] = {
              { w/2,  0 },
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 82a7c1c..754e6e5 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -76,6 +76,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Random;
 
 class BackupManagerService extends IBackupManager.Stub {
     private static final String TAG = "BackupManagerService";
@@ -85,6 +86,9 @@
     // trigger an immediate pass.
     private static final long BACKUP_INTERVAL = AlarmManager.INTERVAL_HOUR;
 
+    // Random variation in backup scheduling time to avoid server load spikes
+    private static final int FUZZ_MILLIS = 5 * 60 * 1000;
+
     // The amount of time between the initial provisioning of the device and
     // the first backup pass.
     private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR;
@@ -1949,9 +1953,15 @@
     }
 
     private void startBackupAlarmsLocked(long delayBeforeFirstBackup) {
-        long when = System.currentTimeMillis() + delayBeforeFirstBackup;
-        mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, when,
-                BACKUP_INTERVAL, mRunBackupIntent);
+        // We used to use setInexactRepeating(), but that may be linked to
+        // backups running at :00 more often than not, creating load spikes.
+        // Schedule at an exact time for now, and also add a bit of "fuzz".
+
+        Random random = new Random();
+        long when = System.currentTimeMillis() + delayBeforeFirstBackup +
+                random.nextInt(FUZZ_MILLIS);
+        mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when,
+                BACKUP_INTERVAL + random.nextInt(FUZZ_MILLIS), mRunBackupIntent);
         mNextBackupPass = when;
     }
 
diff --git a/services/java/com/android/server/HardwareService.java b/services/java/com/android/server/HardwareService.java
index 7c56a30..b1d58ce 100755
--- a/services/java/com/android/server/HardwareService.java
+++ b/services/java/com/android/server/HardwareService.java
@@ -59,8 +59,6 @@
     private boolean mAttentionLightOn;
     private boolean mPulsing;
 
-    private boolean mAutoBrightnessAvailable;
-
     private class Vibration implements IBinder.DeathRecipient {
         private final IBinder mToken;
         private final long    mTimeout;
@@ -131,9 +129,6 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         context.registerReceiver(mIntentReceiver, filter);
-
-        mAutoBrightnessAvailable = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_hardware_automatic_brightness_available);
     }
 
     protected void finalize() throws Throwable {
@@ -287,12 +282,6 @@
         setLight_native(mNativePointer, light, color, mode, onMS, offMS);
     }
 
-    void setAutoBrightness_UNCHECKED(boolean on) {
-        if (mAutoBrightnessAvailable) {
-            setAutoBrightness_native(mNativePointer, on);
-        }
-    }
-
     public void setAttentionLight(boolean on) {
         // Not worthy of a permission.  We shouldn't have a flashlight permission.
         synchronized (this) {
@@ -493,7 +482,6 @@
     private static native int init_native();
     private static native void finalize_native(int ptr);
 
-    private static native void setAutoBrightness_native(int ptr, boolean automatic);
     private static native void setLight_native(int ptr, int light, int color, int mode,
             int onMS, int offMS);
 
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 4bf606d..93b469f 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -211,7 +211,7 @@
     private long mScreenOnStartTime;
     private boolean mPreventScreenOn;
     private int mScreenBrightnessOverride = -1;
-    private boolean mHasHardwareAutoBrightness;
+    private boolean mUseSoftwareAutoBrightness;
     private boolean mAutoBrightessEnabled;
     private int[] mAutoBrightnessLevels;
     private int[] mLcdBacklightValues;
@@ -438,9 +438,11 @@
         mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
 
         Resources resources = mContext.getResources();
-        mHasHardwareAutoBrightness = resources.getBoolean(
-                com.android.internal.R.bool.config_hardware_automatic_brightness_available);
-        if (!mHasHardwareAutoBrightness) {
+
+        // read settings for auto-brightness
+        mUseSoftwareAutoBrightness = resources.getBoolean(
+                com.android.internal.R.bool.config_automatic_brightness_available);
+        if (mUseSoftwareAutoBrightness) {
             mAutoBrightnessLevels = resources.getIntArray(
                     com.android.internal.R.array.config_autoBrightnessLevels);
             mLcdBacklightValues = resources.getIntArray(
@@ -479,7 +481,7 @@
         // And explicitly do the initial update of our cached settings
         updateGservicesValues();
 
-        if (mAutoBrightessEnabled && !mHasHardwareAutoBrightness) {
+        if (mUseSoftwareAutoBrightness) {
             // turn the screen on
             setPowerState(SCREEN_BRIGHT);
         } else {
@@ -581,7 +583,7 @@
             switch (wl.flags & LOCK_MASK)
             {
                 case PowerManager.FULL_WAKE_LOCK:
-                    if (mAutoBrightessEnabled && !mHasHardwareAutoBrightness) {
+                    if (mUseSoftwareAutoBrightness) {
                         wl.minState = SCREEN_BRIGHT;
                     } else {
                         wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
@@ -887,7 +889,7 @@
         pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
         pw.println("  mLightSensorValue=" + mLightSensorValue);
         pw.println("  mLightSensorPendingValue=" + mLightSensorPendingValue);
-        pw.println("  mHasHardwareAutoBrightness=" + mHasHardwareAutoBrightness);
+        pw.println("  mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
         pw.println("  mAutoBrightessEnabled=" + mAutoBrightessEnabled);
         mScreenBrightness.dump(pw, "  mScreenBrightness: ");
         mKeyboardBrightness.dump(pw, "  mKeyboardBrightness: ");
@@ -1290,8 +1292,8 @@
 
     private int setScreenStateLocked(boolean on) {
         int err = Power.setScreenState(on);
-        if (err == 0 && !mHasHardwareAutoBrightness) {
-            enableLightSensor(on && mAutoBrightessEnabled);
+        if (err == 0 && mUseSoftwareAutoBrightness) {
+            enableLightSensor(on);
             if (!on) {
                 // make sure button and key backlights are off too
                 mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, 0);
@@ -1337,7 +1339,7 @@
                 return;
             }
 
-            if (!mDoneBooting && !(mAutoBrightessEnabled && !mHasHardwareAutoBrightness)) {
+            if (!mDoneBooting && !mUseSoftwareAutoBrightness) {
                 newState |= ALL_BRIGHT;
             }
 
@@ -1758,7 +1760,8 @@
         try {
             if (mScreenBrightnessOverride >= 0) {
                 return mScreenBrightnessOverride;
-            } else if (mLightSensorBrightness >= 0 && !mHasHardwareAutoBrightness) {
+            } else if (mLightSensorBrightness >= 0 && mUseSoftwareAutoBrightness
+                    && mAutoBrightessEnabled) {
                 return mLightSensorBrightness;
             }
             final int brightness = Settings.System.getInt(mContext.getContentResolver(),
@@ -1783,6 +1786,8 @@
     }
 
     private void forceUserActivityLocked() {
+        // cancel animation so userActivity will succeed
+        mScreenBrightness.animating = false;
         boolean savedActivityAllowed = mUserActivityAllowed;
         mUserActivityAllowed = true;
         userActivity(SystemClock.uptimeMillis(), false);
@@ -1849,8 +1854,7 @@
                 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
                     // Only turn on button backlights if a button was pressed
                     // and auto brightness is disabled
-                    if (eventType == BUTTON_EVENT &&
-                            !(mAutoBrightessEnabled && !mHasHardwareAutoBrightness)) {
+                    if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
                         mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
                     } else {
                         // don't clear button/keyboard backlights when the screen is touched.
@@ -1908,14 +1912,17 @@
             Log.d(TAG, "lightSensorChangedLocked " + value);
         }
 
-        if (mHasHardwareAutoBrightness) return;
-
         if (mLightSensorValue != value) {
             mLightSensorValue = value;
             if ((mPowerState & BATTERY_LOW_BIT) == 0) {
                 int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
                 int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
-                int keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
+                int keyboardValue;
+                if (mKeyboardVisible) {
+                    keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
+                } else {
+                    keyboardValue = 0;
+                }
                 mLightSensorBrightness = lcdValue;
 
                 if (mDebugLightSensor) {
@@ -1925,7 +1932,7 @@
                 }
 
                 boolean startAnimation = false;
-                if (mScreenBrightnessOverride < 0) {
+                if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
                     if (ANIMATE_SCREEN_LIGHTS) {
                         if (mScreenBrightness.setTargetLocked(lcdValue,
                                 AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_SCREEN_BRIGHTNESS,
@@ -2037,6 +2044,14 @@
                 // will take care of turning on due to a true change to the lid
                 // switch and synchronized with the lock screen.
                 if ((mPowerState & SCREEN_ON_BIT) != 0) {
+                    if (mUseSoftwareAutoBrightness) {
+                        // force recompute of backlight values
+                        if (mLightSensorValue >= 0) {
+                            int value = (int)mLightSensorValue;
+                            mLightSensorValue = -1;
+                            lightSensorChangedLocked(value);
+                        }
+                    }
                     userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
                 }
             }
@@ -2049,26 +2064,20 @@
     public void enableUserActivity(boolean enabled) {
         synchronized (mLocks) {
             mUserActivityAllowed = enabled;
-            mLastEventTime = SystemClock.uptimeMillis(); // we might need to pass this in
         }
     }
 
     private void setScreenBrightnessMode(int mode) {
         boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-        if (mAutoBrightessEnabled != enabled) {
+        if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
             mAutoBrightessEnabled = enabled;
-            // reset computed brightness
-            mLightSensorValue = -1;
-            mLightSensorBrightness = -1;
-
-            if (mHasHardwareAutoBrightness) {
-                // When setting auto-brightness, must reset the brightness afterwards
-                mHardware.setAutoBrightness_UNCHECKED(enabled);
-                if (screenIsOn()) {
-                    setBacklightBrightness((int)mScreenBrightness.curValue);
+            if (screenIsOn()) {
+                // force recompute of backlight values
+                if (mLightSensorValue >= 0) {
+                    int value = (int)mLightSensorValue;
+                    mLightSensorValue = -1;
+                    lightSensorChangedLocked(value);
                 }
-            } else {
-                enableLightSensor(screenIsOn() && enabled);
             }
         }
     }
@@ -2222,9 +2231,9 @@
         mSensorManager = new SensorManager(mHandlerThread.getLooper());
         mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
         // don't bother with the light sensor if auto brightness is handled in hardware
-        if (!mHasHardwareAutoBrightness) {
+        if (mUseSoftwareAutoBrightness) {
             mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
-            enableLightSensor(mAutoBrightessEnabled);
+            enableLightSensor(true);
         }
 
         synchronized (mLocks) {
@@ -2266,7 +2275,8 @@
         // Don't let applications turn the screen all the way off
         brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
         mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BACKLIGHT, brightness);
-        mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD, brightness);
+        mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD,
+            (mKeyboardVisible ? brightness : 0));
         mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, brightness);
         long identity = Binder.clearCallingIdentity();
         try {
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 59e9832..8d73904 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -692,6 +692,7 @@
                     mTicker.addEntry(n, StatusBarIcon.getIcon(mContext, data), n.tickerText);
                 }
             }
+            updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
         }
 
         // icon
@@ -950,7 +951,9 @@
         panelSlightlyVisible(true);
         
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
-        mExpandedDialog.show();
+        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
         mExpandedView.requestFocus(View.FOCUS_FORWARD);
         mTrackingView.setVisibility(View.VISIBLE);
         
@@ -1027,7 +1030,9 @@
         }
         mExpandedVisible = false;
         panelSlightlyVisible(false);
-        mExpandedDialog.hide();
+        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
         mTrackingView.setVisibility(View.GONE);
 
         if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
@@ -1056,6 +1061,7 @@
             else if (mAnimY < mStatusBarView.getHeight()) {
                 if (SPEW) Log.d(TAG, "Animation completed to collapsed state.");
                 mAnimating = false;
+                updateExpandedViewPos(0);
                 performCollapse();
             }
             else {
@@ -1508,17 +1514,18 @@
             }
         }
 
+        final int disph = mDisplay.getHeight();
         lp = mExpandedDialog.getWindow().getAttributes();
         lp.width = ViewGroup.LayoutParams.FILL_PARENT;
         lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
         lp.x = 0;
-        lp.y = 0;
+        mTrackingPosition = lp.y = -disph; // sufficiently large negative
         lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
         lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                | WindowManager.LayoutParams.FLAG_DITHER;
+                | WindowManager.LayoutParams.FLAG_DITHER
+                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
         lp.format = pixelFormat;
         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
         lp.setTitle("StatusBarExpanded");
@@ -1531,7 +1538,6 @@
                 new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                                            ViewGroup.LayoutParams.WRAP_CONTENT));
         mExpandedDialog.show();
-        mExpandedDialog.hide();
         FrameLayout hack = (FrameLayout)mExpandedView.getParent();
         hack.setForeground(null);
     }
@@ -1558,15 +1564,24 @@
                     + " mTrackingPosition=" + mTrackingPosition);
         }
 
-        // If the expanded view is not visible, there is no reason to do
-        // any work.
-        if (!mExpandedVisible) {
-            return;
-        }
-        
-        // tracking view...
         int h = mStatusBarView.getHeight();
         int disph = mDisplay.getHeight();
+
+        // If the expanded view is not visible, make sure they're still off screen.
+        // Maybe the view was resized.
+        if (!mExpandedVisible) {
+            if (mTrackingView != null) {
+                mTrackingPosition = mTrackingParams.y = -disph;
+                WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
+            }
+            if (mExpandedParams != null) {
+                mExpandedParams.y = -disph;
+                mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+            }
+            return;
+        }
+
+        // tracking view...
         int pos;
         if (expandedPosition == EXPANDED_FULL_OPEN) {
             pos = h;
@@ -1677,7 +1692,7 @@
     private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
         public void onClick(View v) {
             mNotificationCallbacks.onClearAll();
-            performCollapse();
+            addPendingOp(OP_EXPAND, null, false);
         }
     };
 
diff --git a/services/java/com/android/server/status/TrackingPatternView.java b/services/java/com/android/server/status/TrackingPatternView.java
index 0ae9984..4cb8eff 100644
--- a/services/java/com/android/server/status/TrackingPatternView.java
+++ b/services/java/com/android/server/status/TrackingPatternView.java
@@ -55,8 +55,6 @@
         final int textureWidth = mTextureWidth;
         final int textureHeight = mTextureHeight;
 
-        Log.d("TrackingPatternView", "width=" + width + " textureWidth=" + textureWidth);
-
         int x = 0;
         int y;
 
diff --git a/services/jni/com_android_server_HardwareService.cpp b/services/jni/com_android_server_HardwareService.cpp
index a17e29f..22d4bd8 100644
--- a/services/jni/com_android_server_HardwareService.cpp
+++ b/services/jni/com_android_server_HardwareService.cpp
@@ -100,18 +100,6 @@
     free(devices);
 }
 
-static void setAutoBrightness_native(JNIEnv *env, jobject clazz, int ptr,
-        jboolean automatic)
-{
-    Devices* devices = (Devices*)ptr;
-
-    if (devices->lights[LIGHT_INDEX_BACKLIGHT] == NULL) {
-        return;
-    }
-
-    devices->lights[LIGHT_INDEX_BACKLIGHT]->set_als_mode(automatic ? 0 : 1);
-}
-
 static void setLight_native(JNIEnv *env, jobject clazz, int ptr,
         int light, int colorARGB, int flashMode, int onMS, int offMS)
 {
@@ -146,7 +134,6 @@
 static JNINativeMethod method_table[] = {
     { "init_native", "()I", (void*)init_native },
     { "finalize_native", "(I)V", (void*)finalize_native },
-    { "setAutoBrightness_native", "(IZ)V", (void*)setAutoBrightness_native },
     { "setLight_native", "(IIIIII)V", (void*)setLight_native },
     { "vibratorOn", "(J)V", (void*)vibratorOn },
     { "vibratorOff", "()V", (void*)vibratorOff }
diff --git a/test-runner/android/test/InstrumentationTestRunner.java b/test-runner/android/test/InstrumentationTestRunner.java
index b9978d6..773d7a9 100644
--- a/test-runner/android/test/InstrumentationTestRunner.java
+++ b/test-runner/android/test/InstrumentationTestRunner.java
@@ -227,17 +227,22 @@
      */
     private static final String REPORT_KEY_COVERAGE_PATH = "coverageFilePath";
     /**
+     * If included at the start of reporting keys, this prefix marks the key as a performance
+     * metric.
+     */
+    private static final String REPORT_KEY_PREFIX = "performance.";
+    /**
      * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
      * reports the cpu time in milliseconds of the current test.
      */
     private static final String REPORT_KEY_PERF_CPU_TIME =
-        "performance." + PerformanceCollector.METRIC_KEY_CPU_TIME;
+        REPORT_KEY_PREFIX + PerformanceCollector.METRIC_KEY_CPU_TIME;
     /**
      * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
      * reports the run time in milliseconds of the current test.
      */
     private static final String REPORT_KEY_PERF_EXECUTION_TIME =
-        "performance." + PerformanceCollector.METRIC_KEY_EXECUTION_TIME;
+        REPORT_KEY_PREFIX + PerformanceCollector.METRIC_KEY_EXECUTION_TIME;
 
     /**
      * The test is starting.
@@ -739,11 +744,9 @@
         }
 
         public void writeEndSnapshot(Bundle results) {
-            // Copy all snapshot data fields as type long into mResults, which
-            // is outputted via Instrumentation.finish
-            for (String key : results.keySet()) {
-                mResults.putLong(key, results.getLong(key));
-            }
+            // Copy all snapshot data fields into mResults, which is outputted
+            // via Instrumentation.finish
+            mResults.putAll(results);
         }
 
         public void writeStartTiming(String label) {
@@ -768,6 +771,18 @@
             }
         }
 
+        public void writeMeasurement(String label, long value) {
+            mTestResult.putLong(REPORT_KEY_PREFIX + label, value);
+        }
+
+        public void writeMeasurement(String label, float value) {
+            mTestResult.putFloat(REPORT_KEY_PREFIX + label, value);
+        }
+
+        public void writeMeasurement(String label, String value) {
+            mTestResult.putString(REPORT_KEY_PREFIX + label, value);
+        }
+
         // TODO report the end of the cycle
     }
 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java b/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java
index d0fdff4..25b6e0e 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java
@@ -19,8 +19,9 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.PerformanceCollector;
+import android.os.Process;
 import android.os.PerformanceCollector.PerformanceResultsWriter;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -44,6 +45,7 @@
         mPerfCollector = null;
     }
 
+    @SmallTest
     public void testBeginSnapshotNoWriter() throws Exception {
         mPerfCollector.beginSnapshot("testBeginSnapshotNoWriter");
 
@@ -54,15 +56,16 @@
         assertEquals(2, snapshot.size());
     }
 
-    @LargeTest
+    @SmallTest
     public void testEndSnapshotNoWriter() throws Exception {
         mPerfCollector.beginSnapshot("testEndSnapshotNoWriter");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
         Bundle snapshot = mPerfCollector.endSnapshot();
 
         verifySnapshotBundle(snapshot);
     }
 
+    @SmallTest
     public void testStartTimingNoWriter() throws Exception {
         mPerfCollector.startTiming("testStartTimingNoWriter");
 
@@ -73,21 +76,23 @@
         verifyTimingBundle(measurement, new ArrayList<String>());
     }
 
+    @SmallTest
     public void testAddIterationNoWriter() throws Exception {
         mPerfCollector.startTiming("testAddIterationNoWriter");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         Bundle iteration = mPerfCollector.addIteration("timing1");
 
         verifyIterationBundle(iteration, "timing1");
     }
 
+    @SmallTest
     public void testStopTimingNoWriter() throws Exception {
         mPerfCollector.startTiming("testStopTimingNoWriter");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("timing2");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("timing3");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing = mPerfCollector.stopTiming("timing4");
 
         ArrayList<String> labels = new ArrayList<String>();
@@ -97,6 +102,7 @@
         verifyTimingBundle(timing, labels);
     }
 
+    @SmallTest
     public void testBeginSnapshot() throws Exception {
         MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
         mPerfCollector.setPerformanceResultsWriter(writer);
@@ -110,19 +116,20 @@
         assertEquals(2, snapshot.size());
     }
 
-    @LargeTest
+    @SmallTest
     public void testEndSnapshot() throws Exception {
         MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
         mPerfCollector.setPerformanceResultsWriter(writer);
         mPerfCollector.beginSnapshot("testEndSnapshot");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
         Bundle snapshot1 = mPerfCollector.endSnapshot();
         Bundle snapshot2 = writer.snapshotResults;
 
-        assertTrue(snapshot1.equals(snapshot2));
+        assertEqualsBundle(snapshot1, snapshot2);
         verifySnapshotBundle(snapshot1);
     }
 
+    @SmallTest
     public void testStartTiming() throws Exception {
         MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
         mPerfCollector.setPerformanceResultsWriter(writer);
@@ -136,21 +143,23 @@
         verifyTimingBundle(measurement, new ArrayList<String>());
     }
 
+    @SmallTest
     public void testAddIteration() throws Exception {
         mPerfCollector.startTiming("testAddIteration");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         Bundle iteration = mPerfCollector.addIteration("timing5");
 
         verifyIterationBundle(iteration, "timing5");
     }
 
+    @SmallTest
     public void testStopTiming() throws Exception {
         mPerfCollector.startTiming("testStopTiming");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("timing6");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("timing7");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing = mPerfCollector.stopTiming("timing8");
 
         ArrayList<String> labels = new ArrayList<String>();
@@ -160,28 +169,90 @@
         verifyTimingBundle(timing, labels);
     }
 
-    // TODO: flaky test
-    // @LargeTest
+    @SmallTest
+    public void testAddMeasurementLong() throws Exception {
+        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
+        mPerfCollector.setPerformanceResultsWriter(writer);
+        mPerfCollector.startTiming("testAddMeasurementLong");
+        mPerfCollector.addMeasurement("testAddMeasurementLongZero", 0);
+        mPerfCollector.addMeasurement("testAddMeasurementLongPos", 348573);
+        mPerfCollector.addMeasurement("testAddMeasurementLongNeg", -19354);
+        mPerfCollector.stopTiming("");
+
+        assertEquals("testAddMeasurementLong", writer.timingLabel);
+        Bundle results = writer.timingResults;
+        assertEquals(4, results.size());
+        assertTrue(results.containsKey("testAddMeasurementLongZero"));
+        assertEquals(0, results.getLong("testAddMeasurementLongZero"));
+        assertTrue(results.containsKey("testAddMeasurementLongPos"));
+        assertEquals(348573, results.getLong("testAddMeasurementLongPos"));
+        assertTrue(results.containsKey("testAddMeasurementLongNeg"));
+        assertEquals(-19354, results.getLong("testAddMeasurementLongNeg"));
+    }
+
+    @SmallTest
+    public void testAddMeasurementFloat() throws Exception {
+        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
+        mPerfCollector.setPerformanceResultsWriter(writer);
+        mPerfCollector.startTiming("testAddMeasurementFloat");
+        mPerfCollector.addMeasurement("testAddMeasurementFloatZero", 0.0f);
+        mPerfCollector.addMeasurement("testAddMeasurementFloatPos", 348573.345f);
+        mPerfCollector.addMeasurement("testAddMeasurementFloatNeg", -19354.093f);
+        mPerfCollector.stopTiming("");
+
+        assertEquals("testAddMeasurementFloat", writer.timingLabel);
+        Bundle results = writer.timingResults;
+        assertEquals(4, results.size());
+        assertTrue(results.containsKey("testAddMeasurementFloatZero"));
+        assertEquals(0.0f, results.getFloat("testAddMeasurementFloatZero"));
+        assertTrue(results.containsKey("testAddMeasurementFloatPos"));
+        assertEquals(348573.345f, results.getFloat("testAddMeasurementFloatPos"));
+        assertTrue(results.containsKey("testAddMeasurementFloatNeg"));
+        assertEquals(-19354.093f, results.getFloat("testAddMeasurementFloatNeg"));
+    }
+
+    @SmallTest
+    public void testAddMeasurementString() throws Exception {
+        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
+        mPerfCollector.setPerformanceResultsWriter(writer);
+        mPerfCollector.startTiming("testAddMeasurementString");
+        mPerfCollector.addMeasurement("testAddMeasurementStringNull", null);
+        mPerfCollector.addMeasurement("testAddMeasurementStringEmpty", "");
+        mPerfCollector.addMeasurement("testAddMeasurementStringNonEmpty", "Hello World");
+        mPerfCollector.stopTiming("");
+
+        assertEquals("testAddMeasurementString", writer.timingLabel);
+        Bundle results = writer.timingResults;
+        assertEquals(4, results.size());
+        assertTrue(results.containsKey("testAddMeasurementStringNull"));
+        assertNull(results.getString("testAddMeasurementStringNull"));
+        assertTrue(results.containsKey("testAddMeasurementStringEmpty"));
+        assertEquals("", results.getString("testAddMeasurementStringEmpty"));
+        assertTrue(results.containsKey("testAddMeasurementStringNonEmpty"));
+        assertEquals("Hello World", results.getString("testAddMeasurementStringNonEmpty"));
+    }
+
+    @SmallTest
     public void testSimpleSequence() throws Exception {
         MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
         mPerfCollector.setPerformanceResultsWriter(writer);
         mPerfCollector.beginSnapshot("testSimpleSequence");
         mPerfCollector.startTiming("testSimpleSequenceTiming");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration1");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration2");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration3");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration4");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing = mPerfCollector.stopTiming("iteration5");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
         Bundle snapshot1 = mPerfCollector.endSnapshot();
         Bundle snapshot2 = writer.snapshotResults;
 
-        assertTrue(snapshot1.equals(snapshot2));
+        assertEqualsBundle(snapshot1, snapshot2);
         verifySnapshotBundle(snapshot1);
 
         ArrayList<String> labels = new ArrayList<String>();
@@ -193,60 +264,59 @@
         verifyTimingBundle(timing, labels);
     }
 
-    // TODO: flaky test
-    // @LargeTest
+    @SmallTest
     public void testLongSequence() throws Exception {
         MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
         mPerfCollector.setPerformanceResultsWriter(writer);
         mPerfCollector.beginSnapshot("testLongSequence");
         mPerfCollector.startTiming("testLongSequenceTiming1");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration1");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration2");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing1 = mPerfCollector.stopTiming("iteration3");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
 
         mPerfCollector.startTiming("testLongSequenceTiming2");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration4");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration5");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing2 = mPerfCollector.stopTiming("iteration6");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
 
         mPerfCollector.startTiming("testLongSequenceTiming3");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration7");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration8");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing3 = mPerfCollector.stopTiming("iteration9");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
 
         mPerfCollector.startTiming("testLongSequenceTiming4");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration10");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration11");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing4 = mPerfCollector.stopTiming("iteration12");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
 
         mPerfCollector.startTiming("testLongSequenceTiming5");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration13");
-        sleepForRandomTinyPeriod();
+        workForRandomTinyPeriod();
         mPerfCollector.addIteration("iteration14");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing5 = mPerfCollector.stopTiming("iteration15");
-        sleepForRandomLongPeriod();
+        workForRandomLongPeriod();
         Bundle snapshot1 = mPerfCollector.endSnapshot();
         Bundle snapshot2 = writer.snapshotResults;
 
-        assertTrue(snapshot1.equals(snapshot2));
+        assertEqualsBundle(snapshot1, snapshot2);
         verifySnapshotBundle(snapshot1);
 
         ArrayList<String> labels1 = new ArrayList<String>();
@@ -280,57 +350,53 @@
      * Verify that snapshotting and timing do not interfere w/ each other,
      * by staggering calls to snapshot and timing functions.
      */
-    @LargeTest
+    @SmallTest
     public void testOutOfOrderSequence() {
         MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
         mPerfCollector.setPerformanceResultsWriter(writer);
         mPerfCollector.startTiming("testOutOfOrderSequenceTiming");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         mPerfCollector.beginSnapshot("testOutOfOrderSequenceSnapshot");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle timing1 = mPerfCollector.stopTiming("timing1");
-        sleepForRandomShortPeriod();
+        workForRandomShortPeriod();
         Bundle snapshot1 = mPerfCollector.endSnapshot();
 
         Bundle timing2 = writer.timingResults;
         Bundle snapshot2 = writer.snapshotResults;
 
-        assertTrue(snapshot1.equals(snapshot2));
+        assertEqualsBundle(snapshot1, snapshot2);
         verifySnapshotBundle(snapshot1);
 
-        assertTrue(timing1.equals(timing2));
+        assertEqualsBundle(timing1, timing2);
         ArrayList<String> labels = new ArrayList<String>();
         labels.add("timing1");
         verifyTimingBundle(timing1, labels);
     }
 
-    private void sleepForRandomPeriod(int minDuration, int maxDuration) {
+    private void workForRandomPeriod(int minDuration, int maxDuration) {
         Random random = new Random();
         int period = minDuration + random.nextInt(maxDuration - minDuration);
-        int slept = 0;
-        // Generate random positive amount of work, so cpu time is measurable in
+        long start = Process.getElapsedCpuTime();
+        // Generate positive amount of work, so cpu time is measurable in
         // milliseconds
-        while (slept < period) {
-            int step = random.nextInt(minDuration/5);
-            try {
-                Thread.sleep(step);
-            } catch (InterruptedException e ) {
-                // eat the exception
+        while (Process.getElapsedCpuTime() - start < period) {
+            for (int i = 0, temp = 0; i < 50; i++ ) {
+                temp += i;
             }
-            slept += step;
         }
     }
 
-    private void sleepForRandomTinyPeriod() {
-        sleepForRandomPeriod(25, 50);
+    private void workForRandomTinyPeriod() {
+        workForRandomPeriod(2, 5);
     }
 
-    private void sleepForRandomShortPeriod() {
-        sleepForRandomPeriod(100, 250);
+    private void workForRandomShortPeriod() {
+        workForRandomPeriod(10, 25);
     }
 
-    private void sleepForRandomLongPeriod() {
-        sleepForRandomPeriod(500, 1000);
+    private void workForRandomLongPeriod() {
+        workForRandomPeriod(50, 100);
     }
 
     private void verifySnapshotBundle(Bundle snapshot) {
@@ -411,6 +477,13 @@
         }
     }
 
+    private void assertEqualsBundle(Bundle b1, Bundle b2) {
+        assertEquals(b1.keySet(), b2.keySet());
+        for (String key : b1.keySet()) {
+            assertEquals(b1.get(key), b2.get(key));
+        }
+    }
+
     private Object readPrivateField(String fieldName, Object object) throws Exception {
         Field f = object.getClass().getDeclaredField(fieldName);
         f.setAccessible(true);
@@ -429,7 +502,7 @@
         }
 
         public void writeEndSnapshot(Bundle results) {
-            snapshotResults = results;
+            snapshotResults.putAll(results);
         }
 
         public void writeStartTiming(String label) {
@@ -437,7 +510,19 @@
         }
 
         public void writeStopTiming(Bundle results) {
-            timingResults = results;
+            timingResults.putAll(results);
+        }
+
+        public void writeMeasurement(String label, long value) {
+            timingResults.putLong(label, value);
+        }
+
+        public void writeMeasurement(String label, float value) {
+            timingResults.putFloat(label, value);
+        }
+
+        public void writeMeasurement(String label, String value) {
+            timingResults.putString(label, value);
         }
     }
 }
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
index 9e2987a..db1262f 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
@@ -41,7 +41,7 @@
         parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
 
         InputStream input = this.getClass().getClassLoader().getResourceAsStream(
-            "/com/android/layoutlib/testdata/layout1.xml");
+            "com/android/layoutlib/testdata/layout1.xml");
         parser.setInput(input, null /*encoding*/);
 
         assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
index 5314976..d5993db 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
@@ -13,7 +13,7 @@
     @Override
     protected void setUp() throws Exception {
         URL url = this.getClass().getClassLoader().getResource(
-                "/com/android/layoutlib/testdata/button.9.png");
+                "com/android/layoutlib/testdata/button.9.png");
 
         mPatch = NinePatch.load(url, false /* convert */);
     }