Reset dismissal UI to the baseline when exiting the page.

Flip the card back to slice view if users exit the page instead of
getting the dismissal UI preserved. We should also reset the UI to the baseline
if users dismiss a card, so when the view is reused, slice view can
then be displayed correctly.

Change-Id: If5448c57dec44ef5c1d3472358d4ddc9398538b8
Fixes: 119820168
Test: robotests
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();
     }