Merge "Track down unsupported texture target"
diff --git a/api/current.txt b/api/current.txt
index 612d16d..11db5c3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -24062,6 +24062,7 @@
     field public static final java.lang.String CACHED_NUMBER_LABEL = "numberlabel";
     field public static final java.lang.String CACHED_NUMBER_TYPE = "numbertype";
     field public static final java.lang.String CACHED_PHOTO_ID = "photo_id";
+    field public static final java.lang.String CACHED_PHOTO_URI = "photo_uri";
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
@@ -25930,7 +25931,6 @@
     field public static final deprecated java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
     field public static final deprecated java.lang.String ANDROID_ID = "android_id";
     field public static final deprecated java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
-    field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
     field public static final deprecated java.lang.String AUTO_TIME = "auto_time";
     field public static final deprecated java.lang.String AUTO_TIME_ZONE = "auto_time_zone";
     field public static final java.lang.String BLUETOOTH_DISCOVERABILITY = "bluetooth_discoverability";
@@ -25993,14 +25993,6 @@
     field public static final java.lang.String USER_ROTATION = "user_rotation";
     field public static final deprecated java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
     field public static final java.lang.String VIBRATE_ON = "vibrate_on";
-    field public static final java.lang.String VOLUME_ALARM = "volume_alarm";
-    field public static final java.lang.String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
-    field public static final java.lang.String VOLUME_MUSIC = "volume_music";
-    field public static final java.lang.String VOLUME_NOTIFICATION = "volume_notification";
-    field public static final java.lang.String VOLUME_RING = "volume_ring";
-    field public static final java.lang.String[] VOLUME_SETTINGS;
-    field public static final java.lang.String VOLUME_SYSTEM = "volume_system";
-    field public static final java.lang.String VOLUME_VOICE = "volume_voice";
     field public static final deprecated java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
     field public static final deprecated java.lang.String WALLPAPER_ACTIVITY = "wallpaper_activity";
     field public static final deprecated java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
diff --git a/api/removed.txt b/api/removed.txt
index 8668a77..1b209a9 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -34,6 +34,22 @@
 
 }
 
