Merge changes from topic "am-a1205538-cc32-4ec0-9e68-c68e2ae82db6"

* changes:
  [automerger] Support list styles for PagedListView. am: d0e9e80e8d
  Support list styles for PagedListView.
diff --git a/car/build.gradle b/car/build.gradle
index 7ea0873..6aa1865 100644
--- a/car/build.gradle
+++ b/car/build.gradle
@@ -18,6 +18,10 @@
     androidTestImplementation(ESPRESSO_CONTRIB, libs.exclude_support)
     androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
     androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+
+    testImplementation(JUNIT)
+    testImplementation(TEST_RUNNER)
+    testImplementation(MOCKITO_CORE)
 }
 
 android {
diff --git a/car/res/layout/car_paged_list_item.xml b/car/res/drawable/car_card_background.xml
similarity index 70%
rename from car/res/layout/car_paged_list_item.xml
rename to car/res/drawable/car_card_background.xml
index c0861d9..7caa2ff 100644
--- a/car/res/layout/car_paged_list_item.xml
+++ b/car/res/drawable/car_card_background.xml
@@ -14,12 +14,6 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:background="@color/car_card">
-
-    <include layout="@layout/car_paged_list_item_content" />
-
-</FrameLayout>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/car_card"/>
+</shape>
\ No newline at end of file
diff --git a/car/res/layout/car_paged_list_item.xml b/car/res/drawable/car_card_rounded_background.xml
similarity index 70%
copy from car/res/layout/car_paged_list_item.xml
copy to car/res/drawable/car_card_rounded_background.xml
index c0861d9..594705b 100644
--- a/car/res/layout/car_paged_list_item.xml
+++ b/car/res/drawable/car_card_rounded_background.xml
@@ -14,12 +14,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:background="@color/car_card">
-
-    <include layout="@layout/car_paged_list_item_content" />
-
-</FrameLayout>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/car_card"/>
+    <corners
+        android:radius="@dimen/car_radius_3"/>
+</shape>
\ No newline at end of file
diff --git a/car/res/layout/car_paged_list_item.xml b/car/res/drawable/car_card_rounded_bottom_background.xml
similarity index 70%
copy from car/res/layout/car_paged_list_item.xml
copy to car/res/drawable/car_card_rounded_bottom_background.xml
index c0861d9..35dba13 100644
--- a/car/res/layout/car_paged_list_item.xml
+++ b/car/res/drawable/car_card_rounded_bottom_background.xml
@@ -14,12 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:background="@color/car_card">
-
-    <include layout="@layout/car_paged_list_item_content" />
-
-</FrameLayout>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/car_card"/>
+    <corners
+        android:bottomRightRadius="@dimen/car_radius_3"
+        android:bottomLeftRadius="@dimen/car_radius_3"/>
+</shape>
\ No newline at end of file
diff --git a/car/res/layout/car_paged_list_item.xml b/car/res/drawable/car_card_rounded_top_background.xml
similarity index 70%
copy from car/res/layout/car_paged_list_item.xml
copy to car/res/drawable/car_card_rounded_top_background.xml
index c0861d9..dfb5622 100644
--- a/car/res/layout/car_paged_list_item.xml
+++ b/car/res/drawable/car_card_rounded_top_background.xml
@@ -14,12 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:background="@color/car_card">
-
-    <include layout="@layout/car_paged_list_item_content" />
-
-</FrameLayout>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/car_card"/>
+    <corners
+        android:topRightRadius="@dimen/car_radius_3"
+        android:topLeftRadius="@dimen/car_radius_3"/>
+</shape>
\ No newline at end of file
diff --git a/car/res/layout/car_paged_list_card.xml b/car/res/layout/car_paged_list_card.xml
deleted file mode 100644
index fe5de89..0000000
--- a/car/res/layout/car_paged_list_card.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2017 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.
-  -->
-<android.support.v7.widget.CardView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:layout_marginBottom="@dimen/car_padding_1"
-    app:cardCornerRadius="@dimen/car_radius_1"
-    app:cardBackgroundColor="@color/car_card">
-
-    <include layout="@layout/car_paged_list_item_content" />
-
-</android.support.v7.widget.CardView>
diff --git a/car/src/main/java/androidx/car/utils/ListItemBackgroundResolver.java b/car/src/main/java/androidx/car/utils/ListItemBackgroundResolver.java
new file mode 100644
index 0000000..406c047
--- /dev/null
+++ b/car/src/main/java/androidx/car/utils/ListItemBackgroundResolver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017 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.
+ */
+
+package androidx.car.utils;
+
+import android.view.View;
+
+import androidx.car.R;
+
+/**
+ * A utility class that will set the current background for a View that represents an card entry
+ * in a list. The class will set the background depending on the position of the card within the
+ * list.
+ */
+public class ListItemBackgroundResolver {
+    private ListItemBackgroundResolver() {}
+
+    /**
+     * Sets the background on the given view so that the combination of all items looks like a
+     * rectangle with rounded corner. The view is assumed to have a non-rounded corner outline.
+     *
+     * <p>The view will be set with rounded backgrounds if it is the only card within the list.
+     * Or if it is the first or last view, it will have the top or bottom corners rounded
+     * respectively.
+     *
+     * @param view The view whose background to set.
+     * @param currentPosition The current position of the View within the list. This value should
+     *                        be 0-based.
+     * @param totalItems The total items within the list.
+     */
+    public static void setBackground(View view, int currentPosition, int totalItems) {
+        if (currentPosition < 0) {
+            throw new IllegalArgumentException("currentPosition cannot be less than zero.");
+        }
+
+        if (currentPosition >= totalItems) {
+            throw new IndexOutOfBoundsException("currentPosition: " + currentPosition + "; "
+                    + "totalItems: " + totalItems);
+        }
+
+        // Set the background for each card. Only the top and last card should have rounded corners.
+        if (totalItems == 1) {
+            // One card - all corners are rounded.
+            view.setBackgroundResource(R.drawable.car_card_rounded_background);
+        } else if (currentPosition == 0) {
+            // First card gets rounded top.
+            view.setBackgroundResource(R.drawable.car_card_rounded_top_background);
+        } else if (currentPosition == totalItems - 1) {
+            // Last one has a rounded bottom.
+            view.setBackgroundResource(R.drawable.car_card_rounded_bottom_background);
+        } else {
+            // Middle has no rounded corners.
+            view.setBackgroundResource(R.drawable.car_card_background);
+        }
+    }
+}
+
diff --git a/car/src/main/java/androidx/car/widget/ListItem.java b/car/src/main/java/androidx/car/widget/ListItem.java
index 08cc48e..d292d6b 100644
--- a/car/src/main/java/androidx/car/widget/ListItem.java
+++ b/car/src/main/java/androidx/car/widget/ListItem.java
@@ -94,16 +94,6 @@
     }
 
     /**
-     * Used by {@link ListItemAdapter} to choose layout to inflate for view holder.
-     * New view type needs support in {@link ListItemAdapter}.
-     */
-    protected int getViewType() {
-        return mBuilder.mIsCard
-                ? ListItemAdapter.CAR_PAGED_LIST_CARD
-                : ListItemAdapter.CAR_PAGED_LIST_ITEM;
-    }
-
-    /**
      * Functional interface to provide a way to interact with views in
      * {@link ListItemAdapter.ViewHolder}. {@code ViewBinder}s added to a
      * {@code ListItem} will be called when {@code ListItem} {@code bind}s to
@@ -150,8 +140,6 @@
         // Store custom binders separately so they will bind after binders are created in build().
         private final List<ViewBinder> mCustomBinders = new ArrayList<>();
 
-        private boolean mIsCard;
-
         private View.OnClickListener mOnClickListener;
 
         @PrimaryActionType private int mPrimaryActionType = PRIMARY_ACTION_TYPE_NO_ICON;
@@ -499,18 +487,6 @@
         }
 
         /**
-         * Builds the item in a {@link android.support.v7.widget.CardView}.
-         *
-         * <p>Each item will have rounded corner, margin between items, and elevation.
-         *
-         * @return This Builder object to allow for chaining calls to set methods.
-         */
-        public Builder withCardLook() {
-            mIsCard = true;
-            return this;
-        }
-
-        /**
          * Sets {@link View.OnClickListener} of {@code ListItem}.
          *
          * @return This Builder object to allow for chaining calls to set methods.
diff --git a/car/src/main/java/androidx/car/widget/ListItemAdapter.java b/car/src/main/java/androidx/car/widget/ListItemAdapter.java
index 2bdfae6..c9b6177 100644
--- a/car/src/main/java/androidx/car/widget/ListItemAdapter.java
+++ b/car/src/main/java/androidx/car/widget/ListItemAdapter.java
@@ -16,22 +16,20 @@
 
 package androidx.car.widget;
 
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
 import android.content.Context;
-import android.support.annotation.IntDef;
+import android.support.v7.widget.CardView;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import java.lang.annotation.Retention;
-
 import androidx.car.R;
+import androidx.car.utils.ListItemBackgroundResolver;
 
 /**
  * Adapter for {@link PagedListView} to display {@link ListItem}.
@@ -40,11 +38,30 @@
  */
 public class ListItemAdapter extends
         RecyclerView.Adapter<ListItemAdapter.ViewHolder> implements PagedListView.ItemCap {
-    @Retention(SOURCE)
-    @IntDef({CAR_PAGED_LIST_ITEM, CAR_PAGED_LIST_CARD})
-    public @interface PagedListItemType {}
-    public static final int CAR_PAGED_LIST_ITEM = 0;
-    public static final int CAR_PAGED_LIST_CARD = 1;
+
+    /**
+     * Constant class for background style of items.
+     */
+    public static final class BackgroundStyle {
+        private BackgroundStyle() {}
+
+        /**
+         * Sets the background color of each item.
+         */
+        public static final int NONE = 0;
+        /**
+         * Sets each item in {@link CardView} with a rounded corner background and shadow.
+         */
+        public static final int CARD = 1;
+        /**
+         * Sets background of each item so the combined list looks like one elongated card, namely
+         * top and bottom item will have rounded corner at only top/bottom side respectively. If
+         * only one item exists, it will have both top and bottom rounded corner.
+         */
+        public static final int PANEL = 2;
+    }
+
+    private int mBackgroundStyle;
 
     private final Context mContext;
     private final ListItemProvider mItemProvider;
@@ -52,37 +69,66 @@
     private int mMaxItems = PagedListView.ItemCap.UNLIMITED;
 
     public ListItemAdapter(Context context, ListItemProvider itemProvider) {
+        this(context, itemProvider, BackgroundStyle.NONE);
+    }
+
+    public ListItemAdapter(Context context, ListItemProvider itemProvider,
+            int backgroundStyle) {
         mContext = context;
         mItemProvider = itemProvider;
+        mBackgroundStyle = backgroundStyle;
     }
 
     @Override
-    public int getItemViewType(int position) {
-        return mItemProvider.get(position).getViewType();
-    }
-
-    @Override
-    public ViewHolder onCreateViewHolder(ViewGroup parent, @PagedListItemType int viewType) {
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         LayoutInflater inflater = LayoutInflater.from(mContext);
-        int layoutId;
-        switch (viewType) {
-            case CAR_PAGED_LIST_ITEM:
-                layoutId = R.layout.car_paged_list_item;
+        View itemView = inflater.inflate(R.layout.car_paged_list_item_content, parent, false);
+
+        ViewGroup container = createListItemContainer();
+        container.addView(itemView);
+        return new ViewHolder(container);
+    }
+
+    private ViewGroup createListItemContainer() {
+        ViewGroup container;
+        switch (mBackgroundStyle) {
+            case BackgroundStyle.NONE:
+            case BackgroundStyle.PANEL:
+                FrameLayout frameLayout = new FrameLayout(mContext);
+                frameLayout.setLayoutParams(new RecyclerView.LayoutParams(
+                        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+                frameLayout.setBackgroundColor(mContext.getColor(R.color.car_card));
+
+                container = frameLayout;
                 break;
-            case CAR_PAGED_LIST_CARD:
-                layoutId = R.layout.car_paged_list_card;
+            case BackgroundStyle.CARD:
+                CardView card = new CardView(mContext);
+                RecyclerView.LayoutParams cardLayoutParams = new RecyclerView.LayoutParams(
+                        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+                cardLayoutParams.bottomMargin = mContext.getResources().getDimensionPixelSize(
+                        R.dimen.car_padding_3);
+                card.setLayoutParams(cardLayoutParams);
+                card.setRadius(mContext.getResources().getDimensionPixelSize(R.dimen.car_radius_1));
+                card.setCardBackgroundColor(mContext.getColor(R.color.car_card));
+
+                container = card;
                 break;
             default:
-                throw new IllegalArgumentException("Unrecognizable view type: " + viewType);
+                throw new IllegalArgumentException("Unknown background style. "
+                        + "Expected constants in class ListItemAdapter.BackgroundStyle.");
         }
-        View itemView = inflater.inflate(layoutId, parent, false);
-        return new ViewHolder(itemView);
+        return container;
     }
 
     @Override
     public void onBindViewHolder(ViewHolder holder, int position) {
         ListItem item = mItemProvider.get(position);
         item.bind(holder);
+
+        if (mBackgroundStyle == BackgroundStyle.PANEL) {
+            ListItemBackgroundResolver.setBackground(
+                    holder.itemView, position, mItemProvider.size());
+        }
     }
 
     @Override
diff --git a/car/src/test/java/androidx/car/utils/ListItemBackgroundResolverTest.java b/car/src/test/java/androidx/car/utils/ListItemBackgroundResolverTest.java
new file mode 100644
index 0000000..b809c79
--- /dev/null
+++ b/car/src/test/java/androidx/car/utils/ListItemBackgroundResolverTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2017 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.
+ */
+
+package androidx.car.utils;
+
+
+import static org.mockito.Mockito.verify;
+
+import android.view.View;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import androidx.car.R;
+
+/**
+ * Tests for {@link ListItemBackgroundResolver}.
+ */
+@RunWith(JUnit4.class)
+public class ListItemBackgroundResolverTest {
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock
+    View mMockView;
+
+    @Test
+    public void testSingleItemInListHasAllRoundedCorners() {
+        ListItemBackgroundResolver.setBackground(mMockView, 0, 1);
+
+        verify(mMockView).setBackgroundResource(R.drawable.car_card_rounded_background);
+    }
+
+    @Test
+    public void testOnlyTopItemHasTopRoundedCorners() {
+        ListItemBackgroundResolver.setBackground(mMockView, 0, 2);
+
+        verify(mMockView).setBackgroundResource(R.drawable.car_card_rounded_top_background);
+    }
+
+    @Test
+    public void testOnlyBottomItemHasBottomRoundedCorners() {
+        ListItemBackgroundResolver.setBackground(mMockView, 1, 2);
+
+        verify(mMockView).setBackgroundResource(R.drawable.car_card_rounded_bottom_background);
+    }
+
+    @Test
+    public void testMiddleItemHasNoRoundedCorner() {
+        ListItemBackgroundResolver.setBackground(mMockView, 1, 3);
+
+        verify(mMockView).setBackgroundResource(R.drawable.car_card_background);
+    }
+}
diff --git a/car/tests/src/androidx/car/widget/ListItemTest.java b/car/tests/src/androidx/car/widget/ListItemTest.java
index bdf3e29..233e720 100644
--- a/car/tests/src/androidx/car/widget/ListItemTest.java
+++ b/car/tests/src/androidx/car/widget/ListItemTest.java
@@ -25,7 +25,6 @@
 import static junit.framework.TestCase.assertFalse;
 
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.core.Is.is;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.hamcrest.number.IsCloseTo.closeTo;
@@ -39,7 +38,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.widget.CardView;
 import android.support.v7.widget.LinearLayoutManager;
 import android.view.View;
 import android.view.ViewGroup;
@@ -481,18 +479,6 @@
     }
 
     @Test
-    public void testCardLookUsesCardView() {
-        List<ListItem> items = Arrays.asList(
-                new ListItem.Builder(mActivity)
-                        .withCardLook()
-                        .build());
-        setupPagedListView(items);
-
-        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
-        assertThat(viewHolder.itemView, is(instanceOf(CardView.class)));
-    }
-
-    @Test
     public void testSettingTitleOrBodyAsPrimaryText() {
         // Create 2 items, one with Title as primary (default) and one with Body.
         // The primary text, regardless of view, should have consistent look (as primary).
diff --git a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/ListItemActivity.java b/samples/SupportCarDemos/src/main/java/com/example/androidx/car/ListItemActivity.java
index 6aa5ba6..790f1f1 100644
--- a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/ListItemActivity.java
+++ b/samples/SupportCarDemos/src/main/java/com/example/androidx/car/ListItemActivity.java
@@ -54,7 +54,7 @@
         mPagedListView = findViewById(R.id.paged_list_view);
 
         ListItemAdapter adapter = new ListItemAdapter(this,
-                new SampleProvider(this));
+                new SampleProvider(this), ListItemAdapter.BackgroundStyle.PANEL);
         mPagedListView.setAdapter(adapter);
         mPagedListView.setMaxPages(PagedListView.UNLIMITED_PAGES);
     }