Add Indexable.SearchIndexProvider.getNonIndexableKeys(Context)

- getNonIndexableKeys(Context) allow a SearchIndexProvider to tell which data
he does not want to index by providing a list of the data keys
- use this new API for SoundSettings and removing KEY_EMERGENCY_TONE related
settings if the device is not CDMA
- add a BaseSearchIndexProvider for code simplification

Change-Id: I23633ace1d7e390ee05fac0a5458a33e04e72d8d
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index 9b6207b..563a343 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -86,7 +86,6 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.preference.Preference;
-import android.provider.SearchIndexableResource;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
@@ -134,6 +133,7 @@
 import com.android.settings.net.SummaryForAllUidLoader;
 import com.android.settings.net.UidDetail;
 import com.android.settings.net.UidDetailProvider;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settings.widget.ChartDataUsageView;
@@ -2388,14 +2388,7 @@
      * For search
      */
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new SearchIndexProvider() {
-
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                return null;
-            }
-
+        new BaseSearchIndexProvider() {
             @Override
             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
                 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
diff --git a/src/com/android/settings/SoundSettings.java b/src/com/android/settings/SoundSettings.java
index 45fd0db..49928f5 100644
--- a/src/com/android/settings/SoundSettings.java
+++ b/src/com/android/settings/SoundSettings.java
@@ -47,11 +47,14 @@
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.util.Log;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class SoundSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener {
+        Preference.OnPreferenceChangeListener, Indexable {
     private static final String TAG = "SoundSettings";
 
     private static final int DIALOG_NOT_DOCKED = 1;
@@ -446,5 +449,23 @@
         ab.setPositiveButton(android.R.string.ok, null);
         return ab.create();
     }
+
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+        new BaseSearchIndexProvider() {
+            @Override
+            public List<String> getNonIndexableKeys(Context context) {
+                final List<String> keys = new ArrayList<String>();
+
+                int activePhoneType = TelephonyManager.getDefault().getCurrentPhoneType();
+
+                if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) {
+                    // device is not CDMA, do not display CDMA emergency_tone
+                    keys.add(KEY_EMERGENCY_TONE);
+                }
+
+                return keys;
+            }
+        };
+
 }
 
diff --git a/src/com/android/settings/WallpaperTypeSettings.java b/src/com/android/settings/WallpaperTypeSettings.java
index b9237fa..7b2dcbf 100644
--- a/src/com/android/settings/WallpaperTypeSettings.java
+++ b/src/com/android/settings/WallpaperTypeSettings.java
@@ -24,7 +24,7 @@
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
-import android.provider.SearchIndexableResource;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 
@@ -65,13 +65,7 @@
     }
 
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new SearchIndexProvider() {
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                return null;
-            }
-
+        new BaseSearchIndexProvider() {
             @Override
             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
                 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
diff --git a/src/com/android/settings/ZenModeSettings.java b/src/com/android/settings/ZenModeSettings.java
index 65acb15..51b43fd 100644
--- a/src/com/android/settings/ZenModeSettings.java
+++ b/src/com/android/settings/ZenModeSettings.java
@@ -28,7 +28,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.Settings.Global;
-import android.provider.SearchIndexableResource;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.Gravity;
@@ -45,6 +44,7 @@
 import android.widget.ScrollView;
 import android.widget.Switch;
 import android.widget.TextView;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 
@@ -292,14 +292,7 @@
 
     // Enable indexing of searchable data
     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new Indexable.SearchIndexProvider() {
-
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                return null;
-            }
-
+        new BaseSearchIndexProvider() {
             @Override
             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
                 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 7068bc7..b707e7b 100755
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -32,7 +32,6 @@
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
-import android.provider.SearchIndexableResource;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.Menu;
@@ -44,6 +43,7 @@
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 
@@ -418,14 +418,7 @@
     }
 
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new SearchIndexProvider() {
-
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                return null;
-            }
-
+        new BaseSearchIndexProvider() {
             @Override
             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
 
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
index de793cf..68d0d5f 100644
--- a/src/com/android/settings/deviceinfo/Memory.java
+++ b/src/com/android/settings/deviceinfo/Memory.java
@@ -52,6 +52,7 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.google.android.collect.Lists;
@@ -432,14 +433,7 @@
      * Enable indexing of searchable data
      */
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new SearchIndexProvider() {
-
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                return null;
-            }
-
+        new BaseSearchIndexProvider() {
             @Override
             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
                 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java
new file mode 100644
index 0000000..0fe1944
--- /dev/null
+++ b/src/com/android/settings/search/BaseSearchIndexProvider.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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 com.android.settings.search;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A basic SearchIndexProvider that returns no data to index.
+ */
+public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
+
+    private static final List<String> EMPTY_LIST = Collections.<String>emptyList();
+
+    public BaseSearchIndexProvider() {
+    }
+
+    @Override
+    public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, boolean enabled) {
+        return null;
+    }
+
+    @Override
+    public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
+        return null;
+    }
+
+    @Override
+    public List<String> getNonIndexableKeys(Context context) {
+        return EMPTY_LIST;
+    }
+}
diff --git a/src/com/android/settings/search/Index.java b/src/com/android/settings/search/Index.java
index 3281b8a..1aeb1ff 100644
--- a/src/com/android/settings/search/Index.java
+++ b/src/com/android/settings/search/Index.java
@@ -46,6 +46,7 @@
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.ExecutionException;
@@ -136,6 +137,8 @@
     private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference";
     private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference";
 
