Inflate dismissal background instead of drawing while swiping

- Only swipe the foreground out to have the background revealed.
- Inflate dismissal_swipe_background.xml while swiping.
- Fix the fly-in transition.
- Fix the overlapping problem.

Bug: 129742618
Test: robotests
Change-Id: I5311e50332d0ea0437d1693d075d5c3a2176a443
diff --git a/res/layout/dismissal_swipe_background.xml b/res/layout/dismissal_swipe_background.xml
new file mode 100644
index 0000000..49e6129
--- /dev/null
+++ b/res/layout/dismissal_swipe_background.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/dismissal_swipe_background"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/homepage_card_dismissal_background">
+
+    <ImageView
+        android:id="@+id/dismissal_icon_start"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_delete"
+        android:layout_gravity="start|center_vertical"
+        android:layout_marginStart="@dimen/homepage_card_dismissal_side_margin"/>
+
+    <Space
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_weight="1"/>
+
+    <ImageView
+        android:id="@+id/dismissal_icon_end"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_delete"
+        android:layout_gravity="end|center_vertical"
+        android:layout_marginEnd="@dimen/homepage_card_dismissal_side_margin"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/homepage_slice_half_tile.xml b/res/layout/homepage_slice_half_tile.xml
index 8b6d415..205279d 100644
--- a/res/layout/homepage_slice_half_tile.xml
+++ b/res/layout/homepage_slice_half_tile.xml
@@ -21,41 +21,49 @@
     android:layout_height="wrap_content"
     style="@style/ContextualCardStyle">
 
-    <ViewFlipper
-        android:id="@+id/view_flipper"
+    <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
-        <LinearLayout
-            android:id="@+id/content"
+        <include layout="@layout/dismissal_swipe_background"/>
+
+        <ViewFlipper
+            android:id="@+id/view_flipper"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:paddingEnd="@dimen/homepage_card_padding_end"
-            android:paddingTop="@dimen/homepage_half_card_padding_top"
-            android:paddingBottom="@dimen/homepage_half_card_padding_bottom"
-            android:orientation="vertical">
+            android:layout_height="match_parent">
 
-            <ImageView
-                android:id="@android:id/icon"
-                android:layout_width="@dimen/homepage_card_icon_size"
-                android:layout_height="@dimen/homepage_card_icon_size"
-                android:layout_marginStart="@dimen/homepage_card_icon_padding_start"/>
-
-            <TextView
-                android:id="@android:id/title"
+            <LinearLayout
+                android:id="@+id/content"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:maxLines="2"
-                android:minLines="1"
-                android:ellipsize="end"
-                android:layout_marginStart="@dimen/homepage_card_text_padding_start"
-                android:layout_marginTop="@dimen/homepage_half_card_title_margin_top"
-                android:textAppearance="@style/TextAppearance.ConditionCardTitle"/>
+                android:layout_height="match_parent"
+                android:paddingEnd="@dimen/homepage_card_padding_end"
+                android:paddingTop="@dimen/homepage_half_card_padding_top"
+                android:paddingBottom="@dimen/homepage_half_card_padding_bottom"
+                android:background="@color/contextual_card_background"
+                android:orientation="vertical">
 
-        </LinearLayout>
+                <ImageView
+                    android:id="@android:id/icon"
+                    android:layout_width="@dimen/homepage_card_icon_size"
+                    android:layout_height="@dimen/homepage_card_icon_size"
+                    android:layout_marginStart="@dimen/homepage_card_icon_padding_start"/>
 
-        <!--dismissal view-->
-        <include layout="@layout/homepage_dismissal_view"/>
+                <TextView
+                    android:id="@android:id/title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:maxLines="2"
+                    android:minLines="1"
+                    android:ellipsize="end"
+                    android:layout_marginStart="@dimen/homepage_card_text_padding_start"
+                    android:layout_marginTop="@dimen/homepage_half_card_title_margin_top"
+                    android:textAppearance="@style/TextAppearance.ConditionCardTitle"/>
 