+package android.provider {
+
+  public static final class Settings.System extends android.provider.Settings.NameValueTable {
+    field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
+    field public static final java.lang.String VOLUME_ALARM = "volume_alarm";
+    field public static final java.lang.String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
+    field public static final java.lang.String VOLUME_MUSIC = "volume_music";
+    field public static final java.lang.String VOLUME_NOTIFICATION = "volume_notification";
+    field public static final java.lang.String VOLUME_RING = "volume_ring";
+    field public static final java.lang.String[] VOLUME_SETTINGS;
+    field public static final java.lang.String VOLUME_SYSTEM = "volume_system";
+    field public static final java.lang.String VOLUME_VOICE = "volume_voice";
+  }
+
+}
+
 package android.text.format {
 
   public class DateFormat {
diff --git a/api/system-current.txt b/api/system-current.txt
index ff9809f..da5986f5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25667,6 +25667,7 @@
     field public static final java.lang.String CACHED_NUMBER_LABEL = "numberlabel";
     field public static final java.lang.String CACHED_NUMBER_TYPE = "numbertype";
     field public static final java.lang.String CACHED_PHOTO_ID = "photo_id";
+    field public static final java.lang.String CACHED_PHOTO_URI = "photo_uri";
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
@@ -27536,7 +27537,6 @@
     field public static final deprecated java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
     field public static final deprecated java.lang.String ANDROID_ID = "android_id";
     field public static final deprecated java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
-    field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
     field public static final deprecated java.lang.String AUTO_TIME = "auto_time";
     field public static final deprecated java.lang.String AUTO_TIME_ZONE = "auto_time_zone";
     field public static final java.lang.String BLUETOOTH_DISCOVERABILITY = "bluetooth_discoverability";
@@ -27599,14 +27599,6 @@
     field public static final java.lang.String USER_ROTATION = "user_rotation";
     field public static final deprecated java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
     field public static final java.lang.String VIBRATE_ON = "vibrate_on";
-    field public static final java.lang.String VOLUME_ALARM = "volume_alarm";
-    field public static final java.lang.String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
-    field public static final java.lang.String VOLUME_MUSIC = "volume_music";
-    field public static final java.lang.String VOLUME_NOTIFICATION = "volume_notification";
-    field public static final java.lang.String VOLUME_RING = "volume_ring";
-    field public static final java.lang.String[] VOLUME_SETTINGS;
-    field public static final java.lang.String VOLUME_SYSTEM = "volume_system";
-    field public static final java.lang.String VOLUME_VOICE = "volume_voice";
     field public static final deprecated java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
     field public static final deprecated java.lang.String WALLPAPER_ACTIVITY = "wallpaper_activity";
     field public static final deprecated java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 8668a77..1b209a9 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -34,6 +34,22 @@
 
 }
 
+package android.provider {
+
+  public static final class Settings.System extends android.provider.Settings.NameValueTable {
+    field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
+    field public static final java.lang.String VOLUME_ALARM = "volume_alarm";
+    field public static final java.lang.String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
+    field public static final java.lang.String VOLUME_MUSIC = "volume_music";
+    field public static final java.lang.String VOLUME_NOTIFICATION = "volume_notification";
+    field public static final java.lang.String VOLUME_RING = "volume_ring";
+    field public static final java.lang.String[] VOLUME_SETTINGS;
+    field public static final java.lang.String VOLUME_SYSTEM = "volume_system";
+    field public static final java.lang.String VOLUME_VOICE = "volume_voice";
+  }
+
+}
+
 package android.text.format {
 
   public class DateFormat {
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 2df9dbf..6517f35 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -328,6 +328,14 @@
         public static final String CACHED_PHOTO_ID = "photo_id";
 
         /**
+         * The cached photo URI of the picture associated with the phone number, if it exists.
+         * This value may not be current if the contact information associated with this number
+         * has changed.
+         * <P>Type: TEXT (URI)</P>
+         */
+        public static final String CACHED_PHOTO_URI = "photo_uri";
+
+        /**
          * The cached phone number, formatted with formatting rules based on the country the
          * user was in when the call was made or received.
          * This value is not guaranteed to be present, and may not be current if the contact
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c60a906..cc84932 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2254,54 +2254,66 @@
         /**
          * Ringer volume. This is used internally, changing this value will not
          * change the volume. See AudioManager.
+         *
+         * @removed Not used by anything since API 2.
          */
         public static final String VOLUME_RING = "volume_ring";
 
         /**
          * System/notifications volume. This is used internally, changing this
          * value will not change the volume. See AudioManager.
+         *
+         * @removed Not used by anything since API 2.
          */
         public static final String VOLUME_SYSTEM = "volume_system";
 
         /**
          * Voice call volume. This is used internally, changing this value will
          * not change the volume. See AudioManager.
+         *
+         * @removed Not used by anything since API 2.
          */
         public static final String VOLUME_VOICE = "volume_voice";
 
         /**
          * Music/media/gaming volume. This is used internally, changing this
          * value will not change the volume. See AudioManager.
+         *
+         * @removed Not used by anything since API 2.
          */
         public static final String VOLUME_MUSIC = "volume_music";
 
         /**
          * Alarm volume. This is used internally, changing this
          * value will not change the volume. See AudioManager.
+         *
+         * @removed Not used by anything since API 2.
          */
         public static final String VOLUME_ALARM = "volume_alarm";
 
         /**
          * Notification volume. This is used internally, changing this
          * value will not change the volume. See AudioManager.
+         *
+         * @removed Not used by anything since API 2.
          */
         public static final String VOLUME_NOTIFICATION = "volume_notification";
 
         /**
          * Bluetooth Headset volume. This is used internally, changing this value will
          * not change the volume. See AudioManager.
+         *
+         * @removed Not used by anything since API 2.
          */
         public static final String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
 
         /**
          * Master volume (float in the range 0.0f to 1.0f).
+         *
          * @hide
          */
         public static final String VOLUME_MASTER = "volume_master";
 
-        private static final Validator VOLUME_MASTER_VALIDATOR =
-                new InclusiveFloatRangeValidator(0, 1);
-
         /**
          * Master volume mute (int 1 = mute, 0 = not muted).
          *
@@ -2358,6 +2370,8 @@
 
         /**
          * The mapping of stream type (integer) to its setting.
+         *
+         * @removed  Not used by anything since API 2.
          */
         public static final String[] VOLUME_SETTINGS = {
             VOLUME_VOICE, VOLUME_SYSTEM, VOLUME_RING, VOLUME_MUSIC,
@@ -2368,6 +2382,8 @@
          * Appended to various volume related settings to record the previous
          * values before they the settings were affected by a silent/vibrate
          * ringer mode change.
+         *
+         * @removed  Not used by anything since API 2.
          */
         public static final String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
 
@@ -2981,20 +2997,6 @@
             SCREEN_AUTO_BRIGHTNESS_ADJ,
             VIBRATE_INPUT_DEVICES,
             MODE_RINGER_STREAMS_AFFECTED,
-            VOLUME_VOICE,
-            VOLUME_SYSTEM,
-            VOLUME_RING,
-            VOLUME_MUSIC,
-            VOLUME_ALARM,
-            VOLUME_NOTIFICATION,
-            VOLUME_BLUETOOTH_SCO,
-            VOLUME_VOICE + APPEND_FOR_LAST_AUDIBLE,
-            VOLUME_SYSTEM + APPEND_FOR_LAST_AUDIBLE,
-            VOLUME_RING + APPEND_FOR_LAST_AUDIBLE,
-            VOLUME_MUSIC + APPEND_FOR_LAST_AUDIBLE,
-            VOLUME_ALARM + APPEND_FOR_LAST_AUDIBLE,
-            VOLUME_NOTIFICATION + APPEND_FOR_LAST_AUDIBLE,
-            VOLUME_BLUETOOTH_SCO + APPEND_FOR_LAST_AUDIBLE,
             TEXT_AUTO_REPLACE,
             TEXT_AUTO_CAPS,
             TEXT_AUTO_PUNCTUATE,
@@ -3167,7 +3169,6 @@
             VALIDATORS.put(ADVANCED_SETTINGS, ADVANCED_SETTINGS_VALIDATOR);
             VALIDATORS.put(SCREEN_AUTO_BRIGHTNESS_ADJ, SCREEN_AUTO_BRIGHTNESS_ADJ_VALIDATOR);
             VALIDATORS.put(VIBRATE_INPUT_DEVICES, VIBRATE_INPUT_DEVICES_VALIDATOR);
-            VALIDATORS.put(VOLUME_MASTER, VOLUME_MASTER_VALIDATOR);
             VALIDATORS.put(VOLUME_MASTER_MUTE, VOLUME_MASTER_MUTE_VALIDATOR);
             VALIDATORS.put(MICROPHONE_MUTE, MICROPHONE_MUTE_VALIDATOR);
             VALIDATORS.put(NOTIFICATIONS_USE_RING_VOLUME, NOTIFICATIONS_USE_RING_VOLUME_VALIDATOR);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7d49969..085a3f2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13089,6 +13089,7 @@
      *
      * @see #onDetachedFromWindow()
      */
+    @CallSuper
     protected void onAttachedToWindow() {
         if ((mPrivateFlags & PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
             mParent.requestTransparentRegion(this);
@@ -13421,6 +13422,7 @@
      *
      * @see #onAttachedToWindow()
      */
+    @CallSuper
     protected void onDetachedFromWindow() {
     }
 
@@ -13741,6 +13743,7 @@
      * @see #dispatchSaveInstanceState(android.util.SparseArray)
      * @see #setSaveEnabled(boolean)
      */
+    @CallSuper
     protected Parcelable onSaveInstanceState() {
         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
         return BaseSavedState.EMPTY_STATE;
@@ -13799,6 +13802,7 @@
      * @see #restoreHierarchyState(android.util.SparseArray)
      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
      */
+    @CallSuper
     protected void onRestoreInstanceState(Parcelable state) {
         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
         if (state != BaseSavedState.EMPTY_STATE && state != null) {
@@ -17987,6 +17991,7 @@
      * @see #setAnimation(android.view.animation.Animation)
      * @see #getAnimation()
      */
+    @CallSuper
     protected void onAnimationStart() {
         mPrivateFlags |= PFLAG_ANIMATION_STARTED;
     }
@@ -17999,6 +18004,7 @@
      * @see #setAnimation(android.view.animation.Animation)
      * @see #getAnimation()
      */
+    @CallSuper
     protected void onAnimationEnd() {
         mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
     }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 0f99e88..cc44577 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4887,9 +4887,10 @@
                     text.insert(newTextInsertAt, newText);
                 }
             }
-            // Restore the cursor position.
+            // Restore the cursor position. If there wasn't an old cursor (newCursorPos == -1) then
+            // don't explicitly set it and rely on SpannableStringBuilder to position it.
             // TODO: Select all the text that was undone.
-            if (newCursorPos <= text.length()) {
+            if (0 <= newCursorPos && newCursorPos <= text.length()) {
                 Selection.setSelection(text, newCursorPos);
             }
         }
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index a224f5e..d12739f 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -515,6 +515,23 @@
             }
         }
 
+        // Use the top-start-most laid out view as the baseline. RTL offsets are
+        // applied later, so we can use the left-most edge as the starting edge.
+        View baselineView = null;
+        LayoutParams baselineParams = null;
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
+                if (baselineView == null || baselineParams == null
+                        || compareLayoutPosition(childParams, baselineParams) < 0) {
+                    baselineView = child;
+                    baselineParams = childParams;
+                }
+            }
+        }
+        mBaselineView = baselineView;
+
         if (isWrapContentWidth) {
             // Width already has left padding in it since it was calculated by looking at
             // the right of each child view
@@ -616,25 +633,24 @@
             }
         }
 
-        // Use the bottom-most laid out view as the baseline.
-        View baselineView = null;
-        int baseline = 0;
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            if (child.getVisibility() != GONE) {
-                final int childBaseline = child.getBaseline();
-                if (childBaseline >= baseline) {
-                    baselineView = child;
-                    baseline = childBaseline;
-                }
-            }
-        }
-        mBaselineView = baselineView;
-
         setMeasuredDimension(width, height);
     }
 
     /**
+     * @return a negative number if the top of {@code p1} is above the top of
+     *         {@code p2} or if they have identical top values and the left of
+     *         {@code p1} is to the left of {@code p2}, or a positive number
+     *         otherwise
+     */
+    private int compareLayoutPosition(LayoutParams p1, LayoutParams p2) {
+        final int topDiff = p1.mTop - p2.mTop;
+        if (topDiff != 0) {
+            return topDiff;
+        }
+        return p1.mLeft - p2.mLeft;
+    }
+
+    /**
      * Measure a child. The child should have left, top, right and bottom information
      * stored in its LayoutParams. If any of these values is VALUE_NOT_SET it means
      * that the view can extend up to the corresponding edge.
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index a410e45..3ceea9d 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -342,6 +342,9 @@
                         return;
                     }
 
+                    // Do not show the profile switch message anymore.
+                    mProfileSwitchMessageId = -1;
+
                     final Intent intent = intentForDisplayResolveInfo(dri);
                     onIntentSelected(dri.ri, intent, false);
                     finish();
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 5fc5b58..7acd8f5 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -76,7 +76,6 @@
     private final DataOutputStream mSocketOutStream;
     private final BufferedReader mSocketReader;
     private final Credentials peer;
-    private final String peerSecurityContext;
     private final String abiList;
 
     /**
@@ -97,15 +96,13 @@
                 new InputStreamReader(socket.getInputStream()), 256);
 
         mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
-                
+
         try {
             peer = mSocket.getPeerCredentials();
         } catch (IOException ex) {
             Log.e(TAG, "Cannot read peer credentials", ex);
             throw ex;
         }
-
-        peerSecurityContext = SELinux.getPeerContext(mSocket.getFileDescriptor());
     }
 
     /**
@@ -177,10 +174,8 @@
                         ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
             }
 
-            applyUidSecurityPolicy(parsedArgs, peer, peerSecurityContext);
-            applyRlimitSecurityPolicy(parsedArgs, peer, peerSecurityContext);
-            applyInvokeWithSecurityPolicy(parsedArgs, peer, peerSecurityContext);
-            applyseInfoSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+            applyUidSecurityPolicy(parsedArgs, peer);
+            applyInvokeWithSecurityPolicy(parsedArgs, peer);
 
             applyDebuggerSystemProperty(parsedArgs);
             applyInvokeWithSystemProperty(parsedArgs);
@@ -581,7 +576,7 @@
         }
 
         // See bug 1092107: large argc can be used for a DOS attack
-        if (argc > MAX_ZYGOTE_ARGC) {   
+        if (argc > MAX_ZYGOTE_ARGC) {
             throw new IOException("max arg count exceeded");
         }
 
@@ -598,63 +593,30 @@
     }
 
     /**
-     * Applies zygote security policy per bugs #875058 and #1082165. 
-     * Based on the credentials of the process issuing a zygote command:
-     * <ol>
-     * <li> uid 0 (root) may specify any uid, gid, and setgroups() list
-     * <li> uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
+     * uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
      * operation. It may also specify any gid and setgroups() list it chooses.
      * In factory test mode, it may specify any UID.
-     * <li> Any other uid may not specify any uid, gid, or setgroups list. The
-     * uid and gid will be inherited from the requesting process.
-     * </ul>
      *
      * @param args non-null; zygote spawner arguments
      * @param peer non-null; peer credentials
      * @throws ZygoteSecurityException
      */
-    private static void applyUidSecurityPolicy(Arguments args, Credentials peer,
-            String peerSecurityContext)
+    private static void applyUidSecurityPolicy(Arguments args, Credentials peer)
             throws ZygoteSecurityException {
 
-        int peerUid = peer.getUid();
-
-        if (peerUid == 0) {
-            // Root can do what it wants
-        } else if (peerUid == Process.SYSTEM_UID ) {
-            // System UID is restricted, except in factory test mode
+        if (peer.getUid() == Process.SYSTEM_UID) {
             String factoryTest = SystemProperties.get("ro.factorytest");
             boolean uidRestricted;
 
             /* In normal operation, SYSTEM_UID can only specify a restricted
              * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
              */
-            uidRestricted  
-                 = !(factoryTest.equals("1") || factoryTest.equals("2"));
+            uidRestricted = !(factoryTest.equals("1") || factoryTest.equals("2"));
 
-            if (uidRestricted
-                    && args.uidSpecified && (args.uid < Process.SYSTEM_UID)) {
+            if (uidRestricted && args.uidSpecified && (args.uid < Process.SYSTEM_UID)) {
                 throw new ZygoteSecurityException(
                         "System UID may not launch process with UID < "
-                                + Process.SYSTEM_UID);
-            }
-        } else {
-            // Everything else
-            if (args.uidSpecified || args.gidSpecified
-                || args.gids != null) {
-                throw new ZygoteSecurityException(
-                        "App UIDs may not specify uid's or gid's");
-            }
-        }
-
-        if (args.uidSpecified || args.gidSpecified || args.gids != null) {
-            boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
-                                                         peerSecurityContext,
-                                                         "zygote",
-                                                         "specifyids");
-            if (!allowed) {
-                throw new ZygoteSecurityException(
-                        "Peer may not specify uid's or gid's");
+                        + Process.SYSTEM_UID);
             }
         }
 
@@ -669,7 +631,6 @@
         }
     }
 
