Merge "Add onclick listener for PrimaryIcon and clean up code for adding a listener for SupplementalIcon" into pi-preview1-androidx-dev
diff --git a/car/api/current.txt b/car/api/current.txt
index 1396dc5..2128c7b 100644
--- a/car/api/current.txt
+++ b/car/api/current.txt
@@ -378,7 +378,6 @@
   }
 
   public class SeekbarListItem extends androidx.car.widget.ListItem {
-    ctor public deprecated SeekbarListItem(android.content.Context, int, int, android.widget.SeekBar.OnSeekBarChangeListener, java.lang.String);
     ctor public SeekbarListItem(android.content.Context);
     method public static androidx.car.widget.SeekbarListItem.ViewHolder createViewHolder(android.view.View);
     method public int getViewType();
@@ -389,13 +388,14 @@
     method public void setPrimaryActionEmptyIcon();
     method public void setPrimaryActionIcon(int);
     method public void setPrimaryActionIcon(android.graphics.drawable.Drawable);
+    method public void setPrimaryActionIconListener(android.view.View.OnClickListener);
     method public void setProgress(int);
     method public void setSecondaryProgress(int);
     method public void setSupplementalEmptyIcon(boolean);
     method public void setSupplementalIcon(int, boolean);
-    method public void setSupplementalIcon(int, boolean, android.view.View.OnClickListener);
     method public void setSupplementalIcon(android.graphics.drawable.Drawable, boolean);
-    method public void setSupplementalIcon(android.graphics.drawable.Drawable, boolean, android.view.View.OnClickListener);
+    method public deprecated void setSupplementalIcon(android.graphics.drawable.Drawable, boolean, android.view.View.OnClickListener);
+    method public void setSupplementalIconListener(android.view.View.OnClickListener);
     method public void setText(java.lang.String);
   }
 
diff --git a/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java b/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java
index 5233734..82f5268 100644
--- a/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java
+++ b/car/src/androidTest/java/androidx/car/widget/SeekbarListItemTest.java
@@ -74,9 +74,18 @@
         mPagedListView = mActivity.findViewById(R.id.paged_list_view);
     }
 
