Merge "Delay the dispatching of non-wakeup alarms."
diff --git a/api/current.txt b/api/current.txt
index e7f75f7..9ac27db 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -864,6 +864,7 @@
     field public static final int paddingBottom = 16842969; // 0x10100d9
     field public static final int paddingEnd = 16843700; // 0x10103b4
     field public static final int paddingLeft = 16842966; // 0x10100d6
+    field public static final int paddingMode = 16843866; // 0x101045a
     field public static final int paddingRight = 16842968; // 0x10100d8
     field public static final int paddingStart = 16843699; // 0x10103b3
     field public static final int paddingTop = 16842967; // 0x10100d7
@@ -1640,7 +1641,6 @@
     field public static final int selectAll = 16908319; // 0x102001f
     field public static final int selectTextMode = 16908333; // 0x102002d
     field public static final int selectedIcon = 16908302; // 0x102000e
-    field public static final int shared_element = 16908354; // 0x1020042
     field public static final int startSelectingText = 16908328; // 0x1020028
     field public static final int stopSelectingText = 16908329; // 0x1020029
     field public static final int summary = 16908304; // 0x1020010
@@ -2830,6 +2830,12 @@
     method public java.lang.Object evaluate(float, java.lang.Object, java.lang.Object);
   }
 
+  public abstract class BidirectionalTypeConverter extends android.animation.TypeConverter {
+    ctor public BidirectionalTypeConverter(java.lang.Class<T>, java.lang.Class<V>);
+    method public abstract T convertBack(V);
+    method public android.animation.BidirectionalTypeConverter<V, T> invert();
+  }
+
   public class FloatArrayEvaluator implements android.animation.TypeEvaluator {
     ctor public FloatArrayEvaluator();
     ctor public FloatArrayEvaluator(float[]);
@@ -3008,7 +3014,6 @@
   public abstract class TypeConverter {
     ctor public TypeConverter(java.lang.Class<T>, java.lang.Class<V>);
     method public abstract V convert(T);
-    method public T convertBack(V);
   }
 
   public abstract interface TypeEvaluator {
@@ -3336,6 +3341,8 @@
     method public void setContentView(android.view.View);
     method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public final void setDefaultKeyMode(int);
+    method public void setEnterSharedElementListener(android.app.SharedElementListener);
+    method public void setExitSharedElementListener(android.app.SharedElementListener);
     method public final void setFeatureDrawable(int, android.graphics.drawable.Drawable);
     method public final void setFeatureDrawableAlpha(int, int);
     method public final void setFeatureDrawableResource(int, int);
@@ -3351,7 +3358,6 @@
     method public final void setResult(int);
     method public final void setResult(int, android.content.Intent);
     method public final void setSecondaryProgress(int);
-    method public void setSharedElementListener(android.app.SharedElementListener);
     method public void setTaskDescription(android.app.ActivityManager.TaskDescription);
     method public void setTitle(java.lang.CharSequence);
     method public void setTitle(int);
@@ -4418,6 +4424,8 @@
     ctor public Notification(android.os.Parcel);
     method public android.app.Notification clone();
     method public int describeContents();
+    method public java.lang.String getGroup();
+    method public java.lang.String getSortKey();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
@@ -4460,6 +4468,7 @@
     field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
     field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
     field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
     field public static final int FLAG_INSISTENT = 4; // 0x4
     field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
@@ -4510,6 +4519,7 @@
     method public android.app.Notification.Action clone();
     method public int describeContents();
     method public android.os.Bundle getExtras();
+    method public android.app.RemoteInput[] getRemoteInputs();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public android.app.PendingIntent actionIntent;
@@ -4517,14 +4527,20 @@
     field public java.lang.CharSequence title;
   }
 
-  public static class Notification.Action.Builder {
+  public static final class Notification.Action.Builder {
     ctor public Notification.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent);
     ctor public Notification.Action.Builder(android.app.Notification.Action);
     method public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
+    method public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
+    method public android.app.Notification.Action.Builder apply(android.app.Notification.Action.Builder.Extender);
     method public android.app.Notification.Action build();
     method public android.os.Bundle getExtras();
   }
 
+  public static abstract interface Notification.Action.Builder.Extender {
+    method public abstract android.app.Notification.Action.Builder applyTo(android.app.Notification.Action.Builder);
+  }
+
   public static class Notification.BigPictureStyle extends android.app.Notification.Style {
     ctor public Notification.BigPictureStyle();
     ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
@@ -4548,6 +4564,7 @@
     method public android.app.Notification.Builder addAction(android.app.Notification.Action);
     method public android.app.Notification.Builder addExtras(android.os.Bundle);
     method public android.app.Notification.Builder addPerson(java.lang.String);
+    method public android.app.Notification.Builder apply(android.app.Notification.Builder.Extender);
     method public android.app.Notification build();
     method public android.os.Bundle getExtras();
     method public deprecated android.app.Notification getNotification();
@@ -4563,6 +4580,8 @@
     method public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
     method public android.app.Notification.Builder setExtras(android.os.Bundle);
     method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
+    method public android.app.Notification.Builder setGroup(java.lang.String);
+    method public android.app.Notification.Builder setGroupSummary(boolean);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.Builder setLights(int, int, int);
     method public android.app.Notification.Builder setLocalOnly(boolean);
@@ -4575,6 +4594,7 @@
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
+    method public android.app.Notification.Builder setSortKey(java.lang.String);
     method public android.app.Notification.Builder setSound(android.net.Uri);
     method public android.app.Notification.Builder setSound(android.net.Uri, int);
     method public android.app.Notification.Builder setStyle(android.app.Notification.Style);
@@ -4587,6 +4607,10 @@
     method public android.app.Notification.Builder setWhen(long);
   }
 
+  public static abstract interface Notification.Builder.Extender {
+    method public abstract android.app.Notification.Builder applyTo(android.app.Notification.Builder);
+  }
+
   public static class Notification.InboxStyle extends android.app.Notification.Style {
     ctor public Notification.InboxStyle();
     ctor public Notification.InboxStyle(android.app.Notification.Builder);
@@ -4690,6 +4714,31 @@
     field public static final int STYLE_SPINNER = 0; // 0x0
   }
 
+  public final class RemoteInput implements android.os.Parcelable {
+    method public static void addResultsToIntent(android.app.RemoteInput[], android.content.Intent, android.os.Bundle);
+    method public int describeContents();
+    method public boolean getAllowFreeFormInput();
+    method public java.lang.CharSequence[] getChoices();
+    method public android.os.Bundle getExtras();
+    method public java.lang.CharSequence getLabel();
+    method public java.lang.String getResultKey();
+    method public static android.os.Bundle getResultsFromIntent(android.content.Intent);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final java.lang.String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+    field public static final java.lang.String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+  }
+
+  public static final class RemoteInput.Builder {
+    ctor public RemoteInput.Builder(java.lang.String);
+    method public android.app.RemoteInput.Builder addExtras(android.os.Bundle);
+    method public android.app.RemoteInput build();
+    method public android.os.Bundle getExtras();
+    method public android.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+    method public android.app.RemoteInput.Builder setChoices(java.lang.CharSequence[]);
+    method public android.app.RemoteInput.Builder setLabel(java.lang.CharSequence);
+  }
+
   public class SearchManager implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
     method public android.content.ComponentName getGlobalSearchActivity();
     method public android.app.SearchableInfo getSearchableInfo(android.content.ComponentName);
@@ -4810,7 +4859,7 @@
     field public static final int START_STICKY_COMPATIBILITY = 0; // 0x0
   }
 
-  public class SharedElementListener {
+  public abstract class SharedElementListener {
     ctor public SharedElementListener();
     method public void handleRejectedSharedElements(java.util.List<android.view.View>);
     method public void remapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String, android.view.View>);
@@ -8265,6 +8314,7 @@
     field public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
     field public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host";
     field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
+    field public static final java.lang.String FEATURE_WEBVIEW = "android.software.webview";
     field public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi";
     field public static final java.lang.String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct";
     field public static final int GET_ACTIVITIES = 1; // 0x1
@@ -12821,15 +12871,14 @@
 
   public class UsbConfiguration implements android.os.Parcelable {
     method public int describeContents();
-    method public int getAttributes();
     method public int getId();
     method public android.hardware.usb.UsbInterface getInterface(int);
     method public int getInterfaceCount();
     method public int getMaxPower();
     method public java.lang.String getName();
+    method public boolean isRemoteWakeup();
+    method public boolean isSelfPowered();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final int ATTR_REMOTE_WAKEUP_MASK = 32; // 0x20
-    field public static final int ATTR_SELF_POWERED_MASK = 64; // 0x40
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
@@ -25584,20 +25633,24 @@
     method public final deprecated void cancelNotification(java.lang.String, java.lang.String, int);
     method public final void cancelNotification(java.lang.String);
     method public final void cancelNotifications(java.lang.String[]);
+    method public java.lang.String[] getActiveNotificationKeys();
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
     method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[]);
-    method public java.lang.String[] getOrderedNotificationKeys();
+    method public android.service.notification.NotificationListenerService.Ranking getCurrentRanking();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onListenerConnected(java.lang.String[]);
-    method public void onNotificationOrderUpdate();
     method public abstract void onNotificationPosted(android.service.notification.StatusBarNotification);
+    method public void onNotificationRankingUpdate();
     method public abstract void onNotificationRemoved(android.service.notification.StatusBarNotification);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
   }
 