-
     /**
      * Applies debugger system properties to the zygote arguments.
      *
@@ -686,44 +647,6 @@
     }
 
     /**
-     * Applies zygote security policy per bug #1042973. Based on the credentials
-     * of the process issuing a zygote command:
-     * <ol>
-     * <li> peers of  uid 0 (root) and uid 1000 (Process.SYSTEM_UID)
-     * may specify any rlimits.
-     * <li> All other uids may not specify rlimits.
-     * </ul>
-     * @param args non-null; zygote spawner arguments
-     * @param peer non-null; peer credentials
-     * @throws ZygoteSecurityException
-     */
-    private static void applyRlimitSecurityPolicy(
-            Arguments args, Credentials peer, String peerSecurityContext)
-            throws ZygoteSecurityException {
-
-        int peerUid = peer.getUid();
-
-        if (!(peerUid == 0 || peerUid == Process.SYSTEM_UID)) {
-            // All peers with UID other than root or SYSTEM_UID
-            if (args.rlimits != null) {
-                throw new ZygoteSecurityException(
-                        "This UID may not specify rlimits.");
-            }
-        }
-
-        if (args.rlimits != null) {
-            boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
-                                                         peerSecurityContext,
-                                                         "zygote",
-                                                         "specifyrlimits");
-            if (!allowed) {
-                throw new ZygoteSecurityException(
-                        "Peer may not specify rlimits");
-            }
-         }
-    }
-
-    /**
      * Applies zygote security policy.
      * Based on the credentials of the process issuing a zygote command:
      * <ol>
@@ -736,8 +659,7 @@
      * @param peer non-null; peer credentials
      * @throws ZygoteSecurityException
      */