+    private SeekbarListItem initSeekbarListItem() {
+        SeekbarListItem item = new SeekbarListItem(mActivity);
+        item.setMax(0);
+        item.setProgress(0);
+        item.setOnSeekBarChangeListener(null);
+        item.setText(null);
+        return item;
+    }
+
     @Test
     public void testOnlySliderIsVisibleInEmptyItem() {
-        SeekbarListItem item = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item = initSeekbarListItem();
 
         setupPagedListView(Arrays.asList(item));
         verifyViewDefaultVisibility(mPagedListView.getRecyclerView().getLayoutManager()
@@ -85,14 +94,13 @@
 
     @Test
     public void testPrimaryActionVisible() {
-        SeekbarListItem item0 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item0 = initSeekbarListItem();
         item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
 
-        SeekbarListItem item1 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item1 = initSeekbarListItem();
         item1.setPrimaryActionIcon(new ColorDrawable(Color.BLACK));
 
-        List<ListItem> items = Arrays.asList(item0, item1);
-        setupPagedListView(items);
+        setupPagedListView(Arrays.asList(item0, item1));
 
         assertThat(getViewHolderAtPosition(0).getPrimaryIcon().getVisibility(),
                 is(equalTo(View.VISIBLE)));
@@ -102,21 +110,20 @@
 
     @Test
     public void testSliderTextVisible() {
-        SeekbarListItem item = new SeekbarListItem(mActivity, 0, 0, null, "Text");
+        SeekbarListItem item = initSeekbarListItem();
+        item.setText("Text");
 
-        List<ListItem> items = Arrays.asList(item);
-        setupPagedListView(items);
+        setupPagedListView(Arrays.asList(item));
 
         assertThat(getViewHolderAtPosition(0).getText().getVisibility(), is(equalTo(View.VISIBLE)));
     }
 
     @Test
     public void testSupplementalIconVisible() {
-        SeekbarListItem item = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item = initSeekbarListItem();
         item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false);
 
-        List<ListItem> items = Arrays.asList(item);
-        setupPagedListView(items);
+        setupPagedListView(Arrays.asList(item));
 
         assertThat(getViewHolderAtPosition(0).getSupplementalIcon().getVisibility(),
                 is(equalTo(View.VISIBLE)));
@@ -126,11 +133,10 @@
 
     @Test
     public void testSupplementalIconDividerVisible() {
-        SeekbarListItem item = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item = initSeekbarListItem();
         item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true);
 
-        List<ListItem> items = Arrays.asList(item);
-        setupPagedListView(items);
+        setupPagedListView(Arrays.asList(item));
 
         assertThat(getViewHolderAtPosition(0).getSupplementalIcon().getVisibility(),
                 is(equalTo(View.VISIBLE)));
@@ -215,27 +221,41 @@
     }
 
     @Test
-    public void testPrimaryIconIsNotClickable() {
-        SeekbarListItem item0 = new SeekbarListItem(mActivity, 0, 0, null, null);
+    public void testPrimaryIconIsNotClickableWithoutListener() {
+        SeekbarListItem item0 = initSeekbarListItem();
         item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
 
-        SeekbarListItem item1 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item1 = initSeekbarListItem();
         item1.setPrimaryActionIcon(new ColorDrawable(Color.BLACK));
 
-        List<ListItem> items = Arrays.asList(item0, item1);
-        setupPagedListView(items);
+        setupPagedListView(Arrays.asList(item0, item1));
 
         assertFalse(getViewHolderAtPosition(0).getPrimaryIcon().isClickable());
         assertFalse(getViewHolderAtPosition(1).getPrimaryIcon().isClickable());
     }
 
     @Test
+    public void testClickingPrimaryActionIcon() {
+        boolean[] clicked = {false};
+        SeekbarListItem item = initSeekbarListItem();
+        item.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
+        item.setPrimaryActionIconListener(v -> clicked[0] = true);
+
+        setupPagedListView(Arrays.asList(item));
+
+        onView(withId(R.id.recycler_view)).perform(
+                actionOnItemAtPosition(0, clickChildViewWithId(R.id.primary_icon)));
+
+        assertTrue(clicked[0]);
+        assertTrue(getViewHolderAtPosition(0).getPrimaryIcon().isClickable());
+    }
+
+    @Test
     public void testSupplementalIconNotClickableWithoutListener() {
-        SeekbarListItem item = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item = initSeekbarListItem();
         item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false);
 
-        List<ListItem> items = Arrays.asList(item);
-        setupPagedListView(items);
+        setupPagedListView(Arrays.asList(item));
 
         assertFalse(getViewHolderAtPosition(0).getSupplementalIcon().isClickable());
     }
@@ -243,12 +263,11 @@
     @Test
     public void testClickingSupplementalIcon() {
         boolean[] clicked = {false};
-        SeekbarListItem item = new SeekbarListItem(mActivity, 0, 0, null, null);
-        item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false,
-                v -> clicked[0] = true);
+        SeekbarListItem item = initSeekbarListItem();
+        item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false);
+        item.setSupplementalIconListener(v -> clicked[0] = true);
 
-        List<ListItem> items = Arrays.asList(item);
-        setupPagedListView(items);
+        setupPagedListView(Arrays.asList(item));
 
         onView(withId(R.id.recycler_view)).perform(
                 actionOnItemAtPosition(0, clickChildViewWithId(R.id.supplemental_icon)));
@@ -258,13 +277,13 @@
 
     @Test
     public void testPrimaryActionEmptyIconSpacing() {
-        SeekbarListItem item0 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item0 = initSeekbarListItem();
         item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
 
-        SeekbarListItem item1 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item1 = initSeekbarListItem();
         item1.setPrimaryActionIcon(new ColorDrawable(Color.BLACK));
 
-        SeekbarListItem item2 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item2 = initSeekbarListItem();
         item2.setPrimaryActionEmptyIcon();
 
         List<ListItem> items = Arrays.asList(item0, item1, item2);
@@ -279,10 +298,10 @@
     @Test
     public void testSupplementalIconSpacingWithoutDivider() {
         final boolean showDivider = false;
-        SeekbarListItem item0 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item0 = initSeekbarListItem();
         item0.setSupplementalIcon(android.R.drawable.sym_def_app_icon, showDivider);
 
-        SeekbarListItem item1 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item1 = initSeekbarListItem();
         item1.setSupplementalEmptyIcon(showDivider);
 
         List<ListItem> items = Arrays.asList(item0, item1);
@@ -297,10 +316,10 @@
     @Test
     public void testSupplementalIconSpacingWithDivider() {
         final boolean showDivider = true;
-        SeekbarListItem item0 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item0 = initSeekbarListItem();
         item0.setSupplementalIcon(android.R.drawable.sym_def_app_icon, showDivider);
 
-        SeekbarListItem item1 = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item1 = initSeekbarListItem();
         item1.setSupplementalEmptyIcon(showDivider);
 
         List<ListItem> items = Arrays.asList(item0, item1);
@@ -315,7 +334,7 @@
     @Test
     public void testSettingSupplementalIconWithDrawable() {
         Drawable drawable = mActivity.getDrawable(android.R.drawable.sym_def_app_icon);
-        SeekbarListItem item = new SeekbarListItem(mActivity, 0, 0, null, null);
+        SeekbarListItem item = initSeekbarListItem();
         item.setSupplementalIcon(drawable, false);
 
         setupPagedListView(Arrays.asList(item));
diff --git a/car/src/main/java/androidx/car/widget/SeekbarListItem.java b/car/src/main/java/androidx/car/widget/SeekbarListItem.java
index b175334..d859b63 100644
--- a/car/src/main/java/androidx/car/widget/SeekbarListItem.java
+++ b/car/src/main/java/androidx/car/widget/SeekbarListItem.java
@@ -98,6 +98,7 @@
 
     @PrimaryActionType private int mPrimaryActionType = PRIMARY_ACTION_TYPE_NO_ICON;
     private Drawable mPrimaryActionIconDrawable;
+    private View.OnClickListener mPrimaryActionIconOnClickListener;
 
     private String mText;
 
@@ -118,28 +119,6 @@
         return new ViewHolder(itemView);
     }
 
-    /**
-     * Creates a SeekbarListItem.
-     *
-     * @param context context
-     * @param max the upper range of the SeekBar.
-     * @param progress the current progress of the specified value.
-     * @param listener listener to receive notification of changes to progress level.
-     * @param text displays a text on top of the SeekBar.
-     *
-     * @deprecated use {@link #SeekbarListItem(Context)} and individual field setters instead.
-     */
-    @Deprecated
-    public SeekbarListItem(Context context, int max, int progress,
-            SeekBar.OnSeekBarChangeListener listener, String text) {
-        this(context);
-
-        setMax(max);
-        setProgress(progress);
-        setOnSeekBarChangeListener(listener);
-        setText(text);
-    }
-
     public SeekbarListItem(Context context) {
         mContext = context;
         markDirty();
@@ -310,6 +289,10 @@
                 mBinders.add(vh -> {
                     vh.getPrimaryIcon().setVisibility(View.VISIBLE);
                     vh.getPrimaryIcon().setImageDrawable(mPrimaryActionIconDrawable);
+                    vh.getPrimaryIcon().setOnClickListener(
+                            mPrimaryActionIconOnClickListener);
+                    vh.getPrimaryIcon().setClickable(
+                            mPrimaryActionIconOnClickListener != null);
                 });
                 break;
             default:
@@ -494,6 +477,16 @@
     }
 
     /**
+     * Sets an {@code OnClickListener} for the icon representing the {@code Primary Action}.
+     *
+     * @param onClickListener the listener to be set for the primary action icon.
+     */
+    public void setPrimaryActionIconListener(View.OnClickListener onClickListener) {
+        mPrimaryActionIconOnClickListener = onClickListener;
+        markDirty();
+    }
+
+    /**
      * Sets {@code Primary Action} to be empty icon.
      *
      * {@code Seekbar} would have a start margin as if {@code Primary Action} were set as icon.
@@ -508,30 +501,45 @@
      * Sets {@code Supplemental Action} to be represented by an {@code Supplemental Icon}.
      */
     public void setSupplementalIcon(@DrawableRes int iconResId,
-                                    boolean showSupplementalIconDivider) {
-        setSupplementalIcon(mContext.getDrawable(iconResId), showSupplementalIconDivider, null);
-    }
-
-    /**
-     * Sets {@code Supplemental Action} to be represented by an {@code Supplemental Icon}.
-     */
-    public void setSupplementalIcon(@DrawableRes int iconResId, boolean showSupplementalIconDivider,
-                                    @Nullable View.OnClickListener listener) {
-        setSupplementalIcon(mContext.getDrawable(iconResId), showSupplementalIconDivider, listener);
+            boolean showSupplementalIconDivider) {
+        setSupplementalIconInfo(mContext.getDrawable(iconResId), showSupplementalIconDivider);
     }
 
     /**
      * Sets {@code Supplemental Action} to be represented by an {@code Supplemental Icon}.
      */
     public void setSupplementalIcon(Drawable drawable, boolean showSupplementalIconDivider) {
-        setSupplementalIcon(drawable, showSupplementalIconDivider, null);
+        setSupplementalIconInfo(drawable, showSupplementalIconDivider);
+    }
+
+    /**
+     * Sets {@code OnClickListener} for a {@code Supplemental Icon}.
+     */
+    public void setSupplementalIconListener(View.OnClickListener listener) {
+        mSupplementalIconOnClickListener = listener;
+
+        markDirty();
+    }
+
+    private void setSupplementalIconInfo(Drawable drawable, boolean showSupplementalIconDivider) {
+        mSupplementalActionType = SUPPLEMENTAL_ACTION_SUPPLEMENTAL_ICON;
+
+        mSupplementalIconDrawable = drawable;
+        mShowSupplementalIconDivider = showSupplementalIconDivider;
+
+        markDirty();
     }
 
     /**
      * Sets {@code Supplemental Action} to be represented by an {@code Supplemental Icon}.
+     *
+     * @deprecated use either {@link #setSupplementalIcon(Drawable, boolean)} or
+     * {@link #setSupplementalIcon(int, boolean)} and
+     * {@link #setSupplementalIconListener(android.view.View.OnClickListener)}.
      */
+    @Deprecated
     public void setSupplementalIcon(Drawable drawable, boolean showSupplementalIconDivider,
-                                    @Nullable  View.OnClickListener listener) {
+            @Nullable  View.OnClickListener listener) {
         mSupplementalActionType = SUPPLEMENTAL_ACTION_SUPPLEMENTAL_ICON;
 
         mSupplementalIconDrawable = drawable;
diff --git a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/SeekbarListItemActivity.java b/samples/SupportCarDemos/src/main/java/com/example/androidx/car/SeekbarListItemActivity.java
index daa8178..3041264 100644
--- a/samples/SupportCarDemos/src/main/java/com/example/androidx/car/SeekbarListItemActivity.java
+++ b/samples/SupportCarDemos/src/main/java/com/example/androidx/car/SeekbarListItemActivity.java
@@ -88,13 +88,16 @@
             subheaderItem = new SubheaderListItem(mContext, "Slider Only");
             mItems.add(subheaderItem);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, null);
+            item = initSeekbarListItem();
+            item.setText(null);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, "one line text");
+            item = initSeekbarListItem();
+            item.setText("one line text");
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, longText);
+            item = initSeekbarListItem();
+            item.setText(longText);
             mItems.add(item);
 
 
@@ -102,55 +105,73 @@
             subheaderItem = new SubheaderListItem(mContext, "With Primary Action");
             mItems.add(subheaderItem);
             // Only slider. No text.
-            item = new SeekbarListItem(mContext, 100, 0, mListener, null);
+            item = initSeekbarListItem();
+            item.setText(null);
             item.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
             mItems.add(item);
 
             // One line text.
-            item = new SeekbarListItem(mContext, 100, 0, mListener, "one line text");
+            item = initSeekbarListItem();
+            item.setText("one line text");
             item.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
             mItems.add(item);
 
             // Long text.
-            item = new SeekbarListItem(mContext, 100, 0, mListener, longText);
+            item = initSeekbarListItem();
+            item.setText(longText);
             item.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
             mItems.add(item);
 
+            // Clickable PrimaryActionIcon.
+            item = initSeekbarListItem();
+            item.setText("with clickable Primary icon");
+            item.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon);
+            item.setPrimaryActionIconListener(v -> Toast.makeText(mContext,
+                    "Primary icon clicked!", Toast.LENGTH_SHORT).show());
+            mItems.add(item);
+
             // End icon with divider.
             subheaderItem = new SubheaderListItem(mContext, "With Supplemental Action");
             mItems.add(subheaderItem);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, null);