-    </ViewFlipper>
+            </LinearLayout>
+
+            <!--dismissal view-->
+            <include layout="@layout/homepage_dismissal_view"/>
+
+        </ViewFlipper>
+    </FrameLayout>
 </com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/res/layout/homepage_slice_tile.xml b/res/layout/homepage_slice_tile.xml
index ca8791f..b996c7e 100644
--- a/res/layout/homepage_slice_tile.xml
+++ b/res/layout/homepage_slice_tile.xml
@@ -21,21 +21,35 @@
     android:layout_height="wrap_content"
     style="@style/ContextualCardStyle">
 
-    <ViewFlipper
-        android:id="@+id/view_flipper"
+    <FrameLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="match_parent">
 
-        <androidx.slice.widget.SliceView
-            android:id="@+id/slice_view"
+        <include layout="@layout/dismissal_swipe_background"/>
+
+        <ViewFlipper
+            android:id="@+id/view_flipper"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:importantForAccessibility="no"
-            style="@style/SliceViewStyle"/>
+            android:layout_height="wrap_content">
 
-        <!--dismissal view-->
-        <include layout="@layout/homepage_dismissal_view"/>
+            <LinearLayout
+                android:id="@+id/slice_view_wrapper"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:background="@color/contextual_card_background">
 
-    </ViewFlipper>
+                <androidx.slice.widget.SliceView
+                    android:id="@+id/slice_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:importantForAccessibility="no"
+                    style="@style/SliceViewStyle"/>
+            </LinearLayout>
+
+            <!--dismissal view-->
+            <include layout="@layout/homepage_dismissal_view"/>
+
+        </ViewFlipper>
+    </FrameLayout>
 </com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8cd22fe..8c3a633 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -492,6 +492,7 @@
         <item name="android:paddingEnd">8dp</item>
 
         <item name="rowStyle">@style/SliceRowStyle</item>
+        <item name="android:background">@color/contextual_card_background</item>
     </style>
 
     <style name="SliceRowStyle">
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
index 3584578..ddfd20a 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.view.View;
+import android.widget.LinearLayout;
 
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.slice.Slice;
@@ -70,10 +71,12 @@
 
     static class SliceViewHolder extends RecyclerView.ViewHolder {
         public final SliceView sliceView;
+        public final LinearLayout sliceViewWrapper;
 
         public SliceViewHolder(View view) {
             super(view);
             sliceView = view.findViewById(R.id.slice_view);
+            sliceViewWrapper = view.findViewById(R.id.slice_view_wrapper);
         }
     }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java b/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java
index 3564189..c08cc5d 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java
@@ -18,9 +18,6 @@
 
 import android.content.Context;
 import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
 import android.view.View;
 import android.widget.ViewFlipper;
 
@@ -41,18 +38,10 @@
 
     private final Context mContext;
     private final SwipeDismissalDelegate.Listener mListener;
