Merge "Fixed spell check failing to change word."
diff --git a/Android.mk b/Android.mk
index f41130b..07380bc 100644
--- a/Android.mk
+++ b/Android.mk
@@ -434,8 +434,8 @@
 		            resources/samples/NFCDemo "NFC Demo" \
 		-samplecode $(sample_dir)/NotePad \
 		            resources/samples/NotePad "Note Pad" \
-		-samplecode $(sample_dir)/SampleSpellCheckerService \
-		            resources/samples/SampleSpellCheckerService "Spell Checker" \
+		-samplecode $(sample_dir)/SpellChecker/SampleSpellCheckerService \
+		            resources/samples/SpellChecker/SampleSpellCheckerService "Spell Checker" \
 		-samplecode $(sample_dir)/SampleSyncAdapter \
 		            resources/samples/SampleSyncAdapter "Sample Sync Adapter" \
 		-samplecode $(sample_dir)/RandomMusicPlayer \
diff --git a/api/current.txt b/api/current.txt
index ffa46ec..b30f7a6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26782,6 +26782,7 @@
     method public void setChar(int, java.lang.String, char);
     method public void setCharSequence(int, java.lang.String, java.lang.CharSequence);
     method public void setChronometer(int, long, java.lang.String, boolean);
+    method public void setContentDescription(int, java.lang.CharSequence);
     method public void setDisplayedChild(int, int);
     method public void setDouble(int, java.lang.String, double);
     method public void setEmptyView(int, int);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 41a3eaca..e5a5e98 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -463,20 +463,34 @@
      * @return The string representation.
      */
     public static String feedbackTypeToString(int feedbackType) {
-        switch (feedbackType) {
-            case FEEDBACK_AUDIBLE:
-                return "FEEDBACK_AUDIBLE";
-            case FEEDBACK_HAPTIC:
-                return "FEEDBACK_HAPTIC";
-            case FEEDBACK_GENERIC:
-                return "FEEDBACK_GENERIC";
-            case FEEDBACK_SPOKEN:
-                return "FEEDBACK_SPOKEN";
-            case FEEDBACK_VISUAL:
-                return "FEEDBACK_VISUAL";
-            default:
-                return null;
+        StringBuilder builder = new StringBuilder();
+        builder.append("[");
+        while (feedbackType > 0) {
+            final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType);
+            feedbackType &= ~feedbackTypeFlag;
+            if (builder.length() > 1) {
+                builder.append(", ");
+            }
+            switch (feedbackTypeFlag) {
+                case FEEDBACK_AUDIBLE:
+                    builder.append("FEEDBACK_AUDIBLE");
+                    break;
+                case FEEDBACK_HAPTIC:
+                    builder.append("FEEDBACK_HAPTIC");
+                    break;
+                case FEEDBACK_GENERIC:
+                    builder.append("FEEDBACK_GENERIC");
+                    break;
+                case FEEDBACK_SPOKEN:
+                    builder.append("FEEDBACK_SPOKEN");
+                    break;
+                case FEEDBACK_VISUAL:
+                    builder.append("FEEDBACK_VISUAL");
+                    break;
+            }
         }
+        builder.append("]");
+        return builder.toString();
     }
 
     /**
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 7863102..5b8addf 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -22,6 +22,7 @@
 import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.ServiceManager;
+import android.util.Slog;
 import android.view.View;
 
 import com.android.internal.statusbar.IStatusBarService;
@@ -61,8 +62,17 @@
 
     StatusBarManager(Context context) {
         mContext = context;
-        mService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+    }
+
+    private synchronized IStatusBarService getService() {
+        if (mService == null) {
+            mService = IStatusBarService.Stub.asInterface(
+                    ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+            if (mService == null) {
+                Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
+            }
+        }
+        return mService;
     }
 
     /**
@@ -71,8 +81,9 @@
      */
     public void disable(int what) {
         try {
-            if (mService != null) {
-                mService.disable(what, mToken, mContext.getPackageName());
+            final IStatusBarService svc = getService();
+            if (svc != null) {
+                svc.disable(what, mToken, mContext.getPackageName());
             }
         } catch (RemoteException ex) {
             // system process is dead anyway.
@@ -85,7 +96,10 @@
      */
     public void expand() {
         try {
-            mService.expand();
+            final IStatusBarService svc = getService();
+            if (svc != null) {
+                svc.expand();
+            }
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
@@ -97,7 +111,10 @@
      */
     public void collapse() {
         try {
-            mService.collapse();
+            final IStatusBarService svc = getService();
+            if (svc != null) {
+                svc.collapse();
+            }
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
@@ -106,8 +123,11 @@
 
     public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {
         try {
-            mService.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,
+            final IStatusBarService svc = getService();
+            if (svc != null) {
+                svc.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,
                     contentDescription);
+            }
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
@@ -116,7 +136,10 @@
 
     public void removeIcon(String slot) {
         try {
-            mService.removeIcon(slot);
+            final IStatusBarService svc = getService();
+            if (svc != null) {
+                svc.removeIcon(slot);
+            }
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
@@ -125,7 +148,10 @@
 
     public void setIconVisibility(String slot, boolean visible) {
         try {
-            mService.setIconVisibility(slot, visible);
+            final IStatusBarService svc = getService();
+            if (svc != null) {
+                svc.setIconVisibility(slot, visible);
+            }
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 4225393..7d683a5 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -990,8 +990,8 @@
                 mBound = false;
                 mContext.unbindService(this);
             }
-            mSyncWakeLock.setWorkSource(null);
             mSyncWakeLock.release();
+            mSyncWakeLock.setWorkSource(null);
         }
 
         @Override
diff --git a/core/java/android/database/sqlite/package.html b/core/java/android/database/sqlite/package.html
index ff0f9f5..ceed171 100644
--- a/core/java/android/database/sqlite/package.html
+++ b/core/java/android/database/sqlite/package.html
@@ -3,7 +3,7 @@
 Contains the SQLite database management
 classes that an application would use to manage its own private database.
 <p>
-Applications use these classes to maange private databases. If creating a
+Applications use these classes to manage private databases. If creating a
 content provider, you will probably have to use these classes to create and
 manage your own database to store content. See <a
 href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> to learn
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e344197..438c536 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1095,6 +1095,16 @@
         }
     }
 
+    private static long computeWakeLock(Timer timer, long batteryRealtime, int which) {
+        if (timer != null) {
+            // Convert from microseconds to milliseconds with rounding
+            long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
+            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
+            return totalTimeMillis;
+        }
+        return 0;
+    }
+
     /**
      *
      * @param sb a StringBuilder object.
@@ -1109,9 +1119,7 @@
             long batteryRealtime, String name, int which, String linePrefix) {
         
         if (timer != null) {
-            // Convert from microseconds to milliseconds with rounding
-            long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
-            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
+            long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
             
             int count = timer.getCountLocked(which);
             if (totalTimeMillis != 0) {
@@ -1735,6 +1743,8 @@
 
             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
             if (wakelocks.size() > 0) {
+                long totalFull = 0, totalPartial = 0, totalWindow = 0;
+                int count = 0;
                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
                     : wakelocks.entrySet()) {
                     Uid.Wakelock wl = ent.getValue();
@@ -1754,6 +1764,44 @@
                         // Only print out wake locks that were held
                         pw.println(sb.toString());
                         uidActivity = true;
+                        count++;
+                    }
+                    totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
+                            batteryRealtime, which);
+                    totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
+                            batteryRealtime, which);
+                    totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
+                            batteryRealtime, which);
+                }
+                if (count > 1) {
+                    if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
+                        sb.setLength(0);
+                        sb.append(prefix);
+                        sb.append("    TOTAL wake: ");
+                        boolean needComma = false;
+                        if (totalFull != 0) {
+                            needComma = true;
+                            formatTimeMs(sb, totalFull);
+                            sb.append("full");
+                        }
+                        if (totalPartial != 0) {
+                            if (needComma) {
+                                sb.append(", ");
+                            }
+                            needComma = true;
+                            formatTimeMs(sb, totalPartial);
+                            sb.append("partial");
+                        }
+                        if (totalWindow != 0) {
+                            if (needComma) {
+                                sb.append(", ");
+                            }
+                            needComma = true;
+                            formatTimeMs(sb, totalWindow);
+                            sb.append("window");
+                        }
+                        sb.append(" realtime");
+                        pw.println(sb.toString());
                     }
                 }
             }
diff --git a/core/java/android/os/CountDownTimer.java b/core/java/android/os/CountDownTimer.java
index 0c5c615..15e6405 100644
--- a/core/java/android/os/CountDownTimer.java
+++ b/core/java/android/os/CountDownTimer.java
@@ -25,7 +25,7 @@
  * Example of showing a 30 second countdown in a text field:
  *
  * <pre class="prettyprint">
- * new CountdownTimer(30000, 1000) {
+ * new CountDownTimer(30000, 1000) {
  *
  *     public void onTick(long millisUntilFinished) {
  *         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 44f259a..b14ca2b0 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -72,7 +72,7 @@
  * {@link Calendars#MAX_REMINDERS} which is set by the Sync Adapter that owns
  * the given calendar. Reminders are specified in minutes before the event and
  * have a type.</li>
- * <li>The {@link ExtendedProperties} table hold opaque data fields used by the
+ * <li>The {@link ExtendedProperties} table holds opaque data fields used by the
  * sync adapter. The provider takes no action with items in this table except to
  * delete them when their related events are deleted.</li>
  * </ul>
@@ -304,7 +304,8 @@
          * or an empty string are reserved for indicating that the calendar does
          * not use an index for looking up the color. The provider will update
          * {@link #CALENDAR_COLOR} automatically when a valid index is written
-         * to this column. @see Colors
+         * to this column. The index must reference an existing row of the
+         * {@link Colors} table. @see Colors
          * <P>
          * Type: TEXT
          * </P>
@@ -852,8 +853,11 @@
          * string are reserved for indicating that the event does not use an
          * index for looking up the color. The provider will update
          * {@link #EVENT_COLOR} automatically when a valid index is written to
-         * this column. @see Colors
-         * <P>Type: TEXT</P>
+         * this column. The index must reference an existing row of the
+         * {@link Colors} table. @see Colors
+         * <P>
+         * Type: TEXT
+         * </P>
          * TODO UNHIDE
          *
          * @hide
@@ -2329,7 +2333,7 @@
         /**
          * The index used to reference this color. This can be any non-empty
          * string, but must be unique for a given {@link #ACCOUNT_TYPE} and
-         * {@link #ACCOUNT_NAME} . Column name.
+         * {@link #ACCOUNT_NAME}. Column name.
          * <P>
          * Type: TEXT
          * </P>
@@ -2353,8 +2357,10 @@
     /**
      * Fields for accessing colors available for a given account. Colors are
      * referenced by {@link #COLOR_INDEX} which must be unique for a given
-     * account name/type. These values should only be updated by the sync
-     * adapter.
+     * account name/type. These values can only be updated by the sync
+     * adapter. Only {@link #COLOR} may be updated after the initial insert. In
+     * addition, a row can only be deleted once all references to that color
+     * have been removed from the {@link Calendars} or {@link Events} tables.
      * TODO UNHIDE
      *
      * @hide
@@ -2400,7 +2406,7 @@
 
     /**
      * Fields for accessing the Extended Properties. This is a generic set of
-     * name/value pairs for use by sync adapters or apps to add extra
+     * name/value pairs for use by sync adapters to add extra
      * information to events. There are three writable columns and all three
      * must be present when inserting a new value. They are:
      * <ul>
diff --git a/core/java/android/service/textservice/package.html b/core/java/android/service/textservice/package.html
index 89c6dbc..b498719 100644
--- a/core/java/android/service/textservice/package.html
+++ b/core/java/android/service/textservice/package.html
@@ -32,7 +32,7 @@
 </pre>
 
 <p>For example code, see the <a
-href="{@docRoot}resources/samples/SampleSpellCheckerService/index.html">Spell
+href="{@docRoot}resources/samples/SpellChecker/SampleSpellCheckerService/index.html">Spell
 Checker</a> sample app.</p>
 </BODY>
 </HTML>
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index f82c9c4..026af34 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -281,9 +281,9 @@
         }
 
         reflowed.generate(text, where, where + after,
-                getPaint(), getWidth(), getAlignment(), getTextDirectionHeuristic(),
-                getSpacingMultiplier(), getSpacingAdd(),
-                false, true, mEllipsizedWidth, mEllipsizeAt);
+                getPaint(), getWidth(), getTextDirectionHeuristic(), getSpacingMultiplier(),
+                getSpacingAdd(), false,
+                true, mEllipsizedWidth, mEllipsizeAt);
         int n = reflowed.getLineCount();
 
         // If the new layout has a blank line at the end, but it is not
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 583cbe6..1dd4c8a 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -137,9 +137,9 @@
 
         mMeasured = MeasuredText.obtain();
 
-        generate(source, bufstart, bufend, paint, outerwidth, align, textDir,
-                 spacingmult, spacingadd, includepad, includepad,
-                 ellipsizedWidth, ellipsize);
+        generate(source, bufstart, bufend, paint, outerwidth, textDir, spacingmult,
+                 spacingadd, includepad, includepad, ellipsizedWidth,
+                 ellipsize);
 
         mMeasured = MeasuredText.recycle(mMeasured);
         mFontMetricsInt = null;
@@ -157,10 +157,10 @@
 
     /* package */ void generate(CharSequence source, int bufStart, int bufEnd,
                         TextPaint paint, int outerWidth,
-                        Alignment align, TextDirectionHeuristic textDir,
-                        float spacingmult, float spacingadd,
-                        boolean includepad, boolean trackpad,
-                        float ellipsizedWidth, TextUtils.TruncateAt ellipsize) {
+                        TextDirectionHeuristic textDir, float spacingmult,
+                        float spacingadd, boolean includepad,
+                        boolean trackpad, float ellipsizedWidth,
+                        TextUtils.TruncateAt ellipsize) {
         mLineCount = 0;
 
         int v = 0;
@@ -328,9 +328,7 @@
                                     whichPaint = mWorkPaint;
                                 }
 
-                                float wid = bm.getWidth() *
-                                            -whichPaint.ascent() /
-                                            bm.getHeight();
+                                float wid = bm.getWidth() * -whichPaint.ascent() / bm.getHeight();
 
                                 w += wid;
                                 hasTabOrEmoji = true;
@@ -398,67 +396,49 @@
                                 okBottom = fitBottom;
                         }
                     } else {
-                            final boolean moreChars = (j + 1 < spanEnd);
-                            if (ok != here) {
-                                // Log.e("text", "output ok " + here + " to " +ok);
+                        final boolean moreChars = (j + 1 < spanEnd);
+                        int endPos;
+                        int above, below, top, bottom;
+                        float currentTextWidth;
 
-                                while (ok < spanEnd && chs[ok - paraStart] == CHAR_SPACE) {
-                                    ok++;
-                                }
+                        if (ok != here) {
+                            // If it is a space that makes the length exceed width, cut here
+                            if (c == CHAR_SPACE) ok = j + 1;
 
-                                v = out(source,
-                                        here, ok,
-                                        okAscent, okDescent, okTop, okBottom,
-                                        v,
-                                        spacingmult, spacingadd, chooseHt,
-                                        chooseHtv, fm, hasTabOrEmoji,
-                                        needMultiply, paraStart, chdirs, dir, easy,
-                                        ok == bufEnd, includepad, trackpad,
-                                        chs, widths, paraStart,
-                                        ellipsize, ellipsizedWidth, okWidth,
-                                        paint, moreChars);
-
-                                here = ok;
-                            } else if (fit != here) {
-                                // Log.e("text", "output fit " + here + " to " +fit);
-                                v = out(source,
-                                        here, fit,
-                                        fitAscent, fitDescent,
-                                        fitTop, fitBottom,
-                                        v,
-                                        spacingmult, spacingadd, chooseHt,
-                                        chooseHtv, fm, hasTabOrEmoji,
-                                        needMultiply, paraStart, chdirs, dir, easy,
-                                        fit == bufEnd, includepad, trackpad,
-                                        chs, widths, paraStart,
-                                        ellipsize, ellipsizedWidth, fitWidth,
-                                        paint, moreChars);
-
-                                here = fit;
-                            } else {
-                                // Log.e("text", "output one " + here + " to " +(here + 1));
-                                // XXX not sure why the existing fm wasn't ok.
-                                // measureText(paint, mWorkPaint,
-                                //             source, here, here + 1, fm, tab,
-                                //             null);
-
-                                v = out(source,
-                                        here, here+1,
-                                        fm.ascent, fm.descent,
-                                        fm.top, fm.bottom,
-                                        v,
-                                        spacingmult, spacingadd, chooseHt,
-                                        chooseHtv, fm, hasTabOrEmoji,
-                                        needMultiply, paraStart, chdirs, dir, easy,
-                                        here + 1 == bufEnd, includepad,
-                                        trackpad,
-                                        chs, widths, paraStart,
-                                        ellipsize, ellipsizedWidth,
-                                        widths[here - paraStart], paint, moreChars);
-
-                                here = here + 1;
+                            while (ok < spanEnd && chs[ok - paraStart] == CHAR_SPACE) {
+                                ok++;
                             }
 
+                            endPos = ok;
+                            above = okAscent;
+                            below = okDescent;
+                            top = okTop;
+                            bottom = okBottom;
+                            currentTextWidth = okWidth;
+                        } else if (fit != here) {
+                            endPos = fit;
+                            above = fitAscent;
+                            below = fitDescent;
+                            top = fitTop;
+                            bottom = fitBottom;
+                            currentTextWidth = fitWidth;
+                        } else {
+                            endPos = here + 1;
+                            above = fm.ascent;
+                            below = fm.descent;
+                            top = fm.top;
+                            bottom = fm.bottom;
+                            currentTextWidth = widths[here - paraStart];
+                        }
+
+                        v = out(source, here, endPos,
+                                above, below, top, bottom,
+                                v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, hasTabOrEmoji,
+                                needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
+                                chs, widths, paraStart, ellipsize, ellipsizedWidth,
+                                currentTextWidth, paint, moreChars);
+                        here = endPos;
+
                         if (here < spanStart) {
                             // didn't output all the text for this span
                             // we've measured the raw widths, though, so
@@ -501,10 +481,10 @@
                         v,
                         spacingmult, spacingadd, chooseHt,
                         chooseHtv, fm, hasTabOrEmoji,
-                        needMultiply, paraStart, chdirs, dir, easy,
-                        paraEnd == bufEnd, includepad, trackpad,
-                        chs, widths, paraStart,
-                        ellipsize, ellipsizedWidth, w, paint, paraEnd != bufEnd);
+                        needMultiply, chdirs, dir, easy, bufEnd,
+                        includepad, trackpad, chs,
+                        widths, paraStart, ellipsize,
+                        ellipsizedWidth, w, paint, paraEnd != bufEnd);
             }
 
             paraStart = paraEnd;
@@ -525,10 +505,10 @@
                     v,
                     spacingmult, spacingadd, null,
                     null, fm, false,
-                    needMultiply, bufEnd, null, DEFAULT_DIR, true,
-                    true, includepad, trackpad,
-                    null, null, bufStart,
-                    ellipsize, ellipsizedWidth, 0, paint, false);
+                    needMultiply, null, DEFAULT_DIR, true, bufEnd,
+                    includepad, trackpad, null,
+                    null, bufStart, ellipsize,
+                    ellipsizedWidth, 0, paint, false);
         }
     }
 
@@ -628,12 +608,12 @@
                       float spacingmult, float spacingadd,
                       LineHeightSpan[] chooseHt, int[] chooseHtv,
                       Paint.FontMetricsInt fm, boolean hasTabOrEmoji,
-                      boolean needMultiply, int pstart, byte[] chdirs,
-                      int dir, boolean easy, boolean last,
-                      boolean includePad, boolean trackPad,
-                      char[] chs, float[] widths, int widthStart,
-                      TextUtils.TruncateAt ellipsize, float ellipsisWidth,
-                      float textWidth, TextPaint paint, boolean moreChars) {
+                      boolean needMultiply, byte[] chdirs, int dir,
+                      boolean easy, int bufEnd, boolean includePad,
+                      boolean trackPad, char[] chs,
+                      float[] widths, int widthStart, TextUtils.TruncateAt ellipsize,
+                      float ellipsisWidth, float textWidth,
+                      TextPaint paint, boolean moreChars) {
         int j = mLineCount;
         int off = j * mColumns;
         int want = off + mColumns + TOP;
@@ -683,7 +663,7 @@
                 above = top;
             }
         }
