Filter out anything HINT_KEY_WORDS when extracting content from Slice

* Add list of keywords to sample app (wifi slice) and render tests

Test: ./gradlew slices-view:connectedCheck look at wifi slice
Bug: 74086214
Change-Id: Ie724022564f712797578fe945e15263dd43cf0f2
diff --git a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
index 0901724..770ebc4 100644
--- a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
+++ b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
@@ -36,6 +36,7 @@
 import android.text.style.ForegroundColorSpan;
 import android.util.SparseArray;
 
+import java.util.Arrays;
 import java.util.Calendar;
 
 import androidx.annotation.NonNull;
@@ -511,6 +512,10 @@
             lb.addRow(rb);
         }
 
+        // Add keywords
+        String[] keywords = new String[] {"internet", "wifi", "data", "network"};
+        lb.setKeywords(Arrays.asList(keywords));
+
         // Add see more intent
         if (TEST_CUSTOM_SEE_MORE) {
             lb.addSeeMoreRow(rb -> rb
diff --git a/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java b/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java
index 62b3610..ef96a27 100644
--- a/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java
+++ b/slices/view/src/androidTest/java/androidx/slice/render/SliceCreator.java
@@ -34,6 +34,8 @@
 import android.text.format.DateUtils;
 import android.text.style.ForegroundColorSpan;
 
+import java.util.Arrays;
+
 import androidx.slice.Slice;
 import androidx.slice.builders.GridBuilder;
 import androidx.slice.builders.ListBuilder;
@@ -379,6 +381,10 @@
                         "Toggle wifi", finalWifiEnabled))
                 .setPrimaryAction(primaryAction));
 
+        // Add keywords
+        String[] keywords = new String[] {"internet", "wifi", "data", "network"};
+        lb.setKeywords(Arrays.asList(keywords));
+
         // Add fake wifi networks
         int[] wifiIcons = new int[] {R.drawable.ic_wifi_full, R.drawable.ic_wifi_low,
                 R.drawable.ic_wifi_fair};
diff --git a/slices/view/src/main/java/androidx/slice/widget/GridContent.java b/slices/view/src/main/java/androidx/slice/widget/GridContent.java
index e6c1dfe..4fb4bde 100644
--- a/slices/view/src/main/java/androidx/slice/widget/GridContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/GridContent.java
@@ -33,6 +33,7 @@
 import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
 import static androidx.slice.builders.ListBuilder.LARGE_IMAGE;
 import static androidx.slice.builders.ListBuilder.SMALL_IMAGE;
+import static androidx.slice.core.SliceHints.HINT_KEY_WORDS;
 
 import android.app.slice.Slice;
 import android.content.Context;
@@ -193,8 +194,8 @@
             SliceItem item = items.get(i);
             if (SUBTYPE_CONTENT_DESCRIPTION.equals(item.getSubType())) {
                 mContentDescr = item;
-            } else if (item.hasHint(HINT_LIST_ITEM) && !item.hasHint(HINT_SHORTCUT)
-                    && !item.hasHint(HINT_SEE_MORE)) {
+            } else if (item.hasHint(HINT_LIST_ITEM) && !item.hasAnyHints(HINT_SHORTCUT,
+                    HINT_SEE_MORE, HINT_KEY_WORDS)) {
                 filteredItems.add(item);
             }
         }
