Merge "Swipe notification to edge of screen" into sc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 3728388..609ca97c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -25,6 +25,7 @@
 import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 
 import com.android.systemui.R;
@@ -101,6 +102,28 @@
         }
     };
 
+    /**
+     * Get the relative start padding of a view relative to this view. This recursively walks up the
+     * hierarchy and does the corresponding measuring.
+     *
+     * @param view the view to get the padding for. The requested view has to be a child of this
+     *             notification.
+     * @return the start padding
+     */
+    public int getRelativeStartPadding(View view) {
+        boolean isRtl = isLayoutRtl();
+        int startPadding = 0;
+        while (view.getParent() instanceof ViewGroup) {
+            View parent = (View) view.getParent();
+            startPadding += isRtl ? parent.getWidth() - view.getRight() : view.getLeft();
+            view = parent;
+            if (view == this) {
+                return startPadding;
+            }
+        }
+        return startPadding;
+    }
+
     protected Path getClipPath(boolean ignoreTranslation) {
         int left;
         int top;
@@ -109,15 +132,17 @@
         int height;
         float topRoundness = mAlwaysRoundBothCorners
                 ? mOutlineRadius : getCurrentBackgroundRadiusTop();
+
         if (!mCustomOutline) {
-            int translation = mShouldTranslateContents && !ignoreTranslation
-                    ? (int) getTranslation() : 0;
-            int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
-            left = Math.max(translation, 0) - halfExtraWidth;
-            top = mClipTopAmount + mBackgroundTop;
-            right = getWidth() + halfExtraWidth + Math.min(translation, 0);
+            // Extend left/right clip bounds beyond the notification by the
+            // 1) space between the notification and edge of screen
+            // 2) corner radius (so we do not see any rounding as the notification goes off screen)
+            left = (int) (-getRelativeStartPadding(this) - mOutlineRadius);
+            right = (int) (((View) getParent()).getWidth() + mOutlineRadius);
+
             // If the top is rounded we want the bottom to be at most at the top roundness, in order
             // to avoid the shadow changing when scrolling up.
+            top = mClipTopAmount + mBackgroundTop;
             bottom = Math.max(mMinimumHeightForClipping,
                     Math.max(getActualHeight() - mClipBottomAmount, (int) (top + topRoundness)));
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 73e0804..1086d67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -69,6 +69,8 @@
     private float mContentTranslation;
     protected boolean mLastInSection;
     protected boolean mFirstInSection;
+    private float mOutlineRadius;
+    private float mParentWidth;
 
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -79,6 +81,7 @@
     private void initDimens() {
         mContentShift = getResources().getDimensionPixelSize(
                 R.dimen.shelf_transform_content_shift);
+        mOutlineRadius = getResources().getDimensionPixelSize(R.dimen.notification_corner_radius);
     }
 
     @Override
@@ -150,6 +153,9 @@
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
+        if (getParent() != null) {
+            mParentWidth = ((View) getParent()).getWidth();
+        }
         updateClipping();
     }
 
@@ -436,11 +442,15 @@
 
     protected void updateClipping() {
         if (mClipToActualHeight && shouldClipToActualHeight()) {
-            int top = getClipTopAmount();
-            int bottom = Math.max(Math.max(getActualHeight() + getExtraBottomPadding()
+            final int top = getClipTopAmount();
+            final int bottom = Math.max(Math.max(getActualHeight() + getExtraBottomPadding()
                     - mClipBottomAmount, top), mMinimumHeightForClipping);
-            int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
-            mClipRect.set(-halfExtraWidth, top, getWidth() + halfExtraWidth, bottom);
+            // Extend left/right clip bounds beyond the notification by the
+            // 1) space between the notification and edge of screen
+            // 2) corner radius (so we do not see any rounding as the notification goes off screen)
+            final int left = (int) (-getRelativeStartPadding(this) - mOutlineRadius);
+            final int right = (int) (mParentWidth + mOutlineRadius);
+            mClipRect.set(left, top, right, bottom);
             setClipBounds(mClipRect);
         } else {
             setClipBounds(null);