+    private static final List<String> EMPTY_LIST = Collections.<String>emptyList();
+
     private static Index sInstance;
     private final AtomicBoolean mIsAvailable = new AtomicBoolean(false);
     private final UpdateData mDataToProcess = new UpdateData();
@@ -530,19 +533,35 @@
 
     private void indexOneResource(SQLiteDatabase database, String localeStr,
                                   SearchIndexableResource sir) {
+
+        if (sir == null) {
+            Log.e(LOG_TAG, "Cannot index a null resource!");
+            return;
+        }
+
+        // Will be non null only for a Local provider
+        final Indexable.SearchIndexProvider provider =
+                TextUtils.isEmpty(sir.className) ? null : getSearchIndexProvider(sir.className);
+
         if (sir.xmlResId > SearchIndexableResources.NO_DATA_RES_ID) {
+            List<String> doNotIndexKeys = EMPTY_LIST;
+            if (provider != null) {
+                doNotIndexKeys = provider.getNonIndexableKeys(sir.context);
+            }
             indexFromResource(sir.context, database, localeStr,
                     sir.xmlResId, sir.className, sir.iconResId, sir.rank,
-                    sir.intentAction, sir.intentTargetPackage, sir.intentTargetClass);
+                    sir.intentAction, sir.intentTargetPackage, sir.intentTargetClass,
+                    doNotIndexKeys);
         } else if (!TextUtils.isEmpty(sir.className)) {
-            sir.context = mContext;
-            indexFromLocalProvider(database, localeStr, sir);
+            indexFromLocalProvider(mContext, database, localeStr, provider, sir.className,
+                    sir.iconResId, sir.rank, sir.enabled);
         }
     }
 
     private void indexFromResource(Context context, SQLiteDatabase database, String localeStr,
-            int xmlResId, String fragmentName, int iconResId, int rank,
-            String intentAction, String intentTargetPackage, String intentTargetClass) {
+           int xmlResId, String fragmentName, int iconResId, int rank,
+           String intentAction, String intentTargetPackage, String intentTargetClass,
+           List<String> doNotIndexKeys) {
 
         XmlResourceParser parser = null;
         try {
@@ -563,18 +582,26 @@
 
             final int outerDepth = parser.getDepth();
             final AttributeSet attrs = Xml.asAttributeSet(parser);
+
             final String screenTitle = getDataTitle(context, attrs);
 
-            String title = getDataTitle(context, attrs);
-            String summary = getDataSummary(context, attrs);
-            String keywords = getDataKeywords(context, attrs);
             String key = getDataKey(context, attrs);
 
+            String title;
+            String summary;
+            String keywords;
+
             // Insert rows for the main PreferenceScreen node. Rewrite the data for removing
             // hyphens.
-            updateOneRowWithFilteredData(database, localeStr, title, summary, null, null,
-                    fragmentName, screenTitle, iconResId, rank,
-                    keywords, intentAction, intentTargetPackage, intentTargetClass, true, key);
+            if (!doNotIndexKeys.contains(key)) {
+                title = getDataTitle(context, attrs);
+                summary = getDataSummary(context, attrs);
+                keywords = getDataKeywords(context, attrs);
+
+                updateOneRowWithFilteredData(database, localeStr, title, summary, null, null,
+                        fragmentName, screenTitle, iconResId, rank,
+                        keywords, intentAction, intentTargetPackage, intentTargetClass, true, key);
+            }
 
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -584,9 +611,13 @@
 
                 nodeName = parser.getName();
 
+                key = getDataKey(context, attrs);
+                if (doNotIndexKeys.contains(key)) {
+                    continue;
+                }
+
                 title = getDataTitle(context, attrs);
                 keywords = getDataKeywords(context, attrs);
-                key = getDataKey(context, attrs);
 
                 if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) {
                     summary = getDataSummary(context, attrs);
@@ -664,16 +695,18 @@
         return null;
     }
 
-    private void indexFromLocalProvider(SQLiteDatabase database, String localeStr,
-                                        SearchIndexableResource sir) {
-        final Indexable.SearchIndexProvider provider = getSearchIndexProvider(sir.className);
+    private void indexFromLocalProvider(Context context, SQLiteDatabase database, String localeStr,
+                Indexable.SearchIndexProvider provider, String className, int iconResId, int rank,
+                boolean enabled) {
+
         if (provider == null) {
-            Log.w(LOG_TAG, "Cannot find provider: " + sir.className);
+            Log.w(LOG_TAG, "Cannot find provider: " + className);
             return;
         }
 
-        final List<SearchIndexableRaw> rawList =
-                provider.getRawDataToIndex(sir.context, sir.enabled);
+        final List<String> doNotIndexKeys = provider.getNonIndexableKeys(context);
+        final List<SearchIndexableRaw> rawList = provider.getRawDataToIndex(context, enabled);
+
         if (rawList != null) {
             final int rawSize = rawList.size();
             for (int i = 0; i < rawSize; i++) {
@@ -684,15 +717,19 @@
                     continue;
                 }
 
+                if (doNotIndexKeys.contains(raw.key)) {
+                    continue;
+                }
+
                 updateOneRowWithFilteredData(database, localeStr,
                         raw.title,
                         raw.summaryOn,
                         raw.summaryOff,
                         raw.entries,
-                        sir.className,
+                        className,
                         raw.screenTitle,
-                        sir.iconResId,
-                        sir.rank,
+                        iconResId,
+                        rank,
                         raw.keywords,
                         raw.intentAction,
                         raw.intentTargetPackage,
@@ -703,7 +740,7 @@
         }
 
         final List<SearchIndexableResource> resList =
-                provider.getXmlResourcesToIndex(sir.context, sir.enabled);
+                provider.getXmlResourcesToIndex(context, enabled);
         if (resList != null) {
             final int resSize = resList.size();
             for (int i = 0; i < resSize; i++) {
@@ -714,10 +751,10 @@
                     continue;
                 }
 
-                indexFromResource(sir.context, database, localeStr,
+                indexFromResource(context, database, localeStr,
                         item.xmlResId, item.className, item.iconResId, item.rank,
                         item.intentAction, item.intentTargetPackage,
-                        item.intentTargetClass);
+                        item.intentTargetClass, doNotIndexKeys);
             }
         }
     }
diff --git a/src/com/android/settings/search/Indexable.java b/src/com/android/settings/search/Indexable.java
index 004e5a7..19f88ae 100644
--- a/src/com/android/settings/search/Indexable.java
+++ b/src/com/android/settings/search/Indexable.java
@@ -57,5 +57,13 @@
          * @return a list of {@link SearchIndexableRaw} references. Can be null.
          */
         List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled);
+
+        /**
+         * Return a list of data keys that cannot be indexed. See {@link SearchIndexableRaw}
+         *
+         * @param context the context.
+         * @return a list of {@link SearchIndexableRaw} references. Can be null.
+         */
+        List<String> getNonIndexableKeys(Context context);
     }
 }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 43f9f75..21efc39 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -20,10 +20,10 @@
 import static android.os.UserManager.DISALLOW_CONFIG_WIFI;
 
 import android.preference.PreferenceActivity;
-import android.provider.SearchIndexableResource;
 import com.android.settings.R;
 import com.android.settings.RestrictedSettingsFragment;
 import com.android.settings.SettingsActivity;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settings.wifi.p2p.WifiP2pSettings;
@@ -1164,13 +1164,7 @@
     }
 
     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new SearchIndexProvider() {
-            @Override
-            public List<SearchIndexableResource> getXmlResourcesToIndex(
-                    Context context, boolean enabled) {
-                return null;
-            }
-
+        new BaseSearchIndexProvider() {
             @Override
             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
                 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();