-  public class NotificationOrderUpdate implements android.os.Parcelable {
-    ctor public NotificationOrderUpdate(android.os.Parcel);
+  public static class NotificationListenerService.Ranking implements android.os.Parcelable {
     method public int describeContents();
+    method public int getIndexOfKey(java.lang.String);
+    method public java.lang.String[] getOrderedKeys();
+    method public boolean isAmbient(java.lang.String);
+    method public boolean isInterceptedByDoNotDisturb(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
diff --git a/core/java/android/animation/BidirectionalTypeConverter.java b/core/java/android/animation/BidirectionalTypeConverter.java
new file mode 100644
index 0000000..960650e
--- /dev/null
+++ b/core/java/android/animation/BidirectionalTypeConverter.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.animation;
+
+/**
+ * Abstract base class used convert type T to another type V and back again. This
+ * is necessary when the value types of in animation are different from the property
+ * type. BidirectionalTypeConverter is needed when only the final value for the
+ * animation is supplied to animators.
+ * @see PropertyValuesHolder#setConverter(TypeConverter)
+ */
+public abstract class BidirectionalTypeConverter<T, V> extends TypeConverter<T, V> {
+    private BidirectionalTypeConverter mInvertedConverter;
+
+    public BidirectionalTypeConverter(Class<T> fromClass, Class<V> toClass) {
+        super(fromClass, toClass);
+    }
+
+    /**
+     * Does a conversion from the target type back to the source type. The subclass
+     * must implement this when a TypeConverter is used in animations and current
+     * values will need to be read for an animation.
+     * @param value The Object to convert.
+     * @return A value of type T, converted from <code>value</code>.
+     */
+    public abstract T convertBack(V value);
+
+    /**
+     * Returns the inverse of this converter, where the from and to classes are reversed.
+     * The inverted converter uses this convert to call {@link #convertBack(Object)} for
+     * {@link #convert(Object)} calls and {@link #convert(Object)} for
+     * {@link #convertBack(Object)} calls.
+     * @return The inverse of this converter, where the from and to classes are reversed.
+     */
+    public BidirectionalTypeConverter<V, T> invert() {
+        if (mInvertedConverter == null) {
+            mInvertedConverter = new InvertedConverter(this);
+        }
+        return mInvertedConverter;
+    }
+
+    private static class InvertedConverter<From, To> extends BidirectionalTypeConverter<From, To> {
+        private BidirectionalTypeConverter<To, From> mConverter;
+
+        public InvertedConverter(BidirectionalTypeConverter<To, From> converter) {
+            super(converter.getTargetType(), converter.getSourceType());
+            mConverter = converter;
+        }
+
+        @Override
+        public From convertBack(To value) {
+            return mConverter.convert(value);
+        }
+
+        @Override
+        public To convert(From value) {
+            return mConverter.convertBack(value);
+        }
+    }
+}
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index c0ce795..130754e 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -610,8 +610,8 @@
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation). This variant supplies a <code>TypeConverter</code> to
      * convert from the animated values to the type of the property. If only one value is
-     * supplied, the <code>TypeConverter</code> must implement
-     * {@link TypeConverter#convertBack(Object)} to retrieve the current value.
+     * supplied, the <code>TypeConverter</code> must be a
+     * {@link android.animation.BidirectionalTypeConverter} to retrieve the current value.
      *
      * @param target The object whose property is to be animated.
      * @param property The property being animated.
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 8fce80a..bf2924c 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -456,7 +456,7 @@
      * cannot automatically interpolate between objects of unknown type. This variant also
      * takes a <code>TypeConverter</code> to convert from animated values to the type
      * of the property. If only one value is supplied, the <code>TypeConverter</code>
-     * must implement {@link TypeConverter#convertBack(Object)} to retrieve the current
+     * must be a {@link android.animation.BidirectionalTypeConverter} to retrieve the current
      * value.
      *
      * @param property The property being animated. Should not be null.
@@ -635,6 +635,8 @@
 
     /**
      * Sets the converter to convert from the values type to the setter's parameter type.
+     * If only one value is supplied, <var>converter</var> must be a
+     * {@link android.animation.BidirectionalTypeConverter}.
      * @param converter The converter to use to convert values.
      */
     public void setConverter(TypeConverter converter) {
@@ -816,12 +818,12 @@
 
     private Object convertBack(Object value) {
         if (mConverter != null) {
-            value = mConverter.convertBack(value);
-            if (value == null) {
+            if (!(mConverter instanceof BidirectionalTypeConverter)) {
                 throw new IllegalArgumentException("Converter "
                         + mConverter.getClass().getName()
-                        + " must implement convertBack and not return null.");
+                        + " must be a BidirectionalTypeConverter");
             }
+            value = ((BidirectionalTypeConverter) mConverter).convertBack(value);
         }
         return value;
     }
diff --git a/core/java/android/animation/TypeConverter.java b/core/java/android/animation/TypeConverter.java
index 03b3eb5..9ead2ad 100644
--- a/core/java/android/animation/TypeConverter.java
+++ b/core/java/android/animation/TypeConverter.java
@@ -53,16 +53,4 @@
      * @return A value of type V, converted from <code>value</code>.
      */
     public abstract V convert(T value);
-
-    /**
-     * Does a conversion from the target type back to the source type. The subclass
-     * must implement this when a TypeConverter is used in animations and current
-     * values will need to be read for an animation. By default, this will return null,
-     * indicating that back-conversion is not supported.
-     * @param value The Object to convert.
-     * @return A value of type T, converted from <code>value</code>.
-     */
-    public T convertBack(V value) {
-        return null;
-    }
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e1a94d7..3de971c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -779,7 +779,8 @@
     final Handler mHandler = new Handler();
 
     private ActivityTransitionState mActivityTransitionState = new ActivityTransitionState();
-    SharedElementListener mTransitionListener = new SharedElementListener();
+    SharedElementListener mEnterTransitionListener = SharedElementListener.NULL_LISTENER;
+    SharedElementListener mExitTransitionListener = SharedElementListener.NULL_LISTENER;
 
     /** Return the intent that started this activity. */
     public Intent getIntent() {
@@ -5557,16 +5558,32 @@
     /**
      * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
      * android.view.View, String)} was used to start an Activity, <var>listener</var>
-     * will be called to handle shared elements. This requires
+     * will be called to handle shared elements on the <i>launched</i> Activity. This requires
      * {@link Window#FEATURE_CONTENT_TRANSITIONS}.
      *
-     * @param listener Used to manipulate how shared element transitions function.
+     * @param listener Used to manipulate shared element transitions on the launched Activity.
      */
-    public void setSharedElementListener(SharedElementListener listener) {
+    public void setEnterSharedElementListener(SharedElementListener listener) {
         if (listener == null) {
-            listener = new SharedElementListener();
+            listener = SharedElementListener.NULL_LISTENER;
         }
-        mTransitionListener = listener;
+        mEnterTransitionListener = listener;
+    }
+
+    /**
+     * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.view.View, String)} was used to start an Activity, <var>listener</var>
+     * will be called to handle shared elements on the <i>launching</i> Activity. Most
+     * calls will only come when returning from the started Activity.
+     * This requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * @param listener Used to manipulate shared element transitions on the launching Activity.
+     */
+    public void setExitSharedElementListener(SharedElementListener listener) {
+        if (listener == null) {
+            listener = SharedElementListener.NULL_LISTENER;
+        }
+        mExitTransitionListener = listener;
     }
 
     // ------------------ Internal API ------------------
@@ -5882,7 +5899,8 @@
      * have completed drawing. This is necessary only after an {@link Activity} has been made
      * opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn
      * translucent again following a call to {@link
-     * Activity#convertToTranslucent(TranslucentConversionListener)}.
+     * Activity#convertToTranslucent(android.app.Activity.TranslucentConversionListener,
+     * ActivityOptions)}
      *
      * @hide
      */
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 6c6a52f..2acf5b2 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -189,15 +189,17 @@
     final protected SharedElementListener mListener;
     protected ResultReceiver mResultReceiver;
     final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback();
+    final protected boolean mIsReturning;
 
     public ActivityTransitionCoordinator(Window window,
             ArrayList<String> allSharedElementNames,
             ArrayList<String> accepted, ArrayList<String> localNames,
-            SharedElementListener listener) {
+            SharedElementListener listener, boolean isReturning) {
         super(new Handler());
         mWindow = window;
         mListener = listener;
         mAllSharedElementNames = allSharedElementNames;
+        mIsReturning = isReturning;
         setSharedElements(accepted, localNames);
         if (getViewsTransition() != null) {
             getDecor().captureTransitioningViews(mTransitioningViews);
@@ -330,7 +332,21 @@
         mResultReceiver = resultReceiver;
     }
 
-    protected abstract Transition getViewsTransition();
+    protected Transition getViewsTransition() {
+        if (mIsReturning) {
+            return getWindow().getExitTransition();
+        } else {
+            return getWindow().getEnterTransition();
+        }
+    }
+
+    protected Transition getSharedElementTransition() {
+        if (mIsReturning) {
+            return getWindow().getSharedElementExitTransition();
+        } else {
+            return getWindow().getSharedElementEnterTransition();
+        }
+    }
 
     private static class FixedEpicenterCallback extends Transition.EpicenterCallback {
         private Rect mEpicenter;
@@ -342,4 +358,5 @@
             return mEpicenter;
         }
     }
+
 }
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 636205b..b40d16c 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -51,7 +51,6 @@
     private static final long MAX_WAIT_MS = 1500;
 
     private boolean mSharedElementTransitionStarted;
-    private boolean mIsReturning;
     private Activity mActivity;
     private boolean mHasStopped;
     private Handler mHandler;
@@ -61,9 +60,8 @@
             ArrayList<String> sharedElementNames,
             ArrayList<String> acceptedNames, ArrayList<String> mappedNames) {
         super(activity.getWindow(), sharedElementNames, acceptedNames, mappedNames,
-                activity.mTransitionListener);
+                getListener(activity, acceptedNames), acceptedNames != null);
         mActivity = activity;
-        mIsReturning = acceptedNames != null;
         setResultReceiver(resultReceiver);
         prepareEnter();
         Bundle resultReceiverBundle = new Bundle();
@@ -80,6 +78,12 @@
         }
     }
 
+    private static SharedElementListener getListener(Activity activity,
+            ArrayList<String> acceptedNames) {
+        boolean isReturning = acceptedNames != null;
+        return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
+    }
+
     @Override
     protected void onReceiveResult(int resultCode, Bundle resultData) {
         switch (resultCode) {
@@ -299,7 +303,6 @@
             if (sharedElementBundle != null) {
                 Bitmap bitmap = sharedElementBundle.getParcelable(KEY_BITMAP);
                 View snapshot = new View(context);
-                snapshot.setId(com.android.internal.R.id.shared_element);
                 Resources resources = getWindow().getContext().getResources();
                 snapshot.setBackground(new BitmapDrawable(resources, bitmap));
                 snapshot.setViewName(name);
@@ -420,12 +423,4 @@
         }
     }
 
-    @Override
-    protected Transition getViewsTransition() {
-        return getWindow().getEnterTransition();
-    }
-
-    protected Transition getSharedElementTransition() {
-        return getWindow().getSharedElementEnterTransition();
-    }
 }
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 43a60a3..1d78b30 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -53,20 +53,22 @@
 
     private boolean mIsBackgroundReady;
 
-    private boolean mIsReturning;
-
     private boolean mIsCanceled;
 
     private Handler mHandler;
 
     public ExitTransitionCoordinator(Activity activity, ArrayList<String> names,
             ArrayList<String> accepted, ArrayList<String> mapped, boolean isReturning) {
-        super(activity.getWindow(), names, accepted, mapped, activity.mTransitionListener);
-        mIsReturning = isReturning;
+        super(activity.getWindow(), names, accepted, mapped, getListener(activity, isReturning),
+                isReturning);
         mIsBackgroundReady = !mIsReturning;
         mActivity = activity;
     }
 
+    private static SharedElementListener getListener(Activity activity, boolean isReturning) {
+        return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
+    }
+
     @Override
     protected void onReceiveResult(int resultCode, Bundle resultData) {
         switch (resultCode) {
@@ -271,13 +273,4 @@
         }
         return -1;
     }
-
-    @Override
-    protected Transition getViewsTransition() {
-        return getWindow().getExitTransition();
-    }
-
-    protected Transition getSharedElementTransition() {
-        return getWindow().getSharedElementExitTransition();
-    }
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fd76b9c4..59b3a27 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -45,6 +45,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.text.NumberFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 
 /**
  * A class that represents how a persistent notification is to be presented to
@@ -370,6 +371,14 @@
      */
     public static final int FLAG_LOCAL_ONLY         = 0x00000100;
 
+    /**
+     * Bit to be bitswise-ored into the {@link #flags} field that should be
+     * set if this notification is the group summary for a group of notifications.
+     * Grouped notifications may display in a cluster or stack on devices which
+     * support such rendering. Requires a group key also be set using {@link Builder#setGroup}.
+     */
+    public static final int FLAG_GROUP_SUMMARY      = 0x00000200;
+
     public int flags;
 
     /** @hide */
@@ -539,6 +548,34 @@
      */
     public String category;
 
+    private String mGroupKey;
+
+    /**
+     * Get the key used to group this notification into a cluster or stack
+     * with other notifications on devices which support such rendering.
+     */
+    public String getGroup() {
+        return mGroupKey;
+    }
+
+    private String mSortKey;
+
+    /**
+     * Get a sort key that orders this notification among other notifications from the
+     * same package. This can be useful if an external sort was already applied and an app
+     * would like to preserve this. Notifications will be sorted lexicographically using this
+     * value, although providing different priorities in addition to providing sort key may
+     * cause this value to be ignored.
+     *
+     * <p>This sort key can also be used to order members of a notification group. See
+     * {@link Builder#setGroup}.
+     *
+     * @see String#compareTo(String)
+     */
+    public String getSortKey() {
+        return mSortKey;
+    }
+
     /**
      * Additional semantic data to be carried around with this Notification.
      * <p>
@@ -706,15 +743,18 @@
      */
     public static class Action implements Parcelable {
         private final Bundle mExtras;
+        private RemoteInput[] mRemoteInputs;
 
         /**
          * Small icon representing the action.
          */
         public int icon;
+
         /**
          * Title of the action.
          */
         public CharSequence title;
+
         /**
          * Intent to send when the user invokes this action. May be null, in which case the action
          * may be rendered in a disabled presentation by the system UI.
@@ -728,19 +768,23 @@
                 actionIntent = PendingIntent.CREATOR.createFromParcel(in);
             }
             mExtras = in.readBundle();
+            mRemoteInputs = in.createTypedArray(RemoteInput.CREATOR);
         }
+
         /**
          * Use {@link Notification.Builder#addAction(int, CharSequence, PendingIntent)}.
          */
         public Action(int icon, CharSequence title, PendingIntent intent) {
-            this(icon, title, intent, new Bundle());
+            this(icon, title, intent, new Bundle(), null);
         }
 
-        private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras) {
+        private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras,
+                RemoteInput[] remoteInputs) {
             this.icon = icon;
             this.title = title;
             this.actionIntent = intent;
             this.mExtras = extras != null ? extras : new Bundle();
+            this.mRemoteInputs = remoteInputs;
         }
 
         /**
@@ -751,13 +795,22 @@
         }
 
         /**
+         * Get the list of inputs to be collected from the user when this action is sent.
+         * May return null if no remote inputs were added.
+         */
+        public RemoteInput[] getRemoteInputs() {
+            return mRemoteInputs;
+        }
+
+        /**
          * Builder class for {@link Action} objects.
          */
-        public static class Builder {
+        public static final class Builder {
             private final int mIcon;
             private final CharSequence mTitle;
             private final PendingIntent mIntent;
             private final Bundle mExtras;
+            private ArrayList<RemoteInput> mRemoteInputs;
 
             /**
              * Construct a new builder for {@link Action} object.
@@ -766,7 +819,7 @@
              * @param intent the {@link PendingIntent} to fire when users trigger this action
              */
             public Builder(int icon, CharSequence title, PendingIntent intent) {
-                this(icon, title, intent, new Bundle());
+                this(icon, title, intent, new Bundle(), null);
             }
 
             /**
@@ -775,14 +828,20 @@
              * @param action the action to read fields from.
              */
             public Builder(Action action) {
-                this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras));
+                this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras),
+                        action.getRemoteInputs());
             }
 
-            private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras) {
+            private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras,
+                    RemoteInput[] remoteInputs) {
                 mIcon = icon;
                 mTitle = title;
                 mIntent = intent;
                 mExtras = extras;
+                if (remoteInputs != null) {
+                    mRemoteInputs = new ArrayList<RemoteInput>(remoteInputs.length);
+                    Collections.addAll(mRemoteInputs, remoteInputs);
+                }
             }
 
             /**
@@ -809,22 +868,62 @@
             }
 
             /**
+             * Add an input to be collected from the user when this action is sent.
+             * Response values can be retrieved from the fired intent by using the
+             * {@link RemoteInput#getResultsFromIntent} function.
+             * @param remoteInput a {@link RemoteInput} to add to the action
+             * @return this object for method chaining
+             */
+            public Builder addRemoteInput(RemoteInput remoteInput) {
+                if (mRemoteInputs == null) {
+                    mRemoteInputs = new ArrayList<RemoteInput>();
+                }
+                mRemoteInputs.add(remoteInput);
+                return this;
+            }
+
+            /**
+             * Apply an extender to this action builder. Extenders may be used to add
+             * metadata or change options on this builder.
+             */
+            public Builder apply(Extender extender) {
+                extender.applyTo(this);
+                return this;
+            }
+
+            /**
+             * Extender interface for use with {@link #apply}. Extenders may be used to add
+             * metadata or change options on this builder.
+             */
+            public interface Extender {
+                /**
+                 * Apply this extender to a notification action builder.
+                 * @param builder the builder to be modified.
+                 * @return the build object for chaining.
+                 */
+                public Builder applyTo(Builder builder);
+            }
+
+            /**
              * Combine all of the options that have been set and return a new {@link Action}
              * object.
              * @return the built action
              */
             public Action build() {
-                return new Action(mIcon, mTitle, mIntent, mExtras);
+                RemoteInput[] remoteInputs = mRemoteInputs != null
+                        ? mRemoteInputs.toArray(new RemoteInput[mRemoteInputs.size()]) : null;
+                return new Action(mIcon, mTitle, mIntent, mExtras, remoteInputs);
             }
         }
 
         @Override
         public Action clone() {
             return new Action(
-                this.icon,
-                this.title,
-                this.actionIntent, // safe to alias
-                new Bundle(this.mExtras));
+                    icon,
+                    title,
+                    actionIntent, // safe to alias
+                    new Bundle(mExtras),
+                    getRemoteInputs());
         }
         @Override
         public int describeContents() {
@@ -841,6 +940,7 @@
                 out.writeInt(0);
             }
             out.writeBundle(mExtras);