-        if (last) {
+        if (end == bufEnd) {
             if (trackPad) {
                 mBottomPadding = bottom - below;
             }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index fe32a5f..93a9d50 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -224,4 +224,9 @@
      * Block until the given window has been drawn to the screen.
      */
     void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
+
+    /**
+     * Device has a software navigation bar (separate from the status bar).
+     */
+    boolean hasNavigationBar();
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a2f9b36..fea79d5 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4219,6 +4219,7 @@
      *
      * @attr ref android.R.styleable#View_contentDescription
      */
+    @RemotableViewMethod
     public void setContentDescription(CharSequence contentDescription) {
         mContentDescription = contentDescription;
     }
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 5e104f9e..3441f7e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -292,8 +292,7 @@
         if (!sHasPermanentMenuKeySet) {
             IWindowManager wm = Display.getWindowManager();
             try {
-                sHasPermanentMenuKey = wm.canStatusBarHide() && !res.getBoolean(
-                        com.android.internal.R.bool.config_showNavigationBar);
+                sHasPermanentMenuKey = wm.canStatusBarHide() && !wm.hasNavigationBar();
                 sHasPermanentMenuKeySet = true;
             } catch (RemoteException ex) {
                 sHasPermanentMenuKey = false;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index abb5bc8..a36aecb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -287,7 +287,7 @@
 
     final AccessibilityManager mAccessibilityManager;
 
-    AccessibilityInteractionController mAccessibilityInteractionContrtoller;
+    AccessibilityInteractionController mAccessibilityInteractionController;
 
     AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager;
 
@@ -3526,10 +3526,10 @@
             throw new IllegalStateException("getAccessibilityInteractionController"
                     + " called when there is no mView");
         }
-        if (mAccessibilityInteractionContrtoller == null) {
-            mAccessibilityInteractionContrtoller = new AccessibilityInteractionController();
+        if (mAccessibilityInteractionController == null) {
+            mAccessibilityInteractionController = new AccessibilityInteractionController();
         }
-        return mAccessibilityInteractionContrtoller;
+        return mAccessibilityInteractionController;
     }
 
     private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 17bdff2..2e19bf6 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1010,6 +1010,11 @@
     public int adjustSystemUiVisibilityLw(int visibility);
 
     /**
+     * Specifies whether there is an on-screen navigation bar separate from the status bar.
+     */
+    public boolean hasNavigationBar();
+
+    /**
      * Print the WindowManagerPolicy's state into the given stream.
      *
      * @param prefix Text to print at the front of each line.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 3ead9df..b41e6f5 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -384,14 +384,18 @@
         }
     }
     
-    class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
-        public ControlledInputConnectionWrapper(Looper mainLooper, InputConnection conn) {
+    private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
+        private final InputMethodManager mParentInputMethodManager;
+
+        public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn,
+                final InputMethodManager inputMethodManager) {
             super(mainLooper, conn);
+            mParentInputMethodManager = inputMethodManager;
         }
 
         @Override
         public boolean isActive() {
-            return mActive;
+            return mParentInputMethodManager.mActive;
         }
     }
     
@@ -439,7 +443,7 @@
         mMainLooper = looper;
         mH = new H(looper);
         mIInputContext = new ControlledInputConnectionWrapper(looper,
-                mDummyInputConnection);
+                mDummyInputConnection, this);
         
         if (mInstance == null) {
             mInstance = this;
@@ -1016,7 +1020,7 @@
                 mCursorCandStart = -1;
                 mCursorCandEnd = -1;
                 mCursorRect.setEmpty();
-                servedContext = new ControlledInputConnectionWrapper(vh.getLooper(), ic);
+                servedContext = new ControlledInputConnectionWrapper(vh.getLooper(), ic, this);
             } else {
                 servedContext = null;
             }
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 793f514..5c3f089 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -123,7 +123,7 @@
         }
         mSpellCheckerInfo = info;
         mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(mHandler);
-        mInternalListener = new InternalListener();
+        mInternalListener = new InternalListener(mSpellCheckerSessionListenerImpl);
         mTextServicesManager = tsm;
         mIsUsed = true;
         mSpellCheckerSessionListener = listener;
@@ -316,13 +316,19 @@
         public void onGetSuggestions(SuggestionsInfo[] results);
     }
 
-    private class InternalListener extends ITextServicesSessionListener.Stub {
+    private static class InternalListener extends ITextServicesSessionListener.Stub {
+        private final SpellCheckerSessionListenerImpl mParentSpellCheckerSessionListenerImpl;
+
+        public InternalListener(SpellCheckerSessionListenerImpl spellCheckerSessionListenerImpl) {
+            mParentSpellCheckerSessionListenerImpl = spellCheckerSessionListenerImpl;
+        }
+
         @Override
         public void onServiceConnected(ISpellCheckerSession session) {
             if (DBG) {
                 Log.w(TAG, "SpellCheckerSession connected.");
             }
-            mSpellCheckerSessionListenerImpl.onServiceConnected(session);
+            mParentSpellCheckerSessionListenerImpl.onServiceConnected(session);
         }
     }
 
diff --git a/core/java/android/webkit/JniUtil.java b/core/java/android/webkit/JniUtil.java
index 7759ff3..4662040 100644
--- a/core/java/android/webkit/JniUtil.java
+++ b/core/java/android/webkit/JniUtil.java
@@ -22,6 +22,7 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import java.io.File;
 import java.io.InputStream;
 
 class JniUtil {
@@ -79,7 +80,12 @@
         checkInitialized();
 
         if (sCacheDirectory == null) {
-            sCacheDirectory = sContext.getCacheDir().getAbsolutePath();
+            File cacheDir = sContext.getCacheDir();
+            if (cacheDir == null) {
+                sCacheDirectory = "";
+            } else {
+                sCacheDirectory = cacheDir.getAbsolutePath();
+            }
         }
 
         return sCacheDirectory;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index f1c2bde..f240a2e 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -777,7 +777,7 @@
     public void setDoubleTapZoom(int doubleTapZoom) {
         if (mDoubleTapZoom != doubleTapZoom) {
             mDoubleTapZoom = doubleTapZoom;
-            mWebView.updateDoubleTapZoom();
+            mWebView.updateDoubleTapZoom(doubleTapZoom);
         }
     }
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 71ba7eb..a814b12 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2995,8 +2995,8 @@
     /**
      * Update the double-tap zoom.
      */
-    /* package */ void updateDoubleTapZoom() {
-        mZoomManager.updateDoubleTapZoom();
+    /* package */ void updateDoubleTapZoom(int doubleTapZoom) {
+        mZoomManager.updateDoubleTapZoom(doubleTapZoom);
     }
 
     private int computeRealHorizontalScrollRange() {
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 9151fdd..7d3cf8e 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -152,6 +152,12 @@
     private float mDisplayDensity;
 
     /*
+     * The factor that is used to tweak the zoom scale on a double-tap,
+     * and can be changed via WebSettings. Range is from 0.75f to 1.25f.
+     */
+    private float mDoubleTapZoomFactor = 1.0f;
+
+    /*
      * The scale factor that is used as the minimum increment when going from
      * overview to reading level on a double tap.
      */
@@ -314,10 +320,7 @@
      * Returns the zoom scale used for reading text on a double-tap.
      */
     public final float getReadingLevelScale() {
-        WebSettings settings = mWebView.getSettings();
-        final float doubleTapZoomFactor = settings != null
-            ? settings.getDoubleTapZoom() / 100.f : 1.0f;
-        return mDisplayDensity * doubleTapZoomFactor;
+        return mDisplayDensity * mDoubleTapZoomFactor;
     }
 
     public final float getInvDefaultScale() {
@@ -516,8 +519,9 @@
         return mZoomScale != 0 || mInHWAcceleratedZoom;
     }
 
-    public void updateDoubleTapZoom() {
+    public void updateDoubleTapZoom(int doubleTapZoom) {
         if (mInZoomOverview) {
+            mDoubleTapZoomFactor = doubleTapZoom / 100.0f;
             mTextWrapScale = getReadingLevelScale();
             refreshZoomScale(true);
         }
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index e16a8bd..5d01a0f 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -925,7 +925,7 @@
         event.setCurrentItemIndex(getSelectedItemPosition());
         event.setFromIndex(getFirstVisiblePosition());
         event.setToIndex(getLastVisiblePosition());
-        event.setItemCount(getAdapter().getCount());
+        event.setItemCount(getCount());
     }
 
     private boolean isScrollableForAccessibility() {
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 5077be6..0f462ff 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -32,6 +32,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.NumberPicker.OnValueChangeListener;
 
 import com.android.internal.R;
@@ -90,6 +91,12 @@
 
     private final NumberPicker mYearSpinner;
 
+    private final EditText mDaySpinnerInput;
+
+    private final EditText mMonthSpinnerInput;
+
+    private final EditText mYearSpinnerInput;
+
     private final CalendarView mCalendarView;
 
     private Locale mCurrentLocale;
@@ -164,6 +171,7 @@
 
         OnValueChangeListener onChangeListener = new OnValueChangeListener() {
             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                updateInputState();
                 mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
                 // take care of wrapping of days and months to update greater fields
                 if (picker == mDaySpinner) {
@@ -214,6 +222,7 @@
         mDaySpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
         mDaySpinner.setOnLongPressUpdateInterval(100);
         mDaySpinner.setOnValueChangedListener(onChangeListener);
+        mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
 
         // month
         mMonthSpinner = (NumberPicker) findViewById(R.id.month);
@@ -222,11 +231,13 @@
         mMonthSpinner.setDisplayedValues(mShortMonths);
         mMonthSpinner.setOnLongPressUpdateInterval(200);
         mMonthSpinner.setOnValueChangedListener(onChangeListener);
+        mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
 
         // year
         mYearSpinner = (NumberPicker) findViewById(R.id.year);
         mYearSpinner.setOnLongPressUpdateInterval(100);
         mYearSpinner.setOnValueChangedListener(onChangeListener);
+        mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
 
         // show only what the user required but make sure we
         // show something and the spinners have higher priority
@@ -709,6 +720,27 @@
         mYearSpinner.findViewById(R.id.decrement).setContentDescription(text);
     }
 
+    private void updateInputState() {
+        // Make sure that if the user changes the value and the IME is active
+        // for one of the inputs if this widget, the IME is closed. If the user
+        // changed the value via the IME and there is a next input the IME will
+        // be shown, otherwise the user chose another means of changing the
+        // value and having the IME up makes no sense.
+        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+        if (inputMethodManager != null) {
+            if (inputMethodManager.isActive(mYearSpinnerInput)) {
+                mYearSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
+                mMonthSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
+                mDaySpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+            }
+        }
+    }
+
     /**
      * Class for managing state storing/restoring.
      */
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index b4c844b..cf015c4 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -536,6 +536,10 @@
 
         OnClickListener onClickListener = new OnClickListener() {
             public void onClick(View v) {
+                InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+                if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) {
+                    inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+                }
                 mInputText.clearFocus();
                 if (v.getId() == R.id.increment) {
                     changeCurrentByOne(true);
@@ -571,17 +575,14 @@
         mInputText = (EditText) findViewById(R.id.numberpicker_input);
         mInputText.setOnFocusChangeListener(new OnFocusChangeListener() {
             public void onFocusChange(View v, boolean hasFocus) {
-                InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
                 if (hasFocus) {
                     mInputText.selectAll();
+                    InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
                     if (inputMethodManager != null) {
                         inputMethodManager.showSoftInput(mInputText, 0);
                     }
                 } else {
                     mInputText.setSelection(0, 0);
-                    if (inputMethodManager != null) {
-                        inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-                    }
                     validateInputTextView(v);
                 }
             }
@@ -996,17 +997,14 @@
      * enabled.
      * </p>
      *
-     * @param wrapSelector Whether to wrap.
+     * @param wrapSelectorWheel Whether to wrap.
      */
-    public void setWrapSelectorWheel(boolean wrapSelector) {
-        if (wrapSelector && (mMaxValue - mMinValue) < mSelectorIndices.length) {
+    public void setWrapSelectorWheel(boolean wrapSelectorWheel) {
+        if (wrapSelectorWheel && (mMaxValue - mMinValue) < mSelectorIndices.length) {
             throw new IllegalStateException("Range less than selector items count.");
         }
-        if (wrapSelector != mWrapSelectorWheel) {
-            // force the selector indices array to be reinitialized
-            mSelectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] = Integer.MAX_VALUE;
-            mWrapSelectorWheel = wrapSelector;
-            // force redraw since we might look different
+        if (wrapSelectorWheel != mWrapSelectorWheel) {
+            mWrapSelectorWheel = wrapSelectorWheel;
             updateIncrementAndDecrementButtonsVisibilityState();
         }
     }
@@ -1206,7 +1204,13 @@
         for (int i = 0; i < selectorIndices.length; i++) {
             int selectorIndex = selectorIndices[i];
             String scrollSelectorValue = mSelectorIndexToStringCache.get(selectorIndex);
-            canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
+            // Do not draw the middle item if input is visible since the input is shown only
+            // if the wheel is static and it covers the middle item. Otherwise, if the user
+            // starts editing the text via the IME he may see a dimmed version of the old
+            // value intermixed with the new one.
+            if (i != SELECTOR_MIDDLE_ITEM_INDEX || mInputText.getVisibility() != VISIBLE) {
+                canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
+            }
             y += mSelectorElementHeight;
         }
 
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 9cf2718..1592061 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1546,6 +1546,16 @@
     }
 
     /**
+     * Equivalent to calling View.setContentDescription
+     *
+     * @param viewId The id of the view whose content description should change
+     * @param contentDescription The new content description for the view
+     */
+    public void setContentDescription(int viewId, CharSequence contentDescription) {
+        setCharSequence(viewId, "setContentDescription", contentDescription);
+    }
+
+    /**
      * Inflates the view hierarchy represented by this object and applies
      * all of the actions.
      * 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 55e49ea..5a300e8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -359,7 +359,7 @@
 
     private SpellChecker mSpellChecker;
 
-    private boolean mShowSoftInputOnFocus = true;
+    private boolean mSoftInputShownOnFocus = true;
 
     // The alignment to pass to Layout, or null if not resolved.
     private Layout.Alignment mLayoutAlignment;
@@ -2381,23 +2381,23 @@
      * Sets whether the soft input method will be made visible when this
      * TextView gets focused. The default is true.
      *
-     * @attr ref android.R.styleable#TextView_showSoftInputOnFocus
+     * @attr ref android.R.styleable#TextView_softInputShownOnFocus
      * @hide
      */
     @android.view.RemotableViewMethod
-    public final void setShowSoftInputOnFocus(boolean show) {
-        mShowSoftInputOnFocus = show;
+    public final void setSoftInputShownOnFocus(boolean show) {
+        mSoftInputShownOnFocus = show;
     }
 
     /**
      * Returns whether the soft input method will be made visible when this
      * TextView gets focused. The default is true.
      *
-     * @attr ref android.R.styleable#TextView_showSoftInputOnFocus
+     * @attr ref android.R.styleable#TextView_softInputShownOnFocus
      * @hide
      */
-    public final boolean getShowSoftInputOnFocus() {
-        return mShowSoftInputOnFocus;
+    public final boolean getSoftInputShownOnFocus() {
+        return mSoftInputShownOnFocus;
     }
 
     /**
@@ -5502,7 +5502,7 @@
                                 && mLayout != null && onCheckIsTextEditor()) {
                             InputMethodManager imm = InputMethodManager.peekInstance();
                             viewClicked(imm);
-                            if (imm != null && mShowSoftInputOnFocus) {
+                            if (imm != null && mSoftInputShownOnFocus) {
                                 imm.showSoftInput(this, 0);
                             }
                         }
@@ -8344,7 +8344,7 @@
                 // Show the IME, except when selecting in read-only text.
                 final InputMethodManager imm = InputMethodManager.peekInstance();
                 viewClicked(imm);
-                if (!mTextIsSelectable && mShowSoftInputOnFocus) {
+                if (!mTextIsSelectable && mSoftInputShownOnFocus) {
                     handled |= imm != null && imm.showSoftInput(this, 0);
                 }
 
@@ -10202,7 +10202,7 @@
         final boolean selectionStarted = mSelectionActionMode != null ||
                 extractedTextModeWillBeStartedFullScreen;
 
-        if (selectionStarted && !mTextIsSelectable && imm != null && mShowSoftInputOnFocus) {
+        if (selectionStarted && !mTextIsSelectable && imm != null && mSoftInputShownOnFocus) {
             // Show the IME to be able to replace text, except when selecting non editable text.
             imm.showSoftInput(this, 0, null);
         }
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index f52e773..afca2db 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -27,8 +27,8 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
 import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.NumberPicker.OnValueChangeListener;
 
 import com.android.internal.R;
@@ -79,6 +79,12 @@
 
     private final NumberPicker mAmPmSpinner;
 
+    private final EditText mHourSpinnerInput;
+
+    private final EditText mMinuteSpinnerInput;
+
+    private final EditText mAmPmSpinnerInput;
+
     private final TextView mDivider;
 
     // Note that the legacy implementation of the TimePicker is
@@ -140,6 +146,7 @@
         mHourSpinner = (NumberPicker) findViewById(R.id.hour);
         mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
             public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
+                updateInputState();
                 if (!is24HourView()) {
                     if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY)
                             || (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) {
@@ -150,8 +157,8 @@
                 onTimeChanged();
             }
         });
-        EditText hourInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
-        hourInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+        mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
+        mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
 
         // divider (only for the new widget style)
         mDivider = (TextView) findViewById(R.id.divider);
@@ -167,6 +174,7 @@
         mMinuteSpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
         mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
             public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
+                updateInputState();
                 int minValue = mMinuteSpinner.getMinValue();
                 int maxValue = mMinuteSpinner.getMaxValue();
                 if (oldVal == maxValue && newVal == minValue) {
@@ -187,8 +195,8 @@
                 onTimeChanged();
             }
         });
-        EditText minuteInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
-        minuteInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+        mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
+        mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
 
         /* Get the localized am/pm strings and use them in the spinner */
         mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
@@ -197,6 +205,7 @@
         View amPmView = findViewById(R.id.amPm);
         if (amPmView instanceof Button) {
             mAmPmSpinner = null;
+            mAmPmSpinnerInput = null;
             mAmPmButton = (Button) amPmView;
             mAmPmButton.setOnClickListener(new OnClickListener() {
                 public void onClick(View button) {
@@ -213,13 +222,14 @@
             mAmPmSpinner.setDisplayedValues(mAmPmStrings);
             mAmPmSpinner.setOnValueChangedListener(new OnValueChangeListener() {
                 public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                    updateInputState();
                     picker.requestFocus();
                     mIsAm = !mIsAm;
                     updateAmPmControl();
                 }
             });
-            EditText amPmInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
-            amPmInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
+            mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
+            mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
         }
 
         // update controls to initial state
@@ -319,7 +329,7 @@
             dest.writeInt(mMinute);
         }
 
-        @SuppressWarnings("unused")
+        @SuppressWarnings({"unused", "hiding"})
         public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
             public SavedState createFromParcel(Parcel in) {
                 return new SavedState(in);
@@ -524,4 +534,25 @@
             mAmPmSpinner.findViewById(R.id.decrement).setContentDescription(text);
         }
     }
+
+    private void updateInputState() {
+        // Make sure that if the user changes the value and the IME is active
+        // for one of the inputs if this widget, the IME is closed. If the user
+        // changed the value via the IME and there is a next input the IME will
+        // be shown, otherwise the user chose another means of changing the
+        // value and having the IME up makes no sense.
+        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+        if (inputMethodManager != null) {
+            if (inputMethodManager.isActive(mHourSpinnerInput)) {
+                mHourSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) {
+                mMinuteSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) {
+                mAmPmSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index e2a2566..3e96c81 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -98,6 +98,10 @@
     // in to one common name.
     private static final int MAX_WAKELOCKS_PER_UID = 30;
 
+    // The system process gets more.  It is special.  Oh so special.
+    // With, you know, special needs.  Like this.
+    private static final int MAX_WAKELOCKS_PER_UID_IN_SYSTEM = 50;
+
     private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
 
     private static int sNumSpeedSteps;
@@ -2895,12 +2899,10 @@
                 String wakelockName = in.readString();
                 Uid.Wakelock wakelock = new Wakelock();
                 wakelock.readFromParcelLocked(unpluggables, in);
-                if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) {
-                    // We will just drop some random set of wakelocks if
-                    // the previous run of the system was an older version
-                    // that didn't impose a limit.
-                    mWakelockStats.put(wakelockName, wakelock);
-                }
+                // We will just drop some random set of wakelocks if
+                // the previous run of the system was an older version
+                // that didn't impose a limit.
+                mWakelockStats.put(wakelockName, wakelock);
             }
 
             int numSensors = in.readInt();
@@ -3904,7 +3906,9 @@
         public StopwatchTimer getWakeTimerLocked(String name, int type) {
             Wakelock wl = mWakelockStats.get(name);
             if (wl == null) {
-                if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) {
+                final int N = mWakelockStats.size();
+                if (N > MAX_WAKELOCKS_PER_UID && (mUid != Process.SYSTEM_UID
+                        || N > MAX_WAKELOCKS_PER_UID_IN_SYSTEM)) {
                     name = BATCHED_WAKELOCK_NAME;
                     wl = mWakelockStats.get(name);
                 }
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 446dab1..18d45f7 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -94,6 +94,15 @@
     }
 
     @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mActionMenuPresenter != null) {
+            mActionMenuPresenter.hideOverflowMenu();
+            mActionMenuPresenter.hideSubMenus();
+        }
+    }
+
+    @Override
     public void setSplitActionBar(boolean split) {
         if (mSplitActionBar != split) {
             if (mActionMenuPresenter != null) {
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 61bce60..e131242 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -285,6 +285,10 @@
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         removeCallbacks(mTabSelector);
+        if (mActionMenuPresenter != null) {
+            mActionMenuPresenter.hideOverflowMenu();
+            mActionMenuPresenter.hideSubMenus();
+        }
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
index 63a3aa5..979eb81 100644
--- a/core/java/com/android/internal/widget/TransportControlView.java
+++ b/core/java/com/android/internal/widget/TransportControlView.java
@@ -86,11 +86,6 @@
      */
     private Bundle mPopulateMetadataWhenAttached = null;
 
-    /**
-     * Whether to clear the interface next time it is shown (i.e. the generation id changed)
-     */
-    private boolean mClearOnNextShow;
-
     // This handler is required to ensure messages from IRCD are handled in sequence and on
     // the UI thread.
     private Handler mHandler = new Handler() {
@@ -121,7 +116,10 @@
 
             case MSG_SET_GENERATION_ID:
                 if (msg.arg2 != 0) {
-                    mClearOnNextShow = true; // TODO: handle this
+                    // This means nobody is currently registered. Hide the view.
+                    if (mWidgetCallbacks != null) {
+                        mWidgetCallbacks.requestHide(TransportControlView.this);
+                    }
                 }
                 if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
                 mClientGeneration = msg.arg1;
@@ -412,7 +410,7 @@
         if (DEBUG) Log.v(TAG, "onSaveInstanceState()");
         Parcelable superState = super.onSaveInstanceState();
         SavedState ss = new SavedState(superState);
-        ss.wasShowing = mWidgetCallbacks.isVisible(this);
+        ss.wasShowing = mWidgetCallbacks != null && mWidgetCallbacks.isVisible(this);
         return ss;
     }
 
@@ -425,7 +423,7 @@
         }
         SavedState ss = (SavedState) state;
         super.onRestoreInstanceState(ss.getSuperState());
-        if (ss.wasShowing) {
+        if (ss.wasShowing && mWidgetCallbacks != null) {
             mWidgetCallbacks.requestShow(this);
         }
     }
@@ -449,6 +447,11 @@
     }
 
     private void sendMediaButtonClick(int keyCode) {
+        if (mClientIntent == null) {
+            // Shouldn't be possible because this view should be hidden in this case.
+            Log.e(TAG, "sendMediaButtonClick(): No client is currently registered");
+            return;
+        }
         // use the registered PendingIntent that will be processed by the registered
         //    media button event receiver, which is the component of mClientIntent
         KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 0b53850..c207150 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -534,7 +534,7 @@
 #if DEBUG_GLYPHS
     LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs,
             shaperItem.kerning_applied);
-    LOGD("         -- string= '%s'", String8(chars + start, count).string());
+    LOGD("         -- string= '%s'", String8(shaperItem.string + start, count).string());
     LOGD("         -- isDevKernText=%d", paint->isDevKernText());
 
     logGlyphs(shaperItem);
diff --git a/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png
index a32dc0d..56481ce 100644
--- a/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png
index a32dc0d..56481ce 100644
--- a/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png
index 1f71467..d15f9a6 100644
--- a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png
index 00fe8c7..073f91e 100644
--- a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png
index b988435..fe75315 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png
index 0419273..d7f78ab 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png
index b26accb3..769bc0a 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png
index 1eb5e3a..312a0f4 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png
index a32dc0d..56481ce 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png
index a32dc0d..56481ce 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png
index 1f71467..e27b409b 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png
index 00fe8c7..073f91e 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png
index b988435..f33763b 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png
index 0419273..d7f78ab 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png
index b26accb3..2e50f72 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png
index 1eb5e3a..312a0f4 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png
index 03a81d9..6784032 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png
index 03a81d9..74746cb 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
index 3cbafb9..70c0e73 100644
--- a/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
index 7b01984..36e71d8 100644
--- a/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
index 2b6340ac..4be4af5 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
index 49c8c05..e72193f 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
index df1db0e..8f20b9d2 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
index fbc46d0..04f657e 100644
--- a/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
index 87e31e1..99309ef 100644
--- a/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
index 080fc78..9bde7fb 100644
--- a/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png
index c97cff4..b69c3f0 100644
--- a/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png
index c97cff4..b69c3f0 100644
--- a/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png
index bf7df17..6b4bba0 100644
--- a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png
index 6aa64c6..3d8898e 100644
--- a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png
index c5f098c..e922f71 100644
--- a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png
index 8a63152..3b92894 100644
--- a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png
index 7f15e1e..7e44919 100644
--- a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png
index 8bdbb2e..09b5616 100644
--- a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png
index c97cff4..b69c3f0 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png
index c97cff4..b69c3f0 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png
index bf7df17..6b4bba0 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png
index 6aa64c6..3d8898e 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png
index c5f098c..e922f71 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png
index 8a63152..3b92894 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png
index 7f15e1e..7e44919 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png
index 8bdbb2e..09b5616 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png
index efbaef8..2a78e8c 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png
index efbaef8..632d9fc 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
index 039af2f..081657e 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
index eb70db6..3f312b4 100644
--- a/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
index 9b45bb7..b086fae 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
index 67b96e2..73c336a 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
index b09f9dc..726e0ff 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
index 821ad91..726e0ff 100644
--- a/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
index c3a7a2e..1767c16 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
index e769cb5..1767c16 100644
--- a/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png
index 4c4e02c..b3f8cd6 100644
--- a/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png
index 4c4e02c..b3f8cd6 100644
--- a/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png
index 86221f0..b5c5907 100644
--- a/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png
index a604537..30052e9 100644
--- a/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png
index cf1b79f..16be839 100644
--- a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png
index d1ecc73..ddd0559 100644
--- a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png
index e97c5d7..3d143b9 100644
--- a/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png
index 5c52dd5..dfb2185 100644
--- a/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png
index 4c4e02c..b3f8cd6 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png
index 4c4e02c..b3f8cd6 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png
index 86221f0..b5c5907 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png
index a604537..30052e9 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png
index cf1b79f..16be839 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png
index d1ecc73..ddd0559 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png
index e97c5d7..3d143b9 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png
index 5c52dd5..dfb2185 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png
index 3ed03f3..7f0dc65 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png
index 3ed03f3..7f0dc65 100644
--- a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_default_holo_dark.9.png
index 59a9a1b..8fdbbf3 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_default_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_default_holo_light.9.png
index 5d472c8..4e9ae43 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_default_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_dark.9.png
index 3dbef60..98f4871 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_light.9.png
index 197c2bc..733373e 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_dark.9.png
index a765e5b..0c6bb03 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_light.9.png
index 30a3237..0c6bb03 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_dark.9.png
index 3c8ed1e..e5bfd8a 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_selected_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_light.9.png
index f69ebc5..1743da6 100644
--- a/core/res/res/drawable-xhdpi/textfield_search_selected_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/textfield_search_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/edit_text_holo_dark.xml b/core/res/res/drawable/edit_text_holo_dark.xml
index d00747f..2bfe333 100644
--- a/core/res/res/drawable/edit_text_holo_dark.xml
+++ b/core/res/res/drawable/edit_text_holo_dark.xml
@@ -27,7 +27,7 @@
     <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_dark" />
     <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled_holo_dark" />
     <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_activated_holo_dark" />
-    <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_focused_holo_dark" />
+    <item android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_focused_holo_dark" />
     <item android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_dark" />
     <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_focused_holo_dark" />
     <item android:drawable="@drawable/textfield_disabled_holo_dark" />
diff --git a/data/sounds/effects/ogg/KeypressDelete_120.ogg b/data/sounds/effects/ogg/KeypressDelete_120.ogg
new file mode 100644
index 0000000..f2851f7
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressDelete_120.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressReturn_120.ogg b/data/sounds/effects/ogg/KeypressReturn_120.ogg
new file mode 100644
index 0000000..48a26b4
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressReturn_120.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressSpacebar_120.ogg b/data/sounds/effects/ogg/KeypressSpacebar_120.ogg
new file mode 100644
index 0000000..9620927
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressSpacebar_120.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressStandard_120.ogg b/data/sounds/effects/ogg/KeypressStandard_120.ogg
new file mode 100644
index 0000000..e4d916a
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressStandard_120.ogg
Binary files differ
diff --git a/docs/html/guide/topics/resources/drawable-resource.jd b/docs/html/guide/topics/resources/drawable-resource.jd
index ed9f990..fdf6c5a 100644
--- a/docs/html/guide/topics/resources/drawable-resource.jd
+++ b/docs/html/guide/topics/resources/drawable-resource.jd
@@ -1458,7 +1458,7 @@
         android:gradientRadius="<em>integer</em>"
         android:startColor="<em>color</em>"
         android:type=["linear" | "radial" | "sweep"]
-        android:usesLevel=["true" | "false"] /&gt;
+        android:useLevel=["true" | "false"] /&gt;
     &lt;<a href="#padding-element">padding</a>
         android:left="<em>integer</em>"
         android:top="<em>integer</em>"
diff --git a/docs/html/resources/dashboard/opengl.jd b/docs/html/resources/dashboard/opengl.jd
index 2b94b28..9089937 100644
--- a/docs/html/resources/dashboard/opengl.jd
+++ b/docs/html/resources/dashboard/opengl.jd
@@ -57,7 +57,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A9.4,90.6" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A9.2,90.8" />
 
 <table>
 <tr>
@@ -66,14 +66,14 @@
 </tr>
 <tr>
 <td>1.1</th>
-<td>9.4%</td>
+<td>9.2%</td>
 </tr>
 <tr>
 <td>2.0</th>
-<td>90.6%</td>
+<td>90.8%</td>
 </tr>
 </table>
 
-<p><em>Data collected during a 7-day period ending on September 2, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on October 3, 2011</em></p>
 </div>
 
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 51cbae3..135c6f2 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,7 +52,7 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="470"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.0,1.8,13.3,51.2,0.6,30.7,0.2,0.7,0.5&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.1,1.4,11.7,45.3,0.5,38.2,0.2,0.9,0.7&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2&chco=c4df9b,6fad0c" />
 
 <table>
 <tr>
@@ -61,21 +61,21 @@
   <th>API Level</th>
   <th>Distribution</th>
 </tr>
-<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td>  <td>3</td><td>1.0%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td>    <td>4</td><td>1.8%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td>   <td>7</td><td>13.3%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td>    <td>8</td><td>51.2%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td>  <td>3</td><td>1.1%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td>    <td>4</td><td>1.4%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td>   <td>7</td><td>11.7%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td>    <td>8</td><td>45.3%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-2.3.html">Android 2.3 -<br/>
-                             Android 2.3.2</a></td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.6%</td></tr>
+                             Android 2.3.2</a></td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.5%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-2.3.3.html">Android 2.3.3 -<br/>
-      Android 2.3.4</a></td><!-- Gingerbread -->                                       <td>10</td><td>30.7%</td></tr>
+      Android 2.3.7</a></td><!-- Gingerbread -->                                       <td>10</td><td>38.2%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-3.0.html">Android 3.0</a></td>
                                                    <td rowspan="3">Honeycomb</td>      <td>11</td><td>0.2%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>0.7%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>0.5%</td></tr> 
+<tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>0.9%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>0.7%</td></tr> 
 </table>
 
-<p><em>Data collected during a 14-day period ending on September 2, 2011</em></p>
+<p><em>Data collected during a 14-day period ending on October 3, 2011</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -104,9 +104,9 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:100.0,99.8,99.7,99.6,99.6,99.5,99.4,99.3,99.2,99.0,98.8,98.7,98.6|96.7,96.8,97.0,97.1,97.3,97.5,97.5,97.5,97.7,97.6,97.5,97.5,97.5|91.5,92.0,93.5,93.9,94.3,94.8,95.0,95.2,95.5,95.5,95.5,95.6,95.8|61.5,63.0,66.4,68.0,69.8,71.5,73.9,75.4,77.6,79.0,80.2,81.1,82.4|1.1,1.7,2.5,3.1,4.0,6.1,9.5,13.6,17.8,20.6,24.3,27.5,31.1|0.0,1.0,1.7,2.2,3.0,5.1,8.4,12.6,16.8,20.0,23.7,26.9,30.5&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid 2.3.3,131d02,5,7,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.7,99.6,99.6,99.5,99.4,99.3,99.2,99.0,98.8,98.7,98.5,98.5,98.2|97.0,97.1,97.3,97.5,97.5,97.5,97.7,97.6,97.5,97.5,97.5,97.5,97.1|93.5,93.9,94.3,94.8,95.0,95.2,95.5,95.5,95.5,95.6,95.7,95.8,95.6|66.4,68.0,69.8,71.5,73.9,75.4,77.6,79.0,80.2,81.1,82.4,83.3,83.8|2.5,3.1,4.0,6.1,9.5,13.6,17.8,20.6,24.3,27.5,31.2,34.7,38.3|1.7,2.2,3.0,5.1,8.4,12.6,16.8,20.0,23.7,26.9,30.6,34.1,37.8&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid 2.3.3,131d02,5,5,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
 
-<p><em>Last historical dataset collected during a 14-day period ending on September 2, 2011</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on October 3, 2011</em></p>
 
 
 </div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index 77fd2d2..67b47d0 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -59,7 +59,8 @@
 
 <div class="dashboard-panel">
 
-<img alt="" width="400" height="250" src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi| Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi&chd=t%3A1.5, 3.2,74,0.9,16.9,3.5" />
+<img alt="" width="400" height="250"
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A2.6,0.1,3.0,71.9,0.9,17.6,2.7,1.2" />
 
 <table>
 <tr>
@@ -70,31 +71,31 @@
 <th scope="col">xhdpi</th>
 </tr>
 <tr><th scope="row">small</th> 
-<td></td>     <!-- small/ldpi -->
+<td>1.2%</td>     <!-- small/ldpi -->
 <td></td>     <!-- small/mdpi -->
-<td>3.5%</td> <!-- small/hdpi -->
+<td>2.7%</td> <!-- small/hdpi -->
 <td></td>     <!-- small/xhdpi -->
 </tr> 
 <tr><th scope="row">normal</th> 
 <td>0.9%</td>  <!-- normal/ldpi -->
-<td>16.9%</td> <!-- normal/mdpi -->
-<td>74%</td> <!-- normal/hdpi -->
+<td>17.6%</td> <!-- normal/mdpi -->
+<td>71.9%</td> <!-- normal/hdpi -->
 <td></td>      <!-- normal/xhdpi -->
 </tr> 
 <tr><th scope="row">large</th> 
-<td></td>     <!-- large/ldpi -->
-<td>3.2%</td> <!-- large/mdpi -->
+<td>0.1%</td>     <!-- large/ldpi -->
+<td>3.0%</td> <!-- large/mdpi -->
 <td></td>     <!-- large/hdpi -->
 <td></td>     <!-- large/xhdpi -->
 </tr> 
 <tr><th scope="row">xlarge</th> 
 <td></td>     <!-- xlarge/ldpi -->
-<td>1.5%</td> <!-- xlarge/mdpi -->
+<td>2.6%</td> <!-- xlarge/mdpi -->
 <td></td>     <!-- xlarge/hdpi -->
 <td></td>     <!-- xlarge/xhdpi -->
 </tr> 
 </table>
 
-<p><em>Data collected during a 7-day period ending on September 2, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on October 3, 2011</em></p>
 </div>
 
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 310310e..38357ef 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -599,7 +599,7 @@
   },
   {
     tags: ['sample', 'input', 'new'],
-    path: 'samples/SampleSpellCheckerService/index.html',
+    path: 'samples/SpellChecker/SampleSpellCheckerService/index.html',
     title: {
       en: 'Spell Checker'
     },
diff --git a/docs/html/sdk/android-4.0-highlights.jd b/docs/html/sdk/android-4.0-highlights.jd
index fe69e12..d6a2dcd 100644
--- a/docs/html/sdk/android-4.0-highlights.jd
+++ b/docs/html/sdk/android-4.0-highlights.jd
@@ -14,8 +14,8 @@
 }
 #jd-content div.video {
   float:right;
-  padding:0 60px 40px;
-  margin-top:-15px;
+  padding:0 0 40px 60px;
+  margin-top:-30px;
 }
 #jd-content table.columns {
   margin:0 0 1em 0;
@@ -37,23 +37,21 @@
   font-weight:bold;
 }
 </style>
-<!--
-<div class="video" style="border:1px solid gray;width:250px;height:180px;margin:1.5em">
-<object width="278" height="180">
-<xparam name="movie" value="http://www.youtube.com/v/Jx3pdWBlZ34?hl=en&fs=1"></param>
-<xparam name="allowFullScreen" value="true"></param><param name="allowscriptaccess"
-value="always"></param>
-ICS CONSUMER VIDEO [ziwang]
-<embed xsrc="http://www.youtube.com/v/Jx3pdWBlZ34?hl=en&fs=1" type="application/x-shockwave-flash"
-allowscriptaccess="always" allowfullscreen="true" width="278" height="180"></embed>
-</object>
+
+<div class="video">
+<iframe width="380" height="223" src="http://www.youtube.com/embed/-F_ke3rxopc?hd=1" frameborder="0"
+allowfullscreen></iframe>
 </div>
--->
+
 <p>Welcome to Android 4.0!</p>
 
-<p>Android 4.0 delivers a refined, unified UI for phones and tablets and introduces innovative features for users and developers. This document provides a glimpse of the many new features and technologies that make Android 4.0 simple, beautiful, and beyond smart. <!--For technical details about
+<p>Android 4.0 delivers a refined, unified UI for phones and tablets and
+introduces innovative features for users and developers. This document provides
+a glimpse of the many new features and technologies that make Android 4.0
+simple, beautiful, and beyond smart. <!--For technical details about
 new developer APIs described below, see the <a
-href="{@docRoot}sdk/android-4.0.html">Android 4.0 API Overview</a> document.--></p>
+href="{@docRoot}sdk/android-4.0.html">Android 4.0 API Overview</a>
+document.--></p>
 
 <ul>
   <li><a href="#UserFeatures">Android 4.0 for Users</a></li>
@@ -133,10 +131,10 @@
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Home screen folders and
 favorites tray</strong></p>
 
-<p>New <strong>home screen folders</strong> offer a new way for users to group
-their apps and shortcuts logically, just by dragging one onto another. From the
-All Apps launcher, users can now simply drag an app to get information about it
-or immediately uninstall it, or disable a pre-installed app.</p>
+<p>New home screen <strong>folders</strong> offer a new way for users to group
+their apps and shortcuts logically, just by dragging one onto another. Also, 
+in All Apps launcher, users can now simply <strong>drag an app</strong> to get
+information about it or immediately uninstall it, or disable a pre-installed app.</p>
 
 <p>On smaller-screen devices, the home screen now includes a customizable
 <strong>favorites tray</strong> visible from all home screens. Users can drag
@@ -178,9 +176,9 @@
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Swipe to dismiss
 notifications, tasks, and browser tabs</strong></p>
 
-<p>Android 4.0 makes managing notifications, recent apps, and browoser tabs even
+<p>Android 4.0 makes managing notifications, recent apps, and brwoser tabs even
 easier. Users can now dismiss individual notifications, apps from the Recent
-Apps list, and browser tabs lists with a simple swipe of a finger. </p>
+Apps list, and browser tabs with a simple swipe of a finger. </p>
 
 <div  style="padding-top:0em;">
 <div style="margin-right:1em;float:right;margin-left:1em;margin-top:1.5em;margin-bottom:0;padding-bottom:0;width:200px">
@@ -199,17 +197,17 @@
 <p>The soft keyboard in Android 4.0 makes text input even faster and more
 accurate. Error correction and word suggestion are improved through a new set of
 default dictionaries and more accurate heuristics for handling cases such as
-double-typed characters, skipped letters, and omitted spaces. Word suggestion is
-also improved and the suggestion strip is simplified to show only three words at
-a time.</p>
+double-typed characters, skipped letters, and omitted spaces. Word suggestion
+is also improved and the suggestion strip is simplified to show only three
+words at a time.</p>
 
-<p>To fix misspelled words more easily, Android 4.0 adds a spell-checker that
-locates and underlines errors and suggests replacement words. With one tap,
-users can choose from multiple spelling suggestions, delete a word, or add it to
-the dictionary. Users can even tap to see replacement suggestions for words that
-are spelled correctly. For specialized features or additional languages, users
-can now download and install third-party dictionaries, spell-checkers, and other
-text services.</p>
+<p>To fix misspelled words more easily, Android 4.0 adds a
+<strong>spell-checker</strong> that locates and underlines errors and suggests
+replacement words. With one tap, users can choose from multiple spelling
+suggestions, delete a word, or add it to the dictionary. Users can even tap to
+see replacement suggestions for words that are spelled correctly. For
+specialized features or additional languages, users can now download and install
+third-party dictionaries, spell-checkers, and other text services.</p>
 
 
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Powerful voice input
@@ -218,7 +216,7 @@
 <p>Android 4.0 introduces a powerful new voice input engine that offers a
 continuous "open microphone" experience and streaming voice recognition. The new
 voice input engine lets users dictate the text they want, for as long as they
-want, using the language they want. Users can speak continously for a prolonged
+want, using the language they want. Users can <strong>speak continously</strong> for a prolonged
 time, even pausing for intervals if needed, and dictate punctuation to create
 correct sentences. As the voice input engine enters text, it underlines possible
 dictation errors in gray. After dictating, users can tap the underlined words to
@@ -300,15 +298,15 @@
 linked together and integrated for easy accessibility. At the center is a new
 <strong>People app</strong> that offers richer profile information, including a
 large profile picture, phone numbers, addresses and accounts, status updates,
-and a new button for connecting on integrated social networks. </p>
+events, and a new button for connecting on integrated social networks. </p>
 
 <p>The user's own contact information is stored in a new <strong>"Me"
 profile</strong>, allowing easier sharing with apps and people. All of the
 user's integrated contacts are displayed in an easy to manage list, including
 controls over which contacts are shown from any integrated account or social
 network. Wherever the user navigates across the system, tapping a profile photo
-displays Quick Contacts, with shortcuts to phone numbers, text messaging, and
-more. </p>
+displays Quick Contacts, with large profile pictures, shortcuts to phone numbers,
+text messaging, and more. </p>
 
 
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Unified calendar, visual
@@ -343,7 +341,7 @@
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Rich and versatile camera
 capabilities</strong></p>
 
-<p>The Camera app includes many new features let users capture special moments
+<p>The Camera app includes many new features that let users capture special moments
 with great photos and videos. After capturing images, they can edit and share
 them easily with friemds. </p>
 
@@ -405,7 +403,15 @@
 
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Live Effects for transforming video</strong></p>
 
-<p>Live Effects is a collection of graphical transformations that add interest and fun to videos captured in the Camera app. For example, users can change the background behind them to any stock or custom image, for just the right setting when shooting video or using Google Talk video chat. Also available is Silly Faces, a set of morphing effects that use state-of-the-art face recognition and GPU filters to add great effects facial features during video capture. For example, you can use effects such as small eyes, big mouth, big nose, face squeeze, and more. Outside of the Camera app, Live Effects is available during video chat in the Google Talk app.</p>
+<p>Live Effects is a collection of graphical transformations that add interest
+and fun to videos captured in the Camera app. For example, users can
+<strong>change the background</strong> behind them to any stock or custom image,
+for just the right setting when shooting videeo. Also available for video is
+Silly Faces, a set of morphing effects that use state-of-the-art face
+recognition and GPU filters to transform facial features. For example, you can
+use effects such as small eyes, big mouth, big nose, face squeeze, and more.
+Outside of the Camera app, Live Effects is available during video chat in the
+Google Talk app.</p>
 
 <div  style="padding-top:0em;">
 <div style="margsin-right:.8em;float:left;width:186px;padding-top:1em;">
@@ -418,7 +424,10 @@
 
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Sharing with screenshots</strong></p>
 
-<p>Users can now share what's on their screens more easily by taking screenshots. Hardware buttons let them snap a <strong>screenshot</strong> and store it locally. Afterward, they can view, edit, and share the screen shot in Gallery or a similar app.</p>
+<p>Users can now share what's on their screens more easily by taking
+screenshots. Hardware buttons let them snap a <strong>screenshot</strong> and
+store it locally. Afterward, they can view, edit, and share the screen shot in
+Gallery or a similar app.</p>
 
 
 <h3 id="cloud" style="color:#172861">Cloud-connected experience</h3>
@@ -435,14 +444,18 @@
 </div>
 </div>
 
-<p>Android has always been cloud-connected, letting users browse the web and sync photos, apps, games, email, and contacts &mdash; wherever they are and across all of their devices. Android 4.0 adds new browsing and email capabilities to let users take even more with them and keep communication organized.</p>
+<p>Android has always been cloud-connected, letting users browse the web and
+sync photos, apps, games, email, and contacts &mdash; wherever they are and
+across all of their devices. Android 4.0 adds new browsing and email
+capabilities to let users take even more with them and keep communication
+organized.</p>
 
 
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Powerful web
 browsing</strong></p>
 
 <p>The Android Browser offers an experience that’s as rich and convenient as a
-desktop browser. It lets users instantly and manage <strong>sync Google Chrome
+desktop browser. It lets users instantly sync and manage <strong>Google Chrome
 bookmarks</strong> from all of their accounts, jump to their favorite content
 faster, and even save it for reading later in case there's no network
 available.</p>
@@ -532,11 +545,12 @@
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Face Unlock</strong></p>
 
 <p>Android 4.0 introduces a completely new approach to securing a device, making
-it even more personal &mdash; Face Unlock is a new screen-lock option that lets
-users unlock their devices with their faces. It takes advantage of
-state-of-the-art facial recognition technology to register a face and to
-recognize it later when unlocking the device. Users just hold their devices in
-front of their faces to unlock, or use a backup PIN or pattern. </p>
+each person's device even more personal &mdash; Face Unlock is a new screen-lock
+option that lets users unlock their devices with their faces. It takes advantage
+of the device front-facing camera and state-of-the-art facial recognition
+technology to register a face during setup and then to recognize it again when
+unlocking the device. Users just hold their devices in front of their faces to
+unlock, or use a backup PIN or pattern. </p>
 
 
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Wi-Fi Direct and Bluetooth HDP</strong></p>
@@ -641,7 +655,7 @@
 
 <p>Applications can also let users set up a social connection to a contact from
 the People app. When the user touches Add Connection in a contact, the app
-broadcasts a public intent that other apps can handle, displaying any UI needed
+sends a public intent that other apps can handle, displaying any UI needed
 to create the social connection.</p>
 
 <p>Building on the social API, developers can add powerful new interactions that
@@ -659,7 +673,7 @@
 and handle the display of event alerts and reminders. Using the calendar
 provider, applications can take advantage of event data sourced from a variety
 of apps and protocols, to offer innovative ways of viewing and managing a user’s
-events. Apps can also use of calendar data to improve the relevance of their
+events. Apps can also use calendar data to improve the relevance of their
 other content.</p>
 
 <p>For lighter-weight access to calendar services, the Calendar app defines a
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index da40d52..68f9507 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -158,7 +158,7 @@
 <p>Adding a new raw contact for the profile requires the {@link
 android.Manifest.permission#WRITE_PROFILE} permission. Likewise, in order to read from the profile
 table, you must request the {@link android.Manifest.permission#READ_PROFILE} permission. However,
-most apps should need to read the user profile, even when contributing data to the
+most apps should not need to read the user profile, even when contributing data to the
 profile. Reading the user profile is a sensitive permission and you should expect users to be
 skeptical of apps that request it.</p>
 
@@ -957,8 +957,8 @@
 include a {@code &lt;meta-data&gt;} element that declares configuration information for the spell
 checker. </p>
 
-<p>See the <a href="{@docRoot}resources/samples/SampleSpellCheckerService/index.html">Spell
-Checker</a> sample app for example code.</p>
+<p>See the <a href="{@docRoot}resources/samples/SpellChecker/SampleSpellCheckerService/index.html">
+Spell Checker</a> sample app for example code.</p>
 
 
 
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 59675a8..6a99d35 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -67,7 +67,7 @@
 the ADT Plugin, as denoted by revision number. </p>
 
 <p>For a summary of all known issues in ADT, see <a
-href="http://tools.android.com/release/knownissues">http://tools.android.com/release/knownissues</a>.</p>
+href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
 
 <script type="text/javascript">
 function toggleDiv(link) {
diff --git a/docs/html/sdk/images/4.0/lock-camera-lg.png b/docs/html/sdk/images/4.0/lock-camera-lg.png
index 2a169b3..c82cec6 100644
--- a/docs/html/sdk/images/4.0/lock-camera-lg.png
+++ b/docs/html/sdk/images/4.0/lock-camera-lg.png
Binary files differ
diff --git a/docs/html/sdk/images/4.0/lock-camera.png b/docs/html/sdk/images/4.0/lock-camera.png
index a5c63c3..d3cc153 100644
--- a/docs/html/sdk/images/4.0/lock-camera.png
+++ b/docs/html/sdk/images/4.0/lock-camera.png
Binary files differ
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index f5b61ee..272efcb 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -24,7 +24,7 @@
 and AVD Manager. </p>
 
 <p>For a summary of all known issues in SDK Tools, see <a
-href="http://tools.android.com/release/knownissues">http://tools.android.com/release/knownissues</a>.</p>
+href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
 
 <script type="text/javascript">
 function toggleDiv(link) {
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index f844331..8a9ca85 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -46,13 +46,18 @@
     Element[] mElements;
     String[] mElementNames;
     int[] mArraySizes;
+    int[] mOffsetInBytes;
 
     DataType mType;
     DataKind mKind;
     boolean mNormalized;
     int mVectorSize;
 
-    int getSizeBytes() {return mSize;}
+    /**
+    * @hide
+    * @return element size in bytes
+    */
+    public int getSizeBytes() {return mSize;}
 
 
     /**
@@ -152,6 +157,77 @@
     }
 
     /**
+    * @hide
+    * @return number of sub-elements in this element
+    */
+    public int getSubElementCount() {
+        if (mElements == null) {
+            return 0;
+        }
+        return mElements.length;
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element to return
+    * @return sub-element in this element at given index
+    */
+    public Element getSubElement(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mElements[index];
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return sub-element in this element at given index
+    */
+    public String getSubElementName(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mElementNames[index];
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return array size of sub-element in this element at given index
+    */
+    public int getSubElementArraySize(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mArraySizes[index];
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return offset in bytes of sub-element in this element at given index
+    */
+    public int getSubElementOffsetBytes(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mOffsetInBytes[index];
+    }
+
+    /**
      * Utility function for returning an Element containing a single Boolean.
      *
      * @param rs Context to which the element will belong.
@@ -602,7 +678,9 @@
         mElements = e;
         mElementNames = n;
         mArraySizes = as;
+        mOffsetInBytes = new int[mElements.length];
         for (int ct = 0; ct < mElements.length; ct++ ) {
+            mOffsetInBytes[ct] = mSize;
             mSize += mElements[ct].mSize * mArraySizes[ct];
         }
     }
@@ -653,13 +731,16 @@
         if(numSubElements > 0) {
             mElements = new Element[numSubElements];
             mElementNames = new String[numSubElements];
+            mArraySizes = new int[numSubElements];
+            mOffsetInBytes = new int[numSubElements];
 
             int[] subElementIds = new int[numSubElements];
-            mRS.nElementGetSubElements(getID(), subElementIds, mElementNames);
+            mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes);
             for(int i = 0; i < numSubElements; i ++) {
                 mElements[i] = new Element(subElementIds[i], mRS);
                 mElements[i].updateFromNative();
-                mSize += mElements[i].mSize;
+                mOffsetInBytes[i] = mSize;
+                mSize += mElements[i].mSize * mArraySizes[i];
             }
         }
 
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index 60d9698..93ee0ce 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -37,23 +37,32 @@
         }
     }
 
-    boolean mPointSmooth;
-    boolean mLineSmooth;
     boolean mPointSprite;
-    float mLineWidth;
     CullMode mCullMode;
 
     ProgramRaster(int id, RenderScript rs) {
         super(id, rs);
 
-        mLineWidth = 1.0f;
-        mPointSmooth = false;
-        mLineSmooth = false;
         mPointSprite = false;
-
         mCullMode = CullMode.BACK;
     }
 
+    /**
+     * @hide
+     * @return whether point sprites are enabled
+     */
+    public boolean getPointSpriteEnabled() {
+        return mPointSprite;
+    }
+
+    /**
+     * @hide
+     * @return cull mode
+     */
+    public CullMode getCullMode() {
+        return mCullMode;
+    }
+
     public static ProgramRaster CULL_BACK(RenderScript rs) {
         if(rs.mProgramRaster_CULL_BACK == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -105,7 +114,10 @@
         public ProgramRaster create() {
             mRS.validate();
             int id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
-            return new ProgramRaster(id, mRS);
+            ProgramRaster programRaster = new ProgramRaster(id, mRS);
+            programRaster.mPointSprite = mPointSprite;
+            programRaster.mCullMode = mCullMode;
+            return programRaster;
         }
     }
 
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index fb7c8ca..677dadd 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -135,12 +135,93 @@
         }
     }
 
+    DepthFunc mDepthFunc;
+    boolean mDepthMask;
+    boolean mColorMaskR;
+    boolean mColorMaskG;
+    boolean mColorMaskB;
+    boolean mColorMaskA;
+    BlendSrcFunc mBlendSrc;
+    BlendDstFunc mBlendDst;
+    boolean mDither;
 
     ProgramStore(int id, RenderScript rs) {
         super(id, rs);
     }
 
     /**
+    * @hide
+    * @return depth function
+    */
+    public DepthFunc getDepthFunc() {
+        return mDepthFunc;
+    }
+
+    /**
+    * @hide
+    * @return whether depth writes are enabled
+    */
+    public boolean getDepthMaskEnabled() {
+        return mDepthMask;
+    }
+
+    /**
+    * @hide
+    * @return red color channel mask
+    */
+    public boolean getColorMaskREnabled() {
+        return mColorMaskR;
+    }
+
+    /**
+    * @hide
+    * @return green color channel mask
+    */
+    public boolean getColorMaskGEnabled() {
+        return mColorMaskG;
+    }
+
+    /**
+    * @hide
+    * @return blue color channel mask
+    */
+    public boolean getColorMaskBEnabled() {
+        return mColorMaskB;
+    }
+
+    /**
+    * @hide
+    * @return alpha channel mask
+    */
+    public boolean getColorMaskAEnabled() {
+        return mColorMaskA;
+    }
+
+    /**
+    * @hide
+    * @return source blend function
+    */
+    public BlendSrcFunc getBlendSrcFunc() {
+        return mBlendSrc;
+    }
+
+    /**
+    * @hide
+    * @return destination blend function
+    */
+    public BlendDstFunc getBlendDstFunc() {
+        return mBlendDst;
+    }
+
+    /**
+    * @hide
+    * @return whether dither is enabled
+    */
+    public boolean getDitherEnabled() {
+        return mDither;
+    }
+
+    /**
     * Returns a pre-defined program store object with the following
     * characteristics:
     *  - incoming pixels are drawn if their depth value is less than
@@ -340,7 +421,17 @@
             int id = mRS.nProgramStoreCreate(mColorMaskR, mColorMaskG, mColorMaskB, mColorMaskA,
                                              mDepthMask, mDither,
                                              mBlendSrc.mID, mBlendDst.mID, mDepthFunc.mID);
-            return new ProgramStore(id, mRS);
+            ProgramStore programStore = new ProgramStore(id, mRS);
+            programStore.mDepthFunc = mDepthFunc;
+            programStore.mDepthMask = mDepthMask;
+            programStore.mColorMaskR = mColorMaskR;
+            programStore.mColorMaskG = mColorMaskG;
+            programStore.mColorMaskB = mColorMaskB;
+            programStore.mColorMaskA = mColorMaskA;
+            programStore.mBlendSrc = mBlendSrc;
+            programStore.mBlendDst = mBlendDst;
+            programStore.mDither = mDither;
+            return programStore;
         }
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index d3d65a3..1305633 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -210,10 +210,11 @@
         validate();
         rsnElementGetNativeData(mContext, id, elementData);
     }
-    native void rsnElementGetSubElements(int con, int id, int[] IDs, String[] names);
-    synchronized void nElementGetSubElements(int id, int[] IDs, String[] names) {
+    native void rsnElementGetSubElements(int con, int id,
+                                         int[] IDs, String[] names, int[] arraySizes);
+    synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) {
         validate();
-        rsnElementGetSubElements(mContext, id, IDs, names);
+        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
     }
 
     native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces);
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 98943a1..0a3c91d 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -47,11 +47,58 @@
         }
     }
 
+    Value mMin;
+    Value mMag;
+    Value mWrapS;
+    Value mWrapT;
+    Value mWrapR;
+    float mAniso;
+
     Sampler(int id, RenderScript rs) {
         super(id, rs);
     }
 
     /**
+     * @hide
+     * @return minification setting for the sampler
+     */
+    public Value getMinification() {
+        return mMin;
+    }
+
+    /**
+     * @hide
+     * @return magnification setting for the sampler
+     */
+    public Value getMagnification() {
+        return mMag;
+    }
+
+    /**
+     * @hide
+     * @return S wrapping mode for the sampler
+     */
+    public Value getWrapS() {
+        return mWrapS;
+    }
+
+    /**
+     * @hide
+     * @return T wrapping mode for the sampler
+     */
+    public Value getWrapT() {
+        return mWrapT;
+    }
+
+    /**
+     * @hide
+     * @return anisotropy setting for the sampler
+     */
+    public float getAnisotropy() {
+        return mAniso;
+    }
+
+    /**
      * Retrieve a sampler with min and mag set to nearest and wrap modes set to
      * clamp.
      *
@@ -241,8 +288,16 @@
 
         public Sampler create() {
             mRS.validate();
-            int id = mRS.nSamplerCreate(mMag.mID, mMin.mID, mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
-            return new Sampler(id, mRS);
+            int id = mRS.nSamplerCreate(mMag.mID, mMin.mID, 
+                                        mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
+            Sampler sampler = new Sampler(id, mRS);
+            sampler.mMin = mMin;
+            sampler.mMag = mMag;
+            sampler.mWrapS = mWrapS;
+            sampler.mWrapT = mWrapT;
+            sampler.mWrapR = mWrapR;
+            sampler.mAniso = mAniso;
+            return sampler;
         }
     }
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index ec1f8de..af03ee2 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -371,23 +371,29 @@
 
 
 static void
-nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _IDs, jobjectArray _names)
+nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id,
+                       jintArray _IDs,
+                       jobjectArray _names,
+                       jintArray _arraySizes)
 {
     int dataSize = _env->GetArrayLength(_IDs);
     LOG_API("nElementGetSubElements, con(%p)", con);
 
     uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
     const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
+    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
 
-    rsaElementGetSubElements(con, (RsElement)id, ids, names, (uint32_t)dataSize);
+    rsaElementGetSubElements(con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
 
     for(jint i = 0; i < dataSize; i++) {
         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
         _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
+        _env->SetIntArrayRegion(_arraySizes, i, 1, (const jint*)&arraySizes[i]);
     }
 
     free(ids);
     free(names);
+    free(arraySizes);
 }
 
 // -----------------------------------
@@ -1239,7 +1245,7 @@
 {"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
 {"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
 {"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
-{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;)V",            (void*)nElementGetSubElements },
+{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
 
 {"rsnTypeCreate",                    "(IIIIIZZ)I",                            (void*)nTypeCreate },
 {"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 02ad703..c4cc947 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -78,6 +78,9 @@
             node_id node, OMX_INDEXTYPE index,
             const void *params, size_t size) = 0;
 
+    virtual status_t getState(
+            node_id node, OMX_STATETYPE* state) = 0;
+
     virtual status_t storeMetaDataInBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
 
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 0bee0f1..98fa171 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -409,9 +409,9 @@
 int SurfaceTextureClient::disconnect(int api) {
     LOGV("SurfaceTextureClient::disconnect");
     Mutex::Autolock lock(mMutex);
+    freeAllBuffers();
     int err = mSurfaceTexture->disconnect(api);
     if (!err) {
-        freeAllBuffers();
         mReqFormat = 0;
         mReqWidth = 0;
         mReqHeight = 0;
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index b8bc454..5daafd5 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -334,7 +334,7 @@
 
 class SurfaceTextureGLTest : public GLTest {
 protected:
-    static const GLint TEX_ID = 123;
+    enum { TEX_ID = 123 };
 
     virtual void SetUp() {
         GLTest::SetUp();
@@ -1438,4 +1438,86 @@
     }
 }
 
+TEST_F(SurfaceTextureGLTest, EglDestroySurfaceUnrefsBuffers) {
+    EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
+            mANW.get(), NULL);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
+
+    sp<GraphicBuffer> buffers[3];
+
+    for (int i = 0; i < 3; i++) {
+        // Produce a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        glClear(GL_COLOR_BUFFER_BIT);
+        eglSwapBuffers(mEglDisplay, stcEglSurface);
+
+        // Consume a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        mST->updateTexImage();
+        buffers[i] = mST->getCurrentBuffer();
+    }
+
+    // Destroy the GL texture object to release its ref on buffers[2].
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy the EGLSurface
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, stcEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Release the ref that the SurfaceTexture has on buffers[2].
+    mST->abandon();
+
+    EXPECT_EQ(1, buffers[0]->getStrongCount());
+    EXPECT_EQ(1, buffers[1]->getStrongCount());
+    EXPECT_EQ(1, buffers[2]->getStrongCount());
+}
+
+TEST_F(SurfaceTextureGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
+    EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
+            mANW.get(), NULL);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
+
+    sp<GraphicBuffer> buffers[3];
+
+    for (int i = 0; i < 3; i++) {
+        // Produce a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        glClear(GL_COLOR_BUFFER_BIT);
+        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, stcEglSurface));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        // Consume a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        buffers[i] = mST->getCurrentBuffer();
+    }
+
+    // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
+    // on buffers[2].
+    mST->abandon();
+
+    // Destroy the GL texture object to release its ref on buffers[2].
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy the EGLSurface.
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, stcEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EXPECT_EQ(1, buffers[0]->getStrongCount());
+    EXPECT_EQ(1, buffers[1]->getStrongCount());
+    EXPECT_EQ(1, buffers[2]->getStrongCount());
+}
+
 } // namespace android
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index cedf456..3372d1c 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -382,12 +382,13 @@
                 xDivs = getInts(xDivsCount);
                 yDivs = getInts(yDivsCount);
                 colors = getUInts(numColors);
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                getFloat();
-                getFloat();
-                getFloat();
-                getFloat();
-                getPaint();
+                float left = getFloat();
+                float top = getFloat();
+                float right = getFloat();
+                float bottom = getFloat();
+                SkPaint* paint = getPaint();
+                LOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
+                        left, top, right, bottom);
             }
             break;
             case DrawColor: {
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index f7dacae..47a2c99 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -157,14 +157,17 @@
 
     for (uint32_t i = 0; i < mYCount; i++) {
         float stepY = mYDivs[i];
+        const float segment = stepY - previousStepY;
 
         if (i & 1) {
-            const float segment = stepY - previousStepY;
             y2 = y1 + floorf(segment * stretchY + 0.5f);
         } else {
-            y2 = y1 + stepY - previousStepY;
+            y2 = y1 + segment;
         }
-        float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
+
+        float vOffset = y1 == y2 ? 0.0f : 0.5 - (0.5 * segment / (y2 - y1));
+        float v2 = fmax(0.0f, stepY - vOffset) / bitmapHeight;
+        v1 += vOffset / bitmapHeight;
 
         if (stepY > 0.0f) {
 #if DEBUG_EXPLODE_PATCHES
@@ -179,7 +182,7 @@
         }
 
         y1 = y2;
-        v1 = (stepY + 0.5f) / bitmapHeight;
+        v1 = stepY / bitmapHeight;
 
         previousStepY = stepY;
     }
@@ -190,8 +193,7 @@
         y1 += mYCount * EXPLODE_GAP;
         y2 += mYCount * EXPLODE_GAP;
 #endif
-        generateRow(vertex, y1, y2, v1, 1.0f, stretchX, right - left,
-                bitmapWidth, quadCount);
+        generateRow(vertex, y1, y2, v1, 1.0f, stretchX, right - left, bitmapWidth, quadCount);
     }
 
     if (verticesCount > 0) {
@@ -220,14 +222,17 @@
     // Generate the row quad by quad
     for (uint32_t i = 0; i < mXCount; i++) {
         float stepX = mXDivs[i];
+        const float segment = stepX - previousStepX;
 
         if (i & 1) {
-            const float segment = stepX - previousStepX;
             x2 = x1 + floorf(segment * stretchX + 0.5f);
         } else {
-            x2 = x1 + stepX - previousStepX;
+            x2 = x1 + segment;
         }
-        float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
+
+        float uOffset = x1 == x2 ? 0.0f : 0.5 - (0.5 * segment / (x2 - x1));
+        float u2 = fmax(0.0f, stepX - uOffset) / bitmapWidth;
+        u1 += uOffset / bitmapWidth;
 
         if (stepX > 0.0f) {
 #if DEBUG_EXPLODE_PATCHES
@@ -241,7 +246,7 @@
         }
 
         x1 = x2;
-        u1 = (stepX + 0.5f) / bitmapWidth;
+        u1 = stepX / bitmapWidth;
 
         previousStepX = stepX;
     }
@@ -265,8 +270,8 @@
     if ((mColorKey >> oldQuadCount) & 0x1) {
 #if DEBUG_PATCHES_EMPTY_VERTICES
         PATCH_LOGD("    quad %d (empty)", oldQuadCount);
-        PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1);
-        PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.2f, %.2f", x2, y2, u2, v2);
+        PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1);
+        PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2);
 #endif
         return;
     }
@@ -294,8 +299,8 @@
 
 #if DEBUG_PATCHES_VERTICES
     PATCH_LOGD("    quad %d", oldQuadCount);
-    PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1);
-    PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.2f, %.2f", x2, y2, u2, v2);
+    PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1);
+    PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2);
 #endif
 }
 
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 3ba0123..6d54268 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -34,26 +34,30 @@
 RsFile rsaFileA3DCreateFromAsset(RsContext, void *asset);
 RsFile rsaFileA3DCreateFromFile(RsContext, const char *path);
 void rsaFileA3DGetNumIndexEntries(RsContext, int32_t *numEntries, RsFile);
-void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries,uint32_t numEntries, RsFile);
+void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries,
+                               uint32_t numEntries, RsFile);
 void rsaGetName(RsContext, void * obj, const char **name);
 // Mesh update functions
 void rsaMeshGetVertexBufferCount(RsContext, RsMesh, int32_t *vtxCount);
 void rsaMeshGetIndexCount(RsContext, RsMesh, int32_t *idxCount);
 void rsaMeshGetVertices(RsContext, RsMesh, RsAllocation *vtxData, uint32_t vtxDataCount);
-void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount);
+void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va,
+                       uint32_t *primType, uint32_t idxDataCount);
 // Allocation update
 const void* rsaAllocationGetType(RsContext con, RsAllocation va);
 // Type update
 void rsaTypeGetNativeData(RsContext, RsType, uint32_t *typeData, uint32_t typeDataSize);
 // Element update
 void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize);
-void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, uint32_t dataSize);
+void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names,
+                              uint32_t *arraySizes, uint32_t dataSize);
 
 RsDevice rsDeviceCreate();
 void rsDeviceDestroy(RsDevice dev);
 void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value);
 RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion);
-RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion, RsSurfaceConfig sc, uint32_t dpi);
+RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion,
+                            RsSurfaceConfig sc, uint32_t dpi);
 
 #include "rsgApiFuncDecl.h"
 
diff --git a/libs/rs/driver/rsdFrameBuffer.cpp b/libs/rs/driver/rsdFrameBuffer.cpp
index 8c1b12d..bb07d29 100644
--- a/libs/rs/driver/rsdFrameBuffer.cpp
+++ b/libs/rs/driver/rsdFrameBuffer.cpp
@@ -33,11 +33,11 @@
     RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv;
 
     DrvAllocation *depth = NULL;
-    if (fb->mHal.state.depthTarget.get() != NULL) {
+    if (fb->mHal.state.depthTarget != NULL) {
         depth = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv;
 
         if (depth->uploadDeferred) {
-            rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget.get(),
+            rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget,
                                  RS_ALLOCATION_USAGE_SCRIPT);
         }
     }
@@ -49,11 +49,11 @@
     // Now attach color targets
     for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
         DrvAllocation *color = NULL;
-        if (fb->mHal.state.colorTargets[i].get() != NULL) {
+        if (fb->mHal.state.colorTargets[i] != NULL) {
             color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv;
 
             if (color->uploadDeferred) {
-                rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i].get(),
+                rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i],
                                      RS_ALLOCATION_USAGE_SCRIPT);
             }
         }
@@ -79,10 +79,10 @@
     setColorAttachment(rsc, fb);
 
     RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv;
-    if (fb->mHal.state.colorTargets[0].get()) {
+    if (fb->mHal.state.colorTargets[0]) {
         fbo->setDimensions(fb->mHal.state.colorTargets[0]->getType()->getDimX(),
                            fb->mHal.state.colorTargets[0]->getType()->getDimY());
-    } else if (fb->mHal.state.depthTarget.get()) {
+    } else if (fb->mHal.state.depthTarget) {
         fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(),
                            fb->mHal.state.depthTarget->getType()->getDimY());
     }
diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp
index 019167b..24a7183 100644
--- a/libs/rs/driver/rsdMeshObj.cpp
+++ b/libs/rs/driver/rsdMeshObj.cpp
@@ -138,7 +138,7 @@
     }
 
     for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
-        const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct].get();
+        const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct];
         DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
         if (drv->uploadDeferred) {
             rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT);
@@ -148,7 +148,7 @@
     // update attributes with either buffer information or data ptr based on their current state
     for (uint32_t ct=0; ct < mAttribCount; ct++) {
         uint32_t allocIndex = mAttribAllocationIndex[ct];
-        Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex].get();
+        Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex];
         DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv;
 
         if (drvAlloc->bufferID) {
@@ -163,8 +163,7 @@
     RsdVertexArray va(mAttribs, mAttribCount);
     va.setup(rsc);
 
-    Mesh::Primitive_t *prim = mRSMesh->mHal.state.primitives[primIndex];
-    const Allocation *idxAlloc = prim->mIndexBuffer.get();
+    const Allocation *idxAlloc = mRSMesh->mHal.state.indexBuffers[primIndex];
     if (idxAlloc) {
         DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv;
         if (drvAlloc->uploadDeferred) {
@@ -190,7 +189,7 @@
 void RsdMeshObj::updateGLPrimitives() {
     mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
     for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
-        switch (mRSMesh->mHal.state.primitives[i]->mPrimitive) {
+        switch (mRSMesh->mHal.state.primitives[i]) {
             case RS_PRIMITIVE_POINT:          mGLPrimitives[i] = GL_POINTS; break;
             case RS_PRIMITIVE_LINE:           mGLPrimitives[i] = GL_LINES; break;
             case RS_PRIMITIVE_LINE_STRIP:     mGLPrimitives[i] = GL_LINE_STRIP; break;
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp
index 27a6663..7556e50 100644
--- a/libs/rs/driver/rsdProgram.cpp
+++ b/libs/rs/driver/rsdProgram.cpp
@@ -43,7 +43,7 @@
 
 static void SyncProgramConstants(const Context *rsc, const Program *p) {
     for (uint32_t ct=0; ct < p->mHal.state.texturesCount; ct++) {
-        const Allocation *a = p->mHal.state.textures[ct].get();
+        const Allocation *a = p->mHal.state.textures[ct];
         if (!a) {
             continue;
         }
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index 16ff063..bdb60c2 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -69,7 +69,7 @@
     uint32_t attribCount = 0;
     uint32_t uniformCount = 0;
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
-        initAddUserElement(mRSProgram->mHal.state.inputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
+        initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
     }
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
         initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
@@ -89,7 +89,7 @@
 String8 RsdShader::getGLSLInputString() const {
     String8 s;
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
-        const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
+        const Element *e = mRSProgram->mHal.state.inputElements[ct];
         for (uint32_t field=0; field < e->getFieldCount(); field++) {
             const Element *f = e->getField(field);
 
@@ -113,7 +113,7 @@
 
 void RsdShader::appendAttributes() {
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
-        const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
+        const Element *e = mRSProgram->mHal.state.inputElements[ct];
         for (uint32_t field=0; field < e->getFieldCount(); field++) {
             const Element *f = e->getField(field);
             const char *fn = e->getFieldName(field);
@@ -414,7 +414,7 @@
         RSD_CALL_GL(glActiveTexture, GL_TEXTURE0 + ct);
         RSD_CALL_GL(glUniform1i, sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
 
-        if (!mRSProgram->mHal.state.textures[ct].get()) {
+        if (!mRSProgram->mHal.state.textures[ct]) {
             // if nothing is bound, reset to default GL texture
             RSD_CALL_GL(glBindTexture, mTextureTargets[ct], 0);
             continue;
@@ -427,9 +427,9 @@
         }
         RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID);
         rsdGLCheckError(rsc, "ProgramFragment::setup tex bind");
-        if (mRSProgram->mHal.state.samplers[ct].get()) {
-            setupSampler(rsc, mRSProgram->mHal.state.samplers[ct].get(),
-                         mRSProgram->mHal.state.textures[ct].get());
+        if (mRSProgram->mHal.state.samplers[ct]) {
+            setupSampler(rsc, mRSProgram->mHal.state.samplers[ct],
+                         mRSProgram->mHal.state.textures[ct]);
         } else {
             RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
             RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -448,7 +448,7 @@
 void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) {
     uint32_t uidx = 0;
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
-        Allocation *alloc = mRSProgram->mHal.state.constants[ct].get();
+        Allocation *alloc = mRSProgram->mHal.state.constants[ct];
         if (!alloc) {
             LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set",
                  (uint32_t)this, ct);
@@ -504,7 +504,7 @@
 void RsdShader::initAttribAndUniformArray() {
     mAttribCount = 0;
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
-        const Element *elem = mRSProgram->mHal.state.inputElements[ct].get();
+        const Element *elem = mRSProgram->mHal.state.inputElements[ct];
         for (uint32_t field=0; field < elem->getFieldCount(); field++) {
             if (elem->getFieldName(field)[0] != '#') {
                 mAttribCount ++;
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 4359d95..e732630 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -30,7 +30,7 @@
     mHal.state.usageFlags = usages;
     mHal.state.mipmapControl = mc;
 
-    mHal.state.type.set(type);
+    setType(type);
     updateCache();
 }
 
@@ -47,7 +47,7 @@
 }
 
 void Allocation::updateCache() {
-    const Type *type = mHal.state.type.get();
+    const Type *type = mHal.state.type;
     mHal.state.dimensionX = type->getDimX();
     mHal.state.dimensionY = type->getDimY();
     mHal.state.dimensionZ = type->getDimZ();
@@ -187,7 +187,7 @@
 
     String8 s(prefix);
     s.append(" type ");
-    if (mHal.state.type.get()) {
+    if (mHal.state.type) {
         mHal.state.type->dumpLOGV(s.string());
     }
 
@@ -314,7 +314,7 @@
         decRefs(getPtr(), oldDimX - dimX, dimX);
     }
     rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
-    mHal.state.type.set(t.get());
+    setType(t.get());
     updateCache();
 }
 
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 67fc3b5..714798a 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -41,7 +41,7 @@
         void * drv;
 
         struct State {
-            ObjectBaseRef<const Type> type;
+            const Type * type;
 
             uint32_t usageFlags;
             RsAllocationMipmapControl mipmapControl;
@@ -71,7 +71,7 @@
     void updateCache();
 
     void * getPtr() const {return mHal.drvState.mallocPtr;}
-    const Type * getType() const {return mHal.state.type.get();}
+    const Type * getType() const {return mHal.state.type;}
 
     void syncAll(Context *rsc, RsAllocationUsageType src);
 
@@ -126,6 +126,11 @@
 
 protected:
     Vector<const Program *> mToDirtyList;
+    ObjectBaseRef<const Type> mType;
+    void setType(const Type *t) {
+        mType.set(t);
+        mHal.state.type = t;
+    }
 
 private:
     void freeChildrenUnlocked();
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index d6ab0da..71e1b91 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -364,7 +364,7 @@
 }
 
 void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids,
-                              const char **names, uint32_t dataSize) {
+                              const char **names, uint32_t *arraySizes, uint32_t dataSize) {
     Element *e = static_cast<Element *>(elem);
     rsAssert(e->getFieldCount() == dataSize);
 
@@ -372,5 +372,6 @@
         e->getField(i)->incUserRef();
         ids[i] = (uint32_t)e->getField(i);
         names[i] = e->getFieldName(i);
+        arraySizes[i] = e->getFieldArraySize(i);
     }
 }
diff --git a/libs/rs/rsFBOCache.cpp b/libs/rs/rsFBOCache.cpp
index c5c64c2..f4a8bc6 100644
--- a/libs/rs/rsFBOCache.cpp
+++ b/libs/rs/rsFBOCache.cpp
@@ -26,11 +26,14 @@
 FBOCache::FBOCache() {
     mDirty = true;
     mHal.state.colorTargetsCount = 1;
-    mHal.state.colorTargets = new ObjectBaseRef<Allocation>[mHal.state.colorTargetsCount];
+    mHal.state.colorTargets = new Allocation*[mHal.state.colorTargetsCount];
+    mColorTargets = new ObjectBaseRef<Allocation>[mHal.state.colorTargetsCount];
+    resetAll(NULL);
 }
 
 FBOCache::~FBOCache() {
     delete[] mHal.state.colorTargets;
+    delete[] mColorTargets;
 }
 
 void FBOCache::init(Context *rsc) {
@@ -52,7 +55,8 @@
             return;
         }
     }
-    mHal.state.colorTargets[slot].set(a);
+    mColorTargets[slot].set(a);
+    mHal.state.colorTargets[slot] = a;
     mDirty = true;
 }
 
@@ -63,15 +67,18 @@
             return;
         }
     }
-    mHal.state.depthTarget.set(a);
+    mDepthTarget.set(a);
+    mHal.state.depthTarget = a;
     mDirty = true;
 }
 
 void FBOCache::resetAll(Context *) {
     for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) {
-        mHal.state.colorTargets[i].set(NULL);
+        mColorTargets[i].set(NULL);
+        mHal.state.colorTargets[i] = NULL;
     }
-    mHal.state.depthTarget.set(NULL);
+    mDepthTarget.set(NULL);
+    mHal.state.depthTarget = NULL;
     mDirty = true;
 }
 
diff --git a/libs/rs/rsFBOCache.h b/libs/rs/rsFBOCache.h
index 5d58ba4..abb84de 100644
--- a/libs/rs/rsFBOCache.h
+++ b/libs/rs/rsFBOCache.h
@@ -44,15 +44,17 @@
         mutable void *drv;
 
         struct State {
-            ObjectBaseRef<Allocation> *colorTargets;
+            Allocation **colorTargets;
             uint32_t colorTargetsCount;
-            ObjectBaseRef<Allocation> depthTarget;
+            Allocation *depthTarget;
         };
         State state;
     };
     Hal mHal;
 
 protected:
+    ObjectBaseRef<Allocation> *mColorTargets;
+    ObjectBaseRef<Allocation> mDepthTarget;
     bool mDirty;
     void checkError(Context *);
     void setColorAttachment(Context *rsc);
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 359d09f..bf9284f 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -23,9 +23,14 @@
     mHal.drv = NULL;
     mHal.state.primitives = NULL;
     mHal.state.primitivesCount = 0;
+    mHal.state.indexBuffers = NULL;
+    mHal.state.indexBuffersCount = 0;
     mHal.state.vertexBuffers = NULL;
     mHal.state.vertexBuffersCount = 0;
     mInitialized = false;
+
+    mVertexBuffers = NULL;
+    mIndexBuffers = NULL;
 }
 
 Mesh::Mesh(Context *rsc,
@@ -33,12 +38,23 @@
            uint32_t primitivesCount) : ObjectBase(rsc) {
     mHal.drv = NULL;
     mHal.state.primitivesCount = primitivesCount;
-    mHal.state.primitives = new Primitive_t *[mHal.state.primitivesCount];
+    mHal.state.indexBuffersCount = primitivesCount;
+    mHal.state.primitives = new RsPrimitive[mHal.state.primitivesCount];
+    mHal.state.indexBuffers = new Allocation *[mHal.state.indexBuffersCount];
     for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
-        mHal.state.primitives[i] = new Primitive_t;
+        mHal.state.primitives[i] = RS_PRIMITIVE_POINT;
+    }
+    for (uint32_t i = 0; i < mHal.state.indexBuffersCount; i ++) {
+        mHal.state.indexBuffers[i] = NULL;
     }
     mHal.state.vertexBuffersCount = vertexBuffersCount;
-    mHal.state.vertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
+    mHal.state.vertexBuffers = new Allocation *[mHal.state.vertexBuffersCount];
+    for (uint32_t i = 0; i < mHal.state.vertexBuffersCount; i ++) {
+        mHal.state.vertexBuffers[i] = NULL;
+    }
+
+    mVertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
+    mIndexBuffers = new ObjectBaseRef<Allocation>[mHal.state.primitivesCount];
 }
 
 Mesh::~Mesh() {
@@ -46,17 +62,12 @@
     mRSC->mHal.funcs.mesh.destroy(mRSC, this);
 #endif
 
-    if (mHal.state.vertexBuffers) {
-        delete[] mHal.state.vertexBuffers;
-    }
+    delete[] mHal.state.vertexBuffers;
+    delete[] mHal.state.primitives;
+    delete[] mHal.state.indexBuffers;
 
-    if (mHal.state.primitives) {
-        for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
-            mHal.state.primitives[i]->mIndexBuffer.clear();
-            delete mHal.state.primitives[i];
-        }
-        delete[] mHal.state.primitives;
-    }
+    delete[] mVertexBuffers;
+    delete[] mIndexBuffers;
 }
 
 void Mesh::init() {
@@ -81,13 +92,11 @@
     stream->addU32(mHal.state.primitivesCount);
     // Store the primitives
     for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
-        Primitive_t * prim = mHal.state.primitives[pCount];
+        stream->addU8((uint8_t)mHal.state.primitives[pCount]);
 
-        stream->addU8((uint8_t)prim->mPrimitive);
-
-        if (prim->mIndexBuffer.get()) {
+        if (mHal.state.indexBuffers[pCount]) {
             stream->addU32(1);
-            prim->mIndexBuffer->serialize(stream);
+            mHal.state.indexBuffers[pCount]->serialize(stream);
         } else {
             stream->addU32(0);
         }
@@ -173,10 +182,8 @@
         return;
     }
 
-    Primitive_t *prim = mHal.state.primitives[primIndex];
-
-    if (prim->mIndexBuffer.get()) {
-        renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
+    if (mHal.state.indexBuffers[primIndex]) {
+        renderPrimitiveRange(rsc, primIndex, 0, mHal.state.indexBuffers[primIndex]->getType()->getDimX());
         return;
     }
 
@@ -194,14 +201,14 @@
 
 void Mesh::uploadAll(Context *rsc) {
     for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
-        if (mHal.state.vertexBuffers[ct].get()) {
-            rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.vertexBuffers[ct].get());
+        if (mHal.state.vertexBuffers[ct]) {
+            rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.vertexBuffers[ct]);
         }
     }
 
     for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
-        if (mHal.state.primitives[ct]->mIndexBuffer.get()) {
-            rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.primitives[ct]->mIndexBuffer.get());
+        if (mHal.state.indexBuffers[ct]) {
+            rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.indexBuffers[ct]);
         }
     }
 }
@@ -290,7 +297,7 @@
     rsAssert(vtxDataCount == sm->mHal.state.vertexBuffersCount);
 
     for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
-        vtxData[ct] = sm->mHal.state.vertexBuffers[ct].get();
+        vtxData[ct] = sm->mHal.state.vertexBuffers[ct];
         sm->mHal.state.vertexBuffers[ct]->incUserRef();
     }
 }
@@ -300,10 +307,10 @@
     rsAssert(idxDataCount == sm->mHal.state.primitivesCount);
 
     for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
-        va[ct] = sm->mHal.state.primitives[ct]->mIndexBuffer.get();
-        primType[ct] = sm->mHal.state.primitives[ct]->mPrimitive;
-        if (sm->mHal.state.primitives[ct]->mIndexBuffer.get()) {
-            sm->mHal.state.primitives[ct]->mIndexBuffer->incUserRef();
+        va[ct] = sm->mHal.state.indexBuffers[ct];
+        primType[ct] = sm->mHal.state.primitives[ct];
+        if (sm->mHal.state.indexBuffers[ct]) {
+            sm->mHal.state.indexBuffers[ct]->incUserRef();
         }
     }
 }
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index ed1e93d..0fc73fb 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -32,13 +32,6 @@
     Mesh(Context *, uint32_t vertexBuffersCount, uint32_t primitivesCount);
     ~Mesh();
 
-    // Either mIndexBuffer, mPrimitiveBuffer or both could have a NULL reference
-    // If both are null, mPrimitive only would be used to render the mesh
-    struct Primitive_t {
-        ObjectBaseRef<Allocation> mIndexBuffer;
-        RsPrimitive mPrimitive;
-    };
-
     virtual void serialize(OStream *stream) const;
     virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
     static Mesh *createFromStream(Context *rsc, IStream *stream);
@@ -51,10 +44,13 @@
             // Contains vertex data
             // Position, normal, texcoord, etc could either be strided in one allocation
             // of provided separetely in multiple ones
-            ObjectBaseRef<Allocation> *vertexBuffers;
+            Allocation **vertexBuffers;
             uint32_t vertexBuffersCount;
 
-            Primitive_t ** primitives;
+            // indexBuffers[i] could be NULL, in which case only primitives[i] is used
+            Allocation **indexBuffers;
+            uint32_t indexBuffersCount;
+            RsPrimitive *primitives;
             uint32_t primitivesCount;
         };
         State state;
@@ -62,12 +58,14 @@
     Hal mHal;
 
     void setVertexBuffer(Allocation *vb, uint32_t index) {
-        mHal.state.vertexBuffers[index].set(vb);
+        mVertexBuffers[index].set(vb);
+        mHal.state.vertexBuffers[index] = vb;
     }
 
     void setPrimitive(Allocation *idx, RsPrimitive prim, uint32_t index) {
-        mHal.state.primitives[index]->mIndexBuffer.set(idx);
-        mHal.state.primitives[index]->mPrimitive = prim;
+        mIndexBuffers[index].set(idx);
+        mHal.state.indexBuffers[index] = idx;
+        mHal.state.primitives[index] = prim;
     }
 
     void render(Context *) const;
@@ -80,6 +78,8 @@
     float mBBoxMax[3];
     void computeBBox();
 protected:
+    ObjectBaseRef<Allocation> *mVertexBuffers;
+    ObjectBaseRef<Allocation> *mIndexBuffers;
     bool mInitialized;
 };
 
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 4178aa5..a9fd877 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -37,22 +37,33 @@
         }
     }
 
-    mHal.state.textures = new ObjectBaseRef<Allocation>[mHal.state.texturesCount];
-    mHal.state.samplers = new ObjectBaseRef<Sampler>[mHal.state.texturesCount];
+    mTextures = new ObjectBaseRef<Allocation>[mHal.state.texturesCount];
+    mSamplers = new ObjectBaseRef<Sampler>[mHal.state.texturesCount];
+    mInputElements = new ObjectBaseRef<Element>[mHal.state.inputElementsCount];
+    mConstantTypes = new ObjectBaseRef<Type>[mHal.state.constantsCount];
+    mConstants = new ObjectBaseRef<Allocation>[mHal.state.constantsCount];
+
+    mHal.state.textures = new Allocation*[mHal.state.texturesCount];
+    mHal.state.samplers = new Sampler*[mHal.state.texturesCount];
     mHal.state.textureTargets = new RsTextureTarget[mHal.state.texturesCount];
-    mHal.state.inputElements = new ObjectBaseRef<Element>[mHal.state.inputElementsCount];
-    mHal.state.constantTypes = new ObjectBaseRef<Type>[mHal.state.constantsCount];
-    mHal.state.constants = new ObjectBaseRef<Allocation>[mHal.state.constantsCount];
+    mHal.state.inputElements = new Element*[mHal.state.inputElementsCount];
+    mHal.state.constantTypes = new Type*[mHal.state.constantsCount];
+    mHal.state.constants = new Allocation*[mHal.state.constantsCount];
+
+    // Will initialize everything
+    freeChildren();
 
     uint32_t input = 0;
     uint32_t constant = 0;
     uint32_t texture = 0;
     for (uint32_t ct=0; ct < paramLength; ct+=2) {
         if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
-            mHal.state.inputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
+            mInputElements[input].set(reinterpret_cast<Element *>(params[ct+1]));
+            mHal.state.inputElements[input++] = reinterpret_cast<Element *>(params[ct+1]);
         }
         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
-            mHal.state.constantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
+            mConstantTypes[constant].set(reinterpret_cast<Type *>(params[ct+1]));
+            mHal.state.constantTypes[constant++] = reinterpret_cast<Type *>(params[ct+1]);
         }
         if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
             mHal.state.textureTargets[texture++] = (RsTextureTarget)params[ct+1];
@@ -72,6 +83,12 @@
 Program::~Program() {
     freeChildren();
 
+    delete[] mTextures;
+    delete[] mSamplers;
+    delete[] mInputElements;
+    delete[] mConstantTypes;
+    delete[] mConstants;
+
     delete[] mHal.state.textures;
     delete[] mHal.state.samplers;
     delete[] mHal.state.textureTargets;
@@ -110,6 +127,12 @@
     mHal.state.constantsCount = 0;
     mHal.state.texturesCount = 0;
 
+    mTextures = NULL;
+    mSamplers = NULL;
+    mInputElements = NULL;
+    mConstantTypes = NULL;
+    mConstants = NULL;
+
     mIsInternal = false;
 }
 
@@ -121,20 +144,21 @@
             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
             return;
         }
-        if (alloc->getType() != mHal.state.constantTypes[slot].get()) {
+        if (alloc->getType() != mConstantTypes[slot].get()) {
             LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
                  slot, (uint32_t)this);
             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
             return;
         }
     }
-    if (mHal.state.constants[slot].get() == alloc) {
+    if (mConstants[slot].get() == alloc) {
         return;
     }
-    if (mHal.state.constants[slot].get()) {
-        mHal.state.constants[slot].get()->removeProgramToDirty(this);
+    if (mConstants[slot].get()) {
+        mConstants[slot]->removeProgramToDirty(this);
     }
-    mHal.state.constants[slot].set(alloc);
+    mConstants[slot].set(alloc);
+    mHal.state.constants[slot] = alloc;
     if (alloc) {
         alloc->addProgramToDirty(this);
     }
@@ -154,7 +178,9 @@
         return;
     }
 
-    mHal.state.textures[slot].set(a);
+    mTextures[slot].set(a);
+    mHal.state.textures[slot] = a;
+
     mDirty = true;
 }
 
@@ -165,7 +191,8 @@
         return;
     }
 
-    mHal.state.samplers[slot].set(s);
+    mSamplers[slot].set(s);
+    mHal.state.samplers[slot] = s;
     mDirty = true;
 }
 
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index 3237a72..06fc3ec 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -30,6 +30,33 @@
 
 class Program : public ProgramBase {
 public:
+    struct Hal {
+        mutable void *drv;
+
+        struct State {
+            // The difference between Textures and Constants is how they are accessed
+            // Texture lookups go though a sampler which in effect converts normalized
+            // coordinates into type specific.  Multiple samples may also be taken
+            // and filtered.
+            //
+            // Constants are strictly accessed by the shader code
+            Allocation **textures;
+            RsTextureTarget *textureTargets;
+            uint32_t texturesCount;
+
+            Sampler **samplers;
+            uint32_t samplersCount;
+
+            Allocation **constants;
+            Type **constantTypes;
+            uint32_t constantsCount;
+
+            Element **inputElements;
+            uint32_t inputElementsCount;
+        };
+        State state;
+    };
+    Hal mHal;
 
     Program(Context *, const char * shaderText, uint32_t shaderLength,
                        const uint32_t * params, uint32_t paramLength);
@@ -43,35 +70,13 @@
     void bindTexture(Context *, uint32_t slot, Allocation *);
     void bindSampler(Context *, uint32_t slot, Sampler *);
 
-    struct Hal {
-        mutable void *drv;
-
-        struct State {
-            // The difference between Textures and Constants is how they are accessed
-            // Texture lookups go though a sampler which in effect converts normalized
-            // coordinates into type specific.  Multiple samples may also be taken
-            // and filtered.
-            //
-            // Constants are strictly accessed by the shader code
-            ObjectBaseRef<Allocation> *textures;
-            RsTextureTarget *textureTargets;
-            uint32_t texturesCount;
-
-            ObjectBaseRef<Sampler> *samplers;
-            uint32_t samplersCount;
-
-            ObjectBaseRef<Allocation> *constants;
-            ObjectBaseRef<Type> *constantTypes;
-            uint32_t constantsCount;
-
-            ObjectBaseRef<Element> *inputElements;
-            uint32_t inputElementsCount;
-        };
-        State state;
-    };
-    Hal mHal;
-
 protected:
+    ObjectBaseRef<Allocation> *mTextures;
+    ObjectBaseRef<Sampler> *mSamplers;
+    ObjectBaseRef<Allocation> *mConstants;
+    ObjectBaseRef<Type> *mConstantTypes;
+    ObjectBaseRef<Element> *mInputElements;
+
     bool mIsInternal;
     String8 mUserShader;
     void initMemberVars();
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index ff29520..81eedc4 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -42,7 +42,7 @@
         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot  set fixed function emulation color on user program");
         return;
     }
-    if (mHal.state.constants[0].get() == NULL) {
+    if (mHal.state.constants[0] == NULL) {
         LOGE("Unable to set fixed function emulation color because allocation is missing");
         rsc->setError(RS_ERROR_BAD_SHADER, "Unable to set fixed function emulation color because allocation is missing");
         return;
@@ -62,7 +62,7 @@
     state->mLast.set(this);
 
     for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
-        if (!mHal.state.textures[ct].get()) {
+        if (!mHal.state.textures[ct]) {
             LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
             rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
             continue;
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 51cb2a8a..4a13622 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -38,7 +38,7 @@
     }
 
     if (!isUserProgram()) {
-        if (mHal.state.constants[0].get() == NULL) {
+        if (mHal.state.constants[0] == NULL) {
             rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                           "Unable to set fixed function emulation matrices because allocation is missing");
             return;
@@ -65,7 +65,7 @@
                       "Attempting to set fixed function emulation matrix projection on user program");
         return;
     }
-    if (mHal.state.constants[0].get() == NULL) {
+    if (mHal.state.constants[0] == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to set fixed function emulation matrix projection because allocation is missing");
         return;
@@ -81,7 +81,7 @@
                       "Attempting to set fixed function emulation matrix modelview on user program");
         return;
     }
-    if (mHal.state.constants[0].get() == NULL) {
+    if (mHal.state.constants[0] == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to set fixed function emulation matrix modelview because allocation is missing");
         return;
@@ -97,7 +97,7 @@
                       "Attempting to set fixed function emulation matrix texture on user program");
         return;
     }
-    if (mHal.state.constants[0].get() == NULL) {
+    if (mHal.state.constants[0] == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to set fixed function emulation matrix texture because allocation is missing");
         return;
@@ -113,7 +113,7 @@
                       "Attempting to get fixed function emulation matrix projection on user program");
         return;
     }
-    if (mHal.state.constants[0].get() == NULL) {
+    if (mHal.state.constants[0] == NULL) {
         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
                       "Unable to get fixed function emulation matrix projection because allocation is missing");
         return;
diff --git a/libs/rs/scriptc/rs_quaternion.rsh b/libs/rs/scriptc/rs_quaternion.rsh
index 23945ae..4e08d2f 100644
--- a/libs/rs/scriptc/rs_quaternion.rsh
+++ b/libs/rs/scriptc/rs_quaternion.rsh
@@ -66,19 +66,6 @@
 }
 
 /**
- * Multiply quaternion by another quaternion
- * @param q destination quaternion
- * @param rhs right hand side quaternion to multiply by
- */
-static void __attribute__((overloadable))
-rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
-    q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
-    q->x =  q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
-    q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
-    q->z =  q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
-}
-
-/**
  * Add two quaternions
  * @param q destination quaternion to add to
  * @param rsh right hand side quaternion to add
@@ -168,6 +155,23 @@
 }
 
 /**
+ * Multiply quaternion by another quaternion
+ * @param q destination quaternion
+ * @param rhs right hand side quaternion to multiply by
+ */
+static void __attribute__((overloadable))
+rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
+    rs_quaternion qtmp;
+    rsQuaternionSet(&qtmp, q);
+
+    q->w = qtmp.w*rhs->w - qtmp.x*rhs->x - qtmp.y*rhs->y - qtmp.z*rhs->z;
+    q->x = qtmp.w*rhs->x + qtmp.x*rhs->w + qtmp.y*rhs->z - qtmp.z*rhs->y;
+    q->y = qtmp.w*rhs->y + qtmp.y*rhs->w + qtmp.z*rhs->x - qtmp.x*rhs->z;
+    q->z = qtmp.w*rhs->z + qtmp.z*rhs->w + qtmp.x*rhs->y - qtmp.y*rhs->x;
+    rsQuaternionNormalize(q);
+}
+
+/**
  * Performs spherical linear interpolation between two quaternions
  * @param q result quaternion from interpolation
  * @param q0 first param
@@ -222,34 +226,26 @@
  * @param p normalized quaternion
  */
 static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
-    float x2 = 2.0f * q->x * q->x;
-    float y2 = 2.0f * q->y * q->y;
-    float z2 = 2.0f * q->z * q->z;
-    float xy = 2.0f * q->x * q->y;
-    float wz = 2.0f * q->w * q->z;
-    float xz = 2.0f * q->x * q->z;
-    float wy = 2.0f * q->w * q->y;
-    float wx = 2.0f * q->w * q->x;
-    float yz = 2.0f * q->y * q->z;
+    float xx = q->x * q->x;
+    float xy = q->x * q->y;
+    float xz = q->x * q->z;
+    float xw = q->x * q->w;
+    float yy = q->y * q->y;
+    float yz = q->y * q->z;
+    float yw = q->y * q->w;
+    float zz = q->z * q->z;
+    float zw = q->z * q->w;
 
-    m->m[0] = 1.0f - y2 - z2;
-    m->m[1] = xy - wz;
-    m->m[2] = xz + wy;
-    m->m[3] = 0.0f;
-
-    m->m[4] = xy + wz;
-    m->m[5] = 1.0f - x2 - z2;
-    m->m[6] = yz - wx;
-    m->m[7] = 0.0f;
-
-    m->m[8] = xz - wy;
-    m->m[9] = yz - wx;
-    m->m[10] = 1.0f - x2 - y2;
-    m->m[11] = 0.0f;
-
-    m->m[12] = 0.0f;
-    m->m[13] = 0.0f;
-    m->m[14] = 0.0f;
+    m->m[0]  = 1.0f - 2.0f * ( yy + zz );
+    m->m[4]  =        2.0f * ( xy - zw );
+    m->m[8]  =        2.0f * ( xz + yw );
+    m->m[1]  =        2.0f * ( xy + zw );
+    m->m[5]  = 1.0f - 2.0f * ( xx + zz );
+    m->m[9]  =        2.0f * ( yz - xw );
+    m->m[2]  =        2.0f * ( xz - yw );
+    m->m[6]  =        2.0f * ( yz + xw );
+    m->m[10] = 1.0f - 2.0f * ( xx + yy );
+    m->m[3]  = m->m[7] = m->m[11] = m->m[12] = m->m[13] = m->m[14] = 0.0f;
     m->m[15] = 1.0f;
 }
 
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 638f72f..831d9e3 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -71,6 +71,10 @@
 endif
 endif
 
+ifeq ($(TARGET_OS),linux)
+LOCAL_LDLIBS += -lrt -ldl
+endif
+
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index d3aab08..7d2fbce 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -38,6 +38,7 @@
     SET_PARAMETER,
     GET_CONFIG,
     SET_CONFIG,
+    GET_STATE,
     ENABLE_GRAPHIC_BUFFERS,
     USE_BUFFER,
     USE_GRAPHIC_BUFFER,
@@ -198,6 +199,17 @@
         return reply.readInt32();
     }
 
+    virtual status_t getState(
+            node_id node, OMX_STATETYPE* state) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeIntPtr((intptr_t)node);
+        remote()->transact(GET_STATE, data, &reply);
+
+        *state = static_cast<OMX_STATETYPE>(reply.readInt32());
+        return reply.readInt32();
+    }
+
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable) {
         Parcel data, reply;
@@ -524,6 +536,20 @@
             return NO_ERROR;
         }
 
+        case GET_STATE:
+        {
+            CHECK_INTERFACE(IOMX, data, reply);
+
+            node_id node = (void*)data.readIntPtr();
+            OMX_STATETYPE state = OMX_StateInvalid;
+
+            status_t err = getState(node, &state);
+            reply->writeInt32(state);
+            reply->writeInt32(err);
+
+            return NO_ERROR;
+        }
+
         case ENABLE_GRAPHIC_BUFFERS:
         {
             CHECK_INTERFACE(IOMX, data, reply);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 24e1bfb..2ea2af9 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -374,11 +374,13 @@
         } else {
             for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
                 sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
-                snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid);
-                result.append(buffer);
-                write(fd, result.string(), result.size());
-                result = "\n";
-                c->dump(fd, args);
+                if (c != 0) {
+                    snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid);
+                    result.append(buffer);
+                    write(fd, result.string(), result.size());
+                    result = "\n";
+                    c->dump(fd, args);
+                }
             }
         }
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index f9cb882..7e55790 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3618,11 +3618,24 @@
         mAsyncCompletion.wait(mLock);
     }
 
+    bool isError = false;
     switch (mState) {
         case LOADED:
-        case ERROR:
             break;
 
+        case ERROR:
+        {
+            OMX_STATETYPE state = OMX_StateInvalid;
+            status_t err = mOMX->getState(mNode, &state);
+            CHECK_EQ(err, (status_t)OK);
+
+            if (state != OMX_StateExecuting) {
+                break;
+            }
+            // else fall through to the idling code
+            isError = true;
+        }
+
         case EXECUTING:
         {
             setState(EXECUTING_TO_IDLE);
@@ -3657,6 +3670,12 @@
                 mAsyncCompletion.wait(mLock);
             }
 
+            if (isError) {
+                // We were in the ERROR state coming in, so restore that now
+                // that we've idled the OMX component.
+                setState(ERROR);
+            }
+
             break;
         }
 
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index d54b1c1..53e764f 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -59,6 +59,9 @@
             node_id node, OMX_INDEXTYPE index,
             const void *params, size_t size);
 
+    virtual status_t getState(
+            node_id node, OMX_STATETYPE* state);
+
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable);
 
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 1ccf50d..47ca579 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -49,6 +49,8 @@
     status_t getConfig(OMX_INDEXTYPE index, void *params, size_t size);
     status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size);
 
+    status_t getState(OMX_STATETYPE* state);
+
     status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
 
     status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 33d3f30..3715fe9 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -303,6 +303,12 @@
             index, params, size);
 }
 
+status_t OMX::getState(
+        node_id node, OMX_STATETYPE* state) {
+    return findInstance(node)->getState(
+            state);
+}
+
 status_t OMX::enableGraphicBuffers(
         node_id node, OMX_U32 port_index, OMX_BOOL enable) {
     return findInstance(node)->enableGraphicBuffers(port_index, enable);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index b612f89..0ff398a 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -266,6 +266,14 @@
     return StatusFromOMXError(err);
 }
 
+status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
+    Mutex::Autolock autoLock(mLock);
+
+    OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
+
+    return StatusFromOMXError(err);
+}
+
 status_t OMXNodeInstance::enableGraphicBuffers(
         OMX_U32 portIndex, OMX_BOOL enable) {
     Mutex::Autolock autoLock(mLock);
diff --git a/packages/SystemUI/res/anim/recent_appear.xml b/packages/SystemUI/res/anim/recent_appear.xml
index 20fe052..4400d9d 100644
--- a/packages/SystemUI/res/anim/recent_appear.xml
+++ b/packages/SystemUI/res/anim/recent_appear.xml
@@ -16,5 +16,5 @@
 
 <alpha xmlns:android="http://schemas.android.com/apk/res/android"
     android:fromAlpha="0.0" android:toAlpha="1.0"
-    android:duration="@android:integer/config_mediumAnimTime"
+    android:duration="@android:integer/config_shortAnimTime"
     />
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_image.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_image.png
new file mode 100644
index 0000000..319f925
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_image_error.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_image_error.png
new file mode 100644
index 0000000..fa8d4bf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_image_error.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_image.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_image.png
new file mode 100644
index 0000000..5036e8d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_image_error.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_image_error.png
new file mode 100644
index 0000000..94487bf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_image_error.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_notify_image.png b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image.png
new file mode 100644
index 0000000..3c5c082
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_notify_image_error.png b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image_error.png
new file mode 100644
index 0000000..8aa19e4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image_error.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index 83c4faf..2d76455 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -39,11 +39,11 @@
             android:layout_marginTop="@dimen/status_bar_recents_thumbnail_top_margin"
             android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
             android:background="@drawable/recents_thumbnail_bg"
-            android:foreground="@drawable/recents_thumbnail_fg">
+            android:foreground="@drawable/recents_thumbnail_fg"
+            android:visibility="invisible">
             <ImageView android:id="@+id/app_thumbnail_image"
                 android:layout_width="@dimen/status_bar_recents_thumbnail_width"
                 android:layout_height="@dimen/status_bar_recents_thumbnail_height"
-                android:visibility="invisible"
             />
         </FrameLayout>
 
@@ -58,7 +58,6 @@
             android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
             android:scaleType="centerInside"
             android:adjustViewBounds="true"
-            android:visibility="invisible"
         />
 
         <TextView android:id="@+id/app_label"
@@ -74,7 +73,6 @@
             android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin"
             android:singleLine="true"
             android:ellipsize="marquee"
-            android:visibility="invisible"
             android:textColor="@color/status_bar_recents_app_label_color"
         />
 
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index 3d8b9d6..b653fcd 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -52,11 +52,11 @@
             android:layout_toRightOf="@id/app_label"
             android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
             android:background="@drawable/recents_thumbnail_bg"
-            android:foreground="@drawable/recents_thumbnail_fg">
+            android:foreground="@drawable/recents_thumbnail_fg"
+            android:visibility="invisible">
             <ImageView android:id="@+id/app_thumbnail_image"
                 android:layout_width="@dimen/status_bar_recents_thumbnail_width"
                 android:layout_height="@dimen/status_bar_recents_thumbnail_height"
-                android:visibility="invisible"
             />
         </FrameLayout>
         <View android:id="@+id/recents_callout_line"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index e6336718..18a31f7 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -31,11 +31,11 @@
         android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
         android:scaleType="center"
         android:background="@drawable/recents_thumbnail_bg"
-        android:foreground="@drawable/recents_thumbnail_fg">
+        android:foreground="@drawable/recents_thumbnail_fg"
+        android:visibility="invisible">
         <ImageView android:id="@+id/app_thumbnail_image"
             android:layout_width="@dimen/status_bar_recents_thumbnail_width"
             android:layout_height="@dimen/status_bar_recents_thumbnail_height"
-            android:visibility="invisible"
         />
         <ImageView android:id="@+id/app_icon"
             android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 612c8e7..8108a90 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -169,7 +169,7 @@
     <string name="compat_mode_help_body">When an app was designed for a smaller screen, a zoom control will appear by the clock.</string>
 
     <!-- Notification ticker displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=30] -->
-    <string name="screenshot_saving_ticker">Saving\u2026</string>
+    <string name="screenshot_saving_ticker">Saving screenshot\u2026</string>
     <!-- Notification title displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=50] -->
     <string name="screenshot_saving_title">Saving screenshot\u2026</string>
     <!-- Notification text displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=100] -->
@@ -181,7 +181,7 @@
     <!-- Notification title displayed when we fail to take a screenshot. [CHAR LIMIT=50] -->
     <string name="screenshot_failed_title">Couldn\'t capture screenshot.</string>
     <!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
-    <string name="screenshot_failed_text">Couldn\'t save screenshot. External storage may be in use.</string>
+    <string name="screenshot_failed_text">Couldn\'t save screenshot. Storage may be in use.</string>
 
     <!-- Title for the USB function chooser in UsbPreferenceActivity. [CHAR LIMIT=30] -->
     <string name="usb_preference_title">USB file transfer options</string>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index 47aa849..dcda9c2 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -86,8 +86,8 @@
         mIconDpi = isTablet ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi;
 
         // Render the default thumbnail background
-        int width = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_width);
-        int height = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_height);
+        int width = (int) res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
+        int height = (int) res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
         int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background);
 
         mDefaultThumbnailBackground = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