-    private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer,
-            String peerSecurityContext)
+    private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer)
             throws ZygoteSecurityException {
         int peerUid = peer.getUid();
 
@@ -745,52 +667,6 @@
             throw new ZygoteSecurityException("Peer is not permitted to specify "
                     + "an explicit invoke-with wrapper command");
         }
-
-        if (args.invokeWith != null) {
-            boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
-                                                         peerSecurityContext,
-                                                         "zygote",
-                                                         "specifyinvokewith");
-            if (!allowed) {
-                throw new ZygoteSecurityException("Peer is not permitted to specify "
-                    + "an explicit invoke-with wrapper command");
-            }
-        }
-    }
-
-    /**
-     * Applies zygote security policy for SELinux information.
-     *
-     * @param args non-null; zygote spawner arguments
-     * @param peer non-null; peer credentials
-     * @throws ZygoteSecurityException
-     */
-    private static void applyseInfoSecurityPolicy(
-            Arguments args, Credentials peer, String peerSecurityContext)
-            throws ZygoteSecurityException {
-        int peerUid = peer.getUid();
-
-        if (args.seInfo == null) {
-            // nothing to check
-            return;
-        }
-
-        if (!(peerUid == 0 || peerUid == Process.SYSTEM_UID)) {
-            // All peers with UID other than root or SYSTEM_UID
-            throw new ZygoteSecurityException(
-                    "This UID may not specify SELinux info.");
-        }
-
-        boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
-                                                     peerSecurityContext,
-                                                     "zygote",
-                                                     "specifyseinfo");
-        if (!allowed) {
-            throw new ZygoteSecurityException(
-                    "Peer may not specify SELinux info");
-        }
-
-        return;
     }
 
     /**
@@ -800,20 +676,18 @@
      */
     public static void applyInvokeWithSystemProperty(Arguments args) {
         if (args.invokeWith == null && args.niceName != null) {
-            if (args.niceName != null) {
-                String property = "wrap." + args.niceName;
-                if (property.length() > 31) {
-                    // Properties with a trailing "." are illegal.
-                    if (property.charAt(30) != '.') {
-                        property = property.substring(0, 31);
-                    } else {
-                        property = property.substring(0, 30);
-                    }
+            String property = "wrap." + args.niceName;
+            if (property.length() > 31) {
+                // Properties with a trailing "." are illegal.
+                if (property.charAt(30) != '.') {
+                    property = property.substring(0, 31);
+                } else {
+                    property = property.substring(0, 30);
                 }
-                args.invokeWith = SystemProperties.get(property);
-                if (args.invokeWith != null && args.invokeWith.length() == 0) {
-                    args.invokeWith = null;
-                }
+            }
+            args.invokeWith = SystemProperties.get(property);
+            if (args.invokeWith != null && args.invokeWith.length() == 0) {
+                args.invokeWith = null;
             }
         }
     }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 9d76335..30a7e68 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -18,6 +18,8 @@
 
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 
+LOCAL_CFLAGS += -DU_USING_ICU_NAMESPACE=0
+
 LOCAL_SRC_FILES:= \
     AndroidRuntime.cpp \
     com_android_internal_content_NativeLibraryHelper.cpp \
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index a6f19b1..e5ae147 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -48,10 +48,10 @@
             delete mBreakIterator;
         }
 
-        void setLocale(const Locale& locale) {
+        void setLocale(const icu::Locale& locale) {
             delete mBreakIterator;
             UErrorCode status = U_ZERO_ERROR;
-            mBreakIterator = BreakIterator::createLineInstance(locale, status);
+            mBreakIterator = icu::BreakIterator::createLineInstance(locale, status);
             // TODO: check status
         }
 
@@ -77,13 +77,13 @@
             }
         }
 
-        BreakIterator* breakIterator() const {
+        icu::BreakIterator* breakIterator() const {
             return mBreakIterator;
         }
 
     private:
         const size_t MAX_TEXT_BUF_RETAIN = 32678;
-        BreakIterator* mBreakIterator = nullptr;
+        icu::BreakIterator* mBreakIterator = nullptr;
         UText mUText = UTEXT_INITIALIZER;
         std::vector<uint16_t>mTextBuf;
 };
@@ -560,9 +560,9 @@
     // TODO: this array access is pretty inefficient, but we'll replace it anyway
     ScopedFloatArrayRO widthsScopedArr(env, widths);
 
-    BreakIterator* breakIterator = b->breakIterator();
+    icu::BreakIterator* breakIterator = b->breakIterator();
     int loc = breakIterator->first();
-    while ((loc = breakIterator->next()) != BreakIterator::DONE) {
+    while ((loc = breakIterator->next()) != icu::BreakIterator::DONE) {
         breaks.push_back(loc);
     }
 
diff --git a/docs/html/guide/topics/manifest/data-element.jd b/docs/html/guide/topics/manifest/data-element.jd
index ecba508..77f16dd 100644
--- a/docs/html/guide/topics/manifest/data-element.jd
+++ b/docs/html/guide/topics/manifest/data-element.jd
@@ -24,7 +24,7 @@
 attributes for each of its parts:
 
 <p style="margin-left: 2em">
-{@code &lt;scheme>://&lt;host>:&lt;port>/[&lt;path>|&lt;pathPrefix>|&lt;pathPattern>]}</p>
+{@code &lt;scheme>://&lt;host>:&lt;port>[&lt;path>|&lt;pathPrefix>|&lt;pathPattern>]}</p>
 
 <p>
 These attributes that specify the URL format are optional, but also mutually dependent:
@@ -115,7 +115,8 @@
 <dt><a name="path"></a>{@code android:path}
 <br/>{@code android:pathPrefix}
 <br/>{@code android:pathPattern}</dt>
-<dd>The path part of a URI.  The {@code path} attribute specifies a complete
+<dd>The path part of a URI which must begin with a /.
+The {@code path} attribute specifies a complete
 path that is matched against the complete path in an Intent object.  The
 {@code pathPrefix} attribute specifies a partial path that is matched against
 only the initial part of the path in the Intent object.  The {@code pathPattern}
diff --git a/docs/html/tools/revisions/gradle-plugin.jd b/docs/html/tools/revisions/gradle-plugin.jd
index e083792..fd294d2 100644
--- a/docs/html/tools/revisions/gradle-plugin.jd
+++ b/docs/html/tools/revisions/gradle-plugin.jd
@@ -39,6 +39,36 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>Android Plugin for Gradle, Revision 1.1.3</a> <em>(March 2015)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Gradle 2.2.1 or higher.</li>
+        <li>Build Tools 21.1.1 or higher.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+    <ul>
+      <li>Fixed issue with duplicated dependencies on a test app that triggered a ProGuard failure. </li>
+      <li>Fixed Comparator implementation which did not comply with the JDK Comparator contract and
+      generated a JDK 7 error.</li>
+    </ul>
+    </dd>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>Android Plugin for Gradle, Revision 1.1.2</a> <em>(February 2015)</em>
   </p>
 
@@ -68,7 +98,6 @@
 
 
 
-
 <div class="toggle-content closed">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
diff --git a/graphics/java/android/graphics/drawable/RippleComponent.java b/graphics/java/android/graphics/drawable/RippleComponent.java
index fd3e06c..79407f7 100644
--- a/graphics/java/android/graphics/drawable/RippleComponent.java
+++ b/graphics/java/android/graphics/drawable/RippleComponent.java
@@ -69,7 +69,6 @@
 
         mDensity = density;
 
-        onSetup();
         onTargetRadiusChanged(mTargetRadius);
     }
 
@@ -82,7 +81,10 @@
         cancel();
 
         mSoftwareAnimator = createSoftwareEnter(fast);
-        mSoftwareAnimator.start();
+
+        if (mSoftwareAnimator != null) {
+            mSoftwareAnimator.start();
+        }
     }
 
     /**
@@ -250,14 +252,6 @@
         // Stub.
     }
 
-    /**
-     * Called during ripple setup, which occurs before the first enter
-     * animation.
-     */
-    protected void onSetup() {
-        // Stub.
-    }
-
     protected abstract Animator createSoftwareEnter(boolean fast);
 
     protected abstract Animator createSoftwareExit();
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index bc8c7d2..66160c0 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -564,7 +564,9 @@
                 x = mHotspotBounds.exactCenterX();
                 y = mHotspotBounds.exactCenterY();
             }