+            out.writeTypedArray(mRemoteInputs, flags);
         }
         public static final Parcelable.Creator<Action> CREATOR =
                 new Parcelable.Creator<Action>() {
@@ -960,6 +1060,10 @@
 
         category = parcel.readString();
 
+        mGroupKey = parcel.readString();
+
+        mSortKey = parcel.readString();
+
         extras = parcel.readBundle(); // may be null
 
         actions = parcel.createTypedArray(Action.CREATOR); // may be null
@@ -1037,6 +1141,10 @@
 
         that.category = this.category;
 
+        that.mGroupKey = this.mGroupKey;
+
+        that.mSortKey = this.mSortKey;
+
         if (this.extras != null) {
             try {
                 that.extras = new Bundle(this.extras);
@@ -1188,6 +1296,10 @@
 
         parcel.writeString(category);
 
+        parcel.writeString(mGroupKey);
+
+        parcel.writeString(mSortKey);
+
         parcel.writeBundle(extras); // null ok
 
         parcel.writeTypedArray(actions, 0); // null ok
@@ -1325,7 +1437,18 @@
         sb.append(" flags=0x");
         sb.append(Integer.toHexString(this.flags));
         sb.append(String.format(" color=0x%08x", this.color));
-        sb.append(" category="); sb.append(this.category);
+        if (this.category != null) {
+            sb.append(" category=");
+            sb.append(this.category);
+        }
+        if (this.mGroupKey != null) {
+            sb.append(" groupKey=");
+            sb.append(this.mGroupKey);
+        }
+        if (this.mSortKey != null) {
+            sb.append(" sortKey=");
+            sb.append(this.mSortKey);
+        }
         if (actions != null) {
             sb.append(" ");
             sb.append(actions.length);
@@ -1408,6 +1531,8 @@
         private int mProgress;
         private boolean mProgressIndeterminate;
         private String mCategory;
+        private String mGroupKey;
+        private String mSortKey;
         private Bundle mExtras;
         private int mPriority;
         private ArrayList<Action> mActions = new ArrayList<Action>(MAX_ACTION_BUTTONS);
@@ -1839,6 +1964,51 @@
         }
 
         /**
+         * Set this notification to be part of a group of notifications sharing the same key.
+         * Grouped notifications may display in a cluster or stack on devices which
+         * support such rendering.
+         *
+         * <p>To make this notification the summary for its group, also call
+         * {@link #setGroupSummary}. A sort order can be specified for group members by using
+         * {@link #setSortKey}.
+         * @param groupKey The group key of the group.
+         * @return this object for method chaining
+         */
+        public Builder setGroup(String groupKey) {
+            mGroupKey = groupKey;
+            return this;
+        }
+
+        /**
+         * Set this notification to be the group summary for a group of notifications.
+         * Grouped notifications may display in a cluster or stack on devices which
+         * support such rendering. Requires a group key also be set using {@link #setGroup}.
+         * @param isGroupSummary Whether this notification should be a group summary.
+         * @return this object for method chaining
+         */
+        public Builder setGroupSummary(boolean isGroupSummary) {
+            setFlag(FLAG_GROUP_SUMMARY, isGroupSummary);
+            return this;
+        }
+
+        /**
+         * Set a sort key that orders this notification among other notifications from the
+         * same package. This can be useful if an external sort was already applied and an app
+         * would like to preserve this. Notifications will be sorted lexicographically using this
+         * value, although providing different priorities in addition to providing sort key may
+         * cause this value to be ignored.
+         *
+         * <p>This sort key can also be used to order members of a notification group. See
+         * {@link #setGroup}.
+         *
+         * @see String#compareTo(String)
+         */
+        public Builder setSortKey(String sortKey) {
+            mSortKey = sortKey;
+            return this;
+        }
+
+        /**
          * Merge additional metadata into this notification.
          *
          * <p>Values within the Bundle will replace existing extras values in this Builder.
@@ -1949,7 +2119,7 @@
 
         /**
          * Specify the value of {@link #visibility}.
-
+         *
          * @param visibility One of {@link #VISIBILITY_PRIVATE} (the default),
          * {@link #VISIBILITY_SECRET}, or {@link #VISIBILITY_PUBLIC}.
          *
@@ -1971,6 +2141,28 @@
             return this;
         }
 
+        /**
+         * Apply an extender to this notification builder. Extenders may be used to add
+         * metadata or change options on this builder.
+         */
+        public Builder apply(Extender extender) {
+            extender.applyTo(this);
+            return this;
+        }
+
+        /**
+         * Extender interface for use with {@link #apply}. Extenders may be used to add
+         * metadata or change options on this builder.
+         */
+        public interface Extender {
+            /**
+             * Apply this extender to a notification builder.
+             * @param builder the builder to be modified.
+             * @return the build object for chaining.
+             */
+            public Builder applyTo(Builder builder);
+        }
+
         private void setFlag(int mask, boolean value) {
             if (value) {
                 mFlags |= mask;
@@ -2298,6 +2490,8 @@
                 n.flags |= FLAG_SHOW_LIGHTS;
             }
             n.category = mCategory;
+            n.mGroupKey = mGroupKey;
+            n.mSortKey = mSortKey;
             n.priority = mPriority;
             if (mActions.size() > 0) {
                 n.actions = new Action[mActions.size()];
diff --git a/core/java/android/app/RemoteInput.java b/core/java/android/app/RemoteInput.java
new file mode 100644
index 0000000..9cfc541
--- /dev/null
+++ b/core/java/android/app/RemoteInput.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A {@code RemoteInput} object specifies input to be collected from a user to be passed along with
+ * an intent inside a {@link android.app.PendingIntent} that is sent.
+ * Always use {@link RemoteInput.Builder} to create instances of this class.
+ * <p class="note"> See
+ * <a href="{@docRoot}wear/notifications/remote-input.html">Receiving Voice Input from
+ * a Notification</a> for more information on how to use this class.
+ *
+ * <p>The following example adds a {@code RemoteInput} to a {@link Notification.Action},
+ * sets the result key as {@code quick_reply}, and sets the label as {@code Quick reply}.
+ * Users are prompted to input a response when they trigger the action. The results are sent along
+ * with the intent and can be retrieved with the result key (provided to the {@link Builder}
+ * constructor) from the Bundle returned by {@link #getResultsFromIntent}.
+ *
+ * <pre class="prettyprint">
+ * public static final String KEY_QUICK_REPLY_TEXT = "quick_reply";
+ * Notification.Action action = new Notification.Action.Builder(
+ *         R.drawable.reply, &quot;Reply&quot;, actionIntent)
+ *         <b>.addRemoteInput(new RemoteInput.Builder(KEY_QUICK_REPLY_TEXT)
+ *                 .setLabel("Quick reply").build()</b>)
+ *         .build();</pre>
+ *
+ * <p>When the {@link android.app.PendingIntent} is fired, the intent inside will contain the
+ * input results if collected. To access these results, use the {@link #getResultsFromIntent}
+ * function. The result values will present under the result key passed to the {@link Builder}
+ * constructor.
+ *
+ * <pre class="prettyprint">
+ * public static final String KEY_QUICK_REPLY_TEXT = "quick_reply";
+ * Bundle results = RemoteInput.getResultsFromIntent(intent);
+ * if (results != null) {
+ *     CharSequence quickReplyResult = results.getCharSequence(KEY_QUICK_REPLY_TEXT);
+ * }</pre>
+ */
+public final class RemoteInput implements Parcelable {
+    /** Label used to denote the clip data type used for remote input transport */
+    public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+
+    /** Extra added to a clip data intent object to hold the results bundle. */
+    public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+
+    private final String mResultKey;
+    private final CharSequence mLabel;
+    private final CharSequence[] mChoices;
+    private final boolean mAllowFreeFormInput;
+    private final Bundle mExtras;
+
+    private RemoteInput(String resultKey, CharSequence label, CharSequence[] choices,
+            boolean allowFreeFormInput, Bundle extras) {
+        this.mResultKey = resultKey;
+        this.mLabel = label;
+        this.mChoices = choices;
+        this.mAllowFreeFormInput = allowFreeFormInput;
+        this.mExtras = extras;
+    }
+
+    /**
+     * Get the key that the result of this input will be set in from the Bundle returned by
+     * {@link #getResultsFromIntent} when the {@link android.app.PendingIntent} is sent.
+     */
+    public String getResultKey() {
+        return mResultKey;
+    }
+
+    /**
+     * Get the label to display to users when collecting this input.
+     */
+    public CharSequence getLabel() {
+        return mLabel;
+    }
+
+    /**
+     * Get possible input choices. This can be {@code null} if there are no choices to present.
+     */
+    public CharSequence[] getChoices() {
+        return mChoices;
+    }
+
+    /**
+     * Get whether or not users can provide an arbitrary value for
+     * input. If you set this to {@code false}, users must select one of the
+     * choices in {@link #getChoices}. An {@link IllegalArgumentException} is thrown
+     * if you set this to false and {@link #getChoices} returns {@code null} or empty.
+     */
+    public boolean getAllowFreeFormInput() {
+        return mAllowFreeFormInput;
+    }
+
+    /**
+     * Get additional metadata carried around with this remote input.
+     */
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Builder class for {@link RemoteInput} objects.
+     */
+    public static final class Builder {
+        private final String mResultKey;
+        private CharSequence mLabel;
+        private CharSequence[] mChoices;
+        private boolean mAllowFreeFormInput = true;
+        private Bundle mExtras = new Bundle();
+
+        /**
+         * Create a builder object for {@link RemoteInput} objects.
+         * @param resultKey the Bundle key that refers to this input when collected from the user
+         */
+        public Builder(String resultKey) {
+            if (resultKey == null) {
+                throw new IllegalArgumentException("Result key can't be null");
+            }
+            mResultKey = resultKey;
+        }
+
+        /**
+         * Set a label to be displayed to the user when collecting this input.
+         * @param label The label to show to users when they input a response.
+         * @return this object for method chaining
+         */
+        public Builder setLabel(CharSequence label) {
+            mLabel = Notification.safeCharSequence(label);
+            return this;
+        }
+
+        /**
+         * Specifies choices available to the user to satisfy this input.
+         * @param choices an array of pre-defined choices for users input.
+         *        You must provide a non-null and non-empty array if
+         *        you disabled free form input using {@link #setAllowFreeFormInput}.
+         * @return this object for method chaining
+         */
+        public Builder setChoices(CharSequence[] choices) {
+            if (choices == null) {
+                mChoices = null;
+            } else {
+                mChoices = new CharSequence[choices.length];
+                for (int i = 0; i < choices.length; i++) {
+                    mChoices[i] = Notification.safeCharSequence(choices[i]);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Specifies whether the user can provide arbitrary values.
+         *
+         * @param allowFreeFormInput The default is {@code true}.
+         *         If you specify {@code false}, you must provide a non-null
+         *         and non-empty array to {@link #setChoices} or an
+         *         {@link IllegalArgumentException} is thrown.
+         * @return this object for method chaining
+         */
+        public Builder setAllowFreeFormInput(boolean allowFreeFormInput) {
+            mAllowFreeFormInput = allowFreeFormInput;
+            return this;
+        }
+
+        /**
+         * Merge additional metadata into this builder.
+         *
+         * <p>Values within the Bundle will replace existing extras values in this Builder.
+         *
+         * @see RemoteInput#getExtras
+         */
+        public Builder addExtras(Bundle extras) {
+            if (extras != null) {
+                mExtras.putAll(extras);
+            }
+            return this;
+        }
+
+        /**
+         * Get the metadata Bundle used by this Builder.
+         *
+         * <p>The returned Bundle is shared with this Builder.
+         */
+        public Bundle getExtras() {
+            return mExtras;
+        }
+
+        /**
+         * Combine all of the options that have been set and return a new {@link RemoteInput}
+         * object.
+         */
+        public RemoteInput build() {
+            return new RemoteInput(mResultKey, mLabel, mChoices, mAllowFreeFormInput, mExtras);
+        }
+    }
+
+    private RemoteInput(Parcel in) {
+        mResultKey = in.readString();
+        mLabel = in.readCharSequence();
+        mChoices = in.readCharSequenceArray();
+        mAllowFreeFormInput = in.readInt() != 0;
+        mExtras = in.readBundle();
+    }
+
+    /**
+     * Get the remote input results bundle from an intent. The returned Bundle will
+     * contain a key/value for every result key populated by remote input collector.
+     * Use the {@link Bundle#getCharSequence(String)} method to retrieve a value.
+     * @param intent The intent object that fired in response to an action or content intent
+     *               which also had one or more remote input requested.
+     */
+    public static Bundle getResultsFromIntent(Intent intent) {
+        ClipData clipData = intent.getClipData();
+        if (clipData == null) {
+            return null;
+        }
+        ClipDescription clipDescription = clipData.getDescription();
+        if (!clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_INTENT)) {
+            return null;
+        }
+        if (clipDescription.getLabel().equals(RESULTS_CLIP_LABEL)) {
+            return clipData.getItemAt(0).getIntent().getExtras().getParcelable(EXTRA_RESULTS_DATA);
+        }
+        return null;
+    }
+
+    /**
+     * Populate an intent object with the results gathered from remote input. This method
+     * should only be called by remote input collection services when sending results to a
+     * pending intent.
+     * @param remoteInputs The remote inputs for which results are being provided
+     * @param intent The intent to add remote inputs to. The {@link ClipData}
+     *               field of the intent will be modified to contain the results.
+     * @param results A bundle holding the remote input results. This bundle should
+     *                be populated with keys matching the result keys specified in
+     *                {@code remoteInputs} with values being the result per key.
+     */
+    public static void addResultsToIntent(RemoteInput[] remoteInputs, Intent intent,
+            Bundle results) {
+        Bundle resultsBundle = new Bundle();
+        for (RemoteInput remoteInput : remoteInputs) {
+            Object result = results.get(remoteInput.getResultKey());
+            if (result instanceof CharSequence) {
+                resultsBundle.putCharSequence(remoteInput.getResultKey(), (CharSequence) result);
+            }
+        }
+        Intent clipIntent = new Intent();
+        clipIntent.putExtra(EXTRA_RESULTS_DATA, resultsBundle);
+        intent.setClipData(ClipData.newIntent(RESULTS_CLIP_LABEL, clipIntent));
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mResultKey);
+        out.writeCharSequence(mLabel);
+        out.writeCharSequenceArray(mChoices);
+        out.writeInt(mAllowFreeFormInput ? 1 : 0);
+        out.writeBundle(mExtras);
+    }
+
+    public static final Creator<RemoteInput> CREATOR = new Creator<RemoteInput>() {
+        @Override
+        public RemoteInput createFromParcel(Parcel in) {
+            return new RemoteInput(in);
+        }
+
+        @Override
+        public RemoteInput[] newArray(int size) {
+            return new RemoteInput[size];
+        }
+    };
+}
diff --git a/core/java/android/app/SharedElementListener.java b/core/java/android/app/SharedElementListener.java
index d4bc019..e03e42e 100644
--- a/core/java/android/app/SharedElementListener.java
+++ b/core/java/android/app/SharedElementListener.java
@@ -22,15 +22,27 @@
 
 /**
  * Listener provided in
- * {@link Activity#setSharedElementListener(SharedElementListener)}
- * to monitor the Activity transitions. The events can be used to customize or override Activity
+ * {@link Activity#setEnterSharedElementListener(SharedElementListener)} and
+ * {@link Activity#setExitSharedElementListener(SharedElementListener)}
+ * to monitor the Activity transitions. The events can be used to customize Activity
  * Transition behavior.
  */
-public class SharedElementListener {
+public abstract class SharedElementListener {
+
+    static final SharedElementListener NULL_LISTENER = new SharedElementListener() {
+    };
+
     /**
-     * Called to allow the listener to customize the start state of the shared element for
-     * the shared element entering transition. By default, the shared element is placed in
-     * the position and with the size of the shared element in the calling Activity or Fragment.
+     * Called to allow the listener to customize the start state of the shared element when
+     * transferring in shared element state.
+     * <p>
+     *     The shared element will start at the size and position of the shared element
+     *     in the launching Activity or Fragment. It will also transfer ImageView scaleType
+     *     and imageMatrix if the shared elements in the calling and called Activities are
+     *     ImageViews. Some applications may want to make additional changes, such as
+     *     changing the clip bounds, scaling, or rotation if the shared element end state
+     *     does not map well to the start state.
+     * </p>
      *
      * @param sharedElementNames The names of the shared elements that were accepted into
      *                           the View hierarchy.
@@ -44,8 +56,17 @@
             List<View> sharedElements, List<View> sharedElementSnapshots) {}
 
     /**
-     * Called to allow the listener to customize the end state of the shared element for
-     * the shared element entering transition.
+     * Called to allow the listener to customize the end state of the shared element when
+     * transferring in shared element state.
+     * <p>
+     *     Any customization done in
+     *     {@link #setSharedElementStart(java.util.List, java.util.List, java.util.List)}
+     *     may need to be modified to the final state of the shared element if it is not
+     *     automatically corrected by layout. For example, rotation or scale will not
+     *     be affected by layout and if changed in {@link #setSharedElementStart(java.util.List,
+     *     java.util.List, java.util.List)}, it will also have to be set here again to correct
+     *     the end state.
+     * </p>
      *
      * @param sharedElementNames The names of the shared elements that were accepted into
      *                           the View hierarchy.
@@ -59,13 +80,18 @@
             List<View> sharedElements, List<View> sharedElementSnapshots) {}
 
     /**
-     * If nothing is done, all shared elements that were not accepted by
-     * {@link #remapSharedElements(java.util.List, java.util.Map)} will be Transitioned
-     * out of the entering scene automatically. Any elements removed from
-     * rejectedSharedElements must be handled by the ActivityTransitionListener.
-     * <p>Views in rejectedSharedElements will have their position and size set to the
-     * position of the calling shared element, relative to the Window decor View. This
-     * view may be safely added to the decor View's overlay to remain in position.</p>
+     * Called after {@link #remapSharedElements(java.util.List, java.util.Map)} when
+     * transferring shared elements in. Any shared elements that have no mapping will be in
+     * <var>rejectedSharedElements</var>. The elements remaining in
+     * <var>rejectedSharedElements</var> will be transitioned out of the Scene. If a
+     * View is removed from <var>rejectedSharedElements</var>, it must be handled by the
+     * <code>SharedElementListener</code>.
+     * <p>
+     * Views in rejectedSharedElements will have their position and size set to the
+     * position of the calling shared element, relative to the Window decor View and contain
+     * snapshots of the View from the calling Activity or Fragment. This
+     * view may be safely added to the decor View's overlay to remain in position.
+     * </p>
      *
      * @param rejectedSharedElements Views containing visual information of shared elements
      *                               that are not part of the entering scene. These Views
@@ -78,6 +104,7 @@
     /**
      * Lets the ActivityTransitionListener adjust the mapping of shared element names to
      * Views.
+     *
      * @param names The names of all shared elements transferred from the calling Activity
      *              to the started Activity.
      * @param sharedElements The mapping of shared element names to Views. The best guess
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 58d707c..48ff5b6 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -911,6 +911,35 @@
      */
     public void suggestDesiredDimensions(int minimumWidth, int minimumHeight) {
         try {
+            /**
+             * The framework makes no attempt to limit the window size
+             * to the maximum texture size. Any window larger than this
+             * cannot be composited.
+             *
+             * Read maximum texture size from system property and scale down
+             * minimumWidth and minimumHeight accordingly.
+             */
+            int maximumTextureSize;
+            try {
+                maximumTextureSize = SystemProperties.getInt("sys.max_texture_size", 0);
+            } catch (Exception e) {
+                maximumTextureSize = 0;
+            }
+
+            if (maximumTextureSize > 0) {
+                if ((minimumWidth > maximumTextureSize) ||
+                    (minimumHeight > maximumTextureSize)) {
+                    float aspect = (float)minimumHeight / (float)minimumWidth;
+                    if (minimumWidth > minimumHeight) {
+                        minimumWidth = maximumTextureSize;
+                        minimumHeight = (int)((minimumWidth * aspect) + 0.5);
+                    } else {
+                        minimumHeight = maximumTextureSize;
+                        minimumWidth = (int)((minimumHeight / aspect) + 0.5);
+                    }
+                }
+            }
+
             if (sGlobals.mService == null) {
                 Log.w(TAG, "WallpaperService not running");
             } else {
diff --git a/core/java/android/bluetooth/BluetoothLeAdvertiseScanData.java b/core/java/android/bluetooth/BluetoothLeAdvertiseScanData.java
index 3d85810..d12ac6c 100644
--- a/core/java/android/bluetooth/BluetoothLeAdvertiseScanData.java
+++ b/core/java/android/bluetooth/BluetoothLeAdvertiseScanData.java
@@ -298,8 +298,7 @@
              * Set data type.
              *
              * @param dataType Data type, could only be
-             *            {@link BluetoothLeAdvertiseScanData#ADVERTISING_DATA} or
-             *            {@link BluetoothLeAdvertiseScanData#SCAN_RESPONSE_DATA}
+             *            {@link BluetoothLeAdvertiseScanData#ADVERTISING_DATA}
              * @throws IllegalArgumentException If the {@code dataType} is invalid.
              */
             public Builder dataType(int dataType) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 0e2eab7..35bcc02 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1405,6 +1405,14 @@
     public static final String FEATURE_MANAGEDPROFILES = "android.software.managedprofiles";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device has a full implementation of the android.webkit.* APIs. Devices
+     * lacking this feature will not have a functioning WebView implementation.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_WEBVIEW = "android.software.webview";
+
+    /**
      * Action to external storage service to clean out removed apps.
      * @hide
      */
diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java
index 92d6f75..da5c128 100644
--- a/core/java/android/hardware/usb/UsbConfiguration.java
+++ b/core/java/android/hardware/usb/UsbConfiguration.java
@@ -44,13 +44,13 @@
      * Mask for "self-powered" bit in the configuration's attributes.
      * @see #getAttributes
      */
-    public static final int ATTR_SELF_POWERED_MASK = 1 << 6;
+    private static final int ATTR_SELF_POWERED = 1 << 6;
 
     /**
      * Mask for "remote wakeup" bit in the configuration's attributes.
      * @see #getAttributes
      */
-    public static final int ATTR_REMOTE_WAKEUP_MASK = 1 << 5;
+    private static final int ATTR_REMOTE_WAKEUP = 1 << 5;
 
     /**
      * UsbConfiguration should only be instantiated by UsbService implementation
@@ -83,19 +83,23 @@
     }
 
     /**
-     * Returns the configuration's attributes field.
-     * This field contains a bit field with the following flags:
+     * Returns the self-powered attribute value configuration's attributes field.
+     * This attribute indicates that the device has a power source other than the USB connection.
      *
-     * Bit 7: always set to 1
-     * Bit 6: self-powered
-     * Bit 5: remote wakeup enabled
-     * Bit 0-4: reserved
-     * @see #ATTR_SELF_POWERED_MASK
-     * @see #ATTR_REMOTE_WAKEUP_MASK
-     * @return the configuration's attributes
+     * @return the configuration's self-powered attribute
      */
-    public int getAttributes() {
-        return mAttributes;
+    public boolean isSelfPowered() {
+        return (mAttributes & ATTR_SELF_POWERED) != 0;
+    }
+
+    /**
+     * Returns the remote-wakeup attribute value configuration's attributes field.
+     * This attributes that the device may signal the host to wake from suspend.
+     *
+     * @return the configuration's remote-wakeup attribute
+     */
+    public boolean isRemoteWakeup() {
+        return (mAttributes & ATTR_REMOTE_WAKEUP) != 0;
     }
 
     /**
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 6283951..c062b3a 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -104,7 +104,7 @@
      * Sets the current {@link android.hardware.usb.UsbInterface}.
      * Used to select between two interfaces with the same ID but different alternate setting.
      *
-     * @return true if the interface was successfully released
+     * @return true if the interface was successfully selected
      */
     public boolean setInterface(UsbInterface intf) {
         return native_set_interface(intf.getId(), intf.getAlternateSetting());
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 1837335..80a9598 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1655,9 +1655,16 @@
     }
 
     /** {@hide} */
-    public void registerNetworkFactory(Messenger messenger) {
+    public void registerNetworkFactory(Messenger messenger, String name) {
         try {
-            mService.registerNetworkFactory(messenger);
+            mService.registerNetworkFactory(messenger, name);
+        } catch (RemoteException e) { }
+    }
+
+    /** {@hide} */
+    public void unregisterNetworkFactory(Messenger messenger) {
+        try {
+            mService.unregisterNetworkFactory(messenger);
         } catch (RemoteException e) { }
     }
 
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 885b8b6..d97b1e9 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -153,7 +153,9 @@
 
     void setAirplaneMode(boolean enable);
 
-    void registerNetworkFactory(in Messenger messenger);
+    void registerNetworkFactory(in Messenger messenger, in String name);
+
+    void unregisterNetworkFactory(in Messenger messenger);
 
     void registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
             in NetworkCapabilities nc, int score);
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index ceedd98..7ea6bae 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -155,9 +155,6 @@
             mHost = source.getHost();
             mPort = source.getPort();
             mPacFileUrl = source.mPacFileUrl;
-            if (mPacFileUrl == null) {
-                mPacFileUrl = Uri.EMPTY;
-            }
             mExclusionList = source.getExclusionListAsString();
             mParsedExclusionList = source.mParsedExclusionList;
         } else {
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index d4919eb..b3705d8 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -17,15 +17,15 @@
 package android.service.notification;
 
 import android.service.notification.StatusBarNotification;
-import android.service.notification.NotificationOrderUpdate;
+import android.service.notification.NotificationRankingUpdate;
 
 /** @hide */
 oneway interface INotificationListener
 {
-    void onListenerConnected(in NotificationOrderUpdate update);
+    void onListenerConnected(in NotificationRankingUpdate update);
     void onNotificationPosted(in StatusBarNotification notification,
-            in NotificationOrderUpdate update);
+            in NotificationRankingUpdate update);
     void onNotificationRemoved(in StatusBarNotification notification,
-            in NotificationOrderUpdate update);
-    void onNotificationOrderUpdate(in NotificationOrderUpdate update);
+            in NotificationRankingUpdate update);
+    void onNotificationRankingUpdate(in NotificationRankingUpdate update);
 }
\ No newline at end of file
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index e2e9ff4..7f84877 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -24,12 +24,15 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
 
 /**
- * A service that receives calls from the system when new notifications are posted or removed.
+ * A service that receives calls from the system when new notifications are
+ * posted or removed, or their ranking changed.
  * <p>To extend this class, you must declare the service in your manifest file with
  * the {@link android.Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission
  * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
@@ -48,7 +51,7 @@
             + "[" + getClass().getSimpleName() + "]";
 
     private INotificationListenerWrapper mWrapper = null;
-    private String[] mNotificationKeys;
+    private Ranking mRanking;
 
     private INotificationManager mNoMan;
 
@@ -102,11 +105,11 @@
     }
 
     /**
-     * Implement this method to be notified when the notification order cahnges.
-     *
-     * Call {@link #getOrderedNotificationKeys()} to retrieve the new order.
+     * Implement this method to be notified when the notification ranking changes.
+     * <P>
+     * Call {@link #getCurrentRanking()} to retrieve the new ranking.
      */
-    public void onNotificationOrderUpdate() {
+    public void onNotificationRankingUpdate() {
         // optional
     }
 
@@ -224,6 +227,19 @@
     }
 
     /**
+     * Request the list of notification keys in their current ranking order.
+     * <p>
+     * You can use the notification keys for subsequent retrieval via
+     * {@link #getActiveNotifications(String[]) or dismissal via
+     * {@link #cancelNotifications(String[]).
+     *
+     * @return An array of active notification keys, in their ranking order.
+     */
+    public String[] getActiveNotificationKeys() {
+        return mRanking.getOrderedKeys();
+    }
+
+    /**
      * Request the list of outstanding notifications (that is, those that are visible to the
      * current user). Useful when you don't know what's already been posted.
      *
@@ -242,15 +258,20 @@
     }
 
     /**
-     * Request the list of notification keys in their current natural order.
-     * You can use the notification keys for subsequent retrieval via
-     * {@link #getActiveNotifications(String[]) or dismissal via
-     * {@link #cancelNotifications(String[]).
+     * Returns current ranking information.
      *
-     * @return An array of active notification keys, in their natural order.
+     * <p>
+     * The returned object represents the current ranking snapshot and only
+     * applies for currently active notifications. Hence you must retrieve a
+     * new Ranking after each notification event such as
+     * {@link #onNotificationPosted(StatusBarNotification)},
+     * {@link #onNotificationRemoved(StatusBarNotification)}, etc.
+     *
+     * @return A {@link NotificationListenerService.Ranking} object providing
+     *     access to ranking information
      */
-    public String[] getOrderedNotificationKeys() {
-        return mNotificationKeys;
+    public Ranking getCurrentRanking() {
+        return mRanking;
     }
 
     @Override
@@ -308,59 +329,163 @@
     private class INotificationListenerWrapper extends INotificationListener.Stub {
         @Override
         public void onNotificationPosted(StatusBarNotification sbn,
-                NotificationOrderUpdate update) {
-            try {
-                // protect subclass from concurrent modifications of (@link mNotificationKeys}.
-                synchronized (mWrapper) {
-                    updateNotificationKeys(update);
+                NotificationRankingUpdate update) {
+            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
+            synchronized (mWrapper) {
+                applyUpdate(update);
+                try {
                     NotificationListenerService.this.onNotificationPosted(sbn);
+                } catch (Throwable t) {
+                    Log.w(TAG, "Error running onNotificationPosted", t);
                 }
-            } catch (Throwable t) {
-                Log.w(TAG, "Error running onOrderedNotificationPosted", t);
             }
         }
         @Override
         public void onNotificationRemoved(StatusBarNotification sbn,
-                NotificationOrderUpdate update) {
-            try {
-                // protect subclass from concurrent modifications of (@link mNotificationKeys}.
-                synchronized (mWrapper) {
-                    updateNotificationKeys(update);
+                NotificationRankingUpdate update) {
+            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
+            synchronized (mWrapper) {
+                applyUpdate(update);
+                try {
                     NotificationListenerService.this.onNotificationRemoved(sbn);
+                } catch (Throwable t) {
+                    Log.w(TAG, "Error running onNotificationRemoved", t);
                 }
-            } catch (Throwable t) {
-                Log.w(TAG, "Error running onNotificationRemoved", t);
             }
         }
         @Override
-        public void onListenerConnected(NotificationOrderUpdate update) {
-            try {
-                // protect subclass from concurrent modifications of (@link mNotificationKeys}.
-                synchronized (mWrapper) {
-                    updateNotificationKeys(update);
-                    NotificationListenerService.this.onListenerConnected(mNotificationKeys);
+        public void onListenerConnected(NotificationRankingUpdate update) {
+            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
+            synchronized (mWrapper) {
+                applyUpdate(update);
+                try {
+                    NotificationListenerService.this.onListenerConnected(
+                            mRanking.getOrderedKeys());
+                } catch (Throwable t) {
+                    Log.w(TAG, "Error running onListenerConnected", t);
                 }
-            } catch (Throwable t) {
-                Log.w(TAG, "Error running onListenerConnected", t);
             }
         }
         @Override
-        public void onNotificationOrderUpdate(NotificationOrderUpdate update)
+        public void onNotificationRankingUpdate(NotificationRankingUpdate update)
                 throws RemoteException {
-            try {
-                // protect subclass from concurrent modifications of (@link mNotificationKeys}.
-                synchronized (mWrapper) {
-                    updateNotificationKeys(update);
-                    NotificationListenerService.this.onNotificationOrderUpdate();
+            // protect subclass from concurrent modifications of (@link mNotificationKeys}.
+            synchronized (mWrapper) {
+                applyUpdate(update);
+                try {
+                    NotificationListenerService.this.onNotificationRankingUpdate();
+                } catch (Throwable t) {
+                    Log.w(TAG, "Error running onNotificationRankingUpdate", t);
                 }
-            } catch (Throwable t) {
-                Log.w(TAG, "Error running onNotificationOrderUpdate", t);
             }
         }
     }
 
-    private void updateNotificationKeys(NotificationOrderUpdate update) {
-        // TODO: avoid garbage by comparing the lists
-        mNotificationKeys = update.getOrderedKeys();
+    private void applyUpdate(NotificationRankingUpdate update) {
+        mRanking = new Ranking(update);
+    }
+
+    /**
+     * Provides access to ranking information on currently active
+     * notifications.
+     *
+     * <p>
+     * Note that this object represents a ranking snapshot that only applies to
+     * notifications active at the time of retrieval.
+     */
+    public static class Ranking implements Parcelable {
+        private final NotificationRankingUpdate mRankingUpdate;
+
+        private Ranking(NotificationRankingUpdate rankingUpdate) {
+            mRankingUpdate = rankingUpdate;
+        }
+
+        /**
+         * Request the list of notification keys in their current ranking
+         * order.
+         *
+         * @return An array of active notification keys, in their ranking order.
+         */
+        public String[] getOrderedKeys() {
+            return mRankingUpdate.getOrderedKeys();
+        }
+
+        /**
+         * Returns the rank of the notification with the given key, that is the
+         * index of <code>key</code> in the array of keys returned by
+         * {@link #getOrderedKeys()}.
+         *
+         * @return The rank of the notification with the given key; -1 when the
+         *      given key is unknown.
+         */
+        public int getIndexOfKey(String key) {
+            // TODO: Optimize.
+            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
+            for (int i = 0; i < orderedKeys.length; i++) {
+                if (orderedKeys[i].equals(key)) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        /**
+         * Returns whether the notification with the given key was intercepted
+         * by &quot;Do not disturb&quot;.
+         */
+        public boolean isInterceptedByDoNotDisturb(String key) {
+            // TODO: Optimize.
+            for (String interceptedKey : mRankingUpdate.getDndInterceptedKeys()) {
+                if (interceptedKey.equals(key)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns whether the notification with the given key is an ambient
+         * notification, that is a notification that doesn't require the user's
+         * immediate attention.
+         */
+        public boolean isAmbient(String key) {
+            // TODO: Optimize.
+            int firstAmbientIndex = mRankingUpdate.getFirstAmbientIndex();
+            if (firstAmbientIndex < 0) {
+                return false;
+            }
+            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
+            for (int i = firstAmbientIndex; i < orderedKeys.length; i++) {
+                if (orderedKeys[i].equals(key)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        // ----------- Parcelable
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeParcelable(mRankingUpdate, flags);
+        }
+
+        public static final Creator<Ranking> CREATOR = new Creator<Ranking>() {
+            @Override
+            public Ranking createFromParcel(Parcel source) {
+                NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
+                return new Ranking(rankingUpdate);
+            }
+
+            @Override
+            public Ranking[] newArray(int size) {
+                return new Ranking[size];
+            }
+        };
     }
 }
diff --git a/core/java/android/service/notification/NotificationOrderUpdate.java b/core/java/android/service/notification/NotificationOrderUpdate.java
deleted file mode 100644
index 20e19a3..0000000
--- a/core/java/android/service/notification/NotificationOrderUpdate.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.service.notification;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class NotificationOrderUpdate implements Parcelable {
-    // TODO replace this with an update instead of the whole array
-    private final String[] mKeys;
-
-    /** @hide */
-    public NotificationOrderUpdate(String[] keys) {
-        this.mKeys = keys;
-    }
-
-    public NotificationOrderUpdate(Parcel in) {
-        this.mKeys = in.readStringArray();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeStringArray(this.mKeys);
-    }
-
-    public static final Parcelable.Creator<NotificationOrderUpdate> CREATOR
-            = new Parcelable.Creator<NotificationOrderUpdate>() {
-        public NotificationOrderUpdate createFromParcel(Parcel parcel) {
-            return new NotificationOrderUpdate(parcel);
-        }
-
-        public NotificationOrderUpdate[] newArray(int size) {
-            return new NotificationOrderUpdate[size];
-        }
-    };
-
-    /**
-     * @hide
-     * @return ordered list of keys
-     */
-    String[] getOrderedKeys() {
-        return mKeys;
-    }
-}
diff --git a/core/java/android/service/notification/NotificationOrderUpdate.aidl b/core/java/android/service/notification/NotificationRankingUpdate.aidl
similarity index 94%
rename from core/java/android/service/notification/NotificationOrderUpdate.aidl
rename to core/java/android/service/notification/NotificationRankingUpdate.aidl
index 5d50641..1393cb9 100644
--- a/core/java/android/service/notification/NotificationOrderUpdate.aidl
+++ b/core/java/android/service/notification/NotificationRankingUpdate.aidl
@@ -16,4 +16,4 @@
 
 package android.service.notification;
 
-parcelable NotificationOrderUpdate;
+parcelable NotificationRankingUpdate;
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
new file mode 100644
index 0000000..4b13d95
--- /dev/null
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.service.notification;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+public class NotificationRankingUpdate implements Parcelable {
+    // TODO: Support incremental updates.
+    private final String[] mKeys;
+    private final String[] mDndInterceptedKeys;
+    private final int mFirstAmbientIndex;
+
+    public NotificationRankingUpdate(String[] keys, String[] dndInterceptedKeys,
+                                     int firstAmbientIndex) {
+        mKeys = keys;
+        mFirstAmbientIndex = firstAmbientIndex;
+        mDndInterceptedKeys = dndInterceptedKeys;
+    }
+
+    public NotificationRankingUpdate(Parcel in) {
+        mKeys = in.readStringArray();
+        mFirstAmbientIndex = in.readInt();
+        mDndInterceptedKeys = in.readStringArray();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeStringArray(mKeys);
+        out.writeInt(mFirstAmbientIndex);
+        out.writeStringArray(mDndInterceptedKeys);
+    }
+
+    public static final Parcelable.Creator<NotificationRankingUpdate> CREATOR
+            = new Parcelable.Creator<NotificationRankingUpdate>() {
+        public NotificationRankingUpdate createFromParcel(Parcel parcel) {
+            return new NotificationRankingUpdate(parcel);
+        }
+
+        public NotificationRankingUpdate[] newArray(int size) {
+            return new NotificationRankingUpdate[size];
+        }
+    };
+
+    public String[] getOrderedKeys() {
+        return mKeys;
+    }
+
+    public int getFirstAmbientIndex() {
+        return mFirstAmbientIndex;
+    }
+
+    public String[] getDndInterceptedKeys() {
+        return mDndInterceptedKeys;
+    }
+}
diff --git a/core/java/android/tv/TvView.java b/core/java/android/tv/TvView.java
index 7721575..59b6386 100644
--- a/core/java/android/tv/TvView.java
+++ b/core/java/android/tv/TvView.java
@@ -149,6 +149,7 @@
         if (mSession != null) {
             release();
         }
+        mSessionCallback = null;
     }
 
     /**
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index c1a4fee..e918119 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -48,6 +48,8 @@
     public static final int Y = 9;
     public static final int Z = 10;
     public static final int ALPHA = 11;
+    // The last value in the enum, used for array size initialization
+    public static final int LAST_VALUE = ALPHA;
 
     // Keep in sync with enum PaintFields in Animator.h
     public static final int PAINT_STROKE_WIDTH = 0;
@@ -86,7 +88,7 @@
     private boolean mStarted = false;
     private boolean mFinished = false;
 
-    public int mapViewPropertyToRenderProperty(int viewProperty) {
+    public static int mapViewPropertyToRenderProperty(int viewProperty) {
         return sViewPropertyAnimatorMap.get(viewProperty);
     }
 
@@ -125,11 +127,15 @@
         }
     }
 
+    static boolean isNativeInterpolator(TimeInterpolator interpolator) {
+        return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class);
+    }
+
     private void applyInterpolator() {
         if (mInterpolator == null) return;
 
         long ni;
-        if (mInterpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class)) {
+        if (isNativeInterpolator(mInterpolator)) {
             ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator();
         } else {
             long duration = nGetDuration(mNativePtr.get());
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 11d2622..3104862 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.ValueAnimator;
 import android.animation.TimeInterpolator;
+import android.os.Build;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -109,6 +110,11 @@
     private ValueAnimator mTempValueAnimator;
 
     /**
+     * A RenderThread-driven backend that may intercept startAnimation
+     */
+    private ViewPropertyAnimatorRT mRTBackend;
+
+    /**
      * This listener is the mechanism by which the underlying Animator causes changes to the
      * properties currently being animated, as well as the cleanup after an animation is
      * complete.
@@ -227,7 +233,7 @@
      * values are used to calculate the animated value for a given animation fraction
      * during the animation.
      */
-    private static class NameValuesHolder {
+    static class NameValuesHolder {
         int mNameConstant;
         float mFromValue;
         float mDeltaValue;
@@ -247,6 +253,9 @@
     ViewPropertyAnimator(View view) {
         mView = view;
         view.ensureTransformationInfo();
+        if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+            mRTBackend = new ViewPropertyAnimatorRT(view);
+        }
     }
 
     /**
@@ -371,6 +380,10 @@
         return this;
     }
 
+    Animator.AnimatorListener getListener() {
+        return mListener;
+    }
+
     /**
      * Sets a listener for update events in the underlying ValueAnimator that runs
      * the property animations. Note that the underlying animator is animating between
@@ -390,6 +403,10 @@
         return this;
     }
 
+    ValueAnimator.AnimatorUpdateListener getUpdateListener() {
+        return mUpdateListener;
+    }
+
     /**
      * Starts the currently pending property animations immediately. Calling <code>start()</code>
      * is optional because all animations start automatically at the next opportunity. However,
@@ -825,12 +842,22 @@
         return this;
     }
 
+    boolean hasActions() {
+        return mPendingSetupAction != null
+                || mPendingCleanupAction != null
+                || mPendingOnStartAction != null
+                || mPendingOnEndAction != null;
+    }
+
     /**
      * Starts the underlying Animator for a set of properties. We use a single animator that
      * simply runs from 0 to 1, and then use that fractional value to set each property
      * value accordingly.
      */
     private void startAnimation() {
+        if (mRTBackend != null && mRTBackend.startAnimation(this)) {
+            return;
+        }
         mView.setHasTransientState(true);
         ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
         ArrayList<NameValuesHolder> nameValueList =
diff --git a/core/java/android/view/ViewPropertyAnimatorRT.java b/core/java/android/view/ViewPropertyAnimatorRT.java
new file mode 100644
index 0000000..709efdb
--- /dev/null
+++ b/core/java/android/view/ViewPropertyAnimatorRT.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.animation.TimeInterpolator;
+import android.view.ViewPropertyAnimator.NameValuesHolder;
+
+import com.android.internal.view.animation.FallbackLUTInterpolator;
+
+import java.util.ArrayList;
+
+
+/**
+ * This is a RenderThread driven backend for ViewPropertyAnimator.
+ */
+class ViewPropertyAnimatorRT {
+
+    private final View mView;
+
+    private RenderNodeAnimator mAnimators[] = new RenderNodeAnimator[RenderNodeAnimator.LAST_VALUE + 1];
+
+    ViewPropertyAnimatorRT(View view) {
+        mView = view;
+    }
+
+    /**
+     * @return true if ViewPropertyAnimatorRT handled the animation,
+     *         false if ViewPropertyAnimator needs to handle it
+     */
+    public boolean startAnimation(ViewPropertyAnimator parent) {
+        cancelAnimators(parent.mPendingAnimations);
+        if (!canHandleAnimator(parent)) {
+            return false;
+        }
+        doStartAnimation(parent);
+        return true;
+    }
+
+    private void doStartAnimation(ViewPropertyAnimator parent) {
+        int size = parent.mPendingAnimations.size();
+
+        long startDelay = parent.getStartDelay();
+        long duration = parent.getDuration();
+        TimeInterpolator interpolator = parent.getInterpolator();
+        if (!RenderNodeAnimator.isNativeInterpolator(interpolator)) {
+            interpolator = new FallbackLUTInterpolator(interpolator, duration);
+        }
+        for (int i = 0; i < size; i++) {
+            NameValuesHolder holder = parent.mPendingAnimations.get(i);
+            int property = RenderNodeAnimator.mapViewPropertyToRenderProperty(holder.mNameConstant);
+
+            RenderNodeAnimator animator = new RenderNodeAnimator(property, holder.mFromValue + holder.mDeltaValue);
+            animator.setStartDelay(startDelay);
+            animator.setDuration(duration);
+            animator.setInterpolator(interpolator);
+            animator.setTarget(mView);
+            animator.start();
+        }
+
+        parent.mPendingAnimations.clear();
+    }
+
+    private boolean canHandleAnimator(ViewPropertyAnimator parent) {
+        // TODO: Can we eliminate this entirely?
+        // If RenderNode.animatorProperties() can be toggled to point at staging
+        // instead then RNA can be used as the animators for software as well
+        // as the updateListener fallback paths. If this can be toggled
+        // at the top level somehow, combined with requiresUiRedraw, we could
+        // ensure that RT does not self-animate, allowing for safe driving of
+        // the animators from the UI thread using the same mechanisms
+        // ViewPropertyAnimator does, just with everything sitting on a single
+        // animator subsystem instead of multiple.
+
+        if (parent.getUpdateListener() != null) {
+            return false;
+        }
+        if (parent.getListener() != null) {
+            // TODO support
+            return false;
+        }
+        if (!mView.isHardwareAccelerated()) {
+            // TODO handle this maybe?
+            return false;
+        }
+        if (parent.hasActions()) {
+            return false;
+        }
+        // Here goes nothing...
+        return true;
+    }
+
+    private void cancelAnimators(ArrayList<NameValuesHolder> mPendingAnimations) {
+        int size = mPendingAnimations.size();
+        for (int i = 0; i < size; i++) {
+            NameValuesHolder holder = mPendingAnimations.get(i);
+            int property = RenderNodeAnimator.mapViewPropertyToRenderProperty(holder.mNameConstant);
+            if (mAnimators[property] != null) {
+                mAnimators[property].cancel();
+                mAnimators[property] = null;
+            }
+        }
+    }
+
+}
diff --git a/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java b/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java
index 1feb943..06838c9 100644
--- a/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java
+++ b/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java
@@ -24,10 +24,13 @@
  * Interpolator that builds a lookup table to use. This is a fallback for
  * building a native interpolator from a TimeInterpolator that is not marked
  * with {@link HasNativeInterpolator}
+ *
+ * This implements TimeInterpolator to allow for easier interop with Animators
  */
 @HasNativeInterpolator
-public class FallbackLUTInterpolator implements NativeInterpolatorFactory {
+public class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeInterpolator {
 
+    private TimeInterpolator mSourceInterpolator;
     private final float mLut[];
 
     /**
@@ -35,6 +38,7 @@
      * interpolator creation
      */
     public FallbackLUTInterpolator(TimeInterpolator interpolator, long duration) {
+        mSourceInterpolator = interpolator;
         mLut = createLUT(interpolator, duration);
     }
 
@@ -63,4 +67,9 @@
         float[] lut = createLUT(interpolator, duration);
         return NativeInterpolatorFactoryHelper.createLutInterpolator(lut);
     }
+
+    @Override
+    public float getInterpolation(float input) {
+        return mSourceInterpolator.getInterpolation(input);
+    }
 }
diff --git a/core/jni/android_hardware_UsbRequest.cpp b/core/jni/android_hardware_UsbRequest.cpp
index 01eaec4..a3c7b0a 100644
--- a/core/jni/android_hardware_UsbRequest.cpp
+++ b/core/jni/android_hardware_UsbRequest.cpp
@@ -100,18 +100,19 @@
     }
     request->buffer_length = length;
 
+    // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
+    request->client_data = (void *)env->NewGlobalRef(thiz);
+
     if (usb_request_queue(request)) {
         if (request->buffer) {
             // free our buffer if usb_request_queue fails
             free(request->buffer);
             request->buffer = NULL;
         }
+        env->DeleteGlobalRef((jobject)request->client_data);
         return false;
-    } else {
-        // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
-        request->client_data = (void *)env->NewGlobalRef(thiz);
-        return true;
     }
+    return true;
 }
 
 static jint
@@ -152,16 +153,17 @@
     }
     request->buffer_length = length;
 
+    // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
+    // we also need this to make sure our native buffer is not deallocated
+    // while IO is active
+    request->client_data = (void *)env->NewGlobalRef(thiz);
+
     if (usb_request_queue(request)) {
         request->buffer = NULL;
+        env->DeleteGlobalRef((jobject)request->client_data);
         return false;
-    } else {
-        // save a reference to ourselves so UsbDeviceConnection.waitRequest() can find us
-        // we also need this to make sure our native buffer is not deallocated
-        // while IO is active
-        request->client_data = (void *)env->NewGlobalRef(thiz);
-        return true;
     }
+    return true;
 }
 
 static jint
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 55e2983..4b03f31 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4497,7 +4497,7 @@
              RTL (right-to-left). -->
         <attr name="autoMirrored" />
         <!-- Indicates how layer padding should affect the bounds of subsequent layers.
-            The default value is nest. -->
+             The default padding mode value is nest. -->
         <attr name="paddingMode">
             <!-- Nest each layer inside the padding of the previous layer. -->
             <enum name="nest" value="0" />
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 6ea0fae..c966a12 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -83,5 +83,4 @@
   <item type="id" name="current_scene" />
   <item type="id" name="scene_layoutid_cache" />
   <item type="id" name="mask" />
-  <item type="id" name="shared_element" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 44b25f2b..32ce568 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2177,6 +2177,7 @@
   <public type="attr" name="contentInsetEnd" />
   <public type="attr" name="contentInsetLeft" />
   <public type="attr" name="contentInsetRight" />
+  <public type="attr" name="paddingMode" />
 
   <public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
 
@@ -2186,7 +2187,6 @@
   <public-padding type="id" name="l_resource_pad" end="0x01020040" />
 
   <public type="id" name="mask" />
-  <public type="id" name="shared_element" />
 
   <public-padding type="style" name="l_resource_pad" end="0x01030200" />
 
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
index 67203b2..22dce39 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.os.Bundle;
 
+import java.util.Set;
+
 public class BluetoothInstrumentation extends Instrumentation {
 
     private BluetoothTestUtils mUtils = null;
@@ -66,6 +68,8 @@
             getName();
         } else if ("getAddress".equals(command)) {
             getAddress();
+        } else if ("getBondedDevices".equals(command)) {
+            getBondedDevices();
         } else {
             finish(null);
         }
@@ -98,6 +102,16 @@
         finish(mSuccessResult);
     }
 
+    public void getBondedDevices() {
+        Set<BluetoothDevice> devices = getBluetoothAdapter().getBondedDevices();
+        int i = 0;
+        for (BluetoothDevice device : devices) {
+            mSuccessResult.putString(String.format("device-%02d", i), device.getAddress());
+            i++;
+        }
+        finish(mSuccessResult);
+    }
+
     public void finish(Bundle result) {
         if (result == null) {
             result = new Bundle();
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index c78096a..3eabc3a 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -1005,6 +1005,11 @@
         return createFromXmlInnerThemed(r, parser, attrs, null);
     }
 
+    /**
+     * Create a themed drawable from inside an XML document. Called on a parser
+     * positioned at a tag in an XML document, tries to create a Drawable from
+     * that tag. Returns null if the tag is not a valid drawable.
+     */
     public static Drawable createFromXmlInnerThemed(Resources r, XmlPullParser parser,
             AttributeSet attrs, Theme theme) throws XmlPullParserException, IOException {
         final Drawable drawable;
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 373d894..f446000 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -38,10 +38,12 @@
  * order, so the element with the largest index will be drawn on top.
  * <p>
  * It can be defined in an XML file with the <code>&lt;layer-list></code> element.
- * Each Drawable in the layer is defined in a nested <code>&lt;item></code>. For more
- * information, see the guide to <a
- * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p>
+ * Each Drawable in the layer is defined in a nested <code>&lt;item></code>.
+ * <p>
+ * For more information, see the guide to
+ * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
  *
+ * @attr ref android.R.styleable#LayerDrawable_paddingMode
  * @attr ref android.R.styleable#LayerDrawableItem_left
  * @attr ref android.R.styleable#LayerDrawableItem_top
  * @attr ref android.R.styleable#LayerDrawableItem_right
@@ -53,10 +55,16 @@
     /**
      * Padding mode used to nest each layer inside the padding of the previous
      * layer.
+     *
+     * @see #setPaddingMode(int)
      */
     public static final int PADDING_MODE_NEST = 0;
 
-    /** Padding mode used to stack each layer directly atop the previous layer. */
+    /**
+     * Padding mode used to stack each layer directly atop the previous layer.
+     *
+     * @see #setPaddingMode(int)
+     */
     public static final int PADDING_MODE_STACK = 1;
 
     LayerState mLayerState;
@@ -127,9 +135,8 @@
             throws XmlPullParserException, IOException {
         super.inflate(r, parser, attrs, theme);
 
-        final TypedArray a = obtainAttributes(
-                r, theme, attrs, R.styleable.LayerDrawable);
-        inflateStateFromTypedArray(a);
+        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.LayerDrawable);
+        updateStateFromTypedArray(a);
         a.recycle();
 
         inflateLayers(r, parser, attrs, theme);
@@ -141,25 +148,19 @@
     /**
      * Initializes the constant state from the values in the typed array.
      */
-    private void inflateStateFromTypedArray(TypedArray a) {
+    private void updateStateFromTypedArray(TypedArray a) {
         final LayerState state = mLayerState;
 
         // Extract the theme attributes, if any.
         final int[] themeAttrs = a.extractThemeAttrs();
         state.mThemeAttrs = themeAttrs;
 
-        if (themeAttrs == null || themeAttrs[R.styleable.LayerDrawable_opacity] == 0) {
-            mOpacityOverride = a.getInt(R.styleable.LayerDrawable_opacity, PixelFormat.UNKNOWN);
-        }
+        mOpacityOverride = a.getInt(R.styleable.LayerDrawable_opacity, mOpacityOverride);
 
-        if (themeAttrs == null || themeAttrs[R.styleable.LayerDrawable_autoMirrored] == 0) {
-            state.mAutoMirrored = a.getBoolean(R.styleable.LayerDrawable_autoMirrored, false);
-        }
-
-        if (themeAttrs == null || themeAttrs[R.styleable.LayerDrawableItem_drawable] == 0) {
-            state.mPaddingMode = a.getInteger(
-                    R.styleable.LayerDrawableItem_drawable, PADDING_MODE_NEST);
-        }
+        state.mAutoMirrored = a.getBoolean(R.styleable.LayerDrawable_autoMirrored,
+                state.mAutoMirrored);
+        state.mPaddingMode = a.getInteger(R.styleable.LayerDrawable_paddingMode,
+                state.mPaddingMode);
     }
 
     /**
@@ -181,9 +182,9 @@
                 continue;
             }
 
-            a = obtainAttributes(
-                    r, theme, attrs, R.styleable.LayerDrawableItem);
+            a = obtainAttributes(r, theme, attrs, R.styleable.LayerDrawableItem);
 
+            final int[] themeAttrs = a.extractThemeAttrs();
             final int left = a.getDimensionPixelOffset(
                     R.styleable.LayerDrawableItem_left, 0);
             final int top = a.getDimensionPixelOffset(
@@ -197,7 +198,6 @@
             final int id = a.getResourceId(
                     R.styleable.LayerDrawableItem_id, View.NO_ID);
 
-            // TODO: Cache typed array, if necessary.
             a.recycle();
 
             final Drawable dr;
@@ -214,7 +214,7 @@
                 dr = Drawable.createFromXmlInnerThemed(r, parser, attrs, theme);
             }
 
-            addLayer(dr, id, left, top, right, bottom);
+            addLayer(dr, themeAttrs, id, left, top, right, bottom);
         }
     }
 
@@ -224,7 +224,7 @@
 
         final LayerState state = mLayerState;
         if (state == null) {
-            throw new RuntimeException("Can't apply theme to <layer-list> with no constant state");
+            return;
         }
 
         final int[] themeAttrs = state.mThemeAttrs;
@@ -239,9 +239,10 @@
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
         for (int i = 0; i < N; i++) {
-            final Drawable layer = array[i].mDrawable;
-            if (layer.canApplyTheme()) {
-                layer.applyTheme(t);
+            final ChildDrawable layer = array[i];
+            final Drawable d = layer.mDrawable;
+            if (d.canApplyTheme()) {
+                d.applyTheme(t);
             }
         }
 
@@ -249,26 +250,6 @@
         onStateChange(getState());
     }
 
-    /**
-     * Updates the constant state from the values in the typed array.
-     */
-    private void updateStateFromTypedArray(TypedArray a) {
-        final LayerState state = mLayerState;
-
-        if (a.hasValue(R.styleable.LayerDrawable_opacity)) {
-            mOpacityOverride = a.getInt(R.styleable.LayerDrawable_opacity, PixelFormat.UNKNOWN);
-        }
-
-        if (a.hasValue(R.styleable.LayerDrawable_autoMirrored)) {
-            state.mAutoMirrored = a.getBoolean(R.styleable.LayerDrawable_autoMirrored, false);
-        }
-
-        if (a.hasValue(R.styleable.LayerDrawableItem_drawable)) {
-            state.mPaddingMode = a.getInteger(
-                    R.styleable.LayerDrawableItem_drawable, PADDING_MODE_NEST);
-        }
-    }
-
     @Override
     public boolean canApplyTheme() {
         final LayerState state = mLayerState;
@@ -283,14 +264,15 @@
         final ChildDrawable[] array = state.mChildren;
         final int N = state.mNum;
         for (int i = 0; i < N; i++) {
-            if (array[i].mDrawable.canApplyTheme()) {
+            final ChildDrawable layer = array[i];
+            if (layer.mThemeAttrs != null || layer.mDrawable.canApplyTheme()) {
                 return true;
             }
         }
 
         return false;
     }
-    
+
     /**
      * @hide
      */
@@ -315,13 +297,15 @@
      * Add a new layer to this drawable. The new layer is identified by an id.
      *
      * @param layer The drawable to add as a layer.
+     * @param themeAttrs Theme attributes extracted from the layer.
      * @param id The id of the new layer.
      * @param left The left padding of the new layer.
      * @param top The top padding of the new layer.
      * @param right The right padding of the new layer.
      * @param bottom The bottom padding of the new layer.
      */
-    private void addLayer(Drawable layer, int id, int left, int top, int right, int bottom) {
+    private void addLayer(Drawable layer, int[] themeAttrs, int id, int left, int top, int right,
+            int bottom) {
         final LayerState st = mLayerState;
         final int N = st.mChildren != null ? st.mChildren.length : 0;
         final int i = st.mNum;
@@ -339,6 +323,7 @@
         final ChildDrawable childDrawable = new ChildDrawable();
         st.mChildren[i] = childDrawable;
         childDrawable.mId = id;
+        childDrawable.mThemeAttrs = themeAttrs;
         childDrawable.mDrawable = layer;
         childDrawable.mDrawable.setAutoMirrored(isAutoMirrored());
         childDrawable.mInsetL = left;
@@ -471,8 +456,14 @@
      *
      * @param mode padding mode, one of:
      *            <ul>
-     *            <li>{@link #PADDING_MODE_NEST} <li>{@link #PADDING_MODE_STACK}
+     *            <li>{@link #PADDING_MODE_NEST} to nest each layer inside the
+     *            padding of the previous layer
+     *            <li>{@link #PADDING_MODE_STACK} to stack each layer directly
+     *            atop the previous layer
      *            </ul>
+     *
+     * @see #getPaddingMode()
+     * @attr ref android.R.styleable#LayerDrawable_paddingMode
      */
     public void setPaddingMode(int mode) {
         if (mLayerState.mPaddingMode != mode) {
@@ -482,7 +473,9 @@
 
     /**
      * @return the current padding mode
+     *
      * @see #setPaddingMode(int)
+     * @attr ref android.R.styleable#LayerDrawable_paddingMode
      */
     public int getPaddingMode() {
       return mLayerState.mPaddingMode;
@@ -905,7 +898,7 @@
         private boolean mHaveIsStateful;
         private boolean mIsStateful;
 
-        private boolean mAutoMirrored;
+        private boolean mAutoMirrored = false;
 
         private int mPaddingMode = PADDING_MODE_NEST;
 
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index edf1091..5f9d1cd 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -145,6 +145,9 @@
      * Sets the start angle for rotation.
      *
      * @param fromDegrees Starting angle in degrees
+     *
+     * @see #getFromDegrees()
+     * @attr ref android.R.styleable#RotateDrawable_fromDegrees
      */
     public void setFromDegrees(float fromDegrees) {
         if (mState.mFromDegrees != fromDegrees) {
@@ -155,6 +158,9 @@
 
     /**
      * @return The starting angle for rotation in degrees
+     *
+     * @see #setFromDegrees(float)
+     * @attr ref android.R.styleable#RotateDrawable_fromDegrees
      */
     public float getFromDegrees() {
         return mState.mFromDegrees;
@@ -164,6 +170,9 @@
      * Sets the end angle for rotation.
      *
      * @param toDegrees Ending angle in degrees
+     *
+     * @see #getToDegrees()
+     * @attr ref android.R.styleable#RotateDrawable_toDegrees
      */
     public void setToDegrees(float toDegrees) {
         if (mState.mToDegrees != toDegrees) {
@@ -174,6 +183,9 @@
 
     /**
      * @return The ending angle for rotation in degrees
+     *
+     * @see #setToDegrees(float)
+     * @attr ref android.R.styleable#RotateDrawable_toDegrees
      */
     public float getToDegrees() {
         return mState.mToDegrees;
@@ -186,7 +198,9 @@
      *            relative, the position represents a fraction of the drawable
      *            width. Otherwise, the position represents an absolute value in
      *            pixels.
+     *
      * @see #setPivotXRelative(boolean)
+     * @attr ref android.R.styleable#RotateDrawable_pivotX
      */
     public void setPivotX(float pivotX) {
         if (mState.mPivotX == pivotX) {
@@ -197,7 +211,9 @@
 
     /**
      * @return X position around which to rotate
+     *
      * @see #setPivotX(float)
+     * @attr ref android.R.styleable#RotateDrawable_pivotX
      */
     public float getPivotX() {
         return mState.mPivotX;
@@ -209,6 +225,8 @@
      *
      * @param relative True if the X pivot represents a fraction of the drawable
      *            width, or false if it represents an absolute value in pixels
+     *
+     * @see #isPivotXRelative()
      */
     public void setPivotXRelative(boolean relative) {
         if (mState.mPivotXRel == relative) {
@@ -220,6 +238,7 @@
     /**
      * @return True if the X pivot represents a fraction of the drawable width,
      *         or false if it represents an absolute value in pixels
+     *
      * @see #setPivotXRelative(boolean)
      */
     public boolean isPivotXRelative() {
@@ -233,7 +252,9 @@
      *            relative, the position represents a fraction of the drawable
      *            height. Otherwise, the position represents an absolute value
      *            in pixels.
-     * @see #setPivotYRelative(boolean)
+     *
+     * @see #getPivotY()
+     * @attr ref android.R.styleable#RotateDrawable_pivotY
      */
     public void setPivotY(float pivotY) {
         if (mState.mPivotY == pivotY) {
@@ -244,7 +265,9 @@
 
     /**
      * @return Y position around which to rotate
+     *
      * @see #setPivotY(float)
+     * @attr ref android.R.styleable#RotateDrawable_pivotY
      */
     public float getPivotY() {
         return mState.mPivotY;
@@ -256,6 +279,8 @@
      *
      * @param relative True if the Y pivot represents a fraction of the drawable
      *            height, or false if it represents an absolute value in pixels
+     *
+     * @see #isPivotYRelative()
      */
     public void setPivotYRelative(boolean relative) {
         if (mState.mPivotYRel == relative) {
@@ -267,6 +292,7 @@
     /**
      * @return True if the Y pivot represents a fraction of the drawable height,
      *         or false if it represents an absolute value in pixels
+     *
      * @see #setPivotYRelative(boolean)
      */
     public boolean isPivotYRelative() {
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 84028b7..d21b442 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -351,7 +351,7 @@
     if (!data) {
         return NULL;
     }
-    long len = *((long*)data);
+    jsize len = *((uint32_t*)data);
 
     jbyteArray array = env->NewByteArray(len);
     if (array != NULL) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index dc3d92a..724b6a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -45,7 +45,6 @@
             = new PathInterpolator(0.6f, 0, 0.5f, 1);
     private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
             = new PathInterpolator(0, 0, 0.5f, 1);
-    private final int mMaxNotificationHeight;
 
     private boolean mDimmed;
 
@@ -81,8 +80,6 @@
                 AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
         mLinearOutSlowInInterpolator =
                 AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
-        mMaxNotificationHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_max_height);
         setClipChildren(false);
         setClipToPadding(false);
     }
@@ -296,27 +293,6 @@
     }
 
     @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int newHeightSpec = MeasureSpec.makeMeasureSpec(mMaxNotificationHeight,
-                MeasureSpec.AT_MOST);
-        int maxChildHeight = 0;
-        int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = getChildAt(i);
-            if (child != mBackgroundDimmed && child != mBackgroundNormal) {
-                child.measure(widthMeasureSpec, newHeightSpec);
-                int childHeight = child.getMeasuredHeight();
-                maxChildHeight = Math.max(maxChildHeight, childHeight);
-            }
-        }
-        newHeightSpec = MeasureSpec.makeMeasureSpec(maxChildHeight, MeasureSpec.EXACTLY);
-        mBackgroundDimmed.measure(widthMeasureSpec, newHeightSpec);
-        mBackgroundNormal.measure(widthMeasureSpec, newHeightSpec);
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-        setMeasuredDimension(width, maxChildHeight);
-    }
-
-    @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
         setPivotX(getWidth() / 2);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 8f92a4c..84005d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -258,11 +258,4 @@
     public void notifyContentUpdated() {
         mPrivateLayout.notifyContentUpdated();
     }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int newHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
-        mVetoButton.measure(widthMeasureSpec, newHeightSpec);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 5cb1b78..0d3116f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -21,34 +21,74 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import com.android.systemui.R;
+
+import java.util.ArrayList;
 
 /**
  * An abstract view for expandable views.
  */
-public abstract class ExpandableView extends ViewGroup {
+public abstract class ExpandableView extends FrameLayout {
+
+    private final int mMaxNotificationHeight;
 
     private OnHeightChangedListener mOnHeightChangedListener;
     protected int mActualHeight;
     protected int mClipTopAmount;
     private boolean mActualHeightInitialized;
+    private ArrayList<View> mMatchParentViews = new ArrayList<View>();
 
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mMaxNotificationHeight = getResources().getDimensionPixelSize(
+                R.dimen.notification_max_height);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int ownMaxHeight = mMaxNotificationHeight;
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
+        boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
+        if (hasFixedHeight || isHeightLimited) {
+            int size = MeasureSpec.getSize(heightMeasureSpec);
+            ownMaxHeight = Math.min(ownMaxHeight, size);
+        }
+        int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
+        int maxChildHeight = 0;
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            int childHeightSpec = newHeightSpec;
+            ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
+            if (layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT) {
+                if (layoutParams.height >= 0) {
+                    // An actual height is set
+                    childHeightSpec = layoutParams.height > ownMaxHeight
+                        ? MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.EXACTLY)
+                        : MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
+                }
+                child.measure(widthMeasureSpec, childHeightSpec);
+                int childHeight = child.getMeasuredHeight();
+                maxChildHeight = Math.max(maxChildHeight, childHeight);
+            } else {
+                mMatchParentViews.add(child);
+            }
+        }
+        int ownHeight = hasFixedHeight ? ownMaxHeight : maxChildHeight;
+        newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
+        for (View child : mMatchParentViews) {
+            child.measure(widthMeasureSpec, newHeightSpec);
+        }
+        mMatchParentViews.clear();
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        setMeasuredDimension(width, ownHeight);
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            int height = child.getMeasuredHeight();
-            int width = child.getMeasuredWidth();
-            int center = getWidth() / 2;
-            int childLeft = center - width / 2;
-            child.layout(childLeft,
-                    0,
-                    childLeft + width,
-                    height);
-        }
+        super.onLayout(changed, left, top, right, bottom);
         if (!mActualHeightInitialized && mActualHeight == 0) {
             mActualHeight = getInitialHeight();
         }
diff --git a/policy/src/com/android/internal/policy/impl/BarController.java b/policy/src/com/android/internal/policy/impl/BarController.java
index 49e1072..bfbd60d 100644
--- a/policy/src/com/android/internal/policy/impl/BarController.java
+++ b/policy/src/com/android/internal/policy/impl/BarController.java
@@ -121,7 +121,7 @@
                 }
             } else {
                 vis = (vis & ~mTranslucentFlag) | (oldVis & mTranslucentFlag);
-                vis = (vis & View.SYSTEM_UI_TRANSPARENT) | (oldVis & View.SYSTEM_UI_TRANSPARENT);
+                vis = (vis & ~View.SYSTEM_UI_TRANSPARENT) | (oldVis & View.SYSTEM_UI_TRANSPARENT);
             }
         }
         return vis;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index cc132be..af53fef0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -398,7 +398,7 @@
 
     /**
      * used internally when registering NetworkFactories
-     * obj = Messenger
+     * obj = NetworkFactoryInfo
      */
     private static final int EVENT_REGISTER_NETWORK_FACTORY = 17;
 
@@ -434,6 +434,13 @@
      */
     private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
 
+    /**
+     * used internally when registering NetworkFactories
+     * obj = Messenger
+     */
+    private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23;
+
+
     /** Handler used for internal events. */
     final private InternalHandler mHandler;
     /** Handler used for incoming {@link NetworkStateTracker} events. */
@@ -2889,6 +2896,14 @@
             return;
         }
 
+        pw.println("NetworkFactories for:");
+        pw.increaseIndent();
+        for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
+            pw.println(nfi.name);
+        }
+        pw.decreaseIndent();
+        pw.println();
+
         NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
         pw.print("Active default network: ");
         if (defaultNai == null) {
@@ -2983,6 +2998,7 @@
                     if (nai == null) {
                         loge("NetworkAgent not found for EVENT_NETWORK_PROPERTIES_CHANGED");
                     } else {
+                        if (VDBG) log("Update of Linkproperties for " + nai.name());
                         LinkProperties oldLp = nai.linkProperties;
                         nai.linkProperties = (LinkProperties)msg.obj;
                         updateLinkProperties(nai, oldLp);
@@ -3096,18 +3112,19 @@
 
     private void handleAsyncChannelHalfConnect(Message msg) {
         AsyncChannel ac = (AsyncChannel) msg.obj;
-        if (mNetworkFactories.contains(ac)) {
+        if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                 if (VDBG) log("NetworkFactory connected");
                 // A network factory has connected.  Send it all current NetworkRequests.
                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
+                    if (nri.isRequest == false) continue;
                     NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
                     ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK,
                             (nai != null ? nai.currentScore : 0), 0, nri.request);
                 }
             } else {
                 loge("Error connecting NetworkFactory");
-                mNetworkFactories.remove(ac);
+                mNetworkFactoryInfos.remove(msg.obj);
             }
         } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {
             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
@@ -3214,8 +3231,8 @@
         mNetworkRequests.put(nri.request, nri);
         if (msg.what == EVENT_REGISTER_NETWORK_REQUEST) {
             if (DBG) log("sending new NetworkRequest to factories");
-            for (AsyncChannel ac : mNetworkFactories) {
-                ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, nri.request);
+            for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
+                nfi.asyncChannel.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, nri.request);
             }
         }
     }
@@ -3236,8 +3253,8 @@
             }
 
             if (nri.isRequest) {
-                for (AsyncChannel factory : mNetworkFactories) {
-                    factory.sendMessage(NetworkFactoryProtocol.CMD_CANCEL_REQUEST, nri.request);
+                for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
+                    nfi.asyncChannel.sendMessage(NetworkFactoryProtocol.CMD_CANCEL_REQUEST, nri.request);
                 }
 
                 if (affectedNetwork != null) {
@@ -3356,7 +3373,11 @@
                     break;
                 }
                 case EVENT_REGISTER_NETWORK_FACTORY: {
-                    handleRegisterNetworkFactory((Messenger)msg.obj);
+                    handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);
+                    break;
+                }
+                case EVENT_UNREGISTER_NETWORK_FACTORY: {
+                    handleUnregisterNetworkFactory((Messenger)msg.obj);
                     break;
                 }
                 case EVENT_REGISTER_NETWORK_AGENT: {
@@ -5222,10 +5243,22 @@
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime, intent);
     }
 
-    private final ArrayList<AsyncChannel> mNetworkFactories = new ArrayList<AsyncChannel>();
+    private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos =
+            new HashMap<Messenger, NetworkFactoryInfo>();
     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
             new HashMap<NetworkRequest, NetworkRequestInfo>();
 
+    private static class NetworkFactoryInfo {
+        public final String name;
+        public final Messenger messenger;
+        public final AsyncChannel asyncChannel;
+
+        public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
+            this.name = name;
+            this.messenger = messenger;
+            this.asyncChannel = asyncChannel;
+        }
+    }
 
     private class NetworkRequestInfo implements IBinder.DeathRecipient {
         static final boolean REQUEST = true;
@@ -5263,6 +5296,11 @@
                     request + ", " + mBinder + ")");
             releaseNetworkRequest(request);
         }
+
+        public String toString() {
+            return (isRequest ? "Request" : "Listen") + " from uid/pid:" + mUid + "/" +
+                    mPid + " for " + request;
+        }
     }
 
     @Override
@@ -5326,24 +5364,31 @@
     }
 
     @Override
-    public void registerNetworkFactory(Messenger messenger) {
+    public void registerNetworkFactory(Messenger messenger, String name) {
         enforceConnectivityInternalPermission();
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, messenger));
+        NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
     }
 
-    private void handleRegisterNetworkFactory(Messenger messenger) {
-        if (VDBG) log("Got NetworkFactory Messenger");
-        AsyncChannel ac = new AsyncChannel();
-        mNetworkFactories.add(ac);
-        ac.connect(mContext, mTrackerHandler, messenger);
-        for (NetworkRequestInfo nri : mNetworkRequests.values()) {
-            if (nri.isRequest) {
-                int score = 0;
-                NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
-                if (currentNetwork != null) score = currentNetwork.currentScore;
-                ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, nri.request);
-            }
+    private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
+        if (VDBG) log("Got NetworkFactory Messenger for " + nfi.name);
+        mNetworkFactoryInfos.put(nfi.messenger, nfi);
+        nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);
+    }
+
+    @Override
+    public void unregisterNetworkFactory(Messenger messenger) {
+        enforceConnectivityInternalPermission();
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
+    }
+
+    private void handleUnregisterNetworkFactory(Messenger messenger) {
+        NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger);
+        if (nfi == null) {
+            if (VDBG) log("Failed to find Messenger in unregisterNetworkFactory");
+            return;
         }
+        if (VDBG) log("unregisterNetworkFactory for " + nfi.name);
     }
 
     /**
@@ -5535,8 +5580,8 @@
 
     private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
         if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
-        for (AsyncChannel ac : mNetworkFactories) {
-            ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, networkRequest);
+        for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
+            nfi.asyncChannel.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, networkRequest);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7abc75f..7cd4ef8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13837,7 +13837,7 @@
         }
 
         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
-            ProxyInfo proxy = intent.getParcelableExtra("proxy");
+            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
         }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1734a33..9569c0d1 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -63,7 +63,7 @@
 import android.service.notification.IConditionListener;
 import android.service.notification.IConditionProvider;
 import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationOrderUpdate;
+import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.Condition;
 import android.service.notification.ZenModeConfig;
@@ -1744,7 +1744,7 @@
                             sendAccessibilityEvent(notification, pkg);
                         }
 
-                        mListeners.notifyPostedLocked(r.sbn);
+                        mListeners.notifyPostedLocked(r.sbn, cloneNotificationListLocked());
                     } else {
                         Slog.e(TAG, "Not posting notification with icon==0: " + notification);
                         if (old != null && old.statusBarKey != null) {
@@ -1755,7 +1755,7 @@
                                 Binder.restoreCallingIdentity(identity);
                             }
 
-                            mListeners.notifyRemovedLocked(r.sbn);
+                            mListeners.notifyRemovedLocked(r.sbn, cloneNotificationListLocked());
                         }
                         // ATTENTION: in a future release we will bail out here
                         // so that we do not play sounds, show lights, etc. for invalid
@@ -2041,16 +2041,19 @@
 
     private void handleSendRankingUpdate() {
         synchronized (mNotificationList) {
-            final int N = mNotificationList.size();
-            ArrayList<StatusBarNotification> sbns =
-                    new ArrayList<StatusBarNotification>(N);
-            for (int i = 0; i < N; i++ ) {
-                sbns.add(mNotificationList.get(i).sbn);
-            }
-            mListeners.notifyOrderUpdateLocked(sbns);
+            mListeners.notifyRankingUpdateLocked(cloneNotificationListLocked());
         }
     }
 
+    private ArrayList<StatusBarNotification> cloneNotificationListLocked() {
+        final int N = mNotificationList.size();
+        ArrayList<StatusBarNotification> sbns = new ArrayList<StatusBarNotification>(N);
+        for (int i = 0; i < N; i++) {
+            sbns.add(mNotificationList.get(i).sbn);
+        }
+        return sbns;
+    }
+
     private final class WorkerHandler extends Handler
     {
         @Override
@@ -2136,7 +2139,7 @@
                 Binder.restoreCallingIdentity(identity);
             }
             r.statusBarKey = null;
-            mListeners.notifyRemovedLocked(r.sbn);
+            mListeners.notifyRemovedLocked(r.sbn, cloneNotificationListLocked());
         }
 
         // sound
@@ -2442,6 +2445,33 @@
         }
     }
 
+    /**
+     * Generates a NotificationRankingUpdate from 'sbns', considering only
+     * notifications visible to the given listener.
+     */
+    private static NotificationRankingUpdate makeRankingUpdateForListener(ManagedServiceInfo info,
+            ArrayList<StatusBarNotification> sbns) {
+        int speedBumpIndex = -1;
+        ArrayList<String> keys = new ArrayList<String>(sbns.size());
+        ArrayList<String> dndKeys = new ArrayList<String>(sbns.size());
+        for (StatusBarNotification sbn: sbns) {
+            if (!info.enabledAndUserMatches(sbn.getUserId())) {
+                continue;
+            }
+            keys.add(sbn.getKey());
+            if (sbn.getNotification().extras.getBoolean(EXTRA_INTERCEPT)) {
+                dndKeys.add(sbn.getKey());
+            }
+            if (speedBumpIndex == -1 &&
+                    sbn.getNotification().priority == Notification.PRIORITY_MIN) {
+                speedBumpIndex = keys.size() - 1;
+            }
+        }
+        String[] keysAr = keys.toArray(new String[keys.size()]);
+        String[] dndKeysAr = dndKeys.toArray(new String[dndKeys.size()]);
+        return new NotificationRankingUpdate(keysAr, dndKeysAr, speedBumpIndex);
+    }
+
     public class NotificationListeners extends ManagedServices {
 
         public NotificationListeners() {
@@ -2468,9 +2498,12 @@
         @Override
         public void onServiceAdded(ManagedServiceInfo info) {
             final INotificationListener listener = (INotificationListener) info.service;
-            final String[] keys = getActiveNotificationKeys(listener);
+            final ArrayList<StatusBarNotification> sbns;
+            synchronized (mNotificationList) {
+                sbns = cloneNotificationListLocked();
+            }
             try {
-                listener.onListenerConnected(new NotificationOrderUpdate(keys));
+                listener.onListenerConnected(makeRankingUpdateForListener(info, sbns));
             } catch (RemoteException e) {
                 // we tried
             }
@@ -2479,44 +2512,47 @@
         /**
          * asynchronously notify all listeners about a new notification
          */
-        public void notifyPostedLocked(StatusBarNotification sbn) {
+        public void notifyPostedLocked(StatusBarNotification sbn,
+                final ArrayList<StatusBarNotification> sbns) {
             // make a copy in case changes are made to the underlying Notification object
             final StatusBarNotification sbnClone = sbn.clone();
             for (final ManagedServiceInfo info : mServices) {
-                if (info.isEnabledForCurrentProfiles()) {
-                    final INotificationListener listener = (INotificationListener) info.service;
-                    final String[] keys = getActiveNotificationKeys(listener);
-                    if (keys.length > 0) {
-                        mHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                notifyPostedIfUserMatch(info, sbnClone, keys);
-                            }
-                        });
-                    }
+                if (!info.isEnabledForCurrentProfiles()) {
+                    continue;
                 }
+                final NotificationRankingUpdate update = makeRankingUpdateForListener(info, sbns);
+                if (update.getOrderedKeys().length == 0) {
+                    continue;
+                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        notifyPostedIfUserMatch(info, sbnClone, update);
+                    }
+                });
             }
         }
 
         /**
          * asynchronously notify all listeners about a removed notification
          */
-        public void notifyRemovedLocked(StatusBarNotification sbn) {
+        public void notifyRemovedLocked(StatusBarNotification sbn,
+                final ArrayList<StatusBarNotification> sbns) {
             // make a copy in case changes are made to the underlying Notification object
             // NOTE: this copy is lightweight: it doesn't include heavyweight parts of the
             // notification
             final StatusBarNotification sbnLight = sbn.cloneLight();
             for (final ManagedServiceInfo info : mServices) {
-                if (info.isEnabledForCurrentProfiles()) {
-                    final INotificationListener listener = (INotificationListener) info.service;
-                    final String[] keys = getActiveNotificationKeys(listener);
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            notifyRemovedIfUserMatch(info, sbnLight, keys);
-                        }
-                    });
+                if (!info.isEnabledForCurrentProfiles()) {
+                    continue;
                 }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        notifyRemovedIfUserMatch(info, sbnLight,
+                                makeRankingUpdateForListener(info, sbns));
+                    }
+                });
             }
         }
 
@@ -2526,60 +2562,52 @@
          *             must not rely on mutable members of these objects, such as the
          *             {@link Notification}.
          */
-        public void notifyOrderUpdateLocked(final ArrayList<StatusBarNotification> sbns) {
+        public void notifyRankingUpdateLocked(final ArrayList<StatusBarNotification> sbns) {
             for (final ManagedServiceInfo serviceInfo : mServices) {
+                if (!serviceInfo.isEnabledForCurrentProfiles()) {
+                    continue;
+                }
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        notifyOrderUpdateIfUserMatch(serviceInfo, sbns);
+                        notifyRankingUpdate(serviceInfo,
+                                makeRankingUpdateForListener(serviceInfo, sbns));
                     }
                 });
             }
         }
 
         private void notifyPostedIfUserMatch(final ManagedServiceInfo info,
-                final StatusBarNotification sbn, String[] keys) {
+                final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
             if (!info.enabledAndUserMatches(sbn.getUserId())) {
                 return;
             }
             final INotificationListener listener = (INotificationListener)info.service;
             try {
-                listener.onNotificationPosted(sbn, new NotificationOrderUpdate(keys));
+                listener.onNotificationPosted(sbn, rankingUpdate);
             } catch (RemoteException ex) {
                 Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
             }
         }
 
         private void notifyRemovedIfUserMatch(ManagedServiceInfo info, StatusBarNotification sbn,
-                String[] keys) {
+                NotificationRankingUpdate rankingUpdate) {
             if (!info.enabledAndUserMatches(sbn.getUserId())) {
                 return;
             }
-            final INotificationListener listener = (INotificationListener)info.service;
+            final INotificationListener listener = (INotificationListener) info.service;
             try {
-                listener.onNotificationRemoved(sbn, new NotificationOrderUpdate(keys));
+                listener.onNotificationRemoved(sbn, rankingUpdate);
             } catch (RemoteException ex) {
                 Log.e(TAG, "unable to notify listener (removed): " + listener, ex);
             }
         }
 
-        /**
-         * @param sbns an array of {@link StatusBarNotification}s to consider.  This code
-         *             must not rely on mutable members of these objects, such as the
-         *             {@link Notification}.
-         */
-        public void notifyOrderUpdateIfUserMatch(ManagedServiceInfo info,
-                ArrayList<StatusBarNotification> sbns) {
-            ArrayList<String> keys = new ArrayList<String>(sbns.size());
-            for (StatusBarNotification sbn: sbns) {
-                if (info.enabledAndUserMatches(sbn.getUserId())) {
-                    keys.add(sbn.getKey());
-                }
-            }
-            final INotificationListener listener = (INotificationListener)info.service;
+        private void notifyRankingUpdate(ManagedServiceInfo info,
+                                         NotificationRankingUpdate rankingUpdate) {
+            final INotificationListener listener = (INotificationListener) info.service;
             try {
-                listener.onNotificationOrderUpdate(
-                        new NotificationOrderUpdate(keys.toArray(new String[keys.size()])));
+                listener.onNotificationRankingUpdate(rankingUpdate);
             } catch (RemoteException ex) {
                 Log.e(TAG, "unable to notify listener (ranking update): " + listener, ex);
             }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 9b3f7ac..6be073c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -125,7 +125,7 @@
     private static final String WIFI_SERVICE_CLASS =
             "com.android.server.wifi.WifiService";
     private static final String WIFI_PASSPOINT_SERVICE_CLASS =
-            "com.android.server.wifi.passpoint.WifiPasspointService";
+            "com.android.server.wifi.passpoint.PasspointService";
     private static final String WIFI_P2P_SERVICE_CLASS =
             "com.android.server.wifi.p2p.WifiP2pService";
     private static final String HDMI_CEC_SERVICE_CLASS =
diff --git a/tests/RenderThreadTest/Android.mk b/tests/RenderThreadTest/Android.mk
index bdcba2e..e07e943 100644
--- a/tests/RenderThreadTest/Android.mk
+++ b/tests/RenderThreadTest/Android.mk
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
 
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/RenderThreadTest/AndroidManifest.xml b/tests/RenderThreadTest/AndroidManifest.xml
index c76cfce..a7f4f6e 100644
--- a/tests/RenderThreadTest/AndroidManifest.xml
+++ b/tests/RenderThreadTest/AndroidManifest.xml
@@ -4,10 +4,6 @@
     android:versionCode="1"
     android:versionName="1.0" >
 
-    <uses-sdk
-        android:minSdkVersion="18"
-        android:targetSdkVersion="18" />
-
     <application
         android:allowBackup="true"
         android:icon="@drawable/ic_launcher"