@@ -106,6 +106,10 @@
         mRecentsPanel = recentsPanel;
     }
 
+    public Bitmap getDefaultThumbnail() {
+        return mDefaultThumbnailBackground;
+    }
+
     // Create an TaskDescription, returning null if the title or icon is null, or if it's the
     // home activity
     TaskDescription createTaskDescription(int taskId, int persistentTaskId, Intent baseIntent,
@@ -278,7 +282,7 @@
                             TaskDescription td = descriptions.get(i);
                             loadThumbnail(td);
                             long now = SystemClock.uptimeMillis();
-                            nextTime += 150;
+                            nextTime += 0;
                             if (nextTime > now) {
                                 try {
                                     Thread.sleep(nextTime-now);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index bd1fcfc..343b33514 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -37,6 +37,7 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
@@ -57,8 +58,8 @@
 import com.android.systemui.statusbar.tablet.StatusBarPanel;
 import com.android.systemui.statusbar.tablet.TabletStatusBar;
 
-public class RecentsPanelView extends RelativeLayout
-        implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener {
+public class RecentsPanelView extends RelativeLayout implements OnItemClickListener, RecentsCallback,
+        StatusBarPanel, Animator.AnimatorListener, View.OnTouchListener {
     static final String TAG = "RecentsPanelView";
     static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
     private Context mContext;
@@ -74,6 +75,7 @@
 
     private RecentTasksLoader mRecentTasksLoader;
     private ArrayList<TaskDescription> mRecentTaskDescriptions;
+    private boolean mRecentTasksDirty = true;
     private TaskDescriptionAdapter mListAdapter;
     private int mThumbnailWidth;
 
@@ -94,6 +96,7 @@
     /* package */ final static class ViewHolder {
         View thumbnailView;
         ImageView thumbnailViewImage;
+        Bitmap thumbnailViewImageBitmap;
         ImageView iconView;
         TextView labelView;
         TextView descriptionView;
@@ -127,6 +130,10 @@
                 holder.thumbnailView = convertView.findViewById(R.id.app_thumbnail);
                 holder.thumbnailViewImage = (ImageView) convertView.findViewById(
                         R.id.app_thumbnail_image);
+                // If we set the default thumbnail now, we avoid an onLayout when we update
+                // the thumbnail later (if they both have the same dimensions)
+                updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
+
                 holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
                 holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
                 holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
@@ -139,12 +146,15 @@
             // index is reverse since most recent appears at the bottom...
             final int index = mRecentTaskDescriptions.size() - position - 1;
 
-            final TaskDescription taskDescription = mRecentTaskDescriptions.get(index);
-            applyTaskDescription(holder, taskDescription, false);
+            final TaskDescription td = mRecentTaskDescriptions.get(index);
+            holder.iconView.setImageDrawable(td.getIcon());
+            holder.labelView.setText(td.getLabel());
+            holder.thumbnailView.setContentDescription(td.getLabel());
+            updateThumbnail(holder, td.getThumbnail(), true, false);
 
-            holder.thumbnailView.setTag(taskDescription);
+            holder.thumbnailView.setTag(td);
             holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView));
-            holder.taskDescription = taskDescription;
+            holder.taskDescription = td;
 
             return convertView;
         }
@@ -193,6 +203,7 @@
             }
         } else {
             mRecentTasksLoader.cancelLoadingThumbnails();
+            mRecentTasksDirty = true;
         }
         if (animate) {
             if (mShowing != show) {
@@ -250,9 +261,7 @@
             createCustomAnimations(transitioner);
         } else {
             ((ViewGroup)mRecentsContainer).setLayoutTransition(null);
-            // Clear memory used by screenshots
-            mRecentTaskDescriptions.clear();
-            mListAdapter.notifyDataSetInvalidated();
+            clearRecentTasksList();
         }
     }
 
@@ -374,47 +383,33 @@
         }
     }
 
