All Apps header shadow is drawn incorrectly

Bug: 29777304
Change-Id: I9ead05b28d1d57dd6a157126637296a97e3f7058
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index d1da6d9..937485f 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -459,6 +459,16 @@
         lp.leftMargin = bgPadding.left;
         lp.rightMargin = bgPadding.right;
 
+        // Clip the view to the left and right edge of the background to
+        // to prevent shadows from rendering beyond the edges
+        final Rect newClipBounds = new Rect(
+                bgPadding.left,
+                0,
+                getWidth() - bgPadding.right,
+                getHeight()
+        );
+        setClipBounds(newClipBounds);
+
         DeviceProfile grid = mLauncher.getDeviceProfile();
         if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
             if (!grid.isVerticalBarLayout()) {
diff --git a/src/com/android/launcher3/allapps/HeaderElevationController.java b/src/com/android/launcher3/allapps/HeaderElevationController.java
index 07f583c..e8f74eb 100644
--- a/src/com/android/launcher3/allapps/HeaderElevationController.java
+++ b/src/com/android/launcher3/allapps/HeaderElevationController.java
@@ -2,6 +2,7 @@
 
 import android.annotation.TargetApi;
 import android.content.res.Resources;
+import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.drawable.GradientDrawable;
 import android.os.Build;
@@ -82,11 +83,31 @@
 
         public ControllerVL(View header) {
             mHeader = header;
-            mHeader.setOutlineProvider(ViewOutlineProvider.BOUNDS);
-
-            Resources res = header.getContext().getResources();
+            Resources res = mHeader.getContext().getResources();
             mMaxElevation = res.getDimension(R.dimen.all_apps_header_max_elevation);
             mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation);
+
+            // We need to provide a custom outline so the shadow only appears on the bottom edge.
+            // The top, left and right edges are all extended out, and the shadow is clipped
+            // by the parent.
+            final ViewOutlineProvider vop = new ViewOutlineProvider() {
+                @Override
+                public void getOutline(View view, Outline outline) {
+                    final View parent = (View) mHeader.getParent();
+
+                    final int left = parent.getLeft(); // Use the parent to account for offsets
+                    final int top = view.getTop();
+                    final int right = left + view.getWidth();
+                    final int bottom = view.getBottom();
+
+                    outline.setRect(
+                            left - (int) mMaxElevation,
+                            top - (int) mMaxElevation,
+                            right + (int) mMaxElevation,
+                            bottom);
+                }
+            };
+            mHeader.setOutlineProvider(vop);
         }
 
         @Override