Merge "Add setParameter/getParameter to MediaPlayer API. for bug 1982947"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index df7037c..53cae41 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -109,7 +109,10 @@
 
     run_command("NETWORK INTERFACES", 10, "su", "root", "netcfg", NULL);
     dump_file("NETWORK ROUTES", "/proc/net/route");
+    dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
     dump_file("ARP CACHE", "/proc/net/arp");
+    run_command("IPTABLES", 10, "su", "root", "iptables", "-L", NULL);
+    run_command("IPTABLE NAT", 10, "su", "root", "iptables", "-t", "nat", "-L", NULL);
 
     run_command("WIFI NETWORKS", 20,
             "su", "root", "wpa_cli", "list_networks", NULL);
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 1e4cca9..4107c5a 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1170,7 +1170,7 @@
         if (h2 < 0.5f)
             h2 = 0.5f;
 
-        if (h1 == h2) {
+        if (Float.compare(h1, h2) == 0) {
             dest.moveTo(h1, top);
             dest.lineTo(h1, bottom);
         } else {
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 6b2d8e4..6bde802 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -20,6 +20,7 @@
 
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.text.style.SuggestionSpan;
 
 import java.lang.reflect.Array;
 
@@ -277,8 +278,7 @@
         TextWatcher[] recipients = null;
 
         if (notify)
-            recipients = sendTextWillChange(start, end - start,
-                                            tbend - tbstart);
+            recipients = sendTextWillChange(start, end - start, tbend - tbstart);
 
         for (int i = mSpanCount - 1; i >= 0; i--) {
             if ((mSpanFlags[i] & SPAN_PARAGRAPH) == SPAN_PARAGRAPH) {
@@ -353,6 +353,7 @@
         // no need for span fixup on pure insertion
         if (tbend > tbstart && end - start == 0) {
             if (notify) {
+                removeSuggestionSpans(start, end);
                 sendTextChange(recipients, start, end - start, tbend - tbstart);
                 sendTextHasChanged(recipients);
             }
@@ -384,20 +385,10 @@
             }
 
             // remove 0-length SPAN_EXCLUSIVE_EXCLUSIVE
-            // XXX send notification on removal
-
             if (mSpanEnds[i] < mSpanStarts[i]) {
-                System.arraycopy(mSpans, i + 1,
-                                 mSpans, i, mSpanCount - (i + 1));
-                System.arraycopy(mSpanStarts, i + 1,
-                                 mSpanStarts, i, mSpanCount - (i + 1));
-                System.arraycopy(mSpanEnds, i + 1,
-                                 mSpanEnds, i, mSpanCount - (i + 1));
-                System.arraycopy(mSpanFlags, i + 1,
-                                 mSpanFlags, i, mSpanCount - (i + 1));
-
-                mSpanCount--;
+                removeSpan(i);
             }
+            removeSuggestionSpans(start, end);
         }
 
         if (notify) {
@@ -408,6 +399,32 @@
         return ret;
     }
 
+    /**
+     * Removes the SuggestionSpan that overlap the [start, end] range, and that would
+     * not make sense anymore after the change.
+     */
+    private void removeSuggestionSpans(int start, int end) {
+        for (int i = mSpanCount - 1; i >= 0; i--) {
+            final int spanEnd = mSpanEnds[i];
+            final int spanSpart = mSpanStarts[i];
+            if ((mSpans[i] instanceof SuggestionSpan) && (
+                    (spanSpart < start && spanEnd > start) ||
+                    (spanSpart < end && spanEnd > end))) {
+                removeSpan(i);
+            }
+        }
+    }
+
+    private void removeSpan(int i) {
+        // XXX send notification on removal
+        System.arraycopy(mSpans, i + 1, mSpans, i, mSpanCount - (i + 1));
+        System.arraycopy(mSpanStarts, i + 1, mSpanStarts, i, mSpanCount - (i + 1));
+        System.arraycopy(mSpanEnds, i + 1, mSpanEnds, i, mSpanCount - (i + 1));
+        System.arraycopy(mSpanFlags, i + 1, mSpanFlags, i, mSpanCount - (i + 1));
+
+        mSpanCount--;
+    }
+
     // Documentation from interface
     public SpannableStringBuilder replace(int start, int end, CharSequence tb) {
         return replace(start, end, tb, 0, tb.length());
@@ -465,16 +482,15 @@
             mGapStart++;
             mGapLength--;
 
-            if (mGapLength < 1)
+            if (mGapLength < 1) {
                 new Exception("mGapLength < 1").printStackTrace();
+            }
 
             int oldlen = (end + 1) - start;
 
-            int inserted = change(false, start + 1, start + 1,
-                                  tb, tbstart, tbend);
+            int inserted = change(false, start + 1, start + 1, tb, tbstart, tbend);
             change(false, start, start + 1, "", 0, 0);
-            change(false, start + inserted, start + inserted + oldlen - 1,
-                   "", 0, 0);
+            change(false, start + inserted, start + inserted + oldlen - 1, "", 0, 0);
 
             /*
              * Special case to keep the cursor in the same position
@@ -1274,7 +1290,6 @@
     private int[] mSpanFlags;
     private int mSpanCount;
 
-    private static final int MARK = 1;
     private static final int POINT = 2;
     private static final int PARAGRAPH = 3;
 
diff --git a/core/java/android/text/method/MultiTapKeyListener.java b/core/java/android/text/method/MultiTapKeyListener.java
index 6d94788..2a739fa 100644
--- a/core/java/android/text/method/MultiTapKeyListener.java
+++ b/core/java/android/text/method/MultiTapKeyListener.java
@@ -116,7 +116,7 @@
                     content.replace(selStart, selEnd,
                                     String.valueOf(current).toUpperCase());
                     removeTimeouts(content);
-                    Timeout t = new Timeout(content);
+                    new Timeout(content); // for its side effects
 
                     return true;
                 }
@@ -124,7 +124,7 @@
                     content.replace(selStart, selEnd,
                                     String.valueOf(current).toLowerCase());
                     removeTimeouts(content);
-                    Timeout t = new Timeout(content);
+                    new Timeout(content); // for its side effects
 
                     return true;
                 }
@@ -140,7 +140,7 @@
 
                     content.replace(selStart, selEnd, val, ix, ix + 1);
                     removeTimeouts(content);
-                    Timeout t = new Timeout(content);
+                    new Timeout(content); // for its side effects
 
                     return true;
                 }
@@ -206,7 +206,7 @@
             }
 
             removeTimeouts(content);
-            Timeout t = new Timeout(content);
+            new Timeout(content); // for its side effects
 
             // Set up the callback so we can remove the timeout if the
             // cursor moves.
diff --git a/core/java/android/text/style/DrawableMarginSpan.java b/core/java/android/text/style/DrawableMarginSpan.java
index 3c471a5..c2564d5 100644
--- a/core/java/android/text/style/DrawableMarginSpan.java
+++ b/core/java/android/text/style/DrawableMarginSpan.java
@@ -50,9 +50,6 @@
         int dw = mDrawable.getIntrinsicWidth();
         int dh = mDrawable.getIntrinsicHeight();
 
-        if (dir < 0)
-            x -= dw;
-
         // XXX What to do about Paint?
         mDrawable.setBounds(ix, itop, ix+dw, itop+dh);
         mDrawable.draw(c);
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 11c9392..5e18f55 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -253,7 +253,7 @@
     public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
 
     private static final int MAX_POOL_SIZE = 10;
-    private static final Object mPoolLock = new Object();
+    private static final Object sPoolLock = new Object();
     private static AccessibilityEvent sPool;
     private static int sPoolSize;
 
@@ -375,7 +375,7 @@
      * @return An instance.
      */
     public static AccessibilityEvent obtain() {
-        synchronized (mPoolLock) {
+        synchronized (sPoolLock) {
             if (sPool != null) {
                 AccessibilityEvent event = sPool;
                 sPool = sPool.mNext;
@@ -392,14 +392,16 @@
      * Return an instance back to be reused.
      * <p>
      * <b>Note: You must not touch the object after calling this function.</b>
+     *
+     * @throws IllegalStateException If the event is already recycled.
      */
     @Override
     public void recycle() {
         if (mIsInPool) {
-            return;
+            throw new IllegalStateException("Event already recycled!");
         }
         clear();
-        synchronized (mPoolLock) {
+        synchronized (sPoolLock) {
             if (sPoolSize <= MAX_POOL_SIZE) {
                 mNext = sPool;
                 sPool = this;
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index e095f43..fecf9df 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -39,7 +39,7 @@
     private static final int PROPERTY_FULL_SCREEN = 0x00000080;
 
     private static final int MAX_POOL_SIZE = 10;
-    private static final Object mPoolLock = new Object();
+    private static final Object sPoolLock = new Object();
     private static AccessibilityRecord sPool;
     private static int sPoolSize;
 
@@ -342,7 +342,7 @@
      * @return An instance.
      */
     protected static AccessibilityRecord obtain() {
-        synchronized (mPoolLock) {
+        synchronized (sPoolLock) {
             if (sPool != null) {
                 AccessibilityRecord record = sPool;
                 sPool = sPool.mNext;
@@ -359,13 +359,15 @@
      * Return an instance back to be reused.
      * <p>
      * <b>Note: You must not touch the object after calling this function.</b>
+     *
+     * @throws IllegalStateException If the record is already recycled.
      */
     public void recycle() {
         if (mIsInPool) {
-            return;
+            throw new IllegalStateException("Record already recycled!");
         }
         clear();
-        synchronized (mPoolLock) {
+        synchronized (sPoolLock) {
             if (sPoolSize <= MAX_POOL_SIZE) {
                 mNext = sPool;
                 sPool = this;
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 060f1a9..7fbfcbb 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -899,6 +899,8 @@
 
     @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
+
         View selectedView = getSelectedView();
         if (selectedView != null) {
             event.setEnabled(selectedView.isEnabled());
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 5618dbe..d115364 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -2009,16 +2009,12 @@
         ListAdapter adapter = getAdapter();
         if (adapter != null) {
             final int count = adapter.getCount();
-            if (count < 15) {
-                for (int i = 0; i < count; i++) {
-                    if (adapter.isEnabled(i)) {
-                        itemCount++;
-                    } else if (i <= currentItemIndex) {
-                        currentItemIndex--;
-                    }
+            for (int i = 0; i < count; i++) {
+                if (adapter.isEnabled(i)) {
+                    itemCount++;
+                } else if (i <= currentItemIndex) {
+                    currentItemIndex--;
                 }
-            } else {
-                itemCount = count;
             }
         }
 
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 72b70bc..de32c2b 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1489,6 +1489,10 @@
         @Override
         public boolean dispatchKeyEvent(KeyEvent event) {
             if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+                if (getKeyDispatcherState() == null) {
+                    return super.dispatchKeyEvent(event);
+                }
+
                 if (event.getAction() == KeyEvent.ACTION_DOWN
                         && event.getRepeatCount() == 0) {
                     KeyEvent.DispatcherState state = getKeyDispatcherState();
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 96d41a0..c4ba270 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -66,15 +66,16 @@
  *
  * <p>
  * A progress bar can also be made indeterminate. In indeterminate mode, the
- * progress bar shows a cyclic animation. This mode is used by applications
- * when the length of the task is unknown. 
+ * progress bar shows a cyclic animation without an indication of progress. This mode is used by
+ * applications when the length of the task is unknown. The indeterminate progress bar can be either
+ * a spinning wheel or a horizontal bar.
  * </p>
  *
  * <p>The following code example shows how a progress bar can be used from
  * a worker thread to update the user interface to notify the user of progress:
  * </p>
  * 
- * <pre class="prettyprint">
+ * <pre>
  * public class MyActivity extends Activity {
  *     private static final int PROGRESS = 0x1;
  *
@@ -93,7 +94,7 @@
  *         // Start lengthy operation in a background thread
  *         new Thread(new Runnable() {
  *             public void run() {
- *                 while (mProgressStatus < 100) {
+ *                 while (mProgressStatus &lt; 100) {
  *                     mProgressStatus = doWork();
  *
  *                     // Update the progress bar
@@ -106,8 +107,61 @@
  *             }
  *         }).start();
  *     }
- * }
- * </pre>
+ * }</pre>
+ *
+ * <p>To add a progress bar to a layout file, you can use the {@code &lt;ProgressBar&gt;} element.
+ * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a
+ * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal
+ * Widget.ProgressBar.Horizontal} style, like so:</p>
+ *
+ * <pre>
+ * &lt;ProgressBar
+ *     style="@android:style/Widget.ProgressBar.Horizontal"
+ *     ... /&gt;</pre>
+ *
+ * <p>If you will use the progress bar to show real progress, you must use the horizontal bar. You
+ * can then increment the  progress with {@link #incrementProgressBy incrementProgressBy()} or
+ * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If
+ * necessary, you can adjust the maximum value (the value for a full bar) using the {@link
+ * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed
+ * below.</p>
+ *
+ * <p>Another common style to apply to the progress bar is {@link
+ * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller
+ * version of the spinning wheel&mdash;useful when waiting for content to load.
+ * For example, you can insert this kind of progress bar into your default layout for
+ * a view that will be populated by some content fetched from the Internet&mdash;the spinning wheel
+ * appears immediately and when your application receives the content, it replaces the progress bar
+ * with the loaded content. For example:</p>
+ *
+ * <pre>
+ * &lt;LinearLayout
+ *     android:orientation="horizontal"
+ *     ... &gt;
+ *     &lt;ProgressBar
+ *         android:layout_width="wrap_content"
+ *         android:layout_height="wrap_content"
+ *         style="@android:style/Widget.ProgressBar.Small"
+ *         android:layout_marginRight="5dp" /&gt;
+ *     &lt;TextView
+ *         android:layout_width="wrap_content"
+ *         android:layout_height="wrap_content"
+ *         android:text="@string/loading" /&gt;
+ * &lt;/LinearLayout&gt;</pre>
+ *
+ * <p>Other progress bar styles provided by the system include:</p>
+ * <ul>
+ * <li>{@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Small_Inverse
+ * Widget.ProgressBar.Small.Inverse}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Large_Inverse
+ * Widget.ProgressBar.Large.Inverse}</li>
+ * </ul>
+ * <p>The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary
+ * if your application uses a light colored theme (a white background).</p>
  *  
  * <p><strong>XML attributes</b></strong> 
  * <p> 
@@ -115,13 +169,21 @@
  * {@link android.R.styleable#View View Attributes}
  * </p>
  * 
- * <p><strong>Styles</b></strong> 
- * <p> 
- * @attr ref android.R.styleable#Theme_progressBarStyle
- * @attr ref android.R.styleable#Theme_progressBarStyleSmall
- * @attr ref android.R.styleable#Theme_progressBarStyleLarge
- * @attr ref android.R.styleable#Theme_progressBarStyleHorizontal
- * </p>
+ * @attr ref android.R.styleable#ProgressBar_animationResolution
+ * @attr ref android.R.styleable#ProgressBar_indeterminate
+ * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior
+ * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable
+ * @attr ref android.R.styleable#ProgressBar_indeterminateDuration
+ * @attr ref android.R.styleable#ProgressBar_indeterminateOnly
+ * @attr ref android.R.styleable#ProgressBar_interpolator
+ * @attr ref android.R.styleable#ProgressBar_max
+ * @attr ref android.R.styleable#ProgressBar_maxHeight
+ * @attr ref android.R.styleable#ProgressBar_maxWidth
+ * @attr ref android.R.styleable#ProgressBar_minHeight
+ * @attr ref android.R.styleable#ProgressBar_minWidth
+ * @attr ref android.R.styleable#ProgressBar_progress
+ * @attr ref android.R.styleable#ProgressBar_progressDrawable
+ * @attr ref android.R.styleable#ProgressBar_secondaryProgress
  */
 @RemoteView
 public class ProgressBar extends View {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 6c5d117..24b176d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -336,6 +336,8 @@
     // Set when this TextView gained focus with some text selected. Will start selection mode.
     private boolean mCreatedWithASelection = false;
 
+    private WordIterator mWordIterator;
+
     /*
      * Kick-start the font cache for the zygote process (to pay the cost of
      * initializing freetype for our default font only once).
@@ -7754,78 +7756,6 @@
                 type == Character.DECIMAL_DIGIT_NUMBER);
     }
 
-    /**
-     * Returns the offsets delimiting the 'word' located at position offset.
-     *
-     * @param offset An offset in the text.
-     * @return The offsets for the start and end of the word located at <code>offset</code>.
-     * The two ints offsets are packed in a long using {@link #packRangeInLong(int, int)}.
-     * Returns -1 if no valid word was found.
-     */
-    private long getWordLimitsAt(int offset) {
-        int klass = mInputType & InputType.TYPE_MASK_CLASS;
-        int variation = mInputType & InputType.TYPE_MASK_VARIATION;
-
-        // Text selection is not permitted in password fields
-        if (hasPasswordTransformationMethod()) {
-            return -1;
-        }
-
-        final int len = mText.length();
-
-        // Specific text fields: always select the entire text
-        if (klass == InputType.TYPE_CLASS_NUMBER ||
-                klass == InputType.TYPE_CLASS_PHONE ||
-                klass == InputType.TYPE_CLASS_DATETIME ||
-                variation == InputType.TYPE_TEXT_VARIATION_URI ||
-                variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS ||
-                variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS ||
-                variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
-            return len > 0 ? packRangeInLong(0, len) : -1;
-        }
-
-        int end = Math.min(offset, len);
-        if (end < 0) {
-            return -1;
-        }
-
-        final int MAX_LENGTH = 48;
-        int start = end;
-
-        for (; start > 0; start--) {
-            final char c = mTransformed.charAt(start - 1);
-            final int type = Character.getType(c);
-            if (start == end && type == Character.OTHER_PUNCTUATION) { 
-                // Cases where the text ends with a '.' and we select from the end of the line
-                // (right after the dot), or when we select from the space character in "aaa, bbb".
-                continue;
-            }
-            if (type == Character.SURROGATE) { // Two Character codepoint
-                end = start - 1; // Recheck as a pair when scanning forward
-                continue;
-            }
-            if (!isWordCharacter(c, type)) break;
-            if ((end - start) > MAX_LENGTH) return -1;
-        }
-
-        for (; end < len; end++) {
-            final int c = Character.codePointAt(mTransformed, end);
-            final int type = Character.getType(c);
-            if (!isWordCharacter(c, type)) break;
-            if ((end - start) > MAX_LENGTH) return -1;
-            if (c > 0xFFFF) { // Two Character codepoint
-                end++;
-            }
-        }
-
-        if (start == end) {
-            return -1;
-        }
-
-        // Two ints packed in a long
-        return packRangeInLong(start, end);
-    }
-
     private static long packRangeInLong(int start, int end) {
         return (((long) start) << 32) | end;
     }
@@ -7838,21 +7768,40 @@
         return (int) (range & 0x00000000FFFFFFFFL);
     }
 
-    private void selectAll() {
-        Selection.setSelection((Spannable) mText, 0, mText.length());
+    private boolean selectAll() {
+        final int length = mText.length();
+        Selection.setSelection((Spannable) mText, 0, length);
+        return length > 0;
     }
 
-    private void selectCurrentWord() {
+    /**
+     * Adjusts selection to the word under last touch offset.
+     * Return true if the operation was successfully performed.
+     */
+    private boolean selectCurrentWord() {
         if (!canSelectText()) {
-            return;
+            return false;
         }
 
         if (hasPasswordTransformationMethod()) {
             // Always select all on a password field.
             // Cut/copy menu entries are not available for passwords, but being able to select all
             // is however useful to delete or paste to replace the entire content.
-            selectAll();
-            return;
+            return selectAll();
+        }
+
+        int klass = mInputType & InputType.TYPE_MASK_CLASS;
+        int variation = mInputType & InputType.TYPE_MASK_VARIATION;
+
+        // Specific text field types: select the entire text for these
+        if (klass == InputType.TYPE_CLASS_NUMBER ||
+                klass == InputType.TYPE_CLASS_PHONE ||
+                klass == InputType.TYPE_CLASS_DATETIME ||
+                variation == InputType.TYPE_TEXT_VARIATION_URI ||
+                variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS ||
+                variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS ||
+                variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
+            return selectAll();
         }
 
         long lastTouchOffsets = getLastTouchOffsets();
@@ -7868,22 +7817,21 @@
             selectionStart = ((Spanned) mText).getSpanStart(url);
             selectionEnd = ((Spanned) mText).getSpanEnd(url);
         } else {
-            long wordLimits = getWordLimitsAt(minOffset);
-            if (wordLimits >= 0) {
-                selectionStart = extractRangeStartFromLong(wordLimits);
-            } else {
-                selectionStart = Math.max(minOffset - 5, 0);
+            if (mWordIterator == null) {
+                mWordIterator = new WordIterator();
             }
+            // WordIerator handles text changes, this is a no-op if text in unchanged.
+            mWordIterator.setCharSequence(mText);
 
-            wordLimits = getWordLimitsAt(maxOffset);
-            if (wordLimits >= 0) {
-                selectionEnd = extractRangeEndFromLong(wordLimits);
-            } else {
-                selectionEnd = Math.min(maxOffset + 5, mText.length());
-            }
+            selectionStart = mWordIterator.getBeginning(minOffset);
+            if (selectionStart == BreakIterator.DONE) return false;
+
+            selectionEnd = mWordIterator.getEnd(maxOffset);
+            if (selectionEnd == BreakIterator.DONE) return false;
         }
 
         Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
+        return true;
     }
 
     private long getLastTouchOffsets() {
@@ -7903,6 +7851,8 @@
 
     @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
+
         if (!isShown()) {
             return;
         }
@@ -8007,6 +7957,8 @@
      * this will be {@link android.R.id#copyUrl}, {@link android.R.id#selectTextMode},
      * {@link android.R.id#selectAll}, {@link android.R.id#paste}, {@link android.R.id#cut}
      * or {@link android.R.id#copy}.
+     *
+     * @return true if the context menu item action was performed.
      */
     public boolean onTextContextMenuItem(int id) {
         int min = 0;
@@ -8051,7 +8003,7 @@
 
             case ID_SELECT_ALL:
                 // This does not enter text selection mode. Text is highlighted, so that it can be
-                // bulk edited, like selectAllOnFocus does.
+                // bulk edited, like selectAllOnFocus does. Returns true even if text is empty.
                 selectAll();
                 return true;
 
@@ -8177,7 +8129,7 @@
                 mInsertionControllerEnabled) {
             final int offset = getOffset(mLastDownPositionX, mLastDownPositionY);
             stopSelectionActionMode();
-            Selection.setSelection((Spannable)mText, offset);
+            Selection.setSelection((Spannable) mText, offset);
             getInsertionController().showWithPaste();
             handled = true;
         }
@@ -8662,9 +8614,10 @@
             return false;
         }
 
-        if (!hasSelection()) {
-            // If selection mode is started after a device rotation, there is already a selection.
-            selectCurrentWord();
+        boolean currentWordSelected = selectCurrentWord();
+        if (!currentWordSelected) {
+            // No word found under cursor or text selection not permitted.
+            return false;
         }
 
         ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
@@ -8695,16 +8648,17 @@
             (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
         ClipData clip = clipboard.getPrimaryClip();
         if (clip != null) {
-            boolean didfirst = false;
+            boolean didFirst = false;
             for (int i=0; i<clip.getItemCount(); i++) {
                 CharSequence paste = clip.getItemAt(i).coerceToText(getContext());
                 if (paste != null) {
-                    if (!didfirst) {
+                    if (!didFirst) {
                         long minMax = prepareSpacesAroundPaste(min, max, paste);
                         min = extractRangeStartFromLong(minMax);
                         max = extractRangeEndFromLong(minMax);
                         Selection.setSelection((Spannable) mText, max);
                         ((Editable) mText).replace(min, max, paste);
+                        didFirst = true;
                     } else {
                         ((Editable) mText).insert(getSelectionEnd(), "\n");
                         ((Editable) mText).insert(getSelectionEnd(), paste);
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 10d25bb..2a551e9 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -264,8 +264,8 @@
 names.</p>
 <table>
     <tr>
-        <th>Qualifier</th>
-        <th>Values</th>
+        <th>Configuration</th>
+        <th>Qualifier Values</th>
         <th>Description</th>
     </tr>
     <tr id="MccQualifier">
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index a278466..c9c9fd7 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -546,10 +546,8 @@
         mBitmapState = state;
         if (res != null) {
             mTargetDensity = res.getDisplayMetrics().densityDpi;
-        } else if (state != null) {
-            mTargetDensity = state.mTargetDensity;
         } else {
-            mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+            mTargetDensity = state.mTargetDensity;
         }
         setBitmap(state != null ? state.mBitmap : null);
     }
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 3f6f8c3..256435f 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -381,7 +381,7 @@
     LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i)",
             con, eid, dimx, dimy, dimz, mips, faces);
 
-    jint id = (jint)rsaTypeCreate(con, (RsElement)eid, dimx, dimy, dimz, mips, faces);
+    jint id = (jint)rsTypeCreate(con, (RsElement)eid, dimx, dimy, dimz, mips, faces);
     return (jint)id;
 }
 
@@ -409,7 +409,7 @@
 nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage)
 {
     LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i)", con, (RsElement)type, mips, usage);
-    return (jint) rsaAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage);
+    return (jint) rsAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage);
 }
 
 static void
@@ -435,7 +435,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsaAllocationCreateFromBitmap(con,
+    jint id = (jint)rsAllocationCreateFromBitmap(con,
                                                   (RsType)type, (RsAllocationMipmapControl)mip,
                                                   ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
@@ -451,7 +451,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsaAllocationCubeCreateFromBitmap(con,
+    jint id = (jint)rsAllocationCubeCreateFromBitmap(con,
                                                       (RsType)type, (RsAllocationMipmapControl)mip,
                                                       ptr, bitmap.getSize(), usage);
     bitmap.unlockPixels();
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index d2d1d7e..3330ebc 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -31,14 +31,17 @@
  * Error code for DRM Frameowrk
  */
 enum {
-    DRM_ERROR_BASE = -2000,
+    // The following constant values should be in sync with
+    // media/stagefright/MediaErrors.h
+    ERROR_BASE = -2000,
 
-    DRM_ERROR_UNKNOWN                       = DRM_ERROR_BASE,
-    DRM_ERROR_LICENSE_EXPIRED               = DRM_ERROR_BASE - 1,
-    DRM_ERROR_SESSION_NOT_OPENED            = DRM_ERROR_BASE - 2,
-    DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED  = DRM_ERROR_BASE - 3,
-    DRM_ERROR_DECRYPT                       = DRM_ERROR_BASE - 4,
-    DRM_ERROR_CANNOT_HANDLE                 = DRM_ERROR_BASE - 5,
+    DRM_ERROR_UNKNOWN                       = ERROR_BASE,
+    DRM_ERROR_NO_LICENSE                    = ERROR_BASE - 1,
+    DRM_ERROR_LICENSE_EXPIRED               = ERROR_BASE - 2,
+    DRM_ERROR_SESSION_NOT_OPENED            = ERROR_BASE - 3,
+    DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED  = ERROR_BASE - 4,
+    DRM_ERROR_DECRYPT                       = ERROR_BASE - 5,
+    DRM_ERROR_CANNOT_HANDLE                 = ERROR_BASE - 6,
 
     DRM_NO_ERROR                            = NO_ERROR
 };
diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
index 1a6d548..7cc993c 100644
--- a/include/media/stagefright/MediaErrors.h
+++ b/include/media/stagefright/MediaErrors.h
@@ -41,7 +41,17 @@
     INFO_FORMAT_CHANGED    = MEDIA_ERROR_BASE - 12,
     INFO_DISCONTINUITY     = MEDIA_ERROR_BASE - 13,
 
-    ERROR_NO_LICENSE       = MEDIA_ERROR_BASE - 14,
+    // The following constant values should be in sync with
+    // drm/drm_framework_common.h
+    DRM_ERROR_BASE = -2000,
+
+    ERROR_DRM_UNKNOWN                       = DRM_ERROR_BASE,
+    ERROR_DRM_NO_LICENSE                    = DRM_ERROR_BASE - 1,
+    ERROR_DRM_LICENSE_EXPIRED               = DRM_ERROR_BASE - 2,
+    ERROR_DRM_SESSION_NOT_OPENED            = DRM_ERROR_BASE - 3,
+    ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED  = DRM_ERROR_BASE - 4,
+    ERROR_DRM_DECRYPT                       = DRM_ERROR_BASE - 5,
+    ERROR_DRM_CANNOT_HANDLE                 = DRM_ERROR_BASE - 6,
 
     // Heartbeat Error Codes
     HEARTBEAT_ERROR_BASE = -3000,
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 6310cf6..0c4e1ed 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -66,7 +66,7 @@
     direct
 }
 
-aTypeCreate {
+TypeCreate {
     direct
     param RsElement e
     param uint32_t dimX
@@ -77,7 +77,7 @@
     ret RsType
 }
 
-aAllocationCreateTyped {
+AllocationCreateTyped {
     direct
     param RsType vtype
     param RsAllocationMipmapControl mips
@@ -85,7 +85,7 @@
     ret RsAllocation
 }
 
-aAllocationCreateFromBitmap {
+AllocationCreateFromBitmap {
     direct
     param RsType vtype
     param RsAllocationMipmapControl mips
@@ -94,7 +94,7 @@
     ret RsAllocation
 }
 
-aAllocationCubeCreateFromBitmap {
+AllocationCubeCreateFromBitmap {
     direct
     param RsType vtype
     param RsAllocationMipmapControl mips
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 743b2c4..b5f6f56 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -649,11 +649,12 @@
 //
 #ifndef ANDROID_RS_SERIALIZE
 
-static void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va);
 
 namespace android {
 namespace renderscript {
 
+static void AllocationGenerateScriptMips(RsContext con, RsAllocation va);
+
 void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
     Allocation *alloc = static_cast<Allocation *>(va);
     alloc->deferredUploadToTexture(rsc);
@@ -740,7 +741,7 @@
 
 void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
     Allocation *texAlloc = static_cast<Allocation *>(va);
-    rsaAllocationGenerateScriptMips(rsc, texAlloc);
+    AllocationGenerateScriptMips(rsc, texAlloc);
 }
 
 void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
@@ -795,10 +796,7 @@
     a->resize2D(rsc, dimX, dimY);
 }
 
-}
-}
-
-static void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va) {
+static void AllocationGenerateScriptMips(RsContext con, RsAllocation va) {
     Context *rsc = static_cast<Context *>(con);
     Allocation *texAlloc = static_cast<Allocation *>(va);
     uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
@@ -815,29 +813,20 @@
     }
 }
 
-const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
-    Allocation *a = static_cast<Allocation *>(va);
-    a->getType()->incUserRef();
-
-    return a->getType();
-}
-
-RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
-                                      RsAllocationMipmapControl mips,
-                                      uint32_t usages) {
-    Context *rsc = static_cast<Context *>(con);
+RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
+                                       RsAllocationMipmapControl mips,
+                                       uint32_t usages) {
     Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
     alloc->incUserRef();
     return alloc;
 }
 
-RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
-                                           RsAllocationMipmapControl mips,
-                                           const void *data, size_t data_length, uint32_t usages) {
-    Context *rsc = static_cast<Context *>(con);
+RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
+                                            RsAllocationMipmapControl mips,
+                                            const void *data, size_t data_length, uint32_t usages) {
     Type *t = static_cast<Type *>(vtype);
 
-    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
+    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
     Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
     if (texAlloc == NULL) {
         LOGE("Memory allocation failure");
@@ -846,23 +835,22 @@
 
     memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
     if (mips == RS_ALLOCATION_MIPMAP_FULL) {
-        rsaAllocationGenerateScriptMips(rsc, texAlloc);
+        AllocationGenerateScriptMips(rsc, texAlloc);
     }
 
     texAlloc->deferredUploadToTexture(rsc);
     return texAlloc;
 }
 
-RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
-                                               RsAllocationMipmapControl mips,
-                                               const void *data, size_t data_length, uint32_t usages) {
-    Context *rsc = static_cast<Context *>(con);
+RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
+                                                RsAllocationMipmapControl mips,
+                                                const void *data, size_t data_length, uint32_t usages) {
     Type *t = static_cast<Type *>(vtype);
 
     // Cubemap allocation's faces should be Width by Width each.
     // Source data should have 6 * Width by Width pixels
     // Error checking is done in the java layer
-    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
+    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
     Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
     if (texAlloc == NULL) {
         LOGE("Memory allocation failure");
@@ -887,11 +875,21 @@
     }
 
     if (mips == RS_ALLOCATION_MIPMAP_FULL) {
-        rsaAllocationGenerateScriptMips(rsc, texAlloc);
+        AllocationGenerateScriptMips(rsc, texAlloc);
     }
 
     texAlloc->deferredUploadToTexture(rsc);
     return texAlloc;
 }
 
+}
+}
+
+const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
+    Allocation *a = static_cast<Allocation *>(va);
+    a->getType()->incUserRef();
+
+    return a->getType();
+}
+
 #endif //ANDROID_RS_SERIALIZE
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 50f5f55..4321592 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -598,7 +598,7 @@
     *subID = d[0];
 
     //LOGE("getMessageToClient  %i %i", commandID, *subID);
-    if (bufferLen >= bytesData) {
+    if (bufferLen >= (*receiveLen)) {
         memcpy(data, d+1, *receiveLen);
         mIO.mToClient.next();
         return (RsMessageToClientType)commandID;
@@ -740,25 +740,21 @@
     rsc->destroyWorkerThreadResources();;
 }
 
-}
-}
-
-void rsContextDestroy(RsContext vcon) {
-    LOGV("rsContextDestroy %p", vcon);
-    Context *rsc = static_cast<Context *>(vcon);
+void rsi_ContextDestroy(Context *rsc) {
+    LOGV("rsContextDestroy %p", rsc);
     rsContextDestroyWorker(rsc);
     delete rsc;
-    LOGV("rsContextDestroy 2 %p", vcon);
+    LOGV("rsContextDestroy 2 %p", rsc);
 }
 
-RsContext rsContextCreate(RsDevice vdev, uint32_t version) {
+RsContext rsi_ContextCreate(RsDevice vdev, uint32_t version) {
     LOGV("rsContextCreate %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, NULL);
     return rsc;
 }
 
-RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
+RsContext rsi_ContextCreateGL(RsDevice vdev, uint32_t version,
                             RsSurfaceConfig sc, uint32_t dpi) {
     LOGV("rsContextCreateGL %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
@@ -768,32 +764,31 @@
     return rsc;
 }
 
-RsMessageToClientType rsContextPeekMessage(RsContext vrsc,
+RsMessageToClientType rsi_ContextPeekMessage(Context *rsc,
                                            size_t * receiveLen, size_t receiveLen_length,
                                            uint32_t * subID, size_t subID_length, bool wait) {
-    Context * rsc = static_cast<Context *>(vrsc);
     return rsc->peekMessageToClient(receiveLen, subID, wait);
 }
 
-RsMessageToClientType rsContextGetMessage(RsContext vrsc, void * data, size_t data_length,
+RsMessageToClientType rsi_ContextGetMessage(Context *rsc, void * data, size_t data_length,
                                           size_t * receiveLen, size_t receiveLen_length,
                                           uint32_t * subID, size_t subID_length, bool wait) {
-    Context * rsc = static_cast<Context *>(vrsc);
     rsAssert(subID_length == sizeof(uint32_t));
     rsAssert(receiveLen_length == sizeof(size_t));
     return rsc->getMessageToClient(data, receiveLen, subID, data_length, wait);
 }
 
-void rsContextInitToClient(RsContext vrsc) {
-    Context * rsc = static_cast<Context *>(vrsc);
+void rsi_ContextInitToClient(Context *rsc) {
     rsc->initToClient();
 }
 
-void rsContextDeinitToClient(RsContext vrsc) {
-    Context * rsc = static_cast<Context *>(vrsc);
+void rsi_ContextDeinitToClient(Context *rsc) {
     rsc->deinitToClient();
 }
 
+}
+}
+
 // Only to be called at a3d load time, before object is visible to user
 // not thread safe
 void rsaGetName(RsContext con, void * obj, const char **name) {
diff --git a/libs/rs/rsDevice.cpp b/libs/rs/rsDevice.cpp
index d7d03f6..849fd98 100644
--- a/libs/rs/rsDevice.cpp
+++ b/libs/rs/rsDevice.cpp
@@ -40,17 +40,20 @@
     }
 }
 
-RsDevice rsDeviceCreate() {
+namespace android {
+namespace renderscript {
+
+RsDevice rsi_DeviceCreate() {
     Device * d = new Device();
     return d;
 }
 
-void rsDeviceDestroy(RsDevice dev) {
+void rsi_DeviceDestroy(RsDevice dev) {
     Device * d = static_cast<Device *>(dev);
     delete d;
 }
 
-void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value) {
+void rsi_DeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value) {
     Device * d = static_cast<Device *>(dev);
     if (p == RS_DEVICE_PARAM_FORCE_SOFTWARE_GL) {
         d->mForceSW = value != 0;
@@ -59,3 +62,5 @@
     rsAssert(0);
 }
 
+}
+}
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index cd2be94..10e3182 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -274,17 +274,16 @@
 namespace android {
 namespace renderscript {
 
-}
-}
-
-RsType rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimX,
+RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX,
                      uint32_t dimY, uint32_t dimZ, bool mips, bool faces) {
-    Context *rsc = static_cast<Context *>(con);
     Element *e = static_cast<Element *>(_e);
 
     return Type::getType(rsc, e, dimX, dimY, dimZ, mips, faces);
 }
 
+}
+}
+
 void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
     rsAssert(typeDataSize == 6);
     // Pack the data in the follofing way mDimX; mDimY; mDimZ;
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 0059f19..ed20fef 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -97,9 +97,20 @@
     }
 }
 
-void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext) {
+void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext, int isFnPtr) {
     printVarTypeAndName(f, &api->ret);
-    fprintf(f, " %s%s (", prefix, api->name);
+    if (isFnPtr) {
+        char t[1024];
+        strcpy(t, api->name);
+        if (strlen(prefix) == 0) {
+            if (t[0] > 'A' && t[0] < 'Z') {
+                t[0] -= 'A' - 'a';
+            }
+        }
+        fprintf(f, " (* %s%s) (", prefix, api->name);
+    } else {
+        fprintf(f, " %s%s (", prefix, api->name);
+    }
     if (!api->nocontext) {
         if (addContext) {
             fprintf(f, "Context *");
@@ -114,12 +125,24 @@
 void printFuncDecls(FILE *f, const char *prefix, int addContext) {
     int ct;
     for (ct=0; ct < apiCount; ct++) {
-        printFuncDecl(f, &apis[ct], prefix, addContext);
+        printFuncDecl(f, &apis[ct], prefix, addContext, 0);
         fprintf(f, ";\n");
     }
     fprintf(f, "\n\n");
 }
 
+void printFuncPointers(FILE *f, int addContext) {
+    fprintf(f, "\n");
+    fprintf(f, "typedef struct RsApiEntrypoints {\n");
+    int ct;
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    ");
+        printFuncDecl(f, &apis[ct], "", addContext, 1);
+        fprintf(f, ";\n");
+    }
+    fprintf(f, "} RsApiEntrypoints_t;\n\n");
+}
+
 void printPlaybackFuncs(FILE *f, const char *prefix) {
     int ct;
     for (ct=0; ct < apiCount; ct++) {
@@ -172,21 +195,35 @@
     fprintf(f, "#include \"rsHandcode.h\"\n");
     fprintf(f, "\n");
 
+    printFuncPointers(f, 0);
+
+    // Generate RS funcs for local fifo
     for (ct=0; ct < apiCount; ct++) {
         int needFlush = 0;
         const ApiEntry * api = &apis[ct];
 
-        if (api->direct) {
-            continue;
-        }
-
-        printFuncDecl(f, api, "rs", 0);
+        fprintf(f, "static ");
+        printFuncDecl(f, api, "LF_", 0, 0);
         fprintf(f, "\n{\n");
-        if (api->handcodeApi) {
-            fprintf(f, "    rsHCAPI_%s(rsc", api->name);
+        if (api->handcodeApi || api->direct) {
+            if (api->handcodeApi) {
+                fprintf(f, "    rsHCAPI_%s(rsc", api->name);
+            } else {
+                fprintf(f, "    ");
+                if (api->ret.typeName[0]) {
+                    fprintf(f, "return ");
+                }
+                fprintf(f, "rsi_%s(", api->name);
+                if (!api->nocontext) {
+                    fprintf(f, "(Context *)rsc");
+                }
+            }
             for (ct2=0; ct2 < api->paramCount; ct2++) {
                 const VarType *vt = &api->params[ct2];
-                fprintf(f, ", %s", vt->name);
+                if (ct2 > 0 || !api->nocontext) {
+                    fprintf(f, ", ");
+                }
+                fprintf(f, "%s", vt->name);
             }
             fprintf(f, ");\n");
         } else {
@@ -252,6 +289,43 @@
         }
         fprintf(f, "};\n\n");
     }
+
+    fprintf(f, "\n");
+    fprintf(f, "static RsApiEntrypoints_t s_LocalTable = {\n");
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    LF_%s,\n", apis[ct].name);
+    }
+    fprintf(f, "};\n");
+
+    fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
+
+    for (ct=0; ct < apiCount; ct++) {
+        int needFlush = 0;
+        const ApiEntry * api = &apis[ct];
+
+        printFuncDecl(f, api, "rs", 0, 0);
+        fprintf(f, "\n{\n");
+        fprintf(f, "    ");
+        if (api->ret.typeName[0]) {
+            fprintf(f, "return ");
+        }
+        fprintf(f, "s_CurrentTable->%s(", api->name);
+
+        if (!api->nocontext) {
+            fprintf(f, "(Context *)rsc");
+        }
+
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (ct2 > 0 || !api->nocontext) {
+                fprintf(f, ", ");
+            }
+            fprintf(f, "%s", vt->name);
+        }
+        fprintf(f, ");\n");
+        fprintf(f, "}\n\n");
+    }
+
 }
 
 void printPlaybackCpp(FILE *f) {
@@ -373,6 +447,19 @@
             printPlaybackCpp(f);
         }
         break;
+
+        case '4': // rsgApiStream.cpp
+        {
+            printFileHeader(f);
+            printPlaybackCpp(f);
+        }
+
+        case '5': // rsgApiStreamReplay.cpp
+        {
+            printFileHeader(f);
+            printPlaybackCpp(f);
+        }
+        break;
     }
     fclose(f);
     return 0;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 145b935..974efa7 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -312,7 +312,7 @@
     if (mDecryptHandle != NULL) {
         CHECK(mDrmManagerClient);
         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
-            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
+            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
         }
     }
 
@@ -1801,7 +1801,7 @@
     if (mDecryptHandle != NULL) {
         CHECK(mDrmManagerClient);
         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
-            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
+            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
         }
     }
 
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index c4ed516..1f3d581 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -146,18 +146,14 @@
     DrmBuffer *pDecryptedDrmBuffer = &decryptedDrmBuffer;
 
     if ((err = mDrmManagerClient->decrypt(mDecryptHandle, mTrackId,
-            &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != DRM_NO_ERROR) {
+            &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != NO_ERROR) {
 
         if (decryptedDrmBuffer.data) {
             delete [] decryptedDrmBuffer.data;
             decryptedDrmBuffer.data = NULL;
         }
 
-        if (err == DRM_ERROR_LICENSE_EXPIRED) {
-            return ERROR_NO_LICENSE;
-        } else {
-            return ERROR_IO;
-        }
+        return err;
     }
     CHECK(pDecryptedDrmBuffer == &decryptedDrmBuffer);
 
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 1f06dcc..c47383a 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -316,9 +316,10 @@
                 filteredPos++;
             }
 
-            throw new IllegalArgumentException("position " + position + " out of "
-                    + "range of showable actions, filtered count = "
-                    + "= " + getCount() + ", keyguardshowing=" + mKeyguardShowing
+            throw new IllegalArgumentException("position " + position
+                    + " out of range of showable actions"
+                    + ", filtered count=" + getCount()
+                    + ", keyguardshowing=" + mKeyguardShowing
                     + ", provisioned=" + mDeviceProvisioned);
         }
 
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
index df579b0..c3b0ffc 100644
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/IccUtils.java
@@ -416,7 +416,6 @@
         int colorNumber = data[valueIndex++] & 0xFF;
         int clutOffset = ((data[valueIndex++] & 0xFF) << 8)
                 | (data[valueIndex++] & 0xFF);
-        length = length - 6;
 
         int[] colorIndexArray = getCLUT(data, clutOffset, colorNumber);
         if (true == transparency) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index f019487..32c5d75 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -44,22 +44,14 @@
 
     CDMALTEPhone mCdmaLtePhone;
 
-    private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
-
-    private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
+    private ServiceState  mLteSS;  // The last LTE state from Voice Registration
 
     public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
         super(phone);
         mCdmaLtePhone = phone;
-        if (DBG) log("CdmaLteServiceStateTracker Constructors");
-    }
 
-    /**
-     * @return The current GPRS state. IN_SERVICE is the same as "attached" and
-     *         OUT_OF_SERVICE is the same as detached.
-     */
-    public int getCurrentDataConnectionState() {
-        return gprsState;
+        mLteSS = new ServiceState();
+        if (DBG) log("CdmaLteServiceStateTracker Constructors");
     }
 
     @Override
@@ -77,11 +69,13 @@
     }
 
     /**
-     * The LTE data connection state, only return true here
+     * Set the cdmaSS for EVENT_POLL_STATE_REGISTRATION_CDMA
      */
     @Override
-    protected boolean checkAdditionalDataAvaiable() {
-        return newGPRSState != ServiceState.STATE_IN_SERVICE;
+    protected void setCdmaTechnology(int radioTechnology) {
+        // Called on voice registration state response.
+        // Just record new CDMA radio technology
+        newSS.setRadioTechnology(radioTechnology);
     }
 
     /**
@@ -109,14 +103,10 @@
                 }
             }
 
-            newGPRSState = regCodeToServiceState(regState);
             // Not sure if this is needed in CDMALTE phone.
             // mDataRoaming = regCodeIsRoaming(regState);
-            if (newGPRSState == ServiceState.STATE_IN_SERVICE) {
-                this.newCdmaDataConnectionState = newGPRSState;
-                newNetworkType = type;
-                newSS.setRadioTechnology(type);
-            }
+            mLteSS.setRadioTechnology(type);
+            mLteSS.setState(regCodeToServiceState(regState));
         } else {
             super.handlePollStateResultMessage(what, ar);
         }
@@ -216,6 +206,21 @@
 
     @Override
     protected void pollStateDone() {
+        // determine data NetworkType from both LET and CDMA SS
+        if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) {
+            //in LTE service
+            newNetworkType = mLteSS.getRadioTechnology();
+            mNewDataConnectionState = mLteSS.getState();
+            newSS.setRadioTechnology(newNetworkType);
+            log("pollStateDone LTE/eHRPD STATE_IN_SERVICE newNetworkType = " + newNetworkType);
+        } else {
+            // LTE out of service, get CDMA Service State
+            newNetworkType = newSS.getRadioTechnology();
+            mNewDataConnectionState = radioTechnologyToDataServiceState(newNetworkType);
+            log("pollStateDone CDMA STATE_IN_SERVICE newNetworkType = " + newNetworkType +
+                " mNewDataConnectionState = " + mNewDataConnectionState);
+        }
+
         if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
 
         boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE
@@ -225,15 +230,15 @@
                 && newSS.getState() != ServiceState.STATE_IN_SERVICE;
 
         boolean hasCdmaDataConnectionAttached =
-            this.cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE
-                && this.newCdmaDataConnectionState == ServiceState.STATE_IN_SERVICE;
+            mDataConnectionState != ServiceState.STATE_IN_SERVICE
+                && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
 
         boolean hasCdmaDataConnectionDetached =
-            this.cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE
-                && this.newCdmaDataConnectionState != ServiceState.STATE_IN_SERVICE;
+            mDataConnectionState == ServiceState.STATE_IN_SERVICE
+                && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
 
         boolean hasCdmaDataConnectionChanged =
-            cdmaDataConnectionState != newCdmaDataConnectionState;
+            mDataConnectionState != mNewDataConnectionState;
 
         boolean hasNetworkTypeChanged = networkType != newNetworkType;
 
@@ -272,9 +277,9 @@
         }
         // Add an event log when connection state changes
         if (ss.getState() != newSS.getState()
-                || cdmaDataConnectionState != newCdmaDataConnectionState) {
+                || mDataConnectionState != mNewDataConnectionState) {
             EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, ss.getState(),
-                    cdmaDataConnectionState, newSS.getState(), newCdmaDataConnectionState);
+                    mDataConnectionState, newSS.getState(), mNewDataConnectionState);
         }
 
         ServiceState tss;
@@ -283,6 +288,7 @@
         newSS = tss;
         // clean slate for next time
         newSS.setStateOutOfService();
+        mLteSS.setStateOutOfService();
 
         // TODO: 4G Tech Handoff
         // if (has4gHandoff) {
@@ -309,11 +315,9 @@
         cellLoc = newCellLoc;
         newCellLoc = tcl;
 
-        cdmaDataConnectionState = newCdmaDataConnectionState;
+        mDataConnectionState = mNewDataConnectionState;
         networkType = newNetworkType;
 
-        gprsState = newCdmaDataConnectionState;
-
         newSS.setStateOutOfService(); // clean slate for next time
 
         if (hasNetworkTypeChanged) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index ac8352d..afebebe 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -97,8 +97,8 @@
     /**
      * Initially assume no data connection.
      */
-    protected int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
-    protected int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
+    protected int mDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
+    protected int mNewDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
     protected int mRegistrationState = -1;
     protected RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
 
@@ -217,8 +217,8 @@
         phone.mRuimRecords.unregisterForRecordsLoaded(this);
         cm.unSetOnSignalStrengthUpdate(this);
         cm.unSetOnNITZTime(this);
-        cr.unregisterContentObserver(this.mAutoTimeObserver);
-        cr.unregisterContentObserver(this.mAutoTimeZoneObserver);
+        cr.unregisterContentObserver(mAutoTimeObserver);
+        cr.unregisterContentObserver(mAutoTimeZoneObserver);
     }
 
     @Override
@@ -548,10 +548,12 @@
     }
 
     /**
-    * The LTE data connection state, only return true here
+    * Determine data network type based on radio technology.
     */
-    protected boolean checkAdditionalDataAvaiable(){
-        return true;
+    protected void setCdmaTechnology(int radioTechnology){
+        mNewDataConnectionState = radioTechnologyToDataServiceState(radioTechnology);
+        newSS.setRadioTechnology(radioTechnology);
+        newNetworkType = radioTechnology;
     }
 
     /**
@@ -639,12 +641,7 @@
                     regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
             newSS.setState (regCodeToServiceState(registrationState));
 
-            if(checkAdditionalDataAvaiable()) {
-                this.newCdmaDataConnectionState =
-                        radioTechnologyToDataServiceState(radioTechnology);
-                newSS.setRadioTechnology(radioTechnology);
-                newNetworkType = radioTechnology;
-            }
+            setCdmaTechnology(radioTechnology);
 
             newSS.setCssIndicator(cssIndicator);
             newSS.setSystemAndNetworkId(systemId, networkId);
@@ -953,15 +950,15 @@
             && newSS.getState() != ServiceState.STATE_IN_SERVICE;
 
         boolean hasCdmaDataConnectionAttached =
-            this.cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE
-            && this.newCdmaDataConnectionState == ServiceState.STATE_IN_SERVICE;
+            mDataConnectionState != ServiceState.STATE_IN_SERVICE
+            && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
 
         boolean hasCdmaDataConnectionDetached =
-            this.cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE
-            && this.newCdmaDataConnectionState != ServiceState.STATE_IN_SERVICE;
+            mDataConnectionState == ServiceState.STATE_IN_SERVICE
+            && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
 
         boolean hasCdmaDataConnectionChanged =
-                       cdmaDataConnectionState != newCdmaDataConnectionState;
+                       mDataConnectionState != mNewDataConnectionState;
 
         boolean hasNetworkTypeChanged = networkType != newNetworkType;
 
@@ -975,10 +972,10 @@
 
         // Add an event log when connection state changes
         if (ss.getState() != newSS.getState() ||
-                cdmaDataConnectionState != newCdmaDataConnectionState) {
+                mDataConnectionState != mNewDataConnectionState) {
             EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE,
-                    ss.getState(), cdmaDataConnectionState,
-                    newSS.getState(), newCdmaDataConnectionState);
+                    ss.getState(), mDataConnectionState,
+                    newSS.getState(), mNewDataConnectionState);
         }
 
         ServiceState tss;
@@ -992,7 +989,7 @@
         cellLoc = newCellLoc;
         newCellLoc = tcl;
 
-        cdmaDataConnectionState = newCdmaDataConnectionState;
+        mDataConnectionState = mNewDataConnectionState;
         networkType = newNetworkType;
         // this new state has been applied - forget it until we get a new new state
         newNetworkType = 0;
@@ -1175,7 +1172,7 @@
     }
 
 
-    private int radioTechnologyToDataServiceState(int code) {
+    protected int radioTechnologyToDataServiceState(int code) {
         int retVal = ServiceState.STATE_OUT_OF_SERVICE;
         switch(code) {
         case 0:
@@ -1226,14 +1223,14 @@
      * ServiceState.RADIO_TECHNOLOGY_UNKNOWN is the same as detached.
      */
     /*package*/ int getCurrentCdmaDataConnectionState() {
-        return cdmaDataConnectionState;
+        return mDataConnectionState;
     }
 
     /**
     * TODO: In the future, we need remove getCurrentCdmaDataConnectionState
     */
     public int getCurrentDataConnectionState() {
-        return cdmaDataConnectionState;
+        return mDataConnectionState;
     }
 
     /**