-
-    void applyTaskDescription(ViewHolder h, TaskDescription td, boolean anim) {
-        h.iconView.setImageDrawable(td.getIcon());
-        if (h.iconView.getVisibility() != View.VISIBLE) {
-            if (anim) {
-                h.iconView.setAnimation(AnimationUtils.loadAnimation(
-                        mContext, R.anim.recent_appear));
-            }
-            h.iconView.setVisibility(View.VISIBLE);
-        }
-        h.labelView.setText(td.getLabel());
-        h.thumbnailView.setContentDescription(td.getLabel());
-        if (h.labelView.getVisibility() != View.VISIBLE) {
-            if (anim) {
-                h.labelView.setAnimation(AnimationUtils.loadAnimation(
-                        mContext, R.anim.recent_appear));
-            }
-            h.labelView.setVisibility(View.VISIBLE);
-        }
-        Bitmap thumbnail = td.getThumbnail();
+    private void updateThumbnail(ViewHolder h, Bitmap thumbnail, boolean show, boolean anim) {
         if (thumbnail != null) {
             // Should remove the default image in the frame
             // that this now covers, to improve scrolling speed.
             // That can't be done until the anim is complete though.
             h.thumbnailViewImage.setImageBitmap(thumbnail);
-            // scale to fill up the full width
-            Matrix scaleMatrix = new Matrix();
-            float scale = mThumbnailWidth / (float) thumbnail.getWidth();
-            scaleMatrix.setScale(scale, scale);
-            h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
-            h.thumbnailViewImage.setImageMatrix(scaleMatrix);
-            if (h.thumbnailViewImage.getVisibility() != View.VISIBLE) {
-                if (anim) {
-                    h.thumbnailViewImage.setAnimation(
-                            AnimationUtils.loadAnimation(
-                                    mContext, R.anim.recent_appear));
-                }
-                h.thumbnailViewImage.setVisibility(View.VISIBLE);
+
+            // scale the image to fill the full width of the ImageView. do this only if
+            // we haven't set a bitmap before, or if the bitmap size has changed
+            if (h.thumbnailViewImageBitmap == null ||
+                h.thumbnailViewImageBitmap.getWidth() != thumbnail.getWidth() ||
+                h.thumbnailViewImageBitmap.getHeight() != thumbnail.getHeight()) {
+                Matrix scaleMatrix = new Matrix();
+                float scale = mThumbnailWidth / (float) thumbnail.getWidth();
+                scaleMatrix.setScale(scale, scale);
+                h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
+                h.thumbnailViewImage.setImageMatrix(scaleMatrix);
             }
+            if (show && h.thumbnailView.getVisibility() != View.VISIBLE) {
+                if (anim) {
+                    h.thumbnailView.setAnimation(
+                            AnimationUtils.loadAnimation(mContext, R.anim.recent_appear));
+                }
+                h.thumbnailView.setVisibility(View.VISIBLE);
+            }
+            h.thumbnailViewImageBitmap = thumbnail;
         }
-        //h.descriptionView.setText(ad.description);
     }
 
     void onTaskThumbnailLoaded(TaskDescription ad) {
@@ -432,7 +427,11 @@
                     if (v.getTag() instanceof ViewHolder) {
                         ViewHolder h = (ViewHolder)v.getTag();
                         if (h.taskDescription == ad) {
-                            applyTaskDescription(h, ad, true);
+                            // only fade in the thumbnail if recents is already visible-- we
+                            // show it immediately otherwise
+                            boolean animateShow = mShowing &&
+                                mRecentsGlowView.getAlpha() > ViewConfiguration.ALPHA_THRESHOLD;
+                            updateThumbnail(h, ad.getThumbnail(), true, animateShow);
                         }
                     }
                 }
@@ -440,14 +439,55 @@
         }
     }
 
