Add searchable XML attribute for preferences

This attribute, which is already present in phone settings, will allow
specific preferences to be excluded from search with minimal changes.

Bug: 159065704
Test: manual
Change-Id: I989635a925f1052e63db255410ad8a9ae86e1d82
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 5de6cde..df25d0b 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -61,6 +61,8 @@
     <declare-styleable name="Preference">
         <!-- Classname of a PreferenceController corresponding to the preference -->
         <attr name="controller" format="string"/>
+        <!-- Whether or not the preference is searchable, by default it's true. -->
+        <attr name="searchable" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="ProgressBarPreference">
diff --git a/src/com/android/car/settings/common/PreferenceXmlParser.java b/src/com/android/car/settings/common/PreferenceXmlParser.java
index 740e247..0deeeea 100644
--- a/src/com/android/car/settings/common/PreferenceXmlParser.java
+++ b/src/com/android/car/settings/common/PreferenceXmlParser.java
@@ -59,14 +59,17 @@
      */
     @IntDef(flag = true, value = {
             MetadataFlag.FLAG_NEED_KEY,
-            MetadataFlag.FLAG_NEED_PREF_CONTROLLER})
+            MetadataFlag.FLAG_NEED_PREF_CONTROLLER,
+            MetadataFlag.FLAG_NEED_SEARCHABLE})
     @Retention(RetentionPolicy.SOURCE)
     public @interface MetadataFlag {
         int FLAG_NEED_KEY = 1;
         int FLAG_NEED_PREF_CONTROLLER = 1 << 1;
+        int FLAG_NEED_SEARCHABLE = 1 << 9;
     }
 
     public static final String METADATA_KEY = "key";
+    public static final String METADATA_SEARCHABLE = "searchable";
     static final String METADATA_CONTROLLER = "controller";
 
     /**
@@ -114,6 +117,10 @@
                 preferenceMetadata.putString(METADATA_CONTROLLER,
                         getController(preferenceAttributes));
             }
+            if (hasFlag(flags, MetadataFlag.FLAG_NEED_SEARCHABLE)) {
+                preferenceMetadata.putBoolean(METADATA_SEARCHABLE,
+                        isSearchable(preferenceAttributes));
+            }
             metadata.add(preferenceMetadata);
 
             preferenceAttributes.recycle();
@@ -135,4 +142,8 @@
     private static String getController(TypedArray styledAttributes) {
         return styledAttributes.getString(R.styleable.Preference_controller);
     }
+
+    private static boolean isSearchable(TypedArray styledAttributes) {
+        return styledAttributes.getBoolean(R.styleable.Preference_searchable, true);
+    }
 }
diff --git a/src/com/android/car/settings/search/CarBaseSearchIndexProvider.java b/src/com/android/car/settings/search/CarBaseSearchIndexProvider.java
index 22ca3be..690e3c8 100644
--- a/src/com/android/car/settings/search/CarBaseSearchIndexProvider.java
+++ b/src/com/android/car/settings/search/CarBaseSearchIndexProvider.java
@@ -17,10 +17,13 @@
 package com.android.car.settings.search;
 
 import static com.android.car.settings.common.PreferenceXmlParser.METADATA_KEY;
+import static com.android.car.settings.common.PreferenceXmlParser.METADATA_SEARCHABLE;
 import static com.android.car.settings.common.PreferenceXmlParser.MetadataFlag.FLAG_NEED_KEY;
+import static com.android.car.settings.common.PreferenceXmlParser.MetadataFlag.FLAG_NEED_SEARCHABLE;
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.os.Bundle;
 import android.provider.SearchIndexableResource;
 
 import androidx.annotation.NonNull;
@@ -34,9 +37,9 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * A basic SearchIndexProvider.
@@ -82,18 +85,21 @@
 
     @Override
     public List<String> getNonIndexableKeys(Context context) {
-        if (!isPageSearchEnabled(context)) {
-            try {
-                return PreferenceXmlParser.extractMetadata(context, mXmlRes, FLAG_NEED_KEY)
-                        .stream()
-                        .map(bundle -> bundle.getString(METADATA_KEY))
-                        .collect(Collectors.toList());
-            } catch (IOException | XmlPullParserException e) {
-                LOG.w("Error parsing non-indexable XML - " + mXmlRes);
+        boolean searchEnabled = isPageSearchEnabled(context);
+        List<String> keys = new ArrayList<>();
+        try {
+            List<Bundle> metadata = PreferenceXmlParser.extractMetadata(context, mXmlRes,
+                    FLAG_NEED_KEY | FLAG_NEED_SEARCHABLE);
+            for (Bundle bundle : metadata) {
+                if (!searchEnabled || !bundle.getBoolean(METADATA_SEARCHABLE, true)) {
+                    keys.add(bundle.getString(METADATA_KEY));
+                }
             }
+        } catch (IOException | XmlPullParserException e) {
+            LOG.w("Error parsing non-indexable XML - " + mXmlRes);
         }
 
-        return null;
+        return keys;
     }
 
     /**