Merge "add a log for notification alerts." into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 51a1e79..7da4090 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12166,24 +12166,36 @@
     method public abstract void stop();
   }
 
+  public abstract interface Animatable2 implements android.graphics.drawable.Animatable {
+    method public abstract void clearAnimationCallbacks();
+    method public abstract void registerAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
+    method public abstract boolean unregisterAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
+  }
+
+  public static abstract class Animatable2.AnimationCallback {
+    ctor public Animatable2.AnimationCallback();
+    method public void onAnimationEnd(android.graphics.drawable.Drawable);
+    method public void onAnimationStart(android.graphics.drawable.Drawable);
+  }
+
   public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable {
     ctor public AnimatedStateListDrawable();
     method public void addState(int[], android.graphics.drawable.Drawable, int);
     method public void addTransition(int, int, T, boolean);
   }
 
-  public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable {
+  public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable2 {
     ctor public AnimatedVectorDrawable();
-    method public void addListener(android.animation.Animator.AnimatorListener);
+    method public void clearAnimationCallbacks();
     method public void draw(android.graphics.Canvas);
-    method public java.util.List<android.animation.Animator.AnimatorListener> getListeners();
     method public int getOpacity();
     method public boolean isRunning();
-    method public void removeListener(android.animation.Animator.AnimatorListener);
+    method public void registerAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void start();
     method public void stop();
+    method public boolean unregisterAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
   }
 
   public class AnimationDrawable extends android.graphics.drawable.DrawableContainer implements android.graphics.drawable.Animatable java.lang.Runnable {
@@ -35986,7 +35998,6 @@
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
     method public android.graphics.drawable.Drawable getBackground();
-    method public int getBackgroundColor();
     method public android.content.res.ColorStateList getBackgroundTintList();
     method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
     method public int getBaseline();
diff --git a/api/system-current.txt b/api/system-current.txt
index 7ce111c..319ad00 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -12479,24 +12479,36 @@
     method public abstract void stop();
   }
 
+  public abstract interface Animatable2 implements android.graphics.drawable.Animatable {
+    method public abstract void clearAnimationCallbacks();
+    method public abstract void registerAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
+    method public abstract boolean unregisterAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
+  }
+
+  public static abstract class Animatable2.AnimationCallback {
+    ctor public Animatable2.AnimationCallback();
+    method public void onAnimationEnd(android.graphics.drawable.Drawable);
+    method public void onAnimationStart(android.graphics.drawable.Drawable);
+  }
+
   public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable {
     ctor public AnimatedStateListDrawable();
     method public void addState(int[], android.graphics.drawable.Drawable, int);
     method public void addTransition(int, int, T, boolean);
   }
 
-  public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable {
+  public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable2 {
     ctor public AnimatedVectorDrawable();
-    method public void addListener(android.animation.Animator.AnimatorListener);
+    method public void clearAnimationCallbacks();
     method public void draw(android.graphics.Canvas);
-    method public java.util.List<android.animation.Animator.AnimatorListener> getListeners();
     method public int getOpacity();
     method public boolean isRunning();
-    method public void removeListener(android.animation.Animator.AnimatorListener);
+    method public void registerAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void start();
     method public void stop();
+    method public boolean unregisterAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
   }
 
   public class AnimationDrawable extends android.graphics.drawable.DrawableContainer implements android.graphics.drawable.Animatable java.lang.Runnable {
@@ -38251,7 +38263,6 @@
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
     method public android.graphics.drawable.Drawable getBackground();
-    method public int getBackgroundColor();
     method public android.content.res.ColorStateList getBackgroundTintList();
     method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
     method public int getBaseline();
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a572590..9a99a46 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2486,7 +2486,8 @@
         return true;
     }
 
-    /*package*/ Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException {
+    @Nullable
+    Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException {
         if (TRACE_FOR_PRELOAD) {
             // Log only framework resources
             if ((id >>> 24) == 0x1) {
@@ -2541,7 +2542,7 @@
         // Determine if the drawable has unresolved theme attributes. If it
         // does, we'll need to apply a theme and store it in a theme-specific
         // cache.
-        final boolean canApplyTheme = dr.canApplyTheme();
+        final boolean canApplyTheme = dr != null && dr.canApplyTheme();
         if (canApplyTheme && theme != null) {
             dr = dr.mutate();
             dr.applyTheme(theme);
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 7b0f1fb..37e4000 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -516,8 +516,8 @@
     }
 
     /**
-     * Return whether the stylus scale gesture, in which the user uses a stylus
-     * and presses the button, should preform scaling. {@see #setButtonScaleEnabled(boolean)}.
+     * Return whether the stylus scale gesture, in which the user uses a stylus and presses the
+     * button, should perform scaling. {@see #setStylusScaleEnabled(boolean)}
      */
     public boolean isStylusScaleEnabled() {
         return mStylusScaleEnabled;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 126540f..9269fd2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17148,6 +17148,7 @@
      * drawable.
      *
      * @return The color of the ColorDrawable background, if set, otherwise 0.
+     * @hide
      */
     @ColorInt
     public int getBackgroundColor() {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 0c4b1e1..c8d8241 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -125,6 +125,15 @@
     // Tag used when the Editor maintains its own separate UndoManager.
     private static final String UNDO_OWNER_TAG = "Editor";
 
+    // Ordering constants used to place the Action Mode items in their menu.
+    private static final int MENU_ITEM_ORDER_CUT = 1;
+    private static final int MENU_ITEM_ORDER_COPY = 2;
+    private static final int MENU_ITEM_ORDER_PASTE = 3;
+    private static final int MENU_ITEM_ORDER_SHARE = 4;
+    private static final int MENU_ITEM_ORDER_SELECT_ALL = 5;
+    private static final int MENU_ITEM_ORDER_REPLACE = 6;
+    private static final int MENU_ITEM_ORDER_PROCESS_TEXT_INTENT_ACTIONS_START = 10;
+
     // Each Editor manages its own undo stack.
     private final UndoManager mUndoManager = new UndoManager();
     private UndoOwner mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this);
@@ -3160,34 +3169,33 @@
 
         private void populateMenuWithItems(Menu menu) {
             if (mTextView.canCut()) {
-                menu.add(0, TextView.ID_CUT, 0, com.android.internal.R.string.cut).
+                menu.add(Menu.NONE, TextView.ID_CUT, MENU_ITEM_ORDER_CUT,
+                        com.android.internal.R.string.cut).
                     setAlphabeticShortcut('x').
                     setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
             }
 
             if (mTextView.canCopy()) {
-                menu.add(0, TextView.ID_COPY, 0, com.android.internal.R.string.copy).
+                menu.add(Menu.NONE, TextView.ID_COPY, MENU_ITEM_ORDER_COPY,
+                        com.android.internal.R.string.copy).
                     setAlphabeticShortcut('c').
                     setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
             }
 
             if (mTextView.canPaste()) {
-                menu.add(0, TextView.ID_PASTE, 0, com.android.internal.R.string.paste).
-                        setAlphabeticShortcut('v').
-                        setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+                menu.add(Menu.NONE, TextView.ID_PASTE, MENU_ITEM_ORDER_PASTE,
+                        com.android.internal.R.string.paste).
+                    setAlphabeticShortcut('v').
+                    setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
             }
 
             if (mTextView.canShare()) {
-                menu.add(0, TextView.ID_SHARE, 0, com.android.internal.R.string.share).
-                        setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+                menu.add(Menu.NONE, TextView.ID_SHARE, MENU_ITEM_ORDER_SHARE,
+                        com.android.internal.R.string.share).
+                    setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
             }
 
-            if (mTextView.canSelectAllText()) {
-                menu.add(0, TextView.ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
-                        setAlphabeticShortcut('a').
-                        setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-            }
-
+            updateSelectAllItem(menu);
             updateReplaceItem(menu);
         }
 
@@ -3196,8 +3204,11 @@
                 PackageManager packageManager = mTextView.getContext().getPackageManager();
                 List<ResolveInfo> supportedActivities =
                         packageManager.queryIntentActivities(createProcessTextIntent(), 0);
-                for (ResolveInfo info : supportedActivities) {
-                    menu.add(info.loadLabel(packageManager))
+                for (int i = 0; i < supportedActivities.size(); ++i) {
+                    ResolveInfo info = supportedActivities.get(i);
+                    menu.add(Menu.NONE, Menu.NONE,
+                            MENU_ITEM_ORDER_PROCESS_TEXT_INTENT_ACTIONS_START + i,
+                            info.loadLabel(packageManager))
                         .setIntent(createProcessTextIntentForResolveInfo(info))
                         .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
                 }
@@ -3218,6 +3229,7 @@
 
         @Override
         public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            updateSelectAllItem(menu);
             updateReplaceItem(menu);
 
             Callback customCallback = getCustomCallback();
@@ -3227,12 +3239,25 @@
             return true;
         }
 
+        private void updateSelectAllItem(Menu menu) {
+            boolean canSelectAll = mTextView.canSelectAllText();
+            boolean selectAllItemExists = menu.findItem(TextView.ID_SELECT_ALL) != null;
+            if (canSelectAll && !selectAllItemExists) {
+                menu.add(Menu.NONE, TextView.ID_SELECT_ALL, MENU_ITEM_ORDER_SELECT_ALL,
+                        com.android.internal.R.string.selectAll)
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            } else if (!canSelectAll && selectAllItemExists) {
+                menu.removeItem(TextView.ID_SELECT_ALL);
+            }
+        }
+
         private void updateReplaceItem(Menu menu) {
             boolean canReplace = mTextView.isSuggestionsEnabled() && shouldOfferToShowSuggestions();
             boolean replaceItemExists = menu.findItem(TextView.ID_REPLACE) != null;
             if (canReplace && !replaceItemExists) {
-                menu.add(0, TextView.ID_REPLACE, 0, com.android.internal.R.string.replace).
-                    setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+                menu.add(Menu.NONE, TextView.ID_REPLACE, MENU_ITEM_ORDER_REPLACE,
+                        com.android.internal.R.string.replace)
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
             } else if (!canReplace && replaceItemExists) {
                 menu.removeItem(TextView.ID_REPLACE);
             }
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index ca57d1a..11904e1 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Parcel;
 import android.os.Parcelable;
 import com.android.internal.R;
@@ -349,17 +350,24 @@
 
         if (getChildCount() > 0) {
             final View child = getChildAt(0);
-            int height = getMeasuredHeight();
+            final int height = getMeasuredHeight();
             if (child.getMeasuredHeight() < height) {
+                final int widthPadding;
+                final int heightPadding;
                 final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
+                if (targetSdkVersion >= VERSION_CODES.MNC) {
+                    widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
+                    heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
+                } else {
+                    widthPadding = mPaddingLeft + mPaddingRight;
+                    heightPadding = mPaddingTop + mPaddingBottom;
+                }
 
-                int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
-                        mPaddingLeft + mPaddingRight, lp.width);
-                height -= mPaddingTop;
-                height -= mPaddingBottom;
-                int childHeightMeasureSpec =
-                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
-
+                final int childWidthMeasureSpec = getChildMeasureSpec(
+                        widthMeasureSpec, widthPadding, lp.width);
+                final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        height - heightPadding, MeasureSpec.EXACTLY);
                 child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
             }
         }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b0411c9..b68934b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9342,7 +9342,8 @@
     }
 
     boolean canSelectAllText() {
-        return canSelectText() && !hasPasswordTransformationMethod();
+        return canSelectText() && !hasPasswordTransformationMethod()
+                && !(getSelectionStart() == 0 && getSelectionEnd() == mText.length());
     }
 
     boolean selectAllText() {
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 7782ed7..f89dced 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -194,7 +194,7 @@
     </style>
 
     <style name="TextAppearance.Material.Subhead.Inverse">
-        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
         <item name="textColorHint">?attr/textColorHintInverse</item>
         <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
         <item name="textColorLink">?attr/textColorLinkInverse</item>
diff --git a/graphics/java/android/graphics/drawable/Animatable2.java b/graphics/java/android/graphics/drawable/Animatable2.java
new file mode 100644
index 0000000..7c7e60e
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/Animatable2.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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.graphics.drawable;
+
+import android.annotation.NonNull;
+
+/**
+ * Abstract class that drawables supporting animations and callbacks should extend.
+ */
+public interface Animatable2 extends Animatable {
+
+    /**
+     * Adds a callback to listen to the animation events.
+     *
+     * @param callback Callback to add.
+     */
+    void registerAnimationCallback(@NonNull AnimationCallback callback);
+
+    /**
+     * Removes the specified animation callback.
+     *
+     * @param callback Callback to remove.
+     * @return {@code false} if callback didn't exist in the call back list, or {@code true} if
+     *         callback has been removed successfully.
+     */
+    boolean unregisterAnimationCallback(@NonNull AnimationCallback callback);
+
+    /**
+     * Removes all existing animation callbacks.
+     */
+    void clearAnimationCallbacks();
+
+    public static abstract class AnimationCallback {
+        /**
+         * Called when the animation starts.
+         *
+         * @param drawable The drawable started the animation.
+         */
+        public void onAnimationStart(Drawable drawable) {};
+        /**
+         * Called when the animation ends.
+         *
+         * @param drawable The drawable finished the animation.
+         */
+        public void onAnimationEnd(Drawable drawable) {};
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 100c2f4..96f86b4 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -16,6 +16,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.Animator.AnimatorListener;
 import android.annotation.NonNull;
@@ -42,7 +43,6 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.List;
 
 /**
  * This class uses {@link android.animation.ObjectAnimator} and
@@ -129,7 +129,7 @@
  * @attr ref android.R.styleable#AnimatedVectorDrawableTarget_name
  * @attr ref android.R.styleable#AnimatedVectorDrawableTarget_animation
  */
-public class AnimatedVectorDrawable extends Drawable implements Animatable {
+public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
     private static final String LOGTAG = "AnimatedVectorDrawable";
 
     private static final String ANIMATED_VECTOR = "animated-vector";
@@ -153,6 +153,10 @@
 
     private boolean mMutated;
 
+    /** Use a internal AnimatorListener to support callbacks during animation events. */
+    private ArrayList<Animatable2.AnimationCallback> mAnimationCallbacks = null;
+    private AnimatorListener mAnimatorListener = null;
+
     public AnimatedVectorDrawable() {
         this(null, null);
     }
@@ -380,36 +384,6 @@
         }
     }
 
-    /**
-     * Adds a listener to the set of listeners that are sent events through the life of an
-     * animation.
-     *
-     * @param listener the listener to be added to the current set of listeners for this animation.
-     */
-    public void addListener(AnimatorListener listener) {
-        mAnimatorSet.addListener(listener);
-    }
-
-    /**
-     * Removes a listener from the set listening to this animation.
-     *
-     * @param listener the listener to be removed from the current set of listeners for this
-     *                 animation.
-     */
-    public void removeListener(AnimatorListener listener) {
-        mAnimatorSet.removeListener(listener);
-    }
-
-    /**
-     * Gets the set of {@link android.animation.Animator.AnimatorListener} objects that are currently
-     * listening for events on this <code>AnimatedVectorDrawable</code> object.
-     *
-     * @return List<AnimatorListener> The set of listeners.
-     */
-    public List<AnimatorListener> getListeners() {
-        return mAnimatorSet.getListeners();
-    }
-
     private static class AnimatedVectorDrawableState extends ConstantState {
         int mChangingConfigurations;
         VectorDrawable mVectorDrawable;
@@ -674,4 +648,77 @@
             unscheduleSelf(what);
         }
     };
-}
+
+    @Override
+    public void registerAnimationCallback(@NonNull AnimationCallback callback) {
+        if (callback == null) {
+            return;
+        }
+
+        // Add listener accordingly.
+        if (mAnimationCallbacks == null) {
+            mAnimationCallbacks = new ArrayList<>();
+        }
+
+        mAnimationCallbacks.add(callback);
+
+        if (mAnimatorListener == null) {
+            // Create a animator listener and trigger the callback events when listener is
+            // triggered.
+            mAnimatorListener = new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    ArrayList<AnimationCallback> tmpCallbacks = new ArrayList<>(mAnimationCallbacks);
+                    int size = tmpCallbacks.size();
+                    for (int i = 0; i < size; i ++) {
+                        tmpCallbacks.get(i).onAnimationStart(AnimatedVectorDrawable.this);
+                    }
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    ArrayList<AnimationCallback> tmpCallbacks = new ArrayList<>(mAnimationCallbacks);
+                    int size = tmpCallbacks.size();
+                    for (int i = 0; i < size; i ++) {
+                        tmpCallbacks.get(i).onAnimationEnd(AnimatedVectorDrawable.this);
+                    }
+                }
+            };
+        }
+        mAnimatorSet.addListener(mAnimatorListener);
+    }
+
+    // A helper function to clean up the animator listener in the mAnimatorSet.
+    private void removeAnimatorSetListener() {
+        if (mAnimatorListener != null) {
+            mAnimatorSet.removeListener(mAnimatorListener);
+            mAnimatorListener = null;
+        }
+    }
+
+    @Override
+    public boolean unregisterAnimationCallback(@NonNull AnimationCallback callback) {
+        if (mAnimationCallbacks == null || callback == null) {
+            // Nothing to be removed.
+            return false;
+        }
+        boolean removed = mAnimationCallbacks.remove(callback);
+
+        //  When the last call back unregistered, remove the listener accordingly.
+        if (mAnimationCallbacks.size() == 0) {
+            removeAnimatorSetListener();
+        }
+        return removed;
+    }
+
+    @Override
+    public void clearAnimationCallbacks() {
+        removeAnimatorSetListener();
+        if (mAnimationCallbacks == null) {
+            return;
+        }
+
+        mAnimationCallbacks.clear();
+    }
+
+}
\ No newline at end of file
diff --git a/media/java/android/media/tv/DvbDeviceInfo.java b/media/java/android/media/tv/DvbDeviceInfo.java
index 1885a34..e07f3a6 100644
--- a/media/java/android/media/tv/DvbDeviceInfo.java
+++ b/media/java/android/media/tv/DvbDeviceInfo.java
@@ -16,14 +16,10 @@
 
 package android.media.tv;
 
-import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.media.tv.TvInputManager;
 import android.util.Log;
 
-import java.lang.IllegalArgumentException;
-
 /**
  * Simple container for information about DVB device.
  * Not for third-party developers.
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index d480696..f75d601 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -27,7 +27,6 @@
 import android.graphics.Rect;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.media.PlaybackParams;
-import android.media.tv.TvInputService.HardwareSession;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -341,9 +340,13 @@
         }
 
         /**
-         * Notifies the channel of the session is retuned by TV input.
+         * Informs the application that the current channel is re-tuned for some reason and the
+         * session now displays the content from a new channel. This is used to handle special cases
+         * such as when the current channel becomes unavailable, it is necessary to send the user to
+         * a certain channel or the user changes channel in some other way (e.g. by using a
+         * dedicated remote).
          *
-         * @param channelUri The URI of a channel.
+         * @param channelUri The URI of the new channel.
          */
         public void notifyChannelRetuned(final Uri channelUri) {
             executeOrPostRunnable(new Runnable() {
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9f38185..a6313ad 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -341,9 +341,6 @@
     <!-- The grow amount for the camera and phone circles when hinting -->
     <dimen name="hint_grow_amount_sideways">60dp</dimen>
 
-    <!-- The chevron padding to the circle when hinting -->
-    <dimen name="hint_chevron_circle_padding">16dp</dimen>
-
     <!-- Distance between notifications and header when they are considered to be colliding. -->
     <dimen name="header_notifications_collide_distance">48dp</dimen>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 834d5dd..61ae9b9 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -644,7 +644,7 @@
     <!-- QuickSettings: Wifi (Off) [CHAR LIMIT=NONE] -->
     <string name="quick_settings_wifi_off_label">Wi-Fi Off</string>
     <!-- QuickSettings: Wifi detail panel, text when there are no items [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_wifi_detail_empty_text">No saved networks available</string>
+    <string name="quick_settings_wifi_detail_empty_text">No Wi-Fi networks available</string>
     <!-- QuickSettings: Cast title [CHAR LIMIT=NONE] -->
     <string name="quick_settings_cast_title">Cast</string>
     <!-- QuickSettings: Cast detail panel, status text when casting [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 0dcc0b9..86910fe 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -658,7 +658,7 @@
                 mPendingLock = true;
             }
 
-            if (mPendingLock || mPendingReset) {
+            if (mPendingLock) {
                 playSounds(true);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 062ded2..6db4020 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -26,6 +26,7 @@
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.RippleDrawable;
@@ -200,7 +201,8 @@
         mActivityDescription.setContentDescription(t.contentDescription);
 
         // Try and apply the system ui tint
-        int existingBgColor = getBackgroundColor();
+        int existingBgColor = (getBackground() instanceof ColorDrawable) ?
+                ((ColorDrawable) getBackground()).getColor() : 0;
         if (existingBgColor != t.colorPrimary) {
             mBackgroundColorDrawable.setColor(t.colorPrimary);
             mBackgroundColor = t.colorPrimary;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f05ac1a..6fb4b48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1902,7 +1902,7 @@
             logUpdate(entry, n);
         }
         boolean applyInPlace = shouldApplyInPlace(entry, n);
-        boolean shouldInterrupt = shouldInterrupt(notification);
+        boolean shouldInterrupt = shouldInterrupt(entry);
         boolean alertAgain = alertAgain(entry, n);
 
         entry.notification = notification;
@@ -2073,7 +2073,8 @@
                 || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
     }
 
-    protected boolean shouldInterrupt(StatusBarNotification sbn) {
+    protected boolean shouldInterrupt(Entry entry) {
+        StatusBarNotification sbn = entry.notification;
         if (mNotificationData.shouldFilterOut(sbn)) {
             if (DEBUG) {
                 Log.d(TAG, "Skipping HUN check for " + sbn.getKey() + " since it's filtered out.");
@@ -2098,10 +2099,12 @@
                 Notification.HEADS_UP_ALLOWED) != Notification.HEADS_UP_NEVER;
         boolean accessibilityForcesLaunch = isFullscreen
                 && mAccessibilityManager.isTouchExplorationEnabled();
+        boolean justLaunchedFullScreenIntent = entry.hasJustLaunchedFullScreenIntent();
 
         boolean interrupt = (isFullscreen || (isHighPriority && (isNoisy || hasTicker)))
                 && isAllowed
                 && !accessibilityForcesLaunch
+                && !justLaunchedFullScreenIntent
                 && mPowerManager.isScreenOn()
                 && (!mStatusBarKeyguardViewManager.isShowing()
                         || mStatusBarKeyguardViewManager.isOccluded())
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 374d970..58fb2b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -60,22 +60,18 @@
     private final int mNormalColor;
     private final ArgbEvaluator mColorInterpolator;
     private final FlingAnimationUtils mFlingAnimationUtils;
-    private final Drawable mArrowDrawable;
-    private final int mHintChevronPadding;
     private float mCircleRadius;
     private int mCenterX;
     private int mCenterY;
     private ValueAnimator mCircleAnimator;
     private ValueAnimator mAlphaAnimator;
     private ValueAnimator mScaleAnimator;
-    private ValueAnimator mArrowAnimator;
     private float mCircleStartValue;
     private boolean mCircleWillBeHidden;
     private int[] mTempPoint = new int[2];
     private float mImageScale;
     private int mCircleColor;
     private boolean mIsLeft;
-    private float mArrowAlpha = 0.0f;
     private View mPreviewView;
     private float mCircleStartRadius;
     private float mMaxCircleSize;
@@ -113,12 +109,6 @@
             mAlphaAnimator = null;
         }
     };
-    private AnimatorListenerAdapter mArrowEndListener = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mArrowAnimator = null;
-        }
-    };
 
     public KeyguardAffordanceView(Context context) {
         this(context, null);
@@ -144,17 +134,12 @@
         mInverseColor = 0xff000000;
         mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_affordance_min_background_radius);
-        mHintChevronPadding = mContext.getResources().getDimensionPixelSize(
-                R.dimen.hint_chevron_circle_padding);
         mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
                 android.R.interpolator.linear_out_slow_in);
         mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
                 android.R.interpolator.fast_out_linear_in);
         mColorInterpolator = new ArgbEvaluator();
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.3f);
-        mArrowDrawable = context.getDrawable(R.drawable.ic_chevron_left);
-        mArrowDrawable.setBounds(0, 0, mArrowDrawable.getIntrinsicWidth(),
-                mArrowDrawable.getIntrinsicHeight());
     }
 
     @Override
@@ -169,7 +154,6 @@
     protected void onDraw(Canvas canvas) {
         mSupportHardware = canvas.isHardwareAccelerated();
         drawBackgroundCircle(canvas);
-        drawArrow(canvas);
         canvas.save();
         canvas.scale(mImageScale, mImageScale, getWidth() / 2, getHeight() / 2);
         super.onDraw(canvas);
@@ -183,22 +167,6 @@
         }
     }
 
-    private void drawArrow(Canvas canvas) {
-        if (mArrowAlpha > 0) {
-            canvas.save();
-            canvas.translate(mCenterX, mCenterY);
-            if (mIsLeft) {
-                canvas.scale(-1.0f, 1.0f);
-            }
-            canvas.translate(- mCircleRadius - mHintChevronPadding
-                    - mArrowDrawable.getIntrinsicWidth() / 2,
-                    - mArrowDrawable.getIntrinsicHeight() / 2);
-            mArrowDrawable.setAlpha((int) (mArrowAlpha * 255));
-            mArrowDrawable.draw(canvas);
-            canvas.restore();
-        }
-    }
-
     private void updateIconColor() {
         Drawable drawable = getDrawable().mutate();
         float alpha = mCircleRadius / mMinBackgroundRadius;
@@ -533,36 +501,6 @@
         return mCircleRadius;
     }
 
-    public void showArrow(boolean show) {
-        cancelAnimator(mArrowAnimator);
-        float targetAlpha = show ? 1.0f : 0.0f;
-        if (mArrowAlpha == targetAlpha) {
-            return;
-        }
-        ValueAnimator animator = ValueAnimator.ofFloat(mArrowAlpha, targetAlpha);
-        mArrowAnimator = animator;
-        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                mArrowAlpha = (float) animation.getAnimatedValue();
-                invalidate();
-            }
-        });
-        animator.addListener(mArrowEndListener);
-        Interpolator interpolator = show
-                    ? mAppearInterpolator
-                    : mDisappearInterpolator;
-        animator.setInterpolator(interpolator);
-        float durationFactor = Math.abs(mArrowAlpha - targetAlpha);
-        long duration = (long) (NORMAL_ANIMATION_DURATION * durationFactor);
-        animator.setDuration(duration);
-        animator.start();
-    }
-
-    public void setIsLeft(boolean left) {
-        mIsLeft = left;
-    }
-
     @Override
     public boolean performClick() {
         if (isClickable()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 2a8b4ac..dbabe3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar;
 
 import android.app.Notification;
+import android.os.SystemClock;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.NotificationListenerService.RankingMap;
@@ -41,6 +42,8 @@
     private HeadsUpManager mHeadsUpManager;
 
     public static final class Entry {
+        private static final long LAUNCH_COOLDOWN = 2000;
+        private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN;
         public String key;
         public StatusBarNotification notification;
         public StatusBarIconView icon;
@@ -49,6 +52,7 @@
         public boolean autoRedacted; // whether the redacted notification was generated by us
         public boolean legacy; // whether the notification has a legacy, dark background
         public int targetSdk;
+        private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
 
         public Entry(StatusBarNotification n, StatusBarIconView ic) {
             this.key = n.getKey();
@@ -72,6 +76,7 @@
             // We should fix this at some point.
             autoRedacted = false;
             legacy = false;
+            lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
             if (row != null) {
                 row.reset();
             }
@@ -92,6 +97,14 @@
         public View getPublicContentView() {
             return row.getPublicLayout().getContractedChild();
         }
+
+        public void notifyFullScreenIntentLaunched() {
+            lastFullScreenIntentLaunchTime = SystemClock.elapsedRealtime();
+        }
+
+        public boolean hasJustLaunchedFullScreenIntent() {
+            return SystemClock.elapsedRealtime() < lastFullScreenIntentLaunchTime + LAUNCH_COOLDOWN;
+        }
     }
 
     private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 64735ee..0877ff9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -127,10 +127,8 @@
 
     private void initIcons() {
         mLeftIcon = mCallback.getLeftIcon();
-        mLeftIcon.setIsLeft(true);
         mCenterIcon = mCallback.getCenterIcon();
         mRightIcon = mCallback.getRightIcon();
-        mRightIcon.setIsLeft(false);
         updatePreviews();
     }
 
@@ -261,7 +259,6 @@
 
     private void startHintAnimationPhase1(final boolean right, final Runnable onFinishedListener) {
         final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
-        targetView.showArrow(true);
         ValueAnimator animator = getAnimatorToRadius(right, mHintGrowAmount);
         animator.addListener(new AnimatorListenerAdapter() {
             private boolean mCancelled;
@@ -277,7 +274,6 @@
                     mSwipeAnimator = null;
                     mTargetedView = null;
                     onFinishedListener.run();
-                    targetView.showArrow(false);
                 } else {
                     startUnlockHintAnimationPhase2(right, onFinishedListener);
                 }
@@ -301,14 +297,8 @@
             public void onAnimationEnd(Animator animation) {
                 mSwipeAnimator = null;
                 mTargetedView = null;
-                targetView.showArrow(false);
                 onFinishedListener.run();
             }
-
-            @Override
-            public void onAnimationStart(Animator animation) {
-                targetView.showArrow(false);
-            }
         });
         animator.setInterpolator(mDisappearInterpolator);
         animator.setDuration(HINT_PHASE2_DURATION);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index d5209ea..54bd3e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -229,10 +229,6 @@
 
     public void onTrackingStarted(PanelView panel) {
         mTracking = true;
-        if (DEBUG && panel != mTouchingPanel) {
-            LOG("shouldn't happen: onTrackingStarted(%s) != mTouchingPanel(%s)",
-                    panel, mTouchingPanel);
-        }
     }
 
     public void onTrackingStopped(PanelView panel, boolean expand) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 7c7bec9..984c201 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1153,7 +1153,7 @@
         if (shadeEntry == null) {
             return;
         }
-        boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(notification);
+        boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(shadeEntry);
         if (isHeadsUped) {
             mHeadsUpManager.showNotification(shadeEntry);
             // Mark as seen immediately
@@ -1171,6 +1171,7 @@
                 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
                         notification.getKey());
                 notification.getNotification().fullScreenIntent.send();
+                shadeEntry.notifyFullScreenIntentLaunched();
             } catch (PendingIntent.CanceledException e) {
             }
         }
@@ -2045,6 +2046,7 @@
                     EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
                             sbn.getKey());
                     notification.fullScreenIntent.send();