-    private void refreshRecentTasksList(ArrayList<TaskDescription> recentTasksList) {
-        if (recentTasksList != null) {
-            mRecentTaskDescriptions = recentTasksList;
-        } else {
-            mRecentTaskDescriptions = mRecentTasksLoader.getRecentTasks();
+    // additional optimization when we have sofware system buttons - start loading the recent
+    // tasks on touch down
+    @Override
+    public boolean onTouch(View v, MotionEvent ev) {
+        if (!mShowing) {
+            int action = ev.getAction() & MotionEvent.ACTION_MASK;
+            if (action == MotionEvent.ACTION_DOWN) {
+                // If we set our visibility to INVISIBLE here, we avoid an extra call to onLayout
+                // later when we become visible
+                setVisibility(INVISIBLE);
+                refreshRecentTasksList();
+            } else if (action == MotionEvent.ACTION_CANCEL) {
+                setVisibility(GONE);
+                clearRecentTasksList();
+            } else if (action == MotionEvent.ACTION_UP) {
+                if (!v.isPressed()) {
+                    setVisibility(GONE);
+                    clearRecentTasksList();
+                }
+            }
         }
-        mListAdapter.notifyDataSetInvalidated();
-        updateUiElements(getResources().getConfiguration());
+        return false;
+    }
+
+    public void clearRecentTasksList() {
+        // Clear memory used by screenshots
+        if (mRecentTaskDescriptions != null) {
+            mRecentTasksLoader.cancelLoadingThumbnails();
+            mRecentTaskDescriptions.clear();
+            mListAdapter.notifyDataSetInvalidated();
+            mRecentTasksDirty = true;
+        }
+    }
+
+    public void refreshRecentTasksList() {
+        refreshRecentTasksList(null);
+    }
+
+    private void refreshRecentTasksList(ArrayList<TaskDescription> recentTasksList) {
+        if (mRecentTasksDirty) {
+            if (recentTasksList != null) {
+                mRecentTaskDescriptions = recentTasksList;
+            } else {
+                mRecentTaskDescriptions = mRecentTasksLoader.getRecentTasks();
+            }
+            mListAdapter.notifyDataSetInvalidated();
+            updateUiElements(getResources().getConfiguration());
+            mRecentTasksDirty = false;
+        }
     }
 
     public ArrayList<TaskDescription> getRecentTasksList() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 301ae73..cc1b8ed 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -137,7 +137,7 @@
                     + (mTickerAddSpace ? " " : ""))
             .setContentTitle(r.getString(R.string.screenshot_saving_title))
             .setContentText(r.getString(R.string.screenshot_saving_text))
-            .setSmallIcon(android.R.drawable.ic_menu_gallery)
+            .setSmallIcon(R.drawable.stat_notify_image)
             .setWhen(System.currentTimeMillis());
         Notification n = mNotificationBuilder.getNotification();
         n.flags |= Notification.FLAG_NO_CLEAR;
@@ -544,7 +544,7 @@
             .setTicker(r.getString(R.string.screenshot_failed_title))
             .setContentTitle(r.getString(R.string.screenshot_failed_title))
             .setContentText(r.getString(R.string.screenshot_failed_text))
-            .setSmallIcon(android.R.drawable.ic_menu_report_image)
+            .setSmallIcon(R.drawable.stat_notify_image_error)
             .setWhen(System.currentTimeMillis())
             .setAutoCancel(true)
             .getNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index b724552..87e505b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -113,6 +113,8 @@
     // will likely move to a resource or other tunable param at some point
     private static final int INTRUDER_ALERT_DECAY_MS = 10000;
 
+    private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
+
     // fling gesture tuning parameters, scaled to display density
     private float mSelfExpandVelocityPx; // classic value: 2000px/s
     private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
@@ -295,15 +297,15 @@
         mStatusBarView = sb;
 
         try {
-            boolean showNav = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
+            boolean showNav = mWindowManager.hasNavigationBar();
             if (showNav) {
                 mNavigationBarView = 
                     (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
 
                 mNavigationBarView.setDisabledFlags(mDisabled);
             }
-        } catch (Resources.NotFoundException ex) {
-            // no nav bar for you
+        } catch (RemoteException ex) {
+            // no window manager? good luck with that
         }
 
         // figure out which pixel-format to use for the status bar.
@@ -435,13 +437,18 @@
         }
     };
 
