Merge "Reset dismissal UI to the baseline when exiting the page."
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
index 4378be3..8720a3c 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java
@@ -69,9 +69,9 @@
             dbHelper.markContextualCardAsDismissed(mContext, card.getName());
         });
         showFeedbackDialog(card);
-        final ContextualCardFeatureProvider contexualCardFeatureProvider =
+        final ContextualCardFeatureProvider contextualCardFeatureProvider =
                 FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
-        contexualCardFeatureProvider.logContextualCardDismiss(mContext, card);
+        contextualCardFeatureProvider.logContextualCardDismiss(mContext, card);
     }
 
     @Override
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index a2d6e2b..4df2a04 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -28,8 +28,11 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
 import androidx.lifecycle.LifecycleOwner;
 import androidx.lifecycle.LiveData;
+import androidx.lifecycle.OnLifecycleEvent;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.slice.Slice;
 import androidx.slice.SliceItem;
@@ -51,13 +54,15 @@
  * Card renderer for {@link ContextualCard} built as slices.
  */
 public class SliceContextualCardRenderer implements ContextualCardRenderer,
-        SliceView.OnSliceActionListener {
+        SliceView.OnSliceActionListener, LifecycleObserver {
     public static final int VIEW_TYPE = R.layout.homepage_slice_tile;
 
     private static final String TAG = "SliceCardRenderer";
 
     @VisibleForTesting
     final Map<String, LiveData<Slice>> mSliceLiveDataMap;
+    @VisibleForTesting
+    final Set<SliceViewHolder> mFlippedCardSet;
 
     private final Context mContext;
     private final LifecycleOwner mLifecycleOwner;
@@ -71,6 +76,8 @@
         mSliceLiveDataMap = new ArrayMap<>();
         mControllerRendererPool = controllerRendererPool;
         mCardSet = new ArraySet<>();
+        mFlippedCardSet = new ArraySet<>();
+        mLifecycleOwner.getLifecycle().addObserver(this);
     }
 
     @Override
@@ -122,20 +129,23 @@
     }
 
     private void initDismissalActions(SliceViewHolder cardHolder, ContextualCard card) {
-        final ViewFlipper viewFlipper = cardHolder.itemView.findViewById(R.id.viewFlipper);
         cardHolder.sliceView.setOnLongClickListener(v -> {
-            viewFlipper.showNext();
+            cardHolder.viewFlipper.showNext();
+            mFlippedCardSet.add(cardHolder);
             return true;
         });
 
         final Button btnKeep = cardHolder.itemView.findViewById(R.id.keep);
         btnKeep.setOnClickListener(v -> {
-            viewFlipper.showPrevious();
+            cardHolder.resetCard();
+            mFlippedCardSet.remove(cardHolder);
         });
 
         final Button btnRemove = cardHolder.itemView.findViewById(R.id.remove);
         btnRemove.setOnClickListener(v -> {
             mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(card);
+            cardHolder.resetCard();
+            mFlippedCardSet.remove(cardHolder);
         });
     }
 
@@ -158,12 +168,24 @@
         }
     }
 
+    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+    public void onStop() {
+        mFlippedCardSet.stream().forEach(holder -> holder.resetCard());
+        mFlippedCardSet.clear();
+    }
+
     public static class SliceViewHolder extends RecyclerView.ViewHolder {
         public final SliceView sliceView;
+        public final ViewFlipper viewFlipper;
 
         public SliceViewHolder(View view) {
             super(view);
             sliceView = view.findViewById(R.id.slice_view);
+            viewFlipper = view.findViewById(R.id.viewFlipper);
+        }
+
+        public void resetCard() {
+            viewFlipper.setDisplayedChild(0);
         }
     }
 }
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 13a2bc5..11d0106 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
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
 import android.app.Activity;