+                    entry.entry.notifyFullScreenIntentLaunched();
                 } catch (PendingIntent.CanceledException e) {
                 }
             }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 46793b9..8f8b1a4 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4093,7 +4093,12 @@
 
         // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we
         // need to provide information to the clients that want to pretend that you can draw there.
-        if (isDefaultDisplay && (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
+        // We only want to apply outsets to certain types of windows. For example, we never want to
+        // apply the outsets to floating dialogs, because they wouldn't make sense there.
+        final boolean useOutsets = attrs.type == TYPE_WALLPAPER
+                || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0;
+        if (isDefaultDisplay && useOutsets) {
             osf = mTmpOutsetFrame;
             osf.set(cf.left, cf.top, cf.right, cf.bottom);
             int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
index 56c8119..087e68a 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
@@ -14,10 +14,10 @@
 
 package com.android.test.dynamic;
 
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
 import android.app.Activity;
+import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
@@ -56,22 +56,15 @@
             button.setHeight(400);
             button.setBackgroundResource(icon[i]);
             AnimatedVectorDrawable d = (AnimatedVectorDrawable) button.getBackground();
-            d.addListener(new AnimatorListener() {
-                    @Override
-                public void onAnimationStart(Animator animation) {
+            d.registerAnimationCallback(new Animatable2.AnimationCallback() {
+                @Override
+                public void onAnimationStart(Drawable drawable) {
                     Log.v(LOGCAT, "Animator start");
                 }
-                    @Override
-                public void onAnimationRepeat(Animator animation) {
-                    Log.v(LOGCAT, "Animator repeat");
-                }
-                    @Override
-                public void onAnimationEnd(Animator animation) {
-                    Log.v(LOGCAT, "Animator end");
-                }
-                    @Override
-                public void onAnimationCancel(Animator animation) {
-                    Log.v(LOGCAT, "Animator cancel");
+
+                @Override
+                public void onAnimationEnd(Drawable drawable) {
+                        Log.v(LOGCAT, "Animator end");
                 }
             });