+    private void prepareNavigationBarView() {
+        mNavigationBarView.reorient();
+
+        mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
+        mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
+    }
+
     // For small-screen devices (read: phones) that lack hardware navigation buttons
     private void addNavigationBar() {
         if (mNavigationBarView == null) return;
 
-        mNavigationBarView.reorient();
-
-        mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
+        prepareNavigationBarView();
 
         WindowManagerImpl.getDefault().addView(
                 mNavigationBarView, getNavigationBarLayoutParams());
@@ -450,9 +457,7 @@
     private void repositionNavigationBar() {
         if (mNavigationBarView == null) return;
 
-        mNavigationBarView.reorient();
-
-        mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
+        prepareNavigationBarView();
 
         WindowManagerImpl.getDefault().updateViewLayout(
                 mNavigationBarView, getNavigationBarLayoutParams());
@@ -695,6 +700,10 @@
 
             // Recalculate the position of the sliding windows and the titles.
             updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+
+            if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mAnimating) {
+                animateCollapse();
+            }
         }
 
         setAreThereNotifications();
@@ -2007,8 +2016,8 @@
     }
 
     public void toggleRecentApps() {
-        int msg = (mRecentsPanel.getVisibility() == View.GONE)
-                ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL;
+        int msg = (mRecentsPanel.getVisibility() == View.VISIBLE)
+                ? MSG_CLOSE_RECENTS_PANEL : MSG_OPEN_RECENTS_PANEL;
         mHandler.removeMessages(msg);
         mHandler.sendEmptyMessage(msg);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 4f9eb38..1d4b9ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -95,7 +95,7 @@
     final WifiManager mWifiManager;
     AsyncChannel mWifiChannel;
     boolean mWifiEnabled, mWifiConnected;
-    int mWifiLevel;
+    int mWifiRssi, mWifiLevel;
     String mWifiSsid;
     int mWifiIconId = 0;
     int mWifiActivityIconId = 0; // overlay arrows for wifi direction
@@ -654,24 +654,29 @@
             mWifiConnected = networkInfo != null && networkInfo.isConnected();
             // If we just connected, grab the inintial signal strength and ssid
             if (mWifiConnected && !wasConnected) {
-                WifiInfo info = mWifiManager.getConnectionInfo();
+                // try getting it out of the intent first
+                WifiInfo info = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
+                if (info == null) {
+                    info = mWifiManager.getConnectionInfo();
+                }
                 if (info != null) {
-                    mWifiLevel = WifiManager.calculateSignalLevel(info.getRssi(),
-                            WifiIcons.WIFI_LEVEL_COUNT);
                     mWifiSsid = huntForSsid(info);
                 } else {
-                    mWifiLevel = 0;
                     mWifiSsid = null;
                 }
             } else if (!mWifiConnected) {
-                mWifiLevel = 0;
                 mWifiSsid = null;
             }
-
+            // Apparently the wifi level is not stable at this point even if we've just connected to
+            // the network; we need to wait for an RSSI_CHANGED_ACTION for that. So let's just set
+            // it to 0 for now
+            mWifiLevel = 0;
+            mWifiRssi = -200;
         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
             if (mWifiConnected) {
-                final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
-                mWifiLevel = WifiManager.calculateSignalLevel(newRssi, WifiIcons.WIFI_LEVEL_COUNT);
+                mWifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
+                mWifiLevel = WifiManager.calculateSignalLevel(
+                        mWifiRssi, WifiIcons.WIFI_LEVEL_COUNT);
             }
         }
 
@@ -1031,6 +1036,8 @@
         pw.println(mWifiEnabled);
         pw.print("  mWifiConnected=");
         pw.println(mWifiConnected);
+        pw.print("  mWifiRssi=");
+        pw.println(mWifiRssi);
         pw.print("  mWifiLevel=");
         pw.println(mWifiLevel);
         pw.print("  mWifiSsid=");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index f0a10f3..00bdd44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -444,11 +444,14 @@
 
         sb.setHandler(mHandler);
 
-        // Sanity-check that someone hasn't set up the config wrong and asked for a navigation bar
-        // on a tablet that has only the system bar
-        if (mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_showNavigationBar)) {
-            throw new RuntimeException("Tablet device cannot show navigation bar and system bar");
+        try {
+            // Sanity-check that someone hasn't set up the config wrong and asked for a navigation
+            // bar on a tablet that has only the system bar
+            if (mWindowManager.hasNavigationBar()) {
+                throw new RuntimeException(
+                        "Tablet device cannot show navigation bar and system bar");
+            }
+        } catch (RemoteException ex) {
         }
 
         mBarContents = (ViewGroup) sb.findViewById(R.id.bar_contents);
@@ -587,6 +590,7 @@
 
         // Add the windows
         addPanelWindows();
+        mRecentButton.setOnTouchListener(mRecentsPanel);
 
         mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content);
         mPile.removeAllViews();
@@ -1805,8 +1809,8 @@
     }
 
     public void toggleRecentApps() {
-        int msg = (mRecentsPanel.getVisibility() == View.GONE)
-                ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL;
+        int msg = (mRecentsPanel.getVisibility() == View.VISIBLE)
+                ? MSG_CLOSE_RECENTS_PANEL : MSG_OPEN_RECENTS_PANEL;
         mHandler.removeMessages(msg);
         mHandler.sendEmptyMessage(msg);
     }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index de156c9..26bd697 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -47,29 +47,34 @@
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager = null;
 
+    // This is a faster way to draw the background on devices without hardware acceleration
+    Drawable mBackgroundDrawable = new Drawable() {
+        @Override
+        public void draw(Canvas canvas) {
+            canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    };
+
     public KeyguardViewBase(Context context) {
         super(context);
+        resetBackground();
+    }
 
-        // This is a faster way to draw the background on devices without hardware acceleration
-        setBackgroundDrawable(new Drawable() {
-            @Override
-            public void draw(Canvas canvas) {
-                canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
-            }
-
-            @Override
-            public void setAlpha(int alpha) {
-            }
-
-            @Override
-            public void setColorFilter(ColorFilter cf) {
-            }
-
-            @Override
-            public int getOpacity() {
-                return PixelFormat.TRANSLUCENT;
-            }
-        });
+    public void resetBackground() {
+        setBackgroundDrawable(mBackgroundDrawable);
     }
 
     // used to inject callback
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 7a72dcf..b4db01d 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -254,7 +254,7 @@
 
             // TODO: examine all widgets to derive clock status
             mUpdateMonitor.reportClockVisible(true);
-            setBackgroundDrawable(null);
+            resetBackground();
         }
 
         public boolean isVisible(View self) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b9fe182..fd6eceb 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -823,6 +823,14 @@
 
         mHasNavigationBar = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_showNavigationBar);
+        // Allow a system property to override this. Used by the emulator.
+        // See also hasNavigationBar().
+        String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+        if (! "".equals(navBarOverride)) {
+            if      (navBarOverride.equals("1")) mHasNavigationBar = true;
+            else if (navBarOverride.equals("0")) mHasNavigationBar = false;
+        }
+
         mNavigationBarHeight = mHasNavigationBar
                 ? mContext.getResources().getDimensionPixelSize(
                     com.android.internal.R.dimen.navigation_bar_height)
@@ -3725,6 +3733,12 @@
         return diff;
     }
 
+    // Use this instead of checking config_showNavigationBar so that it can be consistently
+    // overridden by qemu.hw.mainkeys in the emulator.
+    public boolean hasNavigationBar() {
+        return mHasNavigationBar;
+    }
+
     public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
                 pw.print(" mSystemReady="); pw.print(mSystemReady);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3e0304f..69560e5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1332,7 +1332,13 @@
                                                             int sessionId)
 {
     Mutex::Autolock _l(mLock);
+    checkSuspendOnEffectEnabled_l(effect, enabled, sessionId);
+}
 
+void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect,
+                                                            bool enabled,
+                                                            int sessionId)
+{
     if (mType != RECORD) {
         // suspend all effects in AUDIO_SESSION_OUTPUT_MIX when enabling any effect on
         // another session. This gives the priority to well behaved effect control panels
@@ -5224,6 +5230,9 @@
                     sp<EffectHandle> handle = effect->mHandles[j].promote();
                     if (handle != 0) {
                         handle->mEffect.clear();
+                        if (handle->mHasControl && handle->mEnabled) {
+                            t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
+                        }
                     }
                 }
                 AudioSystem::unregisterEffect(effect->id());
@@ -6844,7 +6853,7 @@
     }
     mEffect->disconnect(this, unpiniflast);
 