@@ -51,10 +52,14 @@
 @RunWith(SettingsRobolectricTestRunner.class)
 public class SliceContextualCardRendererTest {
 
+    private static final String TEST_SLICE_URI = "content://test/test";
+
     @Mock
     private LiveData<Slice> mSliceLiveData;
     @Mock
     private ControllerRendererPool mControllerRendererPool;
+    @Mock
+    private SliceContextualCardController mController;
 
     private Activity mActivity;
     private SliceContextualCardRenderer mRenderer;
@@ -75,10 +80,9 @@
 
     @Test
     public void bindView_shouldSetScrollableToFalse() {
-        final String sliceUri = "content://com.android.settings.slices/action/flashlight";
         RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
 
-        mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
+        mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
 
         assertThat(
                 ((SliceContextualCardRenderer.SliceViewHolder) viewHolder).sliceView.isScrollable
@@ -99,64 +103,107 @@
 
     @Test
     public void bindView_newSliceLiveData_shouldAddDataToMap() {
-        final String sliceUri = "content://com.android.settings.slices/action/flashlight";
-
-        mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
+        mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
 
         assertThat(mRenderer.mSliceLiveDataMap.size()).isEqualTo(1);
     }
 
     @Test
     public void bindView_sliceLiveDataShouldObserveSliceView() {
-        final String sliceUri = "content://com.android.settings.slices/action/flashlight";
+        mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
 
-        mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
-
-        assertThat(mRenderer.mSliceLiveDataMap.get(sliceUri).hasObservers()).isTrue();
+        assertThat(mRenderer.mSliceLiveDataMap.get(TEST_SLICE_URI).hasObservers()).isTrue();
     }
 
     @Test
     public void bindView_sliceLiveDataShouldRemoveObservers() {
-        final String sliceUri = "content://com.android.settings.slices/action/flashlight";
-        mRenderer.mSliceLiveDataMap.put(sliceUri, mSliceLiveData);
+        mRenderer.mSliceLiveDataMap.put(TEST_SLICE_URI, mSliceLiveData);
 
-        mRenderer.bindView(getSliceViewHolder(), buildContextualCard(sliceUri));
+        mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
 
         verify(mSliceLiveData).removeObservers(mLifecycleOwner);
     }
 
     @Test
     public void longClick_shouldFlipCard() {
-        final String sliceUri = "content://com.android.settings.slices/action/flashlight";
         final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
         final View card = viewHolder.itemView.findViewById(R.id.slice_view);
         final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
         final View dismissalView = viewHolder.itemView.findViewById(R.id.dismissal_view);
-        mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
+        mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
 
-        assertThat(card).isNotNull();
         card.performLongClick();
 
         assertThat(viewFlipper.getCurrentView()).isEqualTo(dismissalView);
     }
 
     @Test
+    public void longClick_shouldAddViewHolderToSet() {
+        final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+        final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+        mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+        card.performLongClick();
+
+        assertThat(mRenderer.mFlippedCardSet).contains(viewHolder);
+    }
+
+    @Test
     public void viewClick_keepCard_shouldFlipBackToSlice() {
-        final String sliceUri = "content://com.android.settings.slices/action/flashlight";
         final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
         final View card = viewHolder.itemView.findViewById(R.id.slice_view);
         final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep);
         final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
-        mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
+        mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
 
-        assertThat(card).isNotNull();
         card.performLongClick();
-        assertThat(btnKeep).isNotNull();
         btnKeep.performClick();
 
         assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
     }
 
+    @Test
+    public void viewClick_keepCard_shouldRemoveViewHolderFromSet() {
+        final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+        final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+        final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep);
+        mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+        card.performLongClick();
+        btnKeep.performClick();
+
+        assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder);
+    }
+
+    @Test
+    public void viewClick_removeCard_shouldRemoveViewHolderFromSet() {
+        final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+        final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+        final Button btnRemove = viewHolder.itemView.findViewById(R.id.remove);
+        final ContextualCard contextualCard = buildContextualCard(TEST_SLICE_URI);
+        mRenderer.bindView(viewHolder, contextualCard);
+        doReturn(mController).when(mControllerRendererPool).getController(mActivity,
+                ContextualCard.CardType.SLICE);
+
+        card.performLongClick();
+        btnRemove.performClick();
+
+        assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder);
+    }
+
+    @Test
+    public void onStop_cardIsFlipped_shouldFlipBack() {
+        final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+        final View card = viewHolder.itemView.findViewById(R.id.slice_view);
+        final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.viewFlipper);
+        mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+        card.performLongClick();
+        mRenderer.onStop();
+
+        assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
+    }
+
     private RecyclerView.ViewHolder getSliceViewHolder() {
         final int viewType = mRenderer.getViewType(false /* isHalfWidth */);
         final RecyclerView recyclerView = new RecyclerView(mActivity);
@@ -169,6 +216,7 @@
     private ContextualCard buildContextualCard(String sliceUri) {
         return new ContextualCard.Builder()
                 .setName("test_name")
+                .setCardType(ContextualCard.CardType.SLICE)
                 .setSliceUri(Uri.parse(sliceUri))
                 .build();
     }