+            item = initSeekbarListItem();
+            item.setText(null);
             item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, "one line text");
+            item = initSeekbarListItem();
+            item.setText("one line text");
             item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, longText);
+            item = initSeekbarListItem();
+            item.setText(longText);
             item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, "with clickable icon");
-            item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true,
-                    v -> Toast.makeText(mContext, "Supplemental icon clicked!", Toast.LENGTH_SHORT)
-                            .show());
+            item = initSeekbarListItem();
+            item.setText("with clickable icon");
+            item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true);
+            item.setSupplementalIconListener(v -> Toast.makeText(mContext,
+                    "Supplemental icon clicked!", Toast.LENGTH_SHORT).show());
             mItems.add(item);
 
             // Empty end icon with divider.
             subheaderItem = new SubheaderListItem(mContext, "With Empty Icon");
             mItems.add(subheaderItem);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, null);
+            item = initSeekbarListItem();
+            item.setText(null);
             item.setSupplementalEmptyIcon(true);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, "one line text");
+            item = initSeekbarListItem();
+            item.setText("one line text");
             item.setSupplementalEmptyIcon(true);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, longText);
+            item = initSeekbarListItem();
+            item.setText(longText);
             item.setSupplementalEmptyIcon(true);
             mItems.add(item);
 
@@ -158,15 +179,18 @@
             subheaderItem = new SubheaderListItem(mContext, "Without Supplemental Action Divider");
             mItems.add(subheaderItem);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, null);