-    if (mEnabled) {
+    if (mHasControl && mEnabled) {
         sp<ThreadBase> thread = mEffect->thread().promote();
         if (thread != 0) {
             thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index ed9d81e..4b794ef 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -492,10 +492,12 @@
                                             int sessionId = AUDIO_SESSION_OUTPUT_MIX);
                     // check if some effects must be suspended/restored when an effect is enabled
                     // or disabled
-        virtual     void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+                    void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
                                                      bool enabled,
                                                      int sessionId = AUDIO_SESSION_OUTPUT_MIX);
-
+                    void checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect,
+                                                       bool enabled,
+                                                       int sessionId = AUDIO_SESSION_OUTPUT_MIX);
         mutable     Mutex                   mLock;
 
     protected:
@@ -1299,7 +1301,7 @@
         // suspend all eligible effects
         void setEffectSuspendedAll_l(bool suspend);
         // check if effects should be suspend or restored when a given effect is enable or disabled
-        virtual void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+        void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
                                               bool enabled);
 
         status_t dump(int fd, const Vector<String16>& args);
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 171710a..bb0e664 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -331,14 +331,8 @@
     Mutex::Autolock lock(mSoundLock);
     sp<MediaPlayer> player = mSoundPlayer[kind];
     if (player != 0) {
-        // do not play the sound if stream volume is 0
-        // (typically because ringer mode is silent).
-        int index;
-        AudioSystem::getStreamVolumeIndex(mAudioStreamType, &index);
-        if (index != 0) {
-            player->seekTo(0);
-            player->start();
-        }
+        player->seekTo(0);
+        player->start();
     }
 }
 
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index f1b8bae..47644de 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -44,6 +44,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.os.Binder;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IPowerManager;
@@ -1656,8 +1657,18 @@
         }
     }
 
+    private boolean isExtStorageEncrypted() {
+        String state = SystemProperties.get("vold.decrypt");
+        return !"".equals(state);
+    }
+
     void wipeDataLocked(int flags) {
-        if ((flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0) {
+        // If the SD card is encrypted and non-removable, we have to force a wipe.
+        boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
+        boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
+
+        // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
+        if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
             Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
             intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
             mWakeLock.acquire(10000);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 6ddbf5a..03d6b41 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -493,11 +493,13 @@
         }
     }
 
-    class MethodCallback extends IInputMethodCallback.Stub {
-        final IInputMethod mMethod;
+    private static class MethodCallback extends IInputMethodCallback.Stub {
+        private final IInputMethod mMethod;
+        private final InputMethodManagerService mParentIMMS;
 
-        MethodCallback(IInputMethod method) {
+        MethodCallback(final IInputMethod method, final InputMethodManagerService imms) {
             mMethod = method;
+            mParentIMMS = imms;
         }
 
         @Override
@@ -506,7 +508,7 @@
 
         @Override
         public void sessionCreated(IInputMethodSession session) throws RemoteException {
-            onSessionCreated(mMethod, session);
+            mParentIMMS.onSessionCreated(mMethod, session);
         }
     }
 
@@ -837,7 +839,7 @@
                         if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs);
                         executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
                                 MSG_CREATE_SESSION, mCurMethod,
-                                new MethodCallback(mCurMethod)));
+                                new MethodCallback(mCurMethod, this)));
                     }
                     // Return to client, and we will get back with it when
                     // we have had a session made for it.
@@ -943,7 +945,7 @@
                             + mCurClient);
                     executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
                             MSG_CREATE_SESSION, mCurMethod,
-                            new MethodCallback(mCurMethod)));
+                            new MethodCallback(mCurMethod, this)));
                 }
             }
         }
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 788ecda..1976eba 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -691,7 +691,7 @@
                 }
                 ISpellCheckerService spellChecker = ISpellCheckerService.Stub.asInterface(service);
                 final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
-                if (this == group.mInternalConnection) {
+                if (group != null && this == group.mInternalConnection) {
                     group.onServiceConnected(spellChecker);
                 }
             }
