Introduce animation for changing top margin.

Change-Id: I7f77a1c69efc2dca3e5a37e7d6fc497ae487ec46
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 236e0e9..c040918 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1415,6 +1415,13 @@
         return mBouncerShowing;
     }
 
+    /**
+     * See {@link PowerManager#isInteractive()} for the meaning of this method.
+     */
+    public boolean isScreenTurnedOn() {
+        return mPowerManager.isInteractive();
+    }
+
     public void destroy() {
         if (mSearchPanelView != null) {
             mWindowManager.removeViewImmediate(mSearchPanelView);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index ec7d80a..b04977a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -79,7 +79,8 @@
                 ((MarginLayoutParams) mKeyguardStatusView.getLayoutParams()).bottomMargin;
         mNotificationStackScroller.setTopPadding(mStatusBar.getBarState() == StatusBarState.KEYGUARD
                 ? mKeyguardStatusView.getBottom() + keyguardBottomMargin
-                : mHeader.getBottom() + mNotificationTopPadding);
+                : mHeader.getBottom() + mNotificationTopPadding,
+                mStatusBar.isScreenTurnedOn() && mStatusBar.isExpandedVisible());
     }
 
     @Override
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 890d1bd..64906ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3195,6 +3195,10 @@
         }
     }
 
+    public boolean isExpandedVisible() {
+        return mExpandedVisible;
+    }
+
     public static boolean inBounds(View view, MotionEvent event, boolean orAbove) {
         final int[] location = new int[2];
         view.getLocationInWindow(location);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 8a49ded..0c37d00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -97,14 +97,15 @@
     private StackScrollState mCurrentStackScrollState = new StackScrollState(this);
     private ArrayList<View> mChildrenToAddAnimated = new ArrayList<View>();
     private ArrayList<View> mChildrenToRemoveAnimated = new ArrayList<View>();
-    private ArrayList<ChildHierarchyChangeEvent> mAnimationEvents
-            = new ArrayList<ChildHierarchyChangeEvent>();
+    private ArrayList<AnimationEvent> mAnimationEvents
+            = new ArrayList<AnimationEvent>();
     private ArrayList<View> mSwipedOutViews = new ArrayList<View>();
     private final StackStateAnimator mStateAnimator = new StackStateAnimator(this);
 
     private OnChildLocationsChangedListener mListener;
     private ExpandableView.OnHeightChangedListener mOnHeightChangedListener;
-    private boolean mChildHierarchyDirty;
+    private boolean mNeedsAnimation;
+    private boolean mTopPaddingNeedsAnimation;
     private boolean mIsExpanded = true;
     private boolean mChildrenUpdateRequested;
     private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
@@ -266,7 +267,7 @@
     private void updateChildren() {
         mCurrentStackScrollState.setScrollY(mOwnScrollY);
         mStackScrollAlgorithm.getStackScrollState(mCurrentStackScrollState);
-        if (!isCurrentlyAnimating() && !mChildHierarchyDirty) {
+        if (!isCurrentlyAnimating() && !mNeedsAnimation) {
             applyCurrentState();
         } else {
             startAnimationToState();
@@ -296,11 +297,15 @@
         return mTopPadding;
     }
 
-    public void setTopPadding(int topPadding) {
+    public void setTopPadding(int topPadding, boolean animate) {
         if (mTopPadding != topPadding) {
             mTopPadding = topPadding;
             updateAlgorithmHeightAndPadding();
             updateContentHeight();
+            if (animate) {
+                mTopPaddingNeedsAnimation = true;
+                mNeedsAnimation =  true;
+            }
             requestChildrenUpdate();
         }
     }
@@ -836,7 +841,7 @@
             if (!mChildrenToAddAnimated.contains(child)) {
                 // Generate Animations
                 mChildrenToRemoveAnimated.add(child);
-                mChildHierarchyDirty = true;
+                mNeedsAnimation = true;
             } else {
                 mChildrenToAddAnimated.remove(child);
             }
@@ -895,7 +900,7 @@
 
             // Generate Animations
             mChildrenToAddAnimated.add(child);
-            mChildHierarchyDirty = true;
+            mNeedsAnimation = true;
         }
     }
 
@@ -912,9 +917,9 @@
     }
 
     private void startAnimationToState() {
-        if (mChildHierarchyDirty) {
+        if (mNeedsAnimation) {
             generateChildHierarchyEvents();
-            mChildHierarchyDirty = false;
+            mNeedsAnimation = false;
         }
         if (!mAnimationEvents.isEmpty()) {
             mStateAnimator.startAnimationForEvents(mAnimationEvents, mCurrentStackScrollState);
@@ -926,16 +931,17 @@
     private void generateChildHierarchyEvents() {
         generateChildAdditionEvents();
         generateChildRemovalEvents();
-        mChildHierarchyDirty = false;
+        generateTopPaddingEvent();
+        mNeedsAnimation = false;
     }
 
     private void generateChildRemovalEvents() {
         for (View  child : mChildrenToRemoveAnimated) {
             boolean childWasSwipedOut = mSwipedOutViews.contains(child);
             int animationType = childWasSwipedOut
-                    ? ChildHierarchyChangeEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT
-                    : ChildHierarchyChangeEvent.ANIMATION_TYPE_REMOVE;
-            mAnimationEvents.add(new ChildHierarchyChangeEvent(child, animationType));
+                    ? AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT
+                    : AnimationEvent.ANIMATION_TYPE_REMOVE;
+            mAnimationEvents.add(new AnimationEvent(child, animationType));
         }
         mSwipedOutViews.clear();
         mChildrenToRemoveAnimated.clear();
@@ -943,12 +949,18 @@
 
     private void generateChildAdditionEvents() {
         for (View  child : mChildrenToAddAnimated) {
-            mAnimationEvents.add(new ChildHierarchyChangeEvent(child,
-                    ChildHierarchyChangeEvent.ANIMATION_TYPE_ADD));
+            mAnimationEvents.add(new AnimationEvent(child,
+                    AnimationEvent.ANIMATION_TYPE_ADD));
         }
         mChildrenToAddAnimated.clear();
     }
 
+    private void generateTopPaddingEvent() {
+        mAnimationEvents.add(
+                new AnimationEvent(null, AnimationEvent.ANIMATION_TYPE_TOP_PADDING_CHANGED));
+        mTopPaddingNeedsAnimation = false;
+    }
+
     private boolean onInterceptTouchEventScroll(MotionEvent ev) {
         /*
          * This method JUST determines whether we want to intercept the motion.
@@ -1150,16 +1162,18 @@
         public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout);
     }
 
-    static class ChildHierarchyChangeEvent {
+    static class AnimationEvent {
 
         static int ANIMATION_TYPE_ADD = 1;
         static int ANIMATION_TYPE_REMOVE = 2;
         static int ANIMATION_TYPE_REMOVE_SWIPED_OUT = 3;
+        static int ANIMATION_TYPE_TOP_PADDING_CHANGED = 4;
+
         final long eventStartTime;
         final View changingView;
         final int animationType;
 
-        ChildHierarchyChangeEvent(View view, int type) {
+        AnimationEvent(View view, int type) {
             eventStartTime = AnimationUtils.currentAnimationTimeMillis();
             changingView = view;
             animationType = type;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 24daa4f..620af0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.stack;
 
-import android.animation.Animator;
 import android.animation.ValueAnimator;
 import android.view.View;
 import android.view.animation.AnimationUtils;
@@ -35,7 +34,7 @@
     private final Interpolator mFastOutSlowInInterpolator;
     public NotificationStackScrollLayout mHostLayout;
     private boolean mAnimationIsRunning;
-    private ArrayList<NotificationStackScrollLayout.ChildHierarchyChangeEvent> mHandledEvents =
+    private ArrayList<NotificationStackScrollLayout.AnimationEvent> mHandledEvents =
             new ArrayList<>();
 
     public StackStateAnimator(NotificationStackScrollLayout hostLayout) {
@@ -49,7 +48,7 @@
     }
 
     public void startAnimationForEvents(
-            ArrayList<NotificationStackScrollLayout.ChildHierarchyChangeEvent> mAnimationEvents,
+            ArrayList<NotificationStackScrollLayout.AnimationEvent> mAnimationEvents,
             StackScrollState finalState) {
         int numEvents = mAnimationEvents.size();
         if (numEvents == 0) {
@@ -136,11 +135,11 @@
      * @param finalState the final state to animate to
      */
     private void initializeAddedViewStates(
-            ArrayList<NotificationStackScrollLayout.ChildHierarchyChangeEvent> animationEvents,
+            ArrayList<NotificationStackScrollLayout.AnimationEvent> animationEvents,
             StackScrollState finalState) {
-        for (NotificationStackScrollLayout.ChildHierarchyChangeEvent event: animationEvents) {
+        for (NotificationStackScrollLayout.AnimationEvent event: animationEvents) {
             View changingView = event.changingView;
-            if (event.animationType == NotificationStackScrollLayout.ChildHierarchyChangeEvent
+            if (event.animationType == NotificationStackScrollLayout.AnimationEvent
                     .ANIMATION_TYPE_ADD && !mHandledEvents.contains(event)) {
 
                 // This item is added, initialize it's properties.