Add content description setters to builders

Content description can be set for:
- On entire grid row or on each cell
- On entire header row or normal row

Test: manual with sample app and talkback on
Bug: 74212452
Change-Id: I8475c5da550e9f7fcf0851387fd6b1ea330f82ce
diff --git a/slices/builders/api/current.txt b/slices/builders/api/current.txt
index 5aa4f42..89275b9 100644
--- a/slices/builders/api/current.txt
+++ b/slices/builders/api/current.txt
@@ -7,6 +7,7 @@
     method public androidx.slice.builders.GridBuilder addSeeMoreAction(android.app.PendingIntent);
     method public androidx.slice.builders.GridBuilder addSeeMoreCell(androidx.slice.builders.GridBuilder.CellBuilder);
     method public androidx.slice.builders.GridBuilder addSeeMoreCell(java.util.function.Consumer<androidx.slice.builders.GridBuilder.CellBuilder>);
+    method public androidx.slice.builders.GridBuilder setContentDescription(java.lang.CharSequence);
     method public androidx.slice.builders.GridBuilder setPrimaryAction(androidx.slice.builders.SliceAction);
     field public static final deprecated int ICON_IMAGE = 0; // 0x0
     field public static final deprecated int LARGE_IMAGE = 2; // 0x2
@@ -26,6 +27,7 @@
     method public androidx.slice.builders.GridBuilder.CellBuilder addText(java.lang.CharSequence, boolean);
     method public androidx.slice.builders.GridBuilder.CellBuilder addTitleText(java.lang.CharSequence);
     method public androidx.slice.builders.GridBuilder.CellBuilder addTitleText(java.lang.CharSequence, boolean);
+    method public androidx.slice.builders.GridBuilder.CellBuilder setContentDescription(java.lang.CharSequence);
     method public androidx.slice.builders.GridBuilder.CellBuilder setContentIntent(android.app.PendingIntent);
   }
 
@@ -52,6 +54,7 @@
 
   public static class ListBuilder.HeaderBuilder extends androidx.slice.builders.TemplateSliceBuilder {
     ctor public ListBuilder.HeaderBuilder(androidx.slice.builders.ListBuilder);
+    method public androidx.slice.builders.ListBuilder.HeaderBuilder setContentDescription(java.lang.CharSequence);
     method public androidx.slice.builders.ListBuilder.HeaderBuilder setPrimaryAction(androidx.slice.builders.SliceAction);
     method public androidx.slice.builders.ListBuilder.HeaderBuilder setSubtitle(java.lang.CharSequence);
     method public androidx.slice.builders.ListBuilder.HeaderBuilder setSummarySubtitle(java.lang.CharSequence);
@@ -61,6 +64,7 @@
   public static class ListBuilder.InputRangeBuilder extends androidx.slice.builders.TemplateSliceBuilder {
     ctor public ListBuilder.InputRangeBuilder(androidx.slice.builders.ListBuilder);
     method public androidx.slice.builders.ListBuilder.InputRangeBuilder setAction(android.app.PendingIntent);
+    method public androidx.slice.builders.ListBuilder.InputRangeBuilder setContentDescription(java.lang.CharSequence);
     method public androidx.slice.builders.ListBuilder.InputRangeBuilder setMax(int);
     method public androidx.slice.builders.ListBuilder.InputRangeBuilder setThumb(android.graphics.drawable.Icon);
     method public androidx.slice.builders.ListBuilder.InputRangeBuilder setTitle(java.lang.CharSequence);
@@ -69,6 +73,7 @@
 
   public static class ListBuilder.RangeBuilder extends androidx.slice.builders.TemplateSliceBuilder {
     ctor public ListBuilder.RangeBuilder(androidx.slice.builders.ListBuilder);
+    method public androidx.slice.builders.ListBuilder.RangeBuilder setContentDescription(java.lang.CharSequence);
     method public androidx.slice.builders.ListBuilder.RangeBuilder setMax(int);
     method public androidx.slice.builders.ListBuilder.RangeBuilder setTitle(java.lang.CharSequence);
     method public androidx.slice.builders.ListBuilder.RangeBuilder setValue(int);
@@ -85,6 +90,7 @@
     method public androidx.slice.builders.ListBuilder.RowBuilder addEndItem(android.graphics.drawable.Icon, int, boolean);
     method public androidx.slice.builders.ListBuilder.RowBuilder addEndItem(androidx.slice.builders.SliceAction);
     method public androidx.slice.builders.ListBuilder.RowBuilder addEndItem(androidx.slice.builders.SliceAction, boolean);
+    method public androidx.slice.builders.ListBuilder.RowBuilder setContentDescription(java.lang.CharSequence);
     method public androidx.slice.builders.ListBuilder.RowBuilder setPrimaryAction(androidx.slice.builders.SliceAction);
     method public androidx.slice.builders.ListBuilder.RowBuilder setSubtitle(java.lang.CharSequence);
     method public androidx.slice.builders.ListBuilder.RowBuilder setSubtitle(java.lang.CharSequence, boolean);
diff --git a/slices/builders/src/main/java/androidx/slice/builders/GridBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/GridBuilder.java
index 57a66b6..488d925 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/GridBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/GridBuilder.java
@@ -22,13 +22,13 @@
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.Build;
+
+import java.util.function.Consumer;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
-
-import java.util.function.Consumer;
-
 import androidx.slice.builders.impl.TemplateBuilderImpl;
 
 
@@ -178,6 +178,15 @@
     }
 
     /**
+     * Sets the content description for the entire grid row.
+     */
+    @NonNull
+    public GridBuilder setContentDescription(@NonNull CharSequence description) {
+        mImpl.setContentDescription(description);
+        return this;
+    }
+
+    /**
      * @hide
      */
     @RestrictTo(LIBRARY)
@@ -381,5 +390,14 @@
             mImpl.setContentIntent(intent);
             return this;
         }
+
+        /**
+         * Sets the content description for this cell.
+         */
+        @NonNull
+        public CellBuilder setContentDescription(@NonNull CharSequence description) {
+            mImpl.setContentDescription(description);
+            return this;
+        }
     }
 }