@@ -701,7 +701,7 @@
         public void onServiceDisconnected(ComponentName name) {
             synchronized(mSpellCheckerMap) {
                 final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
-                if (this == group.mInternalConnection) {
+                if (group != null && this == group.mInternalConnection) {
                     mSpellCheckerBindGroups.remove(mSciId);
                 }
             }
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
index 03b7546..ee62a56 100644
--- a/services/java/com/android/server/wm/Session.java
+++ b/services/java/com/android/server/wm/Session.java
@@ -306,7 +306,15 @@
         synchronized (mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
-                if (mService.mDragState == null || mService.mDragState.mToken != token) {
+                if (mService.mDragState == null) {
+                    // Most likely the drop recipient ANRed and we ended the drag
+                    // out from under it.  Log the issue and move on.
+                    Slog.w(WindowManagerService.TAG, "Drop result given but no drag in progress");
+                    return;
+                }
+
+                if (mService.mDragState.mToken != token) {
+                    // We're in a drag, but the wrong window has responded.
                     Slog.w(WindowManagerService.TAG, "Invalid drop-result claim by " + window);
                     throw new IllegalStateException("reportDropResult() by non-recipient");
                 }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 68f0e66..3af3e06 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9263,6 +9263,11 @@
         }
     }
 
+    @Override
+    public boolean hasNavigationBar() {
+        return mPolicy.hasNavigationBar();
+    }
+
     void dumpInput(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER INPUT (dumpsys window input)");
         mInputManager.dump(pw);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1905a68..dc47a03 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1560,8 +1560,15 @@
         result.append(buffer);
         snprintf(buffer, SIZE,
                 "  last eglSwapBuffers() time: %f us\n"
-                "  last transaction time     : %f us\n",
-                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
+                "  last transaction time     : %f us\n"
+                "  refresh-rate              : %f fps\n"
+                "  x-dpi                     : %f\n"
+                "  y-dpi                     : %f\n",
+                mLastSwapBufferTime/1000.0,
+                mLastTransactionTime/1000.0,
+                hw.getRefreshRate(),
+                hw.getDpiX(),
+                hw.getDpiY());
         result.append(buffer);
 
         if (inSwapBuffersDuration || !locked) {
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 33eed38..9b42dbe 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -292,7 +292,7 @@
     void setOnNewGsmBroadcastSms(Handler h, int what, Object obj);
     void unSetOnNewGsmBroadcastSms(Handler h);
 
-   /**
+    /**
      * Register for NEW_SMS_ON_SIM unsolicited message
      *
      * AsyncResult.result is an int array containing the index of new SMS
@@ -1116,9 +1116,20 @@
     void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
 
     /**
+     * Acknowledge successful or failed receipt of last incoming SMS,
+     * including acknowledgement TPDU to send as the RP-User-Data element
+     * of the RP-ACK or RP-ERROR PDU.
+     *
+     * @param success true to send RP-ACK, false to send RP-ERROR
+     * @param ackPdu the acknowledgement TPDU in hexadecimal format
+     * @param response sent when operation completes.
+     */
+    void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message response);
+
+    /**
      * parameters equivalent to 27.007 AT+CRSM command
      * response.obj will be an AsyncResult
-     * response.obj.userObj will be a IccIoResult on success
+     * response.obj.result will be an IccIoResult on success
      */
     void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
             String data, String pin2, Message response);
@@ -1386,6 +1397,22 @@
     public void sendEnvelope(String contents, Message response);
 
     /**
+     * Send ENVELOPE to the SIM, such as an SMS-PP data download envelope
+     * for a SIM data download message. This method has one difference
+     * from {@link #sendEnvelope}: The SW1 and SW2 status bytes from the UICC response
+     * are returned along with the response data.
+     *
+     * response.obj will be an AsyncResult
+     * response.obj.result will be an IccIoResult on success
+     *
+     * @param contents  String containing SAT/USAT response in hexadecimal
+     *                  format starting with command tag. See TS 102 223 for
+     *                  details.
+     * @param response  Callback message
+     */
+    public void sendEnvelopeWithStatus(String contents, Message response);
+
+    /**
      * Accept or reject the call setup request from SIM.
      *
      * @param accept   true if the call is to be accepted, false otherwise.
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 84bfc40..51ebd99 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -57,7 +57,6 @@
     protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
 
     protected String spn;
-    protected int spnDisplayCondition;
 
     // ***** Constants
 
diff --git a/telephony/java/com/android/internal/telephony/IccServiceTable.java b/telephony/java/com/android/internal/telephony/IccServiceTable.java
new file mode 100644
index 0000000..ed74a11
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IccServiceTable.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.util.Log;
+
+/**
+ * Wrapper class for an ICC EF containing a bit field of enabled services.
+ */
+public abstract class IccServiceTable {
+    protected final byte[] mServiceTable;
+
+    protected IccServiceTable(byte[] table) {
+        mServiceTable = table;
+    }
+
+    // Get the class name to use for log strings
+    protected abstract String getTag();
+
+    // Get the array of enums to use for toString
+    protected abstract Object[] getValues();
+
+    /**
+     * Returns if the specified service is available.
+     * @param service the service number as a zero-based offset (the enum ordinal)
+     * @return true if the service is available; false otherwise
+     */
+    protected boolean isAvailable(int service) {
+        int offset = service / 8;
+        if (offset >= mServiceTable.length) {
+            // Note: Enums are zero-based, but the TS service numbering is one-based
+            Log.e(getTag(), "isAvailable for service " + (service + 1) + " fails, max service is " +
+                    (mServiceTable.length * 8));
+            return false;
+        }
+        int bit = service % 8;
+        return (mServiceTable[offset] & (1 << bit)) != 0;
+    }
+
+    public String toString() {
+        Object[] values = getValues();
+        int numBytes = mServiceTable.length;
+        StringBuilder builder = new StringBuilder(getTag()).append('[')
+                .append(numBytes * 8).append("]={ ");
+
+        boolean addComma = false;
+        for (int i = 0; i < numBytes; i++) {
+            byte currentByte = mServiceTable[i];
+            for (int bit = 0; bit < 8; bit++) {
+                if ((currentByte & (1 << bit)) != 0) {
+                    if (addComma) {
+                        builder.append(", ");
+                    } else {
+                        addComma = true;
+                    }
+                    int ordinal = (i * 8) + bit;
+                    if (ordinal < values.length) {
+                        builder.append(values[ordinal]);
+                    } else {
+                        builder.append('#').append(ordinal + 1);    // service number (one-based)
+                    }
+                }
+            }
+        }
+        return builder.append(" }").toString();
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 8aae0d4..e8d85de 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1407,6 +1407,20 @@
         send(rr);
     }
 
+    public void
+    acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
+        RILRequest rr
+                = RILRequest.obtain(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result);
+
+        rr.mp.writeInt(2);
+        rr.mp.writeString(success ? "1" : "0");
+        rr.mp.writeString(ackPdu);
+
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                + ' ' + success + " [" + ackPdu + ']');
+
+        send(rr);
+    }
 
     public void
     iccIO (int command, int fileid, String path, int p1, int p2, int p3,
@@ -1777,6 +1791,20 @@
     /**
      * {@inheritDoc}
      */
+    public void sendEnvelopeWithStatus(String contents, Message response) {
+        RILRequest rr = RILRequest.obtain(
+                RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, response);
+
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                + '[' + contents + ']');
+
+        rr.mp.writeString(contents);
+        send(rr);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public void handleCallSetupRequestFromSim(
             boolean accept, Message response) {
 
@@ -2245,6 +2273,8 @@
             case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
             case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret =  responseInts(p); break;
             case RIL_REQUEST_ISIM_AUTHENTICATION: ret =  responseString(p); break;
+            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
+            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
             default:
                 throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
             //break;
@@ -2870,7 +2900,7 @@
 
 
     private Object
-     responseICC_IO(Parcel p) {
+    responseICC_IO(Parcel p) {
         int sw1, sw2;
         byte data[] = null;
         Message ret;
@@ -3112,8 +3142,8 @@
         return ret;
     }
 
-   private Object
-   responseCellList(Parcel p) {
+    private Object
+    responseCellList(Parcel p) {
        int num, rssi;
        String location;
        ArrayList<NeighboringCellInfo> response;
@@ -3452,6 +3482,8 @@
             case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
             case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
             case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
+            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
+            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
             default: return "<unknown request>";
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 7fb7f41..ba9d07a 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -262,6 +262,8 @@
     int RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
     int RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
     int RIL_REQUEST_ISIM_AUTHENTICATION = 105;
+    int RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
+    int RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
     int RIL_UNSOL_RESPONSE_BASE = 1000;
     int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
     int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 57aae56..3486190 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -520,16 +520,6 @@
         return false;
     }
 
-    /**
-     * Returns OTASP_NOT_NEEDED as its not needed for LTE
-     */
-    @Override
-    int getOtasp() {
-        int provisioningState = OTASP_NOT_NEEDED;
-        if (DBG) log("getOtasp: state=" + provisioningState);
-        return provisioningState;
-    }
-
     @Override
     protected void log(String s) {
         Log.d(LOG_TAG, "[CdmaLteSST] " + s);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index 47c638f..0a285b9 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -282,6 +282,9 @@
                 obtainMessage(EVENT_GET_MSISDN_DONE));
         recordsToLoad++;
 
+        iccFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
+        recordsToLoad++;
+
         iccFh.loadEFTransparent(EF_CSIM_LI,
                 obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded()));
         recordsToLoad++;
@@ -384,12 +387,12 @@
 
     @Override
     protected void log(String s) {
-        if (DBG) Log.d(LOG_TAG, "[CSIM] " + s);
+        Log.d(LOG_TAG, "[CSIM] " + s);
     }
 
     @Override
     protected void loge(String s) {
-        if (DBG) Log.e(LOG_TAG, "[CSIM] " + s);
+        Log.e(LOG_TAG, "[CSIM] " + s);
     }
 
     public String getMdn() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index e166401..aa475e5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1025,10 +1025,8 @@
      * Handles changes to the APN database.
      */
     private void onApnChanged() {
-        // TODO: How to handle when multiple APNs are active?
-
-        ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
-        boolean defaultApnIsDisconnected = defaultApnContext.isDisconnected();
+        State overallState = getOverallState();
+        boolean isDisconnected = (overallState == State.IDLE || overallState == State.FAILED);
 
         if (mPhone instanceof GSMPhone) {
             // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
@@ -1039,8 +1037,8 @@
         // match the current operator.
         if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
         createAllApnList();
-        cleanUpAllConnections(!defaultApnIsDisconnected, Phone.REASON_APN_CHANGED);
-        if (defaultApnIsDisconnected) {
+        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
+        if (isDisconnected) {
             setupDataOnReadyApns(Phone.REASON_APN_CHANGED);
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 5d6f181..8e965a3 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -91,6 +91,8 @@
 
     String pnnHomeName = null;
 
+    UsimServiceTable mUsimServiceTable;
+
     // ***** Constants
 
     // Bitmasks for SPN display rules.
@@ -134,7 +136,7 @@
     private static final int EVENT_GET_SPDI_DONE = 13;
     private static final int EVENT_UPDATE_DONE = 14;
     private static final int EVENT_GET_PNN_DONE = 15;
-    private static final int EVENT_GET_SST_DONE = 17;
+    protected static final int EVENT_GET_SST_DONE = 17;
     private static final int EVENT_GET_ALL_SMS_DONE = 18;
     private static final int EVENT_MARK_SMS_READ_DONE = 19;
     private static final int EVENT_SET_MBDN_DONE = 20;
@@ -246,6 +248,10 @@
         return msisdn;
     }
 
+    public UsimServiceTable getUsimServiceTable() {
+        return mUsimServiceTable;
+    }
+
     /**
      * Set subscriber number to SIM record
      *
@@ -961,8 +967,9 @@
                     break;
                 }
 
-                //Log.d(LOG_TAG, "SST: " + IccUtils.bytesToHexString(data));
-            break;
+                mUsimServiceTable = new UsimServiceTable(data);
+                if (DBG) log("SST: " + mUsimServiceTable);
+                break;
 
             case EVENT_GET_INFO_CPHS_DONE:
                 isRecordLoadResponse = true;
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java b/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
new file mode 100644
index 0000000..3fe200b
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.gsm;
+
+import com.android.internal.telephony.IccServiceTable;
+
+/**
+ * Wrapper class for the USIM Service Table EF.
+ * See 3GPP TS 31.102 Release 10 section 4.2.8
+ */
+public final class UsimServiceTable extends IccServiceTable {
+    public enum UsimService {
+        PHONEBOOK,
+        FDN,                                // Fixed Dialing Numbers
+        FDN_EXTENSION,                      // FDN extension data in EF_EXT2
+        SDN,                                // Service Dialing Numbers
+        SDN_EXTENSION,                      // SDN extension data in EF_EXT3
+        BDN,                                // Barred Dialing Numbers
+        BDN_EXTENSION,                      // BDN extension data in EF_EXT4
+        OUTGOING_CALL_INFO,
+        INCOMING_CALL_INFO,
+        SM_STORAGE,
+        SM_STATUS_REPORTS,
+        SM_SERVICE_PARAMS,
+        ADVICE_OF_CHARGE,
+        CAP_CONFIG_PARAMS_2,
+        CB_MESSAGE_ID,
+        CB_MESSAGE_ID_RANGES,
+        GROUP_ID_LEVEL_1,
+        GROUP_ID_LEVEL_2,
+        SPN,                                // Service Provider Name
+        USER_PLMN_SELECT,
+        MSISDN,
+        IMAGE,
+        LOCALISED_SERVICE_AREAS,
+        EMLPP,                              // Enhanced Multi-Level Precedence and Preemption
+        EMLPP_AUTO_ANSWER,
+        RFU,
+        GSM_ACCESS,
+        DATA_DL_VIA_SMS_PP,
+        DATA_DL_VIA_SMS_CB,
+        CALL_CONTROL_BY_USIM,
+        MO_SMS_CONTROL_BY_USIM,
+        RUN_AT_COMMAND,
+        IGNORED_1,
+        ENABLED_SERVICES_TABLE,
+        APN_CONTROL_LIST,
+        DEPERSONALISATION_CONTROL_KEYS,
+        COOPERATIVE_NETWORK_LIST,
+        GSM_SECURITY_CONTEXT,
+        CPBCCH_INFO,
+        INVESTIGATION_SCAN,
+        MEXE,
+        OPERATOR_PLMN_SELECT,
+        HPLMN_SELECT,
+        EXTENSION_5,                        // Extension data for ICI, OCI, MSISDN in EF_EXT5
+        PLMN_NETWORK_NAME,
+        OPERATOR_PLMN_LIST,
+        MBDN,                               // Mailbox Dialing Numbers
+        MWI_STATUS,                         // Message Waiting Indication status
+        CFI_STATUS,                         // Call Forwarding Indication status
+        IGNORED_2,
+        SERVICE_PROVIDER_DISPLAY_INFO,
+        MMS_NOTIFICATION,
+        MMS_NOTIFICATION_EXTENSION,         // MMS Notification extension data in EF_EXT8
+        GPRS_CALL_CONTROL_BY_USIM,
+        MMS_CONNECTIVITY_PARAMS,
+        NETWORK_INDICATION_OF_ALERTING,
+        VGCS_GROUP_ID_LIST,
+        VBS_GROUP_ID_LIST,
+        PSEUDONYM,
+        IWLAN_USER_PLMN_SELECT,
+        IWLAN_OPERATOR_PLMN_SELECT,
+        USER_WSID_LIST,
+        OPERATOR_WSID_LIST,
+        VGCS_SECURITY,
+        VBS_SECURITY,
+        WLAN_REAUTH_IDENTITY,
+        MM_STORAGE,
+        GBA,                                // Generic Bootstrapping Architecture
+        MBMS_SECURITY,
+        DATA_DL_VIA_USSD,
+        EQUIVALENT_HPLMN,
+        TERMINAL_PROFILE_AFTER_UICC_ACTIVATION,
+        EQUIVALENT_HPLMN_PRESENTATION,
+        LAST_RPLMN_SELECTION_INDICATION,
+        OMA_BCAST_PROFILE,
+        GBA_LOCAL_KEY_ESTABLISHMENT,
+        TERMINAL_APPLICATIONS,
+        SPN_ICON,
+        PLMN_NETWORK_NAME_ICON,
+        USIM_IP_CONNECTION_PARAMS,
+        IWLAN_HOME_ID_LIST,
+        IWLAN_EQUIVALENT_HPLMN_PRESENTATION,
+        IWLAN_HPLMN_PRIORITY_INDICATION,
+        IWLAN_LAST_REGISTERED_PLMN,
+        EPS_MOBILITY_MANAGEMENT_INFO,
+        ALLOWED_CSG_LISTS_AND_INDICATIONS,
+        CALL_CONTROL_ON_EPS_PDN_CONNECTION_BY_USIM,
+        HPLMN_DIRECT_ACCESS,
+        ECALL_DATA,
+        OPERATOR_CSG_LISTS_AND_INDICATIONS,
+        SM_OVER_IP,
+        CSG_DISPLAY_CONTROL,
+        IMS_COMMUNICATION_CONTROL_BY_USIM,
+        EXTENDED_TERMINAL_APPLICATIONS,
+        UICC_ACCESS_TO_IMS,
+        NAS_CONFIG_BY_USIM
+    }
+
+    public UsimServiceTable(byte[] table) {
+        super(table);
+    }
+
+    public boolean isAvailable(UsimService service) {
+        return super.isAvailable(service.ordinal());
+    }
+
+    @Override
+    protected String getTag() {
+        return "UsimServiceTable";
+    }
+
+    @Override
+    protected Object[] getValues() {
+        return UsimService.values();
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
index 85ce6e0..ab01012 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -206,6 +206,9 @@
             Message result) {
     }
 
+    public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
+            Message result) {
+    }
 
     public void iccIO (int command, int fileid, String path, int p1, int p2,
             int p3, String data, String pin2, Message result) {
@@ -298,6 +301,9 @@
     public void sendEnvelope(String contents, Message response) {
     }
 
+    public void sendEnvelopeWithStatus(String contents, Message response) {
+    }
+
     public void handleCallSetupRequestFromSim(
             boolean accept, Message response) {
     }
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index a2a344f..a0c7d5d 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -810,6 +810,13 @@
     /**
      * {@inheritDoc}
      */
+    public void sendEnvelopeWithStatus(String contents, Message response) {
+        resultSuccess(response, null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public void handleCallSetupRequestFromSim(
             boolean accept, Message response) {
         resultSuccess(response, null);
@@ -1037,6 +1044,11 @@
         unimplemented(result);
     }
 
+    public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
+            Message result) {
+        unimplemented(result);
+    }
+
     /**
      * parameters equivalent to 27.007 AT+CRSM command
      * response.obj will be an AsyncResult
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
new file mode 100644
index 0000000..c89f33a
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Test IccServiceTable class.
+ */
+public class IccServiceTableTest extends AndroidTestCase {
+
+    static class TestIccServiceTable extends IccServiceTable {
+        public enum TestIccService {
+            SERVICE1,
+            SERVICE2,
+            SERVICE3,
+            SERVICE4
+        }
+
+        public TestIccServiceTable(byte[] table) {
+            super(table);
+        }
+
+        public boolean isAvailable(TestIccService service) {
+            return super.isAvailable(service.ordinal());
+        }
+
+        @Override
+        protected String getTag() {
+            return "TestIccServiceTable";
+        }
+
+        @Override
+        protected Object[] getValues() {
+            return TestIccService.values();
+        }
+    }
+
+    @SmallTest
+    public void testIccServiceTable() {
+        byte[] noServices = {0x00};
+        byte[] service1 = {0x01};
+        byte[] service4 = {0x08};
+        byte[] allServices = {0x0f};
+
+        TestIccServiceTable testTable1 = new TestIccServiceTable(noServices);
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+
+        TestIccServiceTable testTable2 = new TestIccServiceTable(service1);
+        assertTrue(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+
+        TestIccServiceTable testTable3 = new TestIccServiceTable(service4);
+        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertTrue(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+
+        TestIccServiceTable testTable4 = new TestIccServiceTable(allServices);
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+    }
+}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
new file mode 100644
index 0000000..56854ed
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.gsm;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Test UsimServiceTable class.
+ */
+public class UsimServiceTableTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testUsimServiceTable() {
+        byte[] noServices = {0x00};
+        byte[] service1 = {0x01, 0x00};
+        byte[] service8 = {(byte) 0x80, 0x00, 0x00};
+        byte[] service8And9 = {(byte) 0x80, 0x01};
+        byte[] service28 = {0x00, 0x00, 0x00, 0x08};
+        byte[] service89To96 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, (byte) 0xff};
+
+        UsimServiceTable testTable1 = new UsimServiceTable(noServices);
+        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.FDN));
+        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable2 = new UsimServiceTable(service1);
+        assertTrue(testTable2.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.FDN));
+        assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable3 = new UsimServiceTable(service8);
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
+        assertTrue(testTable3.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable4 = new UsimServiceTable(service8And9);
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
+        assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
+        assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.SM_STORAGE));
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable5 = new UsimServiceTable(service28);
+        assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertTrue(testTable5.isAvailable(UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP));
+        assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable6 = new UsimServiceTable(service89To96);
+        assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.HPLMN_DIRECT_ACCESS));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.ECALL_DATA));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.SM_OVER_IP));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.UICC_ACCESS_TO_IMS));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+    }
+}
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_focus.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_focus.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_focus.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_focus.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_press.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_press.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_press.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_press.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/green_gradient.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/green_gradient.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/green_gradient.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/green_gradient.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/patch.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/patch.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/patch.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/patch.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/patch2.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/patch2.9.png
new file mode 100644
index 0000000..f65a3559
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable-nodpi/patch2.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/widget_title_bg.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/widget_title_bg.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/widget_title_bg.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/widget_title_bg.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
index cfad6da..656f2b1 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
@@ -44,7 +44,7 @@
     }
 
     private class PatchView extends View {
-        private Drawable mPatch1, mPatch2;
+        private Drawable mPatch1, mPatch2, mPatch3;
         private Bitmap mTexture;
 
         public PatchView(Activity activity) {
@@ -53,6 +53,7 @@
             final Resources resources = activity.getResources();
             mPatch1 = resources.getDrawable(R.drawable.patch);
             mPatch2 = resources.getDrawable(R.drawable.btn_toggle_on);
+            mPatch3 = resources.getDrawable(R.drawable.patch2);
 
             mTexture = Bitmap.createBitmap(4, 3, Bitmap.Config.ARGB_8888);
             mTexture.setPixel(0, 0, 0xffff0000);
@@ -77,6 +78,14 @@
             final int left = (getWidth() - width) / 2;
             final int top  = (getHeight() - height) / 2;
 
+            canvas.save();
+            canvas.translate(0.0f, -height * 2 - 20.0f);
+
+            mPatch3.setBounds(left, top, left + height, top + width);
+            mPatch3.draw(canvas);
+            
+            canvas.restore();
+            
             mPatch1.setBounds(left, top, left + width, top + height);
             mPatch1.draw(canvas);
 
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java
index 1fbf97a..2bfb6b1 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java
@@ -25,6 +25,9 @@
 public class UT_program_raster extends UnitTest {
     private Resources mRes;
 
+    ProgramRaster pointSpriteEnabled;
+    ProgramRaster cullMode;
+
     protected UT_program_raster(RSTestCore rstc, Resources res, Context ctx) {
         super(rstc, "ProgramRaster", ctx);
         mRes = res;
@@ -39,20 +42,41 @@
 
     private void initializeGlobals(RenderScript RS, ScriptC_program_raster s) {
         ProgramRaster.Builder b = getDefaultBuilder(RS);
-        s.set_pointSpriteEnabled(b.setPointSpriteEnabled(true).create());
+        pointSpriteEnabled = b.setPointSpriteEnabled(true).create();
         b = getDefaultBuilder(RS);
-        s.set_cullMode(b.setCullMode(CullMode.FRONT).create());
-        return;
+        cullMode = b.setCullMode(CullMode.FRONT).create();
+
+        s.set_pointSpriteEnabled(pointSpriteEnabled);
+        s.set_cullMode(cullMode);
     }
 
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
+    private void testScriptSide(RenderScript pRS) {
         ScriptC_program_raster s = new ScriptC_program_raster(pRS, mRes, R.raw.program_raster);
         pRS.setMessageHandler(mRsMessage);
         initializeGlobals(pRS, s);
         s.invoke_program_raster_test();
         pRS.finish();
         waitForMessage();
+    }
+
+    private void testJavaSide(RenderScript RS) {
+        _RS_ASSERT("pointSpriteEnabled.getPointSpriteEnabled() == true",
+                    pointSpriteEnabled.getPointSpriteEnabled() == true);
+        _RS_ASSERT("pointSpriteEnabled.getCullMode() == ProgramRaster.CullMode.BACK",
+                    pointSpriteEnabled.getCullMode() == ProgramRaster.CullMode.BACK);
+
+        _RS_ASSERT("cullMode.getPointSpriteEnabled() == false",
+                    cullMode.getPointSpriteEnabled() == false);
+        _RS_ASSERT("cullMode.getCullMode() == ProgramRaster.CullMode.FRONT",
+                    cullMode.getCullMode() == ProgramRaster.CullMode.FRONT);
+
+        updateUI();
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        testScriptSide(pRS);
+        testJavaSide(pRS);
         pRS.destroy();
     }
 }
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java
index e06112c..72a401d 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java
@@ -27,6 +27,16 @@
 public class UT_program_store extends UnitTest {
     private Resources mRes;
 
+    ProgramStore ditherEnable;
+    ProgramStore colorRWriteEnable;
+    ProgramStore colorGWriteEnable;
+    ProgramStore colorBWriteEnable;
+    ProgramStore colorAWriteEnable;
+    ProgramStore blendSrc;
+    ProgramStore blendDst;
+    ProgramStore depthWriteEnable;
+    ProgramStore depthFunc;
+
     protected UT_program_store(RSTestCore rstc, Resources res, Context ctx) {
         super(rstc, "ProgramStore", ctx);
         mRes = res;
@@ -44,44 +54,122 @@
 
     private void initializeGlobals(RenderScript RS, ScriptC_program_store s) {
         ProgramStore.Builder b = getDefaultBuilder(RS);
-        s.set_ditherEnable(b.setDitherEnabled(true).create());
+        ditherEnable = b.setDitherEnabled(true).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorRWriteEnable(b.setColorMaskEnabled(true,  false, false, false).create());
+        colorRWriteEnable = b.setColorMaskEnabled(true,  false, false, false).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorGWriteEnable(b.setColorMaskEnabled(false, true,  false, false).create());
+        colorGWriteEnable = b.setColorMaskEnabled(false, true,  false, false).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorBWriteEnable(b.setColorMaskEnabled(false, false, true,  false).create());
+        colorBWriteEnable = b.setColorMaskEnabled(false, false, true,  false).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorAWriteEnable(b.setColorMaskEnabled(false, false, false, true).create());
+        colorAWriteEnable = b.setColorMaskEnabled(false, false, false, true).create();
 
         b = getDefaultBuilder(RS);
-        s.set_blendSrc(b.setBlendFunc(ProgramStore.BlendSrcFunc.DST_COLOR,
-                                      ProgramStore.BlendDstFunc.ZERO).create());
+        blendSrc = b.setBlendFunc(ProgramStore.BlendSrcFunc.DST_COLOR,
+                                  ProgramStore.BlendDstFunc.ZERO).create();
 
         b = getDefaultBuilder(RS);
-        s.set_blendDst(b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO,
-                                      ProgramStore.BlendDstFunc.DST_ALPHA).create());
+        blendDst = b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO,
+                                  ProgramStore.BlendDstFunc.DST_ALPHA).create();
 
         b = getDefaultBuilder(RS);
-        s.set_depthWriteEnable(b.setDepthMaskEnabled(true).create());
+        depthWriteEnable = b.setDepthMaskEnabled(true).create();
 
         b = getDefaultBuilder(RS);
-        s.set_depthFunc(b.setDepthFunc(ProgramStore.DepthFunc.GREATER).create());
-        return;
+        depthFunc = b.setDepthFunc(ProgramStore.DepthFunc.GREATER).create();
+
+        s.set_ditherEnable(ditherEnable);
+        s.set_colorRWriteEnable(colorRWriteEnable);
+        s.set_colorGWriteEnable(colorGWriteEnable);
+        s.set_colorBWriteEnable(colorBWriteEnable);
+        s.set_colorAWriteEnable(colorAWriteEnable);
+        s.set_blendSrc(blendSrc);
+        s.set_blendDst(blendDst);
+        s.set_depthWriteEnable(depthWriteEnable);
+        s.set_depthFunc(depthFunc);
     }
 
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
+    private void testScriptSide(RenderScript pRS) {
         ScriptC_program_store s = new ScriptC_program_store(pRS, mRes, R.raw.program_store);
         pRS.setMessageHandler(mRsMessage);
         initializeGlobals(pRS, s);
         s.invoke_program_store_test();
         pRS.finish();
         waitForMessage();
+    }
+
+    void checkObject(ProgramStore ps,
+                     boolean depthMask,
+                     DepthFunc df,
+                     BlendSrcFunc bsf,
+                     BlendDstFunc bdf,
+                     boolean R,
+                     boolean G,
+                     boolean B,
+                     boolean A,
+                     boolean dither) {
+        _RS_ASSERT("ps.getDepthMaskEnabled() == depthMask", ps.getDepthMaskEnabled() == depthMask);
+        _RS_ASSERT("ps.getDepthFunc() == df", ps.getDepthFunc() == df);
+        _RS_ASSERT("ps.getBlendSrcFunc() == bsf", ps.getBlendSrcFunc() == bsf);
+        _RS_ASSERT("ps.getBlendDstFunc() == bdf", ps.getBlendDstFunc() == bdf);
+        _RS_ASSERT("ps.getColorMaskREnabled() == R", ps.getColorMaskREnabled() == R);
+        _RS_ASSERT("ps.getColorMaskGEnabled() == G", ps.getColorMaskGEnabled() == G);
+        _RS_ASSERT("ps.getColorMaskBEnabled() == B", ps.getColorMaskBEnabled() == B);
+        _RS_ASSERT("ps.getColorMaskAEnabled() == A", ps.getColorMaskAEnabled() == A);
+        _RS_ASSERT("ps.getDitherEnabled() == dither", ps.getDitherEnabled() == dither);
+    }
+
+    void varyBuilderColorAndDither(ProgramStore.Builder pb,
+                                   boolean depthMask,
+                                   DepthFunc df,
+                                   BlendSrcFunc bsf,
+                                   BlendDstFunc bdf) {
+        for (int r = 0; r <= 1; r++) {
+            boolean isR = (r == 1);
+            for (int g = 0; g <= 1; g++) {
+                boolean isG = (g == 1);
+                for (int b = 0; b <= 1; b++) {
+                    boolean isB = (b == 1);
+                    for (int a = 0; a <= 1; a++) {
+                        boolean isA = (a == 1);
+                        for (int dither = 0; dither <= 1; dither++) {
+                            boolean isDither = (dither == 1);
+                            pb.setDitherEnabled(isDither);
+                            pb.setColorMaskEnabled(isR, isG, isB, isA);
+                            ProgramStore ps = pb.create();
+                            checkObject(ps, depthMask, df, bsf, bdf, isR, isG, isB, isA, isDither);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void testJavaSide(RenderScript RS) {
+        for (int depth = 0; depth <= 1; depth++) {
+            boolean depthMask = (depth == 1);
+            for (DepthFunc df : DepthFunc.values()) {
+                for (BlendSrcFunc bsf : BlendSrcFunc.values()) {
+                    for (BlendDstFunc bdf : BlendDstFunc.values()) {
+                        ProgramStore.Builder b = new ProgramStore.Builder(RS);
+                        b.setDepthFunc(df);
+                        b.setDepthMaskEnabled(depthMask);
+                        b.setBlendFunc(bsf, bdf);
+                        varyBuilderColorAndDither(b, depthMask, df, bsf, bdf);
+                    }
+                }
+            }
+        }
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        testJavaSide(pRS);
+        testScriptSide(pRS);
         pRS.destroy();
     }
 }
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
index b0ccf9d..030b3ff 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
@@ -25,6 +25,12 @@
 public class UT_sampler extends UnitTest {
     private Resources mRes;
 
+    Sampler minification;
+    Sampler magnification;
+    Sampler wrapS;
+    Sampler wrapT;
+    Sampler anisotropy;
+
     protected UT_sampler(RSTestCore rstc, Resources res, Context ctx) {
         super(rstc, "Sampler", ctx);
         mRes = res;
@@ -43,34 +49,103 @@
     private void initializeGlobals(RenderScript RS, ScriptC_sampler s) {
         Sampler.Builder b = getDefaultBuilder(RS);
         b.setMinification(Value.LINEAR_MIP_LINEAR);
-        s.set_minification(b.create());
+        minification = b.create();
 
         b = getDefaultBuilder(RS);
         b.setMagnification(Value.LINEAR);
-        s.set_magnification(b.create());
+        magnification = b.create();
 
         b = getDefaultBuilder(RS);
         b.setWrapS(Value.WRAP);
-        s.set_wrapS(b.create());
+        wrapS = b.create();
 
         b = getDefaultBuilder(RS);
         b.setWrapT(Value.WRAP);
-        s.set_wrapT(b.create());
+        wrapT = b.create();
 
         b = getDefaultBuilder(RS);
         b.setAnisotropy(8.0f);
-        s.set_anisotropy(b.create());
-        return;
+        anisotropy = b.create();
+
+        s.set_minification(minification);
+        s.set_magnification(magnification);
+        s.set_wrapS(wrapS);
+        s.set_wrapT(wrapT);
+        s.set_anisotropy(anisotropy);
     }
 
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
+    private void testScriptSide(RenderScript pRS) {
         ScriptC_sampler s = new ScriptC_sampler(pRS, mRes, R.raw.sampler);
         pRS.setMessageHandler(mRsMessage);
         initializeGlobals(pRS, s);
         s.invoke_sampler_test();
         pRS.finish();
         waitForMessage();
+    }
+
+    private void testJavaSide(RenderScript RS) {
+        _RS_ASSERT("minification.getMagnification() == Sampler.Value.NEAREST",
+                    minification.getMagnification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR",
+                    minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR);
+        _RS_ASSERT("minification.getWrapS() == Sampler.Value.CLAMP",
+                    minification.getWrapS() == Sampler.Value.CLAMP);
+        _RS_ASSERT("minification.getWrapT() == Sampler.Value.CLAMP",
+                    minification.getWrapT() == Sampler.Value.CLAMP);
+        _RS_ASSERT("minification.getAnisotropy() == 1.0f",
+                    minification.getAnisotropy() == 1.0f);
+
+        _RS_ASSERT("magnification.getMagnification() == Sampler.Value.LINEAR",
+                    magnification.getMagnification() == Sampler.Value.LINEAR);
+        _RS_ASSERT("magnification.getMinification() == Sampler.Value.NEAREST",
+                    magnification.getMinification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("magnification.getWrapS() == Sampler.Value.CLAMP",
+                    magnification.getWrapS() == Sampler.Value.CLAMP);
+        _RS_ASSERT("magnification.getWrapT() == Sampler.Value.CLAMP",
+                    magnification.getWrapT() == Sampler.Value.CLAMP);
+        _RS_ASSERT("magnification.getAnisotropy() == 1.0f",
+                    magnification.getAnisotropy() == 1.0f);
+
+        _RS_ASSERT("wrapS.getMagnification() == Sampler.Value.NEAREST",
+                    wrapS.getMagnification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("wrapS.getMinification() == Sampler.Value.NEAREST",
+                    wrapS.getMinification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("wrapS.getWrapS() == Sampler.Value.WRAP",
+                    wrapS.getWrapS() == Sampler.Value.WRAP);
+        _RS_ASSERT("wrapS.getWrapT() == Sampler.Value.CLAMP",
+                    wrapS.getWrapT() == Sampler.Value.CLAMP);
+        _RS_ASSERT("wrapS.getAnisotropy() == 1.0f",
+                    wrapS.getAnisotropy() == 1.0f);
+
+        _RS_ASSERT("wrapT.getMagnification() == Sampler.Value.NEAREST",
+                    wrapT.getMagnification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("wrapT.getMinification() == Sampler.Value.NEAREST",
+                    wrapT.getMinification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("wrapT.getWrapS() == Sampler.Value.CLAMP",
+                    wrapT.getWrapS() == Sampler.Value.CLAMP);
+        _RS_ASSERT("wrapT.getWrapT() == Sampler.Value.WRAP",
+                    wrapT.getWrapT() == Sampler.Value.WRAP);
+        _RS_ASSERT("wrapT.getAnisotropy() == 1.0f",
+                    wrapT.getAnisotropy() == 1.0f);
+
+        _RS_ASSERT("anisotropy.getMagnification() == Sampler.Value.NEAREST",
+                    anisotropy.getMagnification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("anisotropy.getMinification() == Sampler.Value.NEAREST",
+                    anisotropy.getMinification() == Sampler.Value.NEAREST);
+        _RS_ASSERT("anisotropy.getWrapS() == Sampler.Value.CLAMP",
+                    anisotropy.getWrapS() == Sampler.Value.CLAMP);
+        _RS_ASSERT("anisotropy.getWrapT() == Sampler.Value.CLAMP",
+                    anisotropy.getWrapT() == Sampler.Value.CLAMP);
+        _RS_ASSERT("anisotropy.getAnisotropy() == 1.0f",
+                    anisotropy.getAnisotropy() == 8.0f);
+
+        updateUI();
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        testScriptSide(pRS);
+        testJavaSide(pRS);
         pRS.destroy();
     }
 }
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
index 6151431..a97ffa7 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
@@ -16,6 +16,7 @@
 
 package com.android.rs.test;
 import android.content.Context;
+import android.util.Log;
 import android.renderscript.RenderScript.RSMessageHandler;
 
 public class UnitTest extends Thread {
@@ -55,6 +56,28 @@
         this (null, ctx);
     }
 
+    protected void _RS_ASSERT(String message, boolean b) {
+        if(b == false) {
+            result = -1;
+            Log.e(name, message + " FAILED");
+        }
+    }
+
+    protected void updateUI() {
+        if (mItem != null) {
+            mItem.result = result;
+            msgHandled = true;
+            try {
+                mRSTC.refreshTestResults();
+            }
+            catch (IllegalStateException e) {
+                /* Ignore the case where our message receiver has been
+                   disconnected. This happens when we leave the application
+                   before it finishes running all of the unit tests. */
+            }
+        }
+    }
+
     protected RSMessageHandler mRsMessage = new RSMessageHandler() {
         public void run() {
             if (result == 0) {
@@ -71,18 +94,7 @@
                 }
             }
 
-            if (mItem != null) {
-                mItem.result = result;
-                msgHandled = true;
-                try {
-                    mRSTC.refreshTestResults();
-                }
-                catch (IllegalStateException e) {
-                    /* Ignore the case where our message receiver has been
-                       disconnected. This happens when we leave the application
-                       before it finishes running all of the unit tests. */
-                }
-            }
+            updateUI();
         }
     };
 
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index a3e5d9a..cb55a9c 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -44,7 +44,7 @@
 	libpng
 
 ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -lrt -lpthread
+LOCAL_LDLIBS += -lrt -ldl -lpthread
 endif
 
 # Statically link libz for MinGW (Win SDK under Linux),
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 44bdff3..1e66ca2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -467,4 +467,8 @@
 
     public void dismissKeyguard() {
     }
+
+    public boolean hasNavigationBar() {
+        return false; // should this return something else?
+    }
 }
diff --git a/tools/localize/Android.mk b/tools/localize/Android.mk
index f284e86..5ec9feb 100644
--- a/tools/localize/Android.mk
+++ b/tools/localize/Android.mk
@@ -34,7 +34,7 @@
 	libcutils
     
 ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -lrt -lpthread
+LOCAL_LDLIBS += -lrt -ldl -lpthread
 endif
 
 
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index d118bd7..72a9858 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -22,7 +22,7 @@
 	libcutils
 
 ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -lpthread
+LOCAL_LDLIBS += -ldl -lpthread
 endif
 
 LOCAL_MODULE := obbtool
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
index 90979e1..1368a07 100644
--- a/tools/validatekeymaps/Android.mk
+++ b/tools/validatekeymaps/Android.mk
@@ -23,7 +23,7 @@
 	libcutils
 
 ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -lpthread
+LOCAL_LDLIBS += -ldl -lpthread
 endif
 
 LOCAL_MODULE := validatekeymaps
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index b76f8b9..e981da7 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -3043,9 +3043,14 @@
                         deferMessage(message);
                     }
                     break;
-                    /* Handle in  DisconnectedState */
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
+                    /* If we get a SUPPLICANT_STATE_CHANGE_EVENT before NETWORK_DISCONNECTION_EVENT
+                     * we have missed the network disconnection, transition to mDisconnectedState
+                     * and handle the rest of the events there
+                     */
                     deferMessage(message);
+                    handleNetworkDisconnect();
+                    transitionTo(mDisconnectedState);
                     break;
                 default:
                     return NOT_HANDLED;
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 5d5b9ef..b4cbd01 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -92,6 +92,14 @@
     private static final String DEFAULT_WALLED_GARDEN_URL =
             "http://clients3.google.com/generate_204";
     private static final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
+
+    /* Some carrier apps might have support captive portal handling. Add some delay to allow
+        app authentication to be done before our test.
+       TODO: This should go away once we provide an API to apps to disable walled garden test
+       for certain SSIDs
+     */
+    private static final int WALLED_GARDEN_START_DELAY_MS = 3000;
+
     private static final int DNS_INTRATEST_PING_INTERVAL_MS = 200;
     /* With some router setups, it takes a few hunder milli-seconds before connection is active */
     private static final int DNS_START_DELAY_MS = 1000;
@@ -101,29 +109,30 @@
     /**
      * Indicates the enable setting of WWS may have changed
      */
-    private static final int EVENT_WATCHDOG_TOGGLED = BASE + 1;
+    private static final int EVENT_WATCHDOG_TOGGLED                 = BASE + 1;
 
     /**
      * Indicates the wifi network state has changed. Passed w/ original intent
      * which has a non-null networkInfo object
      */
-    private static final int EVENT_NETWORK_STATE_CHANGE = BASE + 2;
+    private static final int EVENT_NETWORK_STATE_CHANGE             = BASE + 2;
     /**
      * Indicates the signal has changed. Passed with arg1
      * {@link #mNetEventCounter} and arg2 [raw signal strength]
      */
-    private static final int EVENT_RSSI_CHANGE = BASE + 3;
-    private static final int EVENT_SCAN_RESULTS_AVAILABLE = BASE + 4;
-    private static final int EVENT_WIFI_RADIO_STATE_CHANGE = BASE + 5;
-    private static final int EVENT_WATCHDOG_SETTINGS_CHANGE = BASE + 6;
+    private static final int EVENT_RSSI_CHANGE                      = BASE + 3;
+    private static final int EVENT_SCAN_RESULTS_AVAILABLE           = BASE + 4;
+    private static final int EVENT_WIFI_RADIO_STATE_CHANGE          = BASE + 5;
+    private static final int EVENT_WATCHDOG_SETTINGS_CHANGE         = BASE + 6;
 
-    private static final int MESSAGE_HANDLE_WALLED_GARDEN = BASE + 100;
-    private static final int MESSAGE_HANDLE_BAD_AP = BASE + 101;
+    private static final int MESSAGE_HANDLE_WALLED_GARDEN           = BASE + 100;
+    private static final int MESSAGE_HANDLE_BAD_AP                  = BASE + 101;
     /**
      * arg1 == mOnlineWatchState.checkCount
      */
-    private static final int MESSAGE_SINGLE_DNS_CHECK = BASE + 103;
-    private static final int MESSAGE_NETWORK_FOLLOWUP = BASE + 104;
+    private static final int MESSAGE_SINGLE_DNS_CHECK               = BASE + 102;
+    private static final int MESSAGE_NETWORK_FOLLOWUP               = BASE + 103;
+    private static final int MESSAGE_DELAYED_WALLED_GARDEN_CHECK    = BASE + 104;
 
     private Context mContext;
     private ContentResolver mContentResolver;
@@ -140,6 +149,7 @@
     private DnsCheckingState mDnsCheckingState = new DnsCheckingState();
     private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
     private DnsCheckFailureState mDnsCheckFailureState = new DnsCheckFailureState();
+    private DelayWalledGardenState mDelayWalledGardenState = new DelayWalledGardenState();
     private WalledGardenState mWalledGardenState = new WalledGardenState();
     private BlacklistedApState mBlacklistedApState = new BlacklistedApState();
 
@@ -209,6 +219,7 @@
                 addState(mConnectedState, mWatchdogEnabledState);
                     addState(mDnsCheckingState, mConnectedState);
                     addState(mDnsCheckFailureState, mConnectedState);
+                    addState(mDelayWalledGardenState, mConnectedState);
                     addState(mWalledGardenState, mConnectedState);
                     addState(mBlacklistedApState, mConnectedState);
                     addState(mOnlineWatchState, mConnectedState);
@@ -727,14 +738,7 @@
                     return HANDLED;
                 }
 
-                mLastWalledGardenCheckTime = SystemClock.elapsedRealtime();
-                if (isWalledGardenConnection()) {
-                    if (DBG) log("Walled garden test complete - walled garden detected");
-                    transitionTo(mWalledGardenState);
-                } else {
-                    if (DBG) log("Walled garden test complete - online");
-                    transitionTo(mOnlineWatchState);
-                }
+                transitionTo(mDelayWalledGardenState);
                 return HANDLED;
             }
 
@@ -780,6 +784,31 @@
         }
     }
 
+    class DelayWalledGardenState extends State {
+        @Override
+        public void enter() {
+            sendMessageDelayed(MESSAGE_DELAYED_WALLED_GARDEN_CHECK, WALLED_GARDEN_START_DELAY_MS);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_DELAYED_WALLED_GARDEN_CHECK:
+                    mLastWalledGardenCheckTime = SystemClock.elapsedRealtime();
+                    if (isWalledGardenConnection()) {
+                        if (DBG) log("Walled garden test complete - walled garden detected");
+                        transitionTo(mWalledGardenState);
+                    } else {
+                        if (DBG) log("Walled garden test complete - online");
+                        transitionTo(mOnlineWatchState);
+                    }
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+    }
+
     class OnlineWatchState extends State {
         /**
          * Signals a short-wait message is enqueued for the current 'guard' counter