+            item = initSeekbarListItem();
+            item.setText(null);
             item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, "one line text");
+            item = initSeekbarListItem();
+            item.setText("one line text");
             item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, longText);
+            item = initSeekbarListItem();
+            item.setText(longText);
             item.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false);
             mItems.add(item);
 
@@ -174,15 +198,18 @@
             subheaderItem = new SubheaderListItem(mContext, "With Empty Icon No Divider");
             mItems.add(subheaderItem);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, null);
+            item = initSeekbarListItem();
+            item.setText(null);
             item.setSupplementalEmptyIcon(false);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, "one line text");
+            item = initSeekbarListItem();
+            item.setText("one line text");
             item.setSupplementalEmptyIcon(false);
             mItems.add(item);
 
-            item = new SeekbarListItem(mContext, 100, 0, mListener, longText);
+            item = initSeekbarListItem();
+            item.setText(longText);
             item.setSupplementalEmptyIcon(false);
             mItems.add(item);
 
@@ -190,7 +217,10 @@
             subheaderItem = new SubheaderListItem(mContext, "Secondary Progress");
             mItems.add(subheaderItem);
 
-            item = new SeekbarListItem(mContext, 100, 0, new SeekBar.OnSeekBarChangeListener() {
+            item = new SeekbarListItem(mContext);
+            item.setMax(100);
+            item.setProgress(0);
+            item.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                 @Override
                 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                     seekBar.setSecondaryProgress(progress + 10);
@@ -203,12 +233,20 @@
                 @Override
                 public void onStopTrackingTouch(SeekBar seekBar) {
                 }
-            }, null);
+            });
             mItems.add(item);
 
             mListProvider = new ListItemProvider.ListProvider(mItems);
         }
 
+        private SeekbarListItem initSeekbarListItem() {
+            SeekbarListItem item = new SeekbarListItem(mContext);
+            item.setMax(100);
+            item.setProgress(0);
+            item.setOnSeekBarChangeListener(mListener);
+            return item;
+        }
+
         @Override
         public ListItem get(int position) {
             return mListProvider.get(position);