diff --git a/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
index 77c6b44..5e8179c 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/ListBuilder.java
@@ -24,15 +24,15 @@
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.Build;
+
+import java.util.function.Consumer;
+
 import androidx.annotation.ColorInt;
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
-
-import java.util.function.Consumer;
-
 import androidx.slice.SliceSpecs;
 import androidx.slice.builders.impl.ListBuilderBasicImpl;
 import androidx.slice.builders.impl.ListBuilderV1Impl;
@@ -356,6 +356,15 @@
             return this;
         }
 
+        /**
+         * Sets the content description.
+         */
+        @NonNull
+        public RangeBuilder setContentDescription(@NonNull CharSequence description) {
+            mImpl.setContentDescription(description);
+            return this;
+        }
+
         @Override
         void setImpl(TemplateBuilderImpl impl) {
             mImpl = (androidx.slice.builders.impl.ListBuilder.RangeBuilder) impl;
@@ -418,6 +427,15 @@
             return this;
         }
 
+        /**
+         * Sets the content description.
+         */
+        @NonNull
+        public InputRangeBuilder setContentDescription(@NonNull CharSequence description) {
+            mImpl.setContentDescription(description);
+            return this;
+        }
+
         @Override
         void setImpl(TemplateBuilderImpl impl) {
             mImpl = (androidx.slice.builders.impl.ListBuilder.InputRangeBuilder) impl;
@@ -774,6 +792,15 @@
             return this;
         }
 
+        /**
+         * Sets the content description for the row.
+         */
+        @NonNull
+        public RowBuilder setContentDescription(@NonNull CharSequence description) {
+            mImpl.setContentDescription(description);
+            return this;
+        }
+
         @Override
         void setImpl(TemplateBuilderImpl impl) {
             mImpl = (androidx.slice.builders.impl.ListBuilder.RowBuilder) impl;
@@ -852,6 +879,15 @@
             return this;
         }
 