-    private final Drawable mIconDelete;
-    private final Paint mBgPaint;
-    private final int mBgCornerRadius;
 
     public SwipeDismissalDelegate(Context context, SwipeDismissalDelegate.Listener listener) {
         mContext = context;
         mListener = listener;
-        mIconDelete = mContext.getDrawable(R.drawable.ic_delete);
-        mBgPaint = new Paint();
-        mBgPaint.setColor(mContext.getColor(R.color.homepage_card_dismissal_background));
-        mBgCornerRadius = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.homepage_card_corner_radius);
     }
 
     /**
@@ -101,40 +90,48 @@
     }
 
     @Override
+    public void clearView(@NonNull RecyclerView recyclerView,
+            @NonNull RecyclerView.ViewHolder viewHolder) {
+        final View view = getSwipeableView(viewHolder);
+        getDefaultUIUtil().clearView(view);
+    }
+
+    @Override
     public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView,
             @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
             boolean isCurrentlyActive) {
-        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
+        final View view = getSwipeableView(viewHolder);
+        final View iconStart = viewHolder.itemView.findViewById(R.id.dismissal_icon_start);
+        final View iconEnd = viewHolder.itemView.findViewById(R.id.dismissal_icon_end);
 
-        final View itemView = viewHolder.itemView;
-        final int iconMargin = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.homepage_card_dismissal_side_margin);
-        final int iconTop =
-                itemView.getTop() + (itemView.getHeight() - mIconDelete.getIntrinsicHeight()) / 2;
-        final int iconBottom = iconTop + mIconDelete.getIntrinsicHeight();
-
-        if (dX > 0) { //swipe to the right
-            final int iconLeft = itemView.getLeft() + iconMargin;
-            final int iconRight = iconLeft + mIconDelete.getIntrinsicWidth();
-            final RectF rect = new RectF(itemView.getLeft(), itemView.getTop(),
-                    itemView.getLeft() + ((int) dX) + mBgCornerRadius, itemView.getBottom());
-            mIconDelete.setBounds(iconLeft, iconTop, iconRight, iconBottom);
-            c.drawRoundRect(rect, mBgCornerRadius, mBgCornerRadius, mBgPaint);
+        if (dX > 0) {
+            iconStart.setVisibility(View.VISIBLE);
+            iconEnd.setVisibility(View.GONE);
         } else if (dX < 0) {
-            final int iconRight = itemView.getRight() - iconMargin;
-            final int iconLeft = iconRight - mIconDelete.getIntrinsicWidth();
-            final RectF rect = new RectF(itemView.getRight() + ((int) dX), itemView.getTop(),
-                    itemView.getRight(), itemView.getBottom());
-            mIconDelete.setBounds(iconLeft, iconTop, iconRight, iconBottom);
-            c.drawRoundRect(rect, mBgCornerRadius, mBgCornerRadius, mBgPaint);
+            iconStart.setVisibility(View.GONE);
+            iconEnd.setVisibility(View.VISIBLE);
         }
-        mIconDelete.draw(c);
+        getDefaultUIUtil().onDraw(c, recyclerView, view, dX, dY, actionState, isCurrentlyActive);
     }
 
     private int getInitialViewId(RecyclerView.ViewHolder viewHolder) {
         if (viewHolder.getItemViewType() == SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH) {
             return R.id.content;
         }
-        return R.id.slice_view;
+        return R.id.slice_view_wrapper;
+    }
+
+    /**
+     * Get the foreground view from the {@link android.widget.FrameLayout} as we only swipe
+     * the foreground out in {@link SwipeDismissalDelegate#onChildDraw} and gets the view
+     * beneath revealed.
+     *
+     * @return The foreground view.
+     */
+    private View getSwipeableView(RecyclerView.ViewHolder viewHolder) {
+        if (viewHolder.getItemViewType() == SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH) {
+            return ((SliceHalfCardRendererHelper.HalfCardViewHolder) viewHolder).content;
+        }
+        return ((SliceFullCardRendererHelper.SliceViewHolder) viewHolder).sliceViewWrapper;
     }
 }
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
index 706f238..1f58550 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
@@ -149,7 +149,7 @@
 
         btnKeep.performClick();
 
-        assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
+        assertThat(viewFlipper.getCurrentView().getId()).isEqualTo(R.id.slice_view_wrapper);
     }
 
     @Test
@@ -204,7 +204,7 @@
 
         mRenderer.onStop();
 
-        assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
+        assertThat(viewFlipper.getCurrentView().getId()).isEqualTo(R.id.slice_view_wrapper);
     }
 
     private RecyclerView.ViewHolder getSliceViewHolder() {
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java
index 00b7815..d7df141 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java
@@ -99,9 +99,9 @@
         final RecyclerView.ViewHolder holder = getSliceViewHolder();
         final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper);
         viewFlipper.setDisplayedChild(0);
-        final View sliceView = holder.itemView.findViewById(R.id.slice_view);
+        final View sliceViewWrapper = holder.itemView.findViewById(R.id.slice_view_wrapper);
 
-        assertThat(viewFlipper.getCurrentView()).isEqualTo(sliceView);
+        assertThat(viewFlipper.getCurrentView()).isEqualTo(sliceViewWrapper);
         assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getSliceViewHolder()))
                 .isNotEqualTo(0);
     }