Merge "Publish new MediaCodec API" into jb-mr2-dev
diff --git a/api/current.txt b/api/current.txt
index 35669de..6fce7a4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11795,6 +11795,7 @@
     method public android.media.MediaRouter.UserRouteInfo createUserRoute(android.media.MediaRouter.RouteCategory);
     method public android.media.MediaRouter.RouteCategory getCategoryAt(int);
     method public int getCategoryCount();
+    method public android.media.MediaRouter.RouteInfo getDefaultRoute();
     method public android.media.MediaRouter.RouteInfo getRouteAt(int);
     method public int getRouteCount();
     method public android.media.MediaRouter.RouteInfo getSelectedRoute(int);
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index a1a147a..7e0a27a 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -123,13 +123,13 @@
 
         if (mToggleMode) {
             if (mRemoteActive) {
-                mRouter.selectRouteInt(mRouteTypes, mRouter.getSystemAudioRoute());
+                mRouter.selectRouteInt(mRouteTypes, mRouter.getDefaultRoute());
             } else {
                 final int N = mRouter.getRouteCount();
                 for (int i = 0; i < N; i++) {
                     final RouteInfo route = mRouter.getRouteAt(i);
                     if ((route.getSupportedTypes() & mRouteTypes) != 0 &&
-                            route != mRouter.getSystemAudioRoute()) {
+                            route != mRouter.getDefaultRoute()) {
                         mRouter.selectRouteInt(mRouteTypes, route);
                     }
                 }
@@ -216,7 +216,7 @@
 
     void updateRemoteIndicator() {
         final RouteInfo selected = mRouter.getSelectedRoute(mRouteTypes);
-        final boolean isRemote = selected != mRouter.getSystemAudioRoute();
+        final boolean isRemote = selected != mRouter.getDefaultRoute();
         final boolean isConnecting = selected != null &&
                 selected.getStatusCode() == RouteInfo.STATUS_CONNECTING;
 
diff --git a/core/java/android/nfc/tech/NfcBarcode.java b/core/java/android/nfc/tech/NfcBarcode.java
index 3149857..76627de 100644
--- a/core/java/android/nfc/tech/NfcBarcode.java
+++ b/core/java/android/nfc/tech/NfcBarcode.java
@@ -86,6 +86,28 @@
     /**
      * Returns the barcode of an NfcBarcode tag.
      *
+     * <p> Tags of {@link #TYPE_KOVIO} return 16 bytes:
+     *     <ul>
+     *     <p> The first byte is 0x80 ORd with a manufacturer ID, corresponding
+     *       to ISO/IEC 7816-6.
+     *     <p> The second byte describes the payload data format. Defined data
+     *       format types include the following:<ul>
+     *       <li>0x00: Reserved for manufacturer assignment</li>
+     *       <li>0x01: 96-bit URL with "http://www." prefix</li>
+     *       <li>0x02: 96-bit URL with "https://www." prefix</li>
+     *       <li>0x03: 96-bit URL with "http://" prefix</li>
+     *       <li>0x04: 96-bit URL with "https://" prefix</li>
+     *       <li>0x05: 96-bit GS1 EPC</li>
+     *       <li>0x06-0xFF: reserved</li>
+     *       </ul>
+     *     <p>The following 12 bytes are payload:<ul>
+     *       <li> In case of a URL payload, the payload is encoded in US-ASCII,
+     *            following the limitations defined in RF3987,
+     *            {@see http://www.ietf.org/rfc/rfc3987.txt}</li>
+     *       <li> In case of GS1 EPC daya, {@see http://www.gs1.org/gsmp/kc/epcglobal/tds/}
+     *            for more details.</li></ul>
+     *     <p>The last 2 bytes comprise the CRC.
+     *     </ul>
      * <p>Does not cause any RF activity and does not block.
      *
      * @return a byte array containing the barcode
diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java
index 3493ea7..0e2c7c1 100644
--- a/core/java/android/nfc/tech/TagTechnology.java
+++ b/core/java/android/nfc/tech/TagTechnology.java
@@ -50,6 +50,7 @@
  * <ul>
  * <li>{@link MifareClassic}
  * <li>{@link MifareUltralight}
+ * <li>{@link NfcBarcode}
  * <li>{@link NdefFormatable} must only be enumerated on tags for which this Android device
  * is capable of formatting. Proprietary knowledge is often required to format a tag
  * to make it NDEF compatible.
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 18a0018..b8769b4 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -218,7 +218,7 @@
             return;
         }
         if (mMap == null) {
-            mMap = new HashMap<String, Object>();
+            mMap = new HashMap<String, Object>(N);
         }
         mParcelledData.readMapInternal(mMap, N, mClassLoader);
         mParcelledData.recycle();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7e0d115..ea5ed68 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10642,7 +10642,7 @@
         // Opaque if:
         //   - Has a background
         //   - Background is opaque
-        //   - Doesn't have scrollbars or scrollbars are inside overlay
+        //   - Doesn't have scrollbars or scrollbars overlay
 
         if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) {
             mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND;
@@ -10652,7 +10652,8 @@
 
         final int flags = mViewFlags;
         if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
-                (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY) {
+                (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY ||
+                (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_OUTSIDE_OVERLAY) {
             mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS;
         } else {
             mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS;
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 5d6ec1e..c9d2d95 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -41,6 +41,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
 
+import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
 import static android.util.Log.d;
 
 /**
@@ -1215,6 +1216,7 @@
         private int mEnd = DEFAULT_RELATIVE;
 
         private boolean mRulesChanged = false;
+        private boolean mIsRtlCompatibilityMode = false;
 
         /**
          * When true, uses the parent as the anchor if the anchor doesn't exist or if
@@ -1229,6 +1231,10 @@
             TypedArray a = c.obtainStyledAttributes(attrs,
                     com.android.internal.R.styleable.RelativeLayout_Layout);
 
+            final int targetSdkVersion = c.getApplicationInfo().targetSdkVersion;
+            mIsRtlCompatibilityMode = (targetSdkVersion < JELLY_BEAN_MR1 ||
+                    !c.getApplicationInfo().hasRtlSupport());
+
             final int[] rules = mRules;
             //noinspection MismatchedReadAndWriteOfArray
             final int[] initialRules = mInitialRules;
@@ -1397,28 +1403,132 @@
                     mInitialRules[ALIGN_PARENT_START] != 0 || mInitialRules[ALIGN_PARENT_END] != 0);
         }
 
+        // The way we are resolving rules depends on the layout direction and if we are pre JB MR1
+        // or not.
+        //
+        // If we are pre JB MR1 (said as "RTL compatibility mode"), "left"/"right" rules are having
+        // predominance over any "start/end" rules that could have been defined. A special case:
+        // if no "left"/"right" rule has been defined and "start"/"end" rules are defined then we
+        // resolve those "start"/"end" rules to "left"/"right" respectively.
+        //
+        // If we are JB MR1+, then "start"/"end" rules are having predominance over "left"/"right"
+        // rules. If no "start"/"end" rule is defined then we use "left"/"right" rules.
+        //
+        // In all cases, the result of the resolution should clear the "start"/"end" rules to leave
+        // only the "left"/"right" rules at the end.
         private void resolveRules(int layoutDirection) {
             final boolean isLayoutRtl = (layoutDirection == View.LAYOUT_DIRECTION_RTL);
+
             // Reset to initial state
             System.arraycopy(mInitialRules, LEFT_OF, mRules, LEFT_OF, VERB_COUNT);
-            // Apply rules depending on direction
-            if (mRules[ALIGN_START] != 0) {
-                mRules[isLayoutRtl ? ALIGN_RIGHT : ALIGN_LEFT] = mRules[ALIGN_START];
-            }
-            if (mRules[ALIGN_END] != 0) {
-                mRules[isLayoutRtl ? ALIGN_LEFT : ALIGN_RIGHT] = mRules[ALIGN_END];
-            }
-            if (mRules[START_OF] != 0) {
-                mRules[isLayoutRtl ? RIGHT_OF : LEFT_OF] = mRules[START_OF];
-            }
-            if (mRules[END_OF] != 0) {
-                mRules[isLayoutRtl ? LEFT_OF : RIGHT_OF] = mRules[END_OF];
-            }
-            if (mRules[ALIGN_PARENT_START] != 0) {
-                mRules[isLayoutRtl ? ALIGN_PARENT_RIGHT : ALIGN_PARENT_LEFT] = mRules[ALIGN_PARENT_START];
-            }
-            if (mRules[ALIGN_PARENT_END] != 0) {
-                mRules[isLayoutRtl ? ALIGN_PARENT_LEFT : ALIGN_PARENT_RIGHT] = mRules[ALIGN_PARENT_END];
+
+            // Apply rules depending on direction and if we are in RTL compatibility mode
+            if (mIsRtlCompatibilityMode) {
+                if (mRules[ALIGN_START] != 0) {
+                    if (mRules[ALIGN_LEFT] == 0) {
+                        // "left" rule is not defined but "start" rule is: use the "start" rule as
+                        // the "left" rule
+                        mRules[ALIGN_LEFT] = mRules[ALIGN_START];
+                    }
+                    mRules[ALIGN_START] = 0;
+                }
+
+                if (mRules[ALIGN_END] != 0) {
+                    if (mRules[ALIGN_RIGHT] == 0) {
+                        // "right" rule is not defined but "end" rule is: use the "end" rule as the
+                        // "right" rule
+                        mRules[ALIGN_RIGHT] = mRules[ALIGN_END];
+                    }
+                    mRules[ALIGN_END] = 0;
+                }
+
+                if (mRules[START_OF] != 0) {
+                    if (mRules[LEFT_OF] == 0) {
+                        // "left" rule is not defined but "start" rule is: use the "start" rule as
+                        // the "left" rule
+                        mRules[LEFT_OF] = mRules[START_OF];
+                    }
+                    mRules[START_OF] = 0;
+                }
+
+                if (mRules[END_OF] != 0) {
+                    if (mRules[RIGHT_OF] == 0) {
+                        // "right" rule is not defined but "end" rule is: use the "end" rule as the
+                        // "right" rule
+                        mRules[RIGHT_OF] = mRules[END_OF];
+                    }
+                    mRules[END_OF] = 0;
+                }
+
+                if (mRules[ALIGN_PARENT_START] != 0) {
+                    if (mRules[ALIGN_PARENT_LEFT] == 0) {
+                        // "left" rule is not defined but "start" rule is: use the "start" rule as
+                        // the "left" rule
+                        mRules[ALIGN_PARENT_LEFT] = mRules[ALIGN_PARENT_START];
+                    }
+                    mRules[ALIGN_PARENT_START] = 0;
+                }
+
+                if (mRules[ALIGN_PARENT_RIGHT] == 0) {
+                    if (mRules[ALIGN_PARENT_RIGHT] == 0) {
+                        // "right" rule is not defined but "end" rule is: use the "end" rule as the
+                        // "right" rule
+                        mRules[ALIGN_PARENT_RIGHT] = mRules[ALIGN_PARENT_END];
+                    }
+                    mRules[ALIGN_PARENT_END] = 0;
+                }
+            } else {
+                // JB MR1+ case
+                if ((mRules[ALIGN_START] != 0 || mRules[ALIGN_END] != 0) &&
+                        (mRules[ALIGN_LEFT] != 0 || mRules[ALIGN_RIGHT] != 0)) {
+                    // "start"/"end" rules take precedence over "left"/"right" rules
+                    mRules[ALIGN_LEFT] = 0;
+                    mRules[ALIGN_RIGHT] = 0;
+                }
+                if (mRules[ALIGN_START] != 0) {
+                    // "start" rule resolved to "left" or "right" depending on the direction
+                    mRules[isLayoutRtl ? ALIGN_RIGHT : ALIGN_LEFT] = mRules[ALIGN_START];
+                    mRules[ALIGN_START] = 0;
+                }
+                if (mRules[ALIGN_END] != 0) {
+                    // "end" rule resolved to "left" or "right" depending on the direction
+                    mRules[isLayoutRtl ? ALIGN_LEFT : ALIGN_RIGHT] = mRules[ALIGN_END];
+                    mRules[ALIGN_END] = 0;
+                }
+
+                if ((mRules[START_OF] != 0 || mRules[END_OF] != 0) &&
+                        (mRules[LEFT_OF] != 0 || mRules[RIGHT_OF] != 0)) {
+                    // "start"/"end" rules take precedence over "left"/"right" rules
+                    mRules[LEFT_OF] = 0;
+                    mRules[RIGHT_OF] = 0;
+                }
+                if (mRules[START_OF] != 0) {
+                    // "start" rule resolved to "left" or "right" depending on the direction
+                    mRules[isLayoutRtl ? RIGHT_OF : LEFT_OF] = mRules[START_OF];
+                    mRules[START_OF] = 0;
+                }
+                if (mRules[END_OF] != 0) {
+                    // "end" rule resolved to "left" or "right" depending on the direction
+                    mRules[isLayoutRtl ? LEFT_OF : RIGHT_OF] = mRules[END_OF];
+                    mRules[END_OF] = 0;
+                }
+
+                if ((mRules[ALIGN_PARENT_START] != 0 || mRules[ALIGN_PARENT_END] != 0) &&
+                        (mRules[ALIGN_PARENT_LEFT] != 0 || mRules[ALIGN_PARENT_RIGHT] != 0)) {
+                    // "start"/"end" rules take precedence over "left"/"right" rules
+                    mRules[ALIGN_PARENT_LEFT] = 0;
+                    mRules[ALIGN_PARENT_RIGHT] = 0;
+                }
+                if (mRules[ALIGN_PARENT_START] != 0) {
+                    // "start" rule resolved to "left" or "right" depending on the direction
+                    mRules[isLayoutRtl ? ALIGN_PARENT_RIGHT : ALIGN_PARENT_LEFT] = mRules[ALIGN_PARENT_START];
+                    mRules[ALIGN_PARENT_START] = 0;
+                }
+                if (mRules[ALIGN_PARENT_END] != 0) {
+                    // "end" rule resolved to "left" or "right" depending on the direction
+                    mRules[isLayoutRtl ? ALIGN_PARENT_LEFT : ALIGN_PARENT_RIGHT] = mRules[ALIGN_PARENT_END];
+                    mRules[ALIGN_PARENT_END] = 0;
+                }
             }
             mRulesChanged = false;
         }
diff --git a/core/tests/coretests/src/android/text/format/DateUtilsTest.java b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
index cf42bb1..c5f6236 100644
--- a/core/tests/coretests/src/android/text/format/DateUtilsTest.java
+++ b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
@@ -21,8 +21,9 @@
 import junit.framework.TestCase;
 
 public class DateUtilsTest extends TestCase {
+    // This test is not in CTS because formatDuration is @hidden.
     @SmallTest
-    public void testFormatDurationSeconds() throws Exception {
+    public void test_formatDuration_seconds() throws Exception {
         assertEquals("0 seconds", DateUtils.formatDuration(0));
         assertEquals("0 seconds", DateUtils.formatDuration(1));
         assertEquals("0 seconds", DateUtils.formatDuration(499));
@@ -31,16 +32,18 @@
         assertEquals("2 seconds", DateUtils.formatDuration(1500));
     }
 
+    // This test is not in CTS because formatDuration is @hidden.
     @SmallTest
-    public void testFormatDurationMinutes() throws Exception {
+    public void test_formatDuration_Minutes() throws Exception {
         assertEquals("59 seconds", DateUtils.formatDuration(59000));
         assertEquals("60 seconds", DateUtils.formatDuration(59500));
         assertEquals("1 minute", DateUtils.formatDuration(60000));
         assertEquals("2 minutes", DateUtils.formatDuration(120000));
     }
 
+    // This test is not in CTS because formatDuration is @hidden.
     @SmallTest
-    public void testFormatDurationHours() throws Exception {
+    public void test_formatDuration_Hours() throws Exception {
         assertEquals("59 minutes", DateUtils.formatDuration(3540000));
         assertEquals("1 hour", DateUtils.formatDuration(3600000));
         assertEquals("48 hours", DateUtils.formatDuration(172800000));
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 93876f8..b2d50ce 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -32,11 +32,11 @@
 </tr>
 <tr><td><a href="/about/versions/android-1.6.html">1.6</a></td><td>Donut</td>    <td>4</td><td>0.2%</td></tr>
 <tr><td><a href="/about/versions/android-2.1.html">2.1</a></td><td>Eclair</td>   <td>7</td><td>1.9%</td></tr>
-<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>7.6%</td></tr>
+<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>7.5%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.html">2.3 - 2.3.2</a>
                                    </td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.2%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.3.html">2.3.3 - 2.3.7
-        </a></td><!-- Gingerbread -->                                       <td>10</td><td>44%</td></tr>
+        </a></td><!-- Gingerbread -->                                       <td>10</td><td>43.9%</td></tr>
 <tr><td><a href="/about/versions/android-3.1.html">3.1</a></td>
                                                    <td rowspan="2">Honeycomb</td>      <td>12</td><td>0.3%</td></tr>
 <tr><td><a href="/about/versions/android-3.2.html">3.2</a></td>      <!-- Honeycomb --><td>13</td><td>0.9%</td></tr>
@@ -51,7 +51,7 @@
 
 <div class="col-8" style="margin-right:0">
 <img style="margin-left:30px" alt=""
-src="//chart.apis.google.com/chart?&cht=p&chs=460x245&chf=bg,s,00000000&chd=t:2.0,7.6,44.2,1.2,28.6,16.5&chl=Eclair%20%26%20older|Froyo|Gingerbread|Honeycomb|Ice%20Cream%20Sandwich|Jelly%20Bean&chco=c4df9b,6fad0c"
+src="//chart.apis.google.com/chart?&cht=p&chs=460x245&chf=bg,s,00000000&chd=t:2.1,7.5,44.1,1.2,28.6,16.5&chl=Eclair%20%26%20older|Froyo|Gingerbread|Honeycomb|Ice%20Cream%20Sandwich|Jelly%20Bean&chco=c4df9b,6fad0c"
 />
 
 </div><!-- end dashboard-panel -->
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index 190a6d9..0cb2635 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -345,7 +345,7 @@
   var playlistId = "PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0"; /* DevBytes */
   var script = "<script type='text/javascript' src='//gdata.youtube.com/feeds/api/playlists/"
                 + playlistId +
-                "?v=2&alt=json-in-script&max-results=10&callback=renderDevelopersLivePlaylist&orderby=published'><\/script > ";
+                "?v=2&alt=json-in-script&max-results=10&callback=renderDevelopersLivePlaylist&orderby=reversedPosition'><\/script > ";
   $("body").append(script);
 }
 
diff --git a/docs/html/images/home/io-logo-2013.png b/docs/html/images/home/io-logo-2013.png
index c95719e..1a200e1 100644
--- a/docs/html/images/home/io-logo-2013.png
+++ b/docs/html/images/home/io-logo-2013.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index a0029b5..f2df7be 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -24,7 +24,7 @@
                     <p>For more information about event details and planned sessions,
                     stay tuned to <a
                     href="http://google.com/+GoogleDevelopers">+Google Developers</a>.</p>
-                    <p><a href="https://developers.google.com/events/io/" class="button">Register here</a></p>
+                    <p><a href="https://developers.google.com/events/io/register" class="button">Register here</a></p>
                     </div>
                 </li>
                 <li class="item carousel-home">
diff --git a/docs/html/training/id-auth/authenticate.jd b/docs/html/training/id-auth/authenticate.jd
index 592fe1c..c316af7 100644
--- a/docs/html/training/id-auth/authenticate.jd
+++ b/docs/html/training/id-auth/authenticate.jd
@@ -179,7 +179,7 @@
     &#64;Override
     public void run(AccountManagerFuture&lt;Bundle&gt; result) {
         ...
-        Intent launch = (Intent) result.get(AccountManager.KEY_INTENT);
+        Intent launch = (Intent) result.getResult().get(AccountManager.KEY_INTENT);
         if (launch != null) {
             startActivityForResult(launch, 0);
             return;
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index bdd539e..5781f4d 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -442,9 +442,8 @@
     for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
         DisplayListOp *op = mDisplayListData->displayListOps[i];
 #if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-        Caches::getInstance().eventMark(strlen(op->name()), op->name());
+        renderer.eventMark(strlen(op->name()), op->name());
 #endif
-
         drawGlStatus |= op->replay(renderer, dirty, flags,
                 saveCount, level, mCaching, mMultipliedAlpha, deferredList);
         logBuffer.writeCommand(level, op->name());
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 22ec93b..11fdd6c 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2633,16 +2633,7 @@
         fontTransform = mat4::identity();
     } else {
         if (CC_UNLIKELY(transform.isPerspective())) {
-            // When the below condition is true, we are rendering text with a
-            // perspective transform inside a layer (either an inline layer
-            // created by Canvas.saveLayer() or a hardware layer.)
-            if (hasLayer() || getTargetFbo() != 0) {
-                float sx, sy;
-                currentTransform().decomposeScale(sx, sy);
-                fontTransform.loadScale(sx, sy, 1.0f);
-            } else {
-                fontTransform = mat4::identity();
-            }
+            fontTransform = mat4::identity();
         } else {
             float sx, sy;
             currentTransform().decomposeScale(sx, sy);
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 9307f11..c932087 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -53,8 +53,8 @@
     mStrokeWidth = paint->getStrokeWidth();
     mAntiAliasing = paint->isAntiAlias();
     mLookupTransform.reset();
-    mLookupTransform[SkMatrix::kMScaleX] = matrix[mat4::kScaleX];
-    mLookupTransform[SkMatrix::kMScaleY] = matrix[mat4::kScaleY];
+    mLookupTransform[SkMatrix::kMScaleX] = roundf(fmaxf(1.0f, matrix[mat4::kScaleX]));
+    mLookupTransform[SkMatrix::kMScaleY] = roundf(fmaxf(1.0f, matrix[mat4::kScaleY]));
     if (!mLookupTransform.invert(&mInverseLookupTransform)) {
         ALOGW("Could not query the inverse lookup transform for this font");
     }
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 8b489b1..795c3c2 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -299,16 +299,21 @@
     }
 
     /**
-     * @hide for use by framework routing UI
+     * Gets the default route for playing media content on the system.
+     * <p>
+     * The system always provides a default route.
+     * </p>
+     *
+     * @return The default route, which is guaranteed to never be null.
      */
-    public RouteInfo getSystemAudioRoute() {
+    public RouteInfo getDefaultRoute() {
         return sStatic.mDefaultAudioVideo;
     }
 
     /**
      * @hide for use by framework routing UI
      */
-    public RouteCategory getSystemAudioCategory() {
+    public RouteCategory getSystemCategory() {
         return sStatic.mSystemCategory;
     }
 
@@ -372,14 +377,17 @@
 
     /**
      * Select the specified route to use for output of the given media types.
+     * <p class="note">
+     * As API version 18, this function may be used to select any route.
+     * In prior versions, this function could only be used to select user
+     * routes and would ignore any attempt to select a system route.
+     * </p>
      *
      * @param types type flags indicating which types this route should be used for.
      *              The route must support at least a subset.
      * @param route Route to select
      */
     public void selectRoute(int types, RouteInfo route) {
-        // Applications shouldn't programmatically change anything but user routes.
-        types &= ROUTE_TYPE_USER;
         selectRouteStatic(types, route);
     }
     
@@ -454,7 +462,7 @@
      * App-specified route definitions are created using {@link #createUserRoute(RouteCategory)}
      *
      * @param info Definition of the route to add
-     * @see #createUserRoute()
+     * @see #createUserRoute(RouteCategory)
      * @see #removeUserRoute(UserRouteInfo)
      */
     public void addUserRoute(UserRouteInfo info) {
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 9f2685b..1e394d6 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -186,8 +186,14 @@
             this.userid = userid;
         }
 
+        boolean userMatches(StatusBarNotification sbn) {
+            if (this.userid == UserHandle.USER_ALL) return true;
+            int nid = sbn.getUserId();
+            return (nid == UserHandle.USER_ALL || nid == this.userid);
+        }
+
         public void notifyPostedIfUserMatch(StatusBarNotification sbn) {
-            if (this.userid != sbn.getUserId()) return;
+            if (!userMatches(sbn)) return;
             try {
                 listener.onNotificationPosted(sbn);
             } catch (RemoteException ex) {
@@ -196,7 +202,7 @@
         }
 
         public void notifyRemovedIfUserMatch(StatusBarNotification sbn) {
-            if (this.userid != sbn.getUserId()) return;
+            if (!userMatches(sbn)) return;
             try {
                 listener.onNotificationRemoved(sbn);
             } catch (RemoteException ex) {