+        /**
+         * Sets the content description for the header.
+         */
+        @NonNull
+        public HeaderBuilder setContentDescription(@NonNull CharSequence description) {
+            mImpl.setContentDescription(description);
+            return this;
+        }
+
         @Override
         void setImpl(TemplateBuilderImpl impl) {
             mImpl = (androidx.slice.builders.impl.ListBuilder.HeaderBuilder) impl;
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilder.java
index 8396f3f..99d5ce4 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilder.java
@@ -21,10 +21,10 @@
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
-
 import androidx.slice.builders.SliceAction;
 
 /**
@@ -75,6 +75,11 @@
     void setPrimaryAction(SliceAction action);
 
     /**
+     * Sets the content description for the entire grid row.
+     */
+    void setContentDescription(CharSequence description);
+
+    /**
      */
     interface CellBuilder {
         /**
@@ -141,5 +146,10 @@
          */
         @NonNull
         void setContentIntent(@NonNull PendingIntent intent);
+
+        /**
+         * Sets the content description for this cell.
+         */
+        void setContentDescription(CharSequence description);
     }
 }
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderBasicImpl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderBasicImpl.java
index 8f16753..96df99e 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderBasicImpl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderBasicImpl.java
@@ -21,10 +21,10 @@
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
-
 import androidx.slice.Slice;
 import androidx.slice.builders.SliceAction;
 
@@ -83,6 +83,12 @@
     /**
      */
     @Override
+    public void setContentDescription(CharSequence description) {
+    }
+
+    /**
+     */
+    @Override
     public void apply(Slice.Builder builder) {
 
     }
@@ -155,6 +161,12 @@
         /**
          */
         @Override
+        public void setContentDescription(CharSequence description) {
+        }
+
+        /**
+         */
+        @Override
         public void apply(Slice.Builder builder) {
 
         }
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderListV1Impl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderListV1Impl.java
index 7920eb1..8dc89fe 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderListV1Impl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/GridBuilderListV1Impl.java
@@ -24,20 +24,21 @@
 import static android.app.slice.Slice.HINT_SEE_MORE;
 import static android.app.slice.Slice.HINT_SHORTCUT;
 import static android.app.slice.Slice.HINT_TITLE;
-import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+import static android.app.slice.Slice.SUBTYPE_CONTENT_DESCRIPTION;
 
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
 import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
 import static androidx.slice.builders.ListBuilder.LARGE_IMAGE;
 
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
 
 import java.util.ArrayList;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
 import androidx.slice.Slice;
 import androidx.slice.builders.SliceAction;
 
@@ -127,6 +128,13 @@
 
     /**
      */
+    @Override
+    public void setContentDescription(CharSequence description) {
+        getBuilder().addText(description, SUBTYPE_CONTENT_DESCRIPTION);
+    }
+
+    /**
+     */
     public static final class CellBuilder extends TemplateBuilderImpl implements
             GridBuilder.CellBuilder {
 
@@ -216,6 +224,13 @@
         }
 
         /**
+         */
+        @Override
+        public void setContentDescription(CharSequence description) {
+            getBuilder().addText(description, SUBTYPE_CONTENT_DESCRIPTION);
+        }
+
+        /**
          * @hide
          */
         @RestrictTo(LIBRARY)
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java
index 5a2e776..2ea33e3 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilder.java
@@ -21,10 +21,10 @@
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
+
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
-
 import androidx.slice.builders.SliceAction;
 
 /**
@@ -139,6 +139,11 @@
          * Set the title.
          */
         void setTitle(@NonNull CharSequence title);
+
+        /**
+         * Sets the content description.
+         */
+        void setContentDescription(CharSequence description);
     }
 
     /**
@@ -280,6 +285,11 @@
          * until updated.
          */
         void addEndItem(SliceAction action, boolean isLoading);
+
+        /**
+         * Sets the content description for this row.
+         */
+        void setContentDescription(CharSequence description);
     }
 
 
@@ -310,6 +320,11 @@
          * Sets the action to invoke when the header is activated.
          */
         void setPrimaryAction(SliceAction action);
+
+        /**
+         * Sets the content description for the header.
+         */
+        void setContentDescription(CharSequence description);
     }
 }
 
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java
index ef10c9a..7c283dd 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderBasicImpl.java
@@ -21,10 +21,10 @@
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
+
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
-
 import androidx.slice.Slice;
 import androidx.slice.SliceSpec;
 import androidx.slice.builders.SliceAction;
@@ -179,6 +179,13 @@
         /**
          */
         @Override