@@ -329,7 +330,9 @@
          */
         private boolean isValidCellContent(SliceItem cellItem) {
             final String format = cellItem.getFormat();
-            return !SUBTYPE_CONTENT_DESCRIPTION.equals(cellItem.getSubType())
+            boolean isSpecial = SUBTYPE_CONTENT_DESCRIPTION.equals(cellItem.getSubType())
+                    || cellItem.hasHint(HINT_KEY_WORDS);
+            return !isSpecial
                     && (FORMAT_TEXT.equals(format)
                     || FORMAT_TIMESTAMP.equals(format)
                     || FORMAT_IMAGE.equals(format));
diff --git a/slices/view/src/main/java/androidx/slice/widget/ListContent.java b/slices/view/src/main/java/androidx/slice/widget/ListContent.java
index 580d9d7..5259ce7 100644
--- a/slices/view/src/main/java/androidx/slice/widget/ListContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/ListContent.java
@@ -27,14 +27,16 @@
 import static android.app.slice.SliceItem.FORMAT_SLICE;
 import static android.app.slice.SliceItem.FORMAT_TEXT;
 
+import static androidx.slice.core.SliceHints.HINT_KEY_WORDS;
+
 import android.content.Context;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
 import androidx.slice.Slice;
 import androidx.slice.SliceItem;
 import androidx.slice.SliceUtils;
@@ -87,7 +89,7 @@
         for (int i = 0; i < children.size(); i++) {
             final SliceItem child = children.get(i);
             final String format = child.getFormat();
-            if (!child.hasAnyHints(HINT_ACTIONS, HINT_SEE_MORE)
+            if (!child.hasAnyHints(HINT_ACTIONS, HINT_SEE_MORE, HINT_KEY_WORDS)
                     && (FORMAT_ACTION.equals(format) || FORMAT_SLICE.equals(format))) {
                 if (mHeaderItem == null && !child.hasHint(HINT_LIST_ITEM)) {
                     mHeaderItem = child;
@@ -209,7 +211,8 @@
     @Nullable
     private static SliceItem findHeaderItem(@NonNull Slice slice) {
         // See if header is specified
-        String[] nonHints = new String[] {HINT_LIST_ITEM, HINT_SHORTCUT, HINT_ACTIONS};
+        String[] nonHints = new String[] {HINT_LIST_ITEM, HINT_SHORTCUT, HINT_ACTIONS,
+                HINT_KEY_WORDS};
         SliceItem header = SliceQuery.find(slice, FORMAT_SLICE, null, nonHints);
         if (header != null && isValidHeader(header)) {
             return header;
@@ -233,8 +236,8 @@
     }
 
     private static boolean isValidHeader(SliceItem sliceItem) {
-        if (FORMAT_SLICE.equals(sliceItem.getFormat()) && !sliceItem.hasHint(HINT_LIST_ITEM)
-                && !sliceItem.hasHint(HINT_ACTIONS)) {
+        if (FORMAT_SLICE.equals(sliceItem.getFormat()) && !sliceItem.hasAnyHints(HINT_LIST_ITEM,
+                HINT_ACTIONS, HINT_KEY_WORDS)) {
              // Minimum valid header is a slice with text
             SliceItem item = SliceQuery.find(sliceItem, FORMAT_TEXT, (String) null, null);
             return item != null;
diff --git a/slices/view/src/main/java/androidx/slice/widget/RowContent.java b/slices/view/src/main/java/androidx/slice/widget/RowContent.java
index d7f7ab6..b6ca48a 100644
--- a/slices/view/src/main/java/androidx/slice/widget/RowContent.java
+++ b/slices/view/src/main/java/androidx/slice/widget/RowContent.java
@@ -30,6 +30,7 @@
 import static android.app.slice.SliceItem.FORMAT_TEXT;
 import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
 
+import static androidx.slice.core.SliceHints.HINT_KEY_WORDS;
 import static androidx.slice.core.SliceHints.SUBTYPE_RANGE;
 
 import android.content.Context;
@@ -88,7 +89,7 @@
         // Find primary action first (otherwise filtered out of valid row items)
         String[] hints = new String[] {HINT_SHORTCUT, HINT_TITLE};
         mPrimaryAction = SliceQuery.find(rowSlice, FORMAT_SLICE, hints,
-                new String[] { HINT_ACTIONS } /* nonHints */);
+                new String[] { HINT_ACTIONS, HINT_KEY_WORDS } /* nonHints */);
 
         mContentDescr = SliceQuery.findSubtype(rowSlice, FORMAT_TEXT, SUBTYPE_CONTENT_DESCRIPTION);
 
@@ -331,7 +332,11 @@
      * @return whether this item is valid content to display in a row.
      */
     private static boolean isValidRowContent(SliceItem slice, SliceItem item) {
-        if (FORMAT_SLICE.equals(item.getFormat()) && !item.hasHint(HINT_SHORTCUT)) {
+        if (item.hasHint(HINT_KEY_WORDS)) {
+            return false;
+        }
+        if (FORMAT_SLICE.equals(item.getFormat())
+                && !item.hasAnyHints(HINT_SHORTCUT, HINT_KEY_WORDS)) {
             // Unpack contents of slice
             item = item.getSlice().getItems().get(0);
         }