-            mRipple = new RippleForeground(this, mHotspotBounds, x, y);
+
+            final boolean isBounded = !isProjected();
+            mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded);
         }
 
         mRipple.setup(mState.mMaxRadius, mDensity);
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index 2023f04..334122d 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -44,9 +44,16 @@
     private static final float WAVE_TOUCH_UP_ACCELERATION = 3400;
     private static final float WAVE_OPACITY_DECAY_VELOCITY = 3;
 
+    // Bounded ripple animation properties.
+    private static final int BOUNDED_ORIGIN_EXIT_DURATION = 300;
+    private static final int BOUNDED_RADIUS_EXIT_DURATION = 800;
+    private static final int BOUNDED_OPACITY_EXIT_DURATION = 400;
+    private static final float MAX_BOUNDED_RADIUS = 350;
+
     private static final int RIPPLE_ENTER_DELAY = 80;
     private static final int OPACITY_ENTER_DURATION_FAST = 120;
 
+    // Parent-relative values for starting position.
     private float mStartingX;
     private float mStartingY;
     private float mClampedStartingX;
@@ -58,30 +65,41 @@
     private CanvasProperty<Float> mPropX;
     private CanvasProperty<Float> mPropY;
 
+    // Target values for tween animations.
+    private float mTargetX = 0;
+    private float mTargetY = 0;
+
+    /** Ripple target radius used when bounded. Not used for clamping. */
+    private float mBoundedRadius = 0;
+
     // Software rendering properties.
     private float mOpacity = 1;
-    private float mOuterX;
-    private float mOuterY;
 
     // Values used to tween between the start and end positions.
     private float mTweenRadius = 0;
     private float mTweenX = 0;
     private float mTweenY = 0;
 
+    /** Whether this ripple is bounded. */
+    private boolean mIsBounded;
+
     /** Whether this ripple has finished its exit animation. */
     private boolean mHasFinishedExit;
 