+        public void setContentDescription(CharSequence description) {
+
+        }
+
+        /**
+         */
+        @Override
         public void setTitleItem(long timeStamp) {
 
         }
@@ -323,5 +330,10 @@
         public void setPrimaryAction(SliceAction action) {
 
         }
+
+        @Override
+        public void setContentDescription(CharSequence description) {
+
+        }
     }
 }
diff --git a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java
index 15cc4c7..9c0ca5d 100644
--- a/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java
+++ b/slices/builders/src/main/java/androidx/slice/builders/impl/ListBuilderV1Impl.java
@@ -26,9 +26,10 @@
 import static android.app.slice.Slice.HINT_SUMMARY;
 import static android.app.slice.Slice.HINT_TITLE;
 import static android.app.slice.Slice.SUBTYPE_COLOR;
+import static android.app.slice.Slice.SUBTYPE_CONTENT_DESCRIPTION;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
-import static androidx.annotation.RestrictTo.Scope.LIBRARY;
 
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
 import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
 import static androidx.slice.builders.ListBuilder.LARGE_IMAGE;
 import static androidx.slice.core.SliceHints.SUBTYPE_MAX;
@@ -38,13 +39,13 @@
 import android.app.PendingIntent;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
-import androidx.annotation.ColorInt;
-import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
 import androidx.slice.Slice;
 import androidx.slice.SliceItem;
 import androidx.slice.SliceSpec;
@@ -154,6 +155,7 @@
         private int mMax = 100;
         private int mValue = 0;
         private CharSequence mTitle;
+        private CharSequence mContentDescr;
 
         public RangeBuilderImpl(Slice.Builder sb) {
             super(sb, null);
@@ -175,10 +177,18 @@
         }
 
         @Override
+        public void setContentDescription(@NonNull CharSequence description) {
+            mContentDescr = description;
+        }
+
+        @Override
         public void apply(Slice.Builder builder) {
             if (mTitle != null) {
                 builder.addText(mTitle, null, HINT_TITLE);
             }
+            if (mContentDescr != null) {
+                builder.addText(mContentDescr, SUBTYPE_CONTENT_DESCRIPTION);
+            }
             builder.addHints(HINT_LIST_ITEM)
                     .addInt(mMax, SUBTYPE_MAX)
                     .addInt(mValue, SUBTYPE_VALUE);
@@ -283,6 +293,7 @@
         private SliceItem mSubtitleItem;
         private Slice mStartItem;
         private ArrayList<Slice> mEndItems = new ArrayList<>();
+        private CharSequence mContentDescr;
 
         /**
          */
@@ -464,6 +475,11 @@
             mEndItems.add(action.buildSlice(sb));
         }
 
+        @Override
+        public void setContentDescription(CharSequence description) {
+            mContentDescr = description;
+        }
+
         /**
          */
         @Override
@@ -481,6 +497,9 @@
                 Slice item = mEndItems.get(i);
                 b.addSubSlice(item);
             }
+            if (mContentDescr != null) {
+                b.addText(mContentDescr, SUBTYPE_CONTENT_DESCRIPTION);
+            }
             if (mPrimaryAction != null) {
                 Slice.Builder sb = new Slice.Builder(
                         getBuilder()).addHints(HINT_TITLE, HINT_SHORTCUT);
@@ -499,6 +518,7 @@
         private CharSequence mSubtitle;
         private CharSequence mSummarySubtitle;
         private SliceAction mPrimaryAction;
+        private CharSequence mContentDescr;
 
         /**
          */
@@ -525,6 +545,9 @@
             if (mSummarySubtitle != null) {
                 b.addText(mSummarySubtitle, null /* subtype */, HINT_SUMMARY);
             }
+            if (mContentDescr != null) {
+                b.addText(mContentDescr, SUBTYPE_CONTENT_DESCRIPTION);
+            }
             if (mPrimaryAction != null) {
                 Slice.Builder sb = new Slice.Builder(
                         getBuilder()).addHints(HINT_TITLE, HINT_SHORTCUT);
@@ -559,5 +582,12 @@
         public void setPrimaryAction(SliceAction action) {
             mPrimaryAction = action;
         }
+
+        /**
+         */
+        @Override
+        public void setContentDescription(CharSequence description) {
+            mContentDescr = description;
+        }
     }
 }