Use "mid" stable id for condition cards conditionally.

When there is no suggestion, use "mid" stableId instead of "top"
stableId for the header card.

This avoid an animation jank: when user swipes away a suggestion, the
condition summary header moves up instead of disappears then reappears.

Old behavior:

---  Suggestion ---   --swipe-->     /// Top Header ///
///  Mid Header ///

New behavior:

--- Suggestion ---   -- swipe -->   /// Mid Header ///
/// Mid Header ///

(Notice the header id change)

Change-Id: I63512d3d21382488e43dddb8819fabe4af40d101
Fixes: 65729560
Test: robotests
diff --git a/src/com/android/settings/dashboard/DashboardData.java b/src/com/android/settings/dashboard/DashboardData.java
index 0fac0a2..b60fef3 100644
--- a/src/com/android/settings/dashboard/DashboardData.java
+++ b/src/com/android/settings/dashboard/DashboardData.java
@@ -222,15 +222,22 @@
         final int hiddenSuggestion =
                 hasSuggestions ? sizeOf(mSuggestions) - sizeOf(suggestions) : 0;
 
+        final boolean hasSuggestionAndCollapsed = hasSuggestions
+                && mSuggestionConditionMode == HEADER_MODE_COLLAPSED;
+        final boolean onlyHasConditionAndCollapsed = !hasSuggestions
+                && hasConditions
+                && mSuggestionConditionMode != HEADER_MODE_FULLY_EXPANDED;
+
         /* Top suggestion/condition header. This will be present when there is any suggestion
-         * and the mode is collapsed, or it only has conditions and the mode is not fully
-         * expanded. */
+         * and the mode is collapsed */
         addToItemList(new SuggestionConditionHeaderData(conditions, hiddenSuggestion),
                 R.layout.suggestion_condition_header,
-                STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER,
-                hasSuggestions && mSuggestionConditionMode == HEADER_MODE_COLLAPSED
-                        || !hasSuggestions && hasConditions
-                        && mSuggestionConditionMode != HEADER_MODE_FULLY_EXPANDED);
+                STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER, hasSuggestionAndCollapsed);
+
+        /* Use mid header if there is only condition & it's in collapsed mode */
+        addToItemList(new SuggestionConditionHeaderData(conditions, hiddenSuggestion),
+                R.layout.suggestion_condition_header,
+                STABLE_ID_SUGGESTION_CONDITION_MIDDLE_HEADER, onlyHasConditionAndCollapsed);
 
         /* Suggestion container. This is the card view that contains the list of suggestions.
          * This will be added whenever the suggestion list is not empty */
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
index 77213f5..ad257ee 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
@@ -16,6 +16,13 @@
 
 package com.android.settings.dashboard;
 
+import static com.android.settings.dashboard.DashboardData.STABLE_ID_CONDITION_CONTAINER;
+import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_FOOTER;
+import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONTAINER;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.support.annotation.NonNull;
 import android.support.v7.util.DiffUtil;
 import android.support.v7.util.ListUpdateCallback;
@@ -39,15 +46,6 @@
 import java.util.List;
 import java.util.Objects;
 
-import static com.android.settings.dashboard.DashboardData.STABLE_ID_CONDITION_CONTAINER;
-import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_FOOTER;
-import static com.android.settings.dashboard.DashboardData
-        .STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER;
-import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONTAINER;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 @RunWith(RobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DashboardDataTest {
@@ -215,6 +213,38 @@
     }
 
     @Test
+    public void testDiffUtil_RemoveOneSuggestion_causeItemRemoveAndChange() {
+        //Build testResultData
+        final List<ListUpdateResult.ResultData> testResultData = new ArrayList<>();
+        testResultData.add(new ListUpdateResult.ResultData(
+                ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 1));
+        testResultData.add(new ListUpdateResult.ResultData(
+                ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 1, 1));
+        // Build DashboardData
+        final List<Condition> oneItemConditions = new ArrayList<>();
+        when(mTestCondition.shouldShow()).thenReturn(true);
+        oneItemConditions.add(mTestCondition);
+        final List<Tile> suggestions = new ArrayList<>();
+        mTestSuggestion.title = TEST_SUGGESTION_TITLE;
+        suggestions.add(mTestSuggestion);
+
+        final DashboardData oldData = new DashboardData.Builder()
+                .setConditions(oneItemConditions)
+                .setCategory(mDashboardCategory)
+                .setSuggestions(suggestions)
+                .setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT)
+                .build();
+        final DashboardData newData = new DashboardData.Builder()
+                .setConditions(oneItemConditions)
+                .setSuggestions(null)
+                .setCategory(mDashboardCategory)
+                .setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT)
+                .build();
+
+        testDiffUtil(oldData, newData, testResultData);
+    }
+
+    @Test
     public void testDiffUtil_DeleteAllData_ResultDataOneDeleted() {
         //Build testResultData
         final List<ListUpdateResult.ResultData> testResultData = new ArrayList<>();