-    public RippleForeground(RippleDrawable owner, Rect bounds, float startingX, float startingY) {
+    public RippleForeground(RippleDrawable owner, Rect bounds, float startingX, float startingY,
+            boolean isBounded) {
         super(owner, bounds);
 
+        mIsBounded = isBounded;
         mStartingX = startingX;
         mStartingY = startingY;
-    }
 
-    @Override
-    public void onSetup() {
-        mOuterX = 0;
-        mOuterY = 0;
+        if (isBounded) {
+            mBoundedRadius = MAX_BOUNDED_RADIUS * 0.9f
+                    + (float) (MAX_BOUNDED_RADIUS * Math.random() * 0.1);
+        } else {
+            mBoundedRadius = 0;
+        }
     }
 
     @Override
@@ -95,12 +113,10 @@
 
         final int origAlpha = p.getAlpha();
         final int alpha = (int) (origAlpha * mOpacity + 0.5f);
-        final float radius = MathUtils.lerp(0, mTargetRadius, mTweenRadius);
+        final float radius = getCurrentRadius();
         if (alpha > 0 && radius > 0) {
-            final float x = MathUtils.lerp(
-                    mClampedStartingX - mBounds.exactCenterX(), mOuterX, mTweenX);
-            final float y = MathUtils.lerp(
-                    mClampedStartingY - mBounds.exactCenterY(), mOuterY, mTweenY);
+            final float x = getCurrentX();
+            final float y = getCurrentY();
             p.setAlpha(alpha);
             c.drawCircle(x, y, radius, p);
             p.setAlpha(origAlpha);
@@ -120,8 +136,8 @@
      * Returns the maximum bounds of the ripple relative to the ripple center.
      */
     public void getBounds(Rect bounds) {
-        final int outerX = (int) mOuterX;
-        final int outerY = (int) mOuterY;
+        final int outerX = (int) mTargetX;
+        final int outerY = (int) mTargetY;
         final int r = (int) mTargetRadius + 1;
         bounds.set(outerX - r, outerY - r, outerX + r, outerY + r);
     }
@@ -146,14 +162,25 @@
 
     @Override
     protected Animator createSoftwareEnter(boolean fast) {
+        // Bounded ripples don't have enter animations.
+        if (mIsBounded) {
+            return null;
+        }
+
         final int duration = (int)
                 (1000 * Math.sqrt(mTargetRadius / WAVE_TOUCH_DOWN_ACCELERATION * mDensity) + 0.5);
 
-        final ObjectAnimator tweenAll = ObjectAnimator.ofFloat(this, TWEEN_ALL, 1);
-        tweenAll.setAutoCancel(true);
-        tweenAll.setDuration(duration);
-        tweenAll.setInterpolator(LINEAR_INTERPOLATOR);
-        tweenAll.setStartDelay(RIPPLE_ENTER_DELAY);
+        final ObjectAnimator tweenRadius = ObjectAnimator.ofFloat(this, TWEEN_RADIUS, 1);
+        tweenRadius.setAutoCancel(true);
+        tweenRadius.setDuration(duration);
+        tweenRadius.setInterpolator(LINEAR_INTERPOLATOR);
+        tweenRadius.setStartDelay(RIPPLE_ENTER_DELAY);
+
+        final ObjectAnimator tweenOrigin = ObjectAnimator.ofFloat(this, TWEEN_ORIGIN, 1);
+        tweenOrigin.setAutoCancel(true);
+        tweenOrigin.setDuration(duration);
+        tweenOrigin.setInterpolator(LINEAR_INTERPOLATOR);
+        tweenOrigin.setStartDelay(RIPPLE_ENTER_DELAY);
 
         final ObjectAnimator opacity = ObjectAnimator.ofFloat(this, OPACITY, 1);
         opacity.setAutoCancel(true);
@@ -161,31 +188,68 @@
         opacity.setInterpolator(LINEAR_INTERPOLATOR);
 
         final AnimatorSet set = new AnimatorSet();
-        set.play(tweenAll).with(opacity);
+        set.play(tweenOrigin).with(tweenRadius).with(opacity);
 
         return set;
     }
 
+    private float getCurrentX() {
+        return MathUtils.lerp(mClampedStartingX - mBounds.exactCenterX(), mTargetX, mTweenX);
+    }
+
+    private float getCurrentY() {
+        return MathUtils.lerp(mClampedStartingY - mBounds.exactCenterY(), mTargetY, mTweenY);
+    }
+
     private int getRadiusExitDuration() {
-        final float radius = MathUtils.lerp(0, mTargetRadius, mTweenRadius);
-        final float remaining = mTargetRadius - radius;
-        return (int) (1000 * Math.sqrt(remaining / (WAVE_TOUCH_UP_ACCELERATION
+        final float remainingRadius = mTargetRadius - getCurrentRadius();
+        return (int) (1000 * Math.sqrt(remainingRadius / (WAVE_TOUCH_UP_ACCELERATION
                 + WAVE_TOUCH_DOWN_ACCELERATION) * mDensity) + 0.5);
     }
 
+    private float getCurrentRadius() {
+        return MathUtils.lerp(0, mTargetRadius, mTweenRadius);
+    }
+
     private int getOpacityExitDuration() {
         return (int) (1000 * mOpacity / WAVE_OPACITY_DECAY_VELOCITY + 0.5f);
     }
 
+    /**
+     * Compute target values that are dependent on bounding.
+     */
+    private void computeBoundedTargetValues() {
+        mTargetX = (mClampedStartingX - mBounds.exactCenterX()) * .7f;
+        mTargetY = (mClampedStartingY - mBounds.exactCenterY()) * .7f;
+        mTargetRadius = mBoundedRadius;
+    }
+
     @Override
     protected Animator createSoftwareExit() {
-        final int radiusDuration = getRadiusExitDuration();
-        final int opacityDuration = getOpacityExitDuration();
+        final int radiusDuration;
+        final int originDuration;
+        final int opacityDuration;
+        if (mIsBounded) {
+            computeBoundedTargetValues();
 
-        final ObjectAnimator tweenAll = ObjectAnimator.ofFloat(this, TWEEN_ALL, 1);
-        tweenAll.setAutoCancel(true);
-        tweenAll.setDuration(radiusDuration);
-        tweenAll.setInterpolator(DECELERATE_INTERPOLATOR);
+            radiusDuration = BOUNDED_RADIUS_EXIT_DURATION;
+            originDuration = BOUNDED_ORIGIN_EXIT_DURATION;
+            opacityDuration = BOUNDED_OPACITY_EXIT_DURATION;
+        } else {
+            radiusDuration = getRadiusExitDuration();
+            originDuration = radiusDuration;
+            opacityDuration = getOpacityExitDuration();
+        }
+
+        final ObjectAnimator tweenRadius = ObjectAnimator.ofFloat(this, TWEEN_RADIUS, 1);
+        tweenRadius.setAutoCancel(true);
+        tweenRadius.setDuration(radiusDuration);
+        tweenRadius.setInterpolator(DECELERATE_INTERPOLATOR);
+
+        final ObjectAnimator tweenOrigin = ObjectAnimator.ofFloat(this, TWEEN_ORIGIN, 1);
+        tweenOrigin.setAutoCancel(true);
+        tweenOrigin.setDuration(originDuration);
+        tweenOrigin.setInterpolator(DECELERATE_INTERPOLATOR);
 
         final ObjectAnimator opacity = ObjectAnimator.ofFloat(this, OPACITY, 0);
         opacity.setAutoCancel(true);
@@ -193,7 +257,7 @@
         opacity.setInterpolator(LINEAR_INTERPOLATOR);
 
         final AnimatorSet set = new AnimatorSet();
-        set.play(tweenAll).with(opacity);
+        set.play(tweenOrigin).with(tweenRadius).with(opacity);
         set.addListener(mAnimationListener);
 
         return set;
@@ -201,15 +265,25 @@
 
     @Override
     protected RenderNodeAnimatorSet createHardwareExit(Paint p) {
-        final int radiusDuration = getRadiusExitDuration();
-        final int opacityDuration = getOpacityExitDuration();
+        final int radiusDuration;
+        final int originDuration;
+        final int opacityDuration;
+        if (mIsBounded) {
+            computeBoundedTargetValues();
 
-        final float startX = MathUtils.lerp(
-                mClampedStartingX - mBounds.exactCenterX(), mOuterX, mTweenX);
-        final float startY = MathUtils.lerp(
-                mClampedStartingY - mBounds.exactCenterY(), mOuterY, mTweenY);
+            radiusDuration = BOUNDED_RADIUS_EXIT_DURATION;
+            originDuration = BOUNDED_ORIGIN_EXIT_DURATION;
+            opacityDuration = BOUNDED_OPACITY_EXIT_DURATION;
+        } else {
+            radiusDuration = getRadiusExitDuration();
+            originDuration = radiusDuration;
+            opacityDuration = getOpacityExitDuration();
+        }
 
-        final float startRadius = MathUtils.lerp(0, mTargetRadius, mTweenRadius);
+        final float startX = getCurrentX();
+        final float startY = getCurrentY();
+        final float startRadius = getCurrentRadius();
+
         p.setAlpha((int) (p.getAlpha() * mOpacity + 0.5f));
 
         mPropPaint = CanvasProperty.createPaint(p);
@@ -221,12 +295,12 @@
         radius.setDuration(radiusDuration);
         radius.setInterpolator(DECELERATE_INTERPOLATOR);
 
-        final RenderNodeAnimator x = new RenderNodeAnimator(mPropX, mOuterX);
-        x.setDuration(radiusDuration);
+        final RenderNodeAnimator x = new RenderNodeAnimator(mPropX, mTargetX);
+        x.setDuration(originDuration);
         x.setInterpolator(DECELERATE_INTERPOLATOR);
 
-        final RenderNodeAnimator y = new RenderNodeAnimator(mPropY, mOuterY);
-        y.setDuration(radiusDuration);
+        final RenderNodeAnimator y = new RenderNodeAnimator(mPropY, mTargetY);
+        y.setDuration(originDuration);
         y.setInterpolator(DECELERATE_INTERPOLATOR);
 
         final RenderNodeAnimator opacity = new RenderNodeAnimator(mPropPaint,
@@ -307,16 +381,13 @@
     }
 
     /**
-     * Property for animating radius, center X, and center Y between their
-     * initial and target values.
+     * Property for animating radius between its initial and target values.
      */
-    private static final FloatProperty<RippleForeground> TWEEN_ALL =
-            new FloatProperty<RippleForeground>("tweenAll") {
+    private static final FloatProperty<RippleForeground> TWEEN_RADIUS =
+            new FloatProperty<RippleForeground>("tweenRadius") {
         @Override
         public void setValue(RippleForeground object, float value) {
             object.mTweenRadius = value;
-            object.mTweenX = value;
-            object.mTweenY = value;
             object.invalidateSelf();
         }
 
@@ -327,6 +398,24 @@
     };
 
     /**
+     * Property for animating origin between its initial and target values.
+     */
+    private static final FloatProperty<RippleForeground> TWEEN_ORIGIN =
+            new FloatProperty<RippleForeground>("tweenOrigin") {
+                @Override
+                public void setValue(RippleForeground object, float value) {
+                    object.mTweenX = value;
+                    object.mTweenY = value;
+                    object.invalidateSelf();
+                }
+
+                @Override
+                public Float get(RippleForeground object) {
+                    return object.mTweenX;
+                }
+            };
+
+    /**
      * Property for animating opacity between 0 and its target value.
      */
     private static final FloatProperty<RippleForeground> OPACITY =
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
index c03bb58..d81daa9 100644
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -238,12 +238,21 @@
 
     public void writePatternHash(byte[] hash, int userId) {
         writeFile(getLockPatternFilename(userId), hash);
+        clearPasswordHash(userId);
+    }
+
+    private void clearPatternHash(int userId) {
+        writeFile(getLockPatternFilename(userId), null);
     }
 
     public void writePasswordHash(byte[] hash, int userId) {
         writeFile(getLockPasswordFilename(userId), hash);
+        clearPatternHash(userId);
     }
 
+    private void clearPasswordHash(int userId) {
+        writeFile(getLockPasswordFilename(userId), null);
+    }
 
     @VisibleForTesting
     String getLockPatternFilename(int userId) {
@@ -279,16 +288,15 @@
         return userId;
     }
 
-
     public void removeUser(int userId) {
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
 
         final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
         final UserInfo parentInfo = um.getProfileParent(userId);
 
-        synchronized (mFileWriteLock) {
-            if (parentInfo == null) {
-                // This user owns its lock settings files - safe to delete them
+        if (parentInfo == null) {
+            // This user owns its lock settings files - safe to delete them
+            synchronized (mFileWriteLock) {
                 String name = getLockPasswordFilename(userId);
                 File file = new File(name);
                 if (file.exists()) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 46f07cc..b9bb8d0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7878,7 +7878,7 @@
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
                     "getTaskThumbnail()");
-            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
+            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
             if (tr != null) {
                 return tr.getTaskThumbnailLocked();
             }
@@ -7991,7 +7991,7 @@
     @Override
     public void setTaskResizeable(int taskId, boolean resizeable) {
         synchronized (this) {
-            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
+            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
             if (task == null) {
                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
                 return;
@@ -8158,7 +8158,7 @@
      * @return Returns true if the given task was found and removed.
      */
     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
-        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
+        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
         if (tr != null) {
             tr.removeTaskActivitiesLocked();
             cleanUpRemovedTaskLocked(tr, killProcess);
@@ -8411,7 +8411,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
+                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
             }
         } finally {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 40a8b86..a1d99e3 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4247,8 +4247,6 @@
                 mActivityContainer.onTaskListEmptyLocked();
             }
         }
-
-        task.stack = null;
     }
 
     TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 8b95ae8..62db20a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -471,16 +471,6 @@
     }
 
     TaskRecord anyTaskForIdLocked(int id) {
-        return anyTaskForIdLocked(id, true);
-    }
-
-    /**
-     * Returns a {@link TaskRecord} for the input id if available. Null otherwise.
-     * @param id Id of the task we would like returned.
-     * @param restoreFromRecents If the id was not in the active list, but was found in recents,
-     *                           restore the task from recents to the active list.
-     */
-    TaskRecord anyTaskForIdLocked(int id, boolean restoreFromRecents) {
         int numDisplays = mActivityDisplays.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -501,10 +491,6 @@
             return null;
         }
 
-        if (!restoreFromRecents) {
-            return task;
-        }
-
         if (!restoreRecentTaskLocked(task)) {
             if (DEBUG_RECENTS) Slog.w(TAG, "Couldn't restore task id=" + id + " found in recents");
             return null;
@@ -539,7 +525,7 @@
             if (mCurTaskId <= 0) {
                 mCurTaskId = 1;
             }
-        } while (anyTaskForIdLocked(mCurTaskId, false) != null);
+        } while (anyTaskForIdLocked(mCurTaskId) != null);
         return mCurTaskId;
     }
 
@@ -2731,7 +2717,7 @@
             final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
             for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx);
-                if (!tmpStack.isHomeStack() && tmpStack.mFullscreen) {
+                if (!tmpStack.isHomeStack()) {
                     stack = tmpStack;
                     break;
                 }
@@ -3993,10 +3979,6 @@
         }
 
         void onTaskListEmptyLocked() {
-            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
-            detachLocked();
-            deleteActivityContainer(this);
-            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
         }
 
         @Override
@@ -4085,6 +4067,13 @@
             return false;
         }
 
+        void onTaskListEmptyLocked() {
+            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
+            detachLocked();
+            deleteActivityContainer(this);
+            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
+        }
+
         private void setSurfaceIfReadyLocked() {
             if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
                     " mContainerState=" + mContainerState + " mSurface=" + mSurface);
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 5363968..b5036db 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -808,6 +808,7 @@
             }
             if (typeChanged) {
                 mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
+                mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
             }
         }
 
@@ -822,6 +823,7 @@
             }
             if (typeChanged) {
                 mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
+                mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
             }
         }
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bedcabe..bb0aa65c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1026,6 +1026,7 @@
     private void updateListenerHintsLocked() {
         final int hints = mListenersDisablingEffects.isEmpty() ? 0 : HINT_HOST_DISABLE_EFFECTS;
         if (hints == mListenerHints) return;
+        ZenLog.traceListenerHintsChanged(mListenerHints, hints, mListenersDisablingEffects.size());
         mListenerHints = hints;
         scheduleListenerHintsChanged(hints);
     }
@@ -1034,6 +1035,7 @@
         final ComponentName suppressor = !mListenersDisablingEffects.isEmpty()
                 ? mListenersDisablingEffects.valueAt(0).component : null;
         if (Objects.equals(suppressor, mEffectsSuppressor)) return;
+        ZenLog.traceEffectsSuppressorChanged(mEffectsSuppressor, suppressor);
         mEffectsSuppressor = suppressor;
         mZenModeHelper.setEffectsSuppressed(suppressor != null);
         getContext().sendBroadcast(new Intent(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED)
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index a83fbc3..1fc967f 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -24,6 +24,7 @@
 import android.provider.Settings.Global;
 import android.service.notification.Condition;
 import android.service.notification.IConditionProvider;
+import android.service.notification.NotificationListenerService;
 import android.service.notification.ZenModeConfig;
 import android.util.Slog;
 
@@ -56,6 +57,8 @@
     private static final int TYPE_CONFIG = 11;
     private static final int TYPE_NOT_INTERCEPTED = 12;
     private static final int TYPE_DISABLE_EFFECTS = 13;
+    private static final int TYPE_SUPPRESSOR_CHANGED = 14;
+    private static final int TYPE_LISTENER_HINTS_CHANGED = 15;
 
     private static int sNext;
     private static int sSize;
@@ -120,6 +123,17 @@
         append(TYPE_DISABLE_EFFECTS, record.getKey() + "," + reason);
     }
 
+    public static void traceEffectsSuppressorChanged(ComponentName oldSuppressor,
+            ComponentName newSuppressor) {
+        append(TYPE_SUPPRESSOR_CHANGED, componentToString(oldSuppressor) + "->"
+            + componentToString(newSuppressor));
+    }
+
+    public static void traceListenerHintsChanged(int oldHints, int newHints, int listenerCount) {
+        append(TYPE_LISTENER_HINTS_CHANGED, hintsToString(oldHints) + "->"
+            + hintsToString(newHints) + ",listeners=" + listenerCount);
+    }
+
     private static String subscribeResult(IConditionProvider provider, RemoteException e) {
         return provider == null ? "no provider" : e != null ? e.getMessage() : "ok";
     }
@@ -139,6 +153,8 @@
             case TYPE_CONFIG: return "config";
             case TYPE_NOT_INTERCEPTED: return "not_intercepted";
             case TYPE_DISABLE_EFFECTS: return "disable_effects";
+            case TYPE_SUPPRESSOR_CHANGED: return "suppressor_changed";
+            case TYPE_LISTENER_HINTS_CHANGED: return "listener_hints_changed";
             default: return "unknown";
         }
     }
@@ -161,6 +177,14 @@
         }
     }
 
+    private static String hintsToString(int hints) {
+        switch (hints) {
+            case 0 : return "none";
+            case NotificationListenerService.HINT_HOST_DISABLE_EFFECTS : return "disable_effects";
+            default: return Integer.toString(hints);
+        }
+    }
+
     private static String componentToString(ComponentName component) {
         return component != null ? component.toShortString() : null;
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7e69e87..a4f3f23 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -496,7 +496,12 @@
     int mLastDisplayFreezeDuration = 0;
     Object mLastFinishedFreezeSource = null;
     boolean mWaitingForConfig = false;
-    boolean mWindowsFreezingScreen = false;
+
+    final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
+    final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
+    final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2;
+    private int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
+
     boolean mClientFreezingScreen = false;
     int mAppsFreezingScreen = 0;
     int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -4699,7 +4704,7 @@
                 if (mAppsFreezingScreen == 1) {
                     startFreezingDisplayLocked(false, 0, 0);
                     mH.removeMessages(H.APP_FREEZE_TIMEOUT);
-                    mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000);
+                    mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
                 }
             }
             final int N = wtoken.allAppWindows.size();
@@ -6415,7 +6420,7 @@
         mAltOrientation = altOrientation;
         mPolicy.setRotationLw(mRotation);
 
-        mWindowsFreezingScreen = true;
+        mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
         mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
         mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
         mWaitingForConfig = true;
@@ -7784,6 +7789,7 @@
                     // TODO(multidisplay): Can non-default displays rotate?
                     synchronized (mWindowMap) {
                         Slog.w(TAG, "Window freeze timeout expired.");
+                        mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
                         final WindowList windows = getDefaultWindowListLocked();
                         int i = windows.size();
                         while (i > 0) {
@@ -7851,6 +7857,7 @@
                 case APP_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
                         Slog.w(TAG, "App freeze timeout expired.");
+                        mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
                         final int numStacks = mStackIdToStack.size();
                         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
                             final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
@@ -8914,8 +8921,8 @@
             w.mOrientationChanging = true;
             w.mLastFreezeDuration = 0;
             mInnerFields.mOrientationChangeComplete = false;
-            if (!mWindowsFreezingScreen) {
-                mWindowsFreezingScreen = true;
+            if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
+                mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
                 // XXX should probably keep timeout from
                 // when we first froze the display.
                 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
@@ -9905,8 +9912,8 @@
                 "With display frozen, orientationChangeComplete="
                 + mInnerFields.mOrientationChangeComplete);
         if (mInnerFields.mOrientationChangeComplete) {
-            if (mWindowsFreezingScreen) {
-                mWindowsFreezingScreen = false;
+            if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
+                mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
                 mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
                 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
             }
@@ -10188,7 +10195,7 @@
         } else {
             mInnerFields.mOrientationChangeComplete = true;
             mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
-            if (mWindowsFreezingScreen) {
+            if (mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
                 doRequest = true;
             }
         }
@@ -10524,7 +10531,8 @@
             return;
         }
 
-        if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
+        if (mWaitingForConfig || mAppsFreezingScreen > 0
+                || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
                 || mClientFreezingScreen) {
             if (DEBUG_ORIENTATION) Slog.d(TAG,
                 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 929d625..e24b3d5 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -1,6 +1,7 @@
 package android.text;
 
 import com.android.annotations.NonNull;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
 import android.text.StaticLayout.LineBreaks;
@@ -27,14 +28,19 @@
     private static final char CHAR_NEWLINE   = 0x0A;
     private static final char CHAR_ZWSP      = 0x200B;  // Zero width space.
 
+    // ---- Builder delegate manager ----
+    private static final DelegateManager<Builder> sBuilderManager =
+        new DelegateManager<Builder>(Builder.class);
+
     @LayoutlibDelegate
-    /*package*/ static int nComputeLineBreaks(String locale, char[] inputText, float[] widths,
+    /*package*/ static int nComputeLineBreaks(long nativeBuilder, char[] inputText, float[] widths,
             int length, float firstWidth, int firstWidthLineCount, float restWidth,
             int[] variableTabStops, int defaultTabStop, boolean optimize, LineBreaks recycle,
             int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength) {
 
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
         // compute all possible breakpoints.
-        BreakIterator it = BreakIterator.getLineInstance(new ULocale(locale));
+        BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
         it.setText(new Segment(inputText, 0, length));
         // average word length in english is 5. So, initialize the possible breaks with a guess.
         List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
@@ -97,4 +103,32 @@
                 PrimitiveType.PENALTY.getNewPrimitive(length, 0, -PrimitiveType.PENALTY_INFINITY));
         return primitives;
     }
+
+    @LayoutlibDelegate
+    /*package*/ static long nNewBuilder() {
+        return sBuilderManager.addNewDelegate(new Builder());
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nFinishBuilder(long nativeBuilder) {
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nFreeBuilder(long nativeBuilder) {
+        sBuilderManager.removeJavaReferenceFor(nativeBuilder);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nBuilderSetLocale(long nativeBuilder, String locale) {
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+        builder.mLocale = locale;
+    }
+
+    /**
+     * Java representation of the native Builder class. It currently only stores the locale
+     * set by nBuilderSetLocale.
+     */
+    static class Builder {
+        String mLocale;
+    }
 }