Add capability for OEMs to supply their own SearchIndexableResources.

This moves SearchIndexableResources to be supplied by FeatureFactory
rather than its own singleton, which in effect allows OEMs to supply their
own, in the case where they have their own classes they want to be
indexed (or, remove certain classes that used to be indexed).

Bug: 72179744
Test: All tests pass.

Change-Id: Ia06b2026df7eca4c53b44a5a589c4aaa0b69d96c
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 878bbfd..cbe49f8 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -48,6 +48,11 @@
 
     DatabaseIndexingManager getIndexingManager(Context context);
 
+    /**
+     * @return a {@link SearchIndexableResources} to be used for indexing search results.
+     */
+    SearchIndexableResources getSearchIndexableResources();
+
     default String getSettingsIntelligencePkgName() {
         return "com.android.settings.intelligence";
     }
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index ccd4ff1..78c47ed 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -36,6 +36,7 @@
 
     private static final String METRICS_ACTION_SETTINGS_INDEX = "search_synchronous_indexing";
     private DatabaseIndexingManager mDatabaseIndexingManager;
+    private SearchIndexableResources mSearchIndexableResources;
 
     @Override
     public void verifyLaunchSearchResultPageCaller(Context context, ComponentName caller) {
@@ -72,6 +73,14 @@
                 .histogram(context, METRICS_ACTION_SETTINGS_INDEX, indexingTime);
     }
 
+    @Override
+    public SearchIndexableResources getSearchIndexableResources() {
+        if (mSearchIndexableResources == null) {
+            mSearchIndexableResources = new SearchIndexableResourcesImpl();
+        }
+        return mSearchIndexableResources;
+    }
+
     protected boolean isSignatureWhitelisted(Context context, String callerPackage) {
         return false;
     }
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index b0159cf..5a0a131 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -16,170 +16,14 @@
 
 package com.android.settings.search;
 
-import android.support.annotation.VisibleForTesting;
-
-import com.android.settings.DateTimeSettings;
-import com.android.settings.DisplaySettings;
-import com.android.settings.LegalSettings;
-import com.android.settings.accessibility.AccessibilitySettings;
-import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
-import com.android.settings.accessibility.MagnificationPreferenceFragment;
-import com.android.settings.accounts.UserAndAccountDashboardFragment;
-import com.android.settings.applications.AppAndNotificationDashboardFragment;
-import com.android.settings.applications.DefaultAppSettings;
-import com.android.settings.applications.SpecialAccessSettings;
-import com.android.settings.applications.assist.ManageAssist;
-import com.android.settings.backup.BackupSettingsActivity;
-import com.android.settings.backup.BackupSettingsFragment;
-import com.android.settings.bluetooth.BluetoothSettings;
-import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
-import com.android.settings.datausage.DataUsageSummary;
-import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
-import com.android.settings.development.DevelopmentSettingsDashboardFragment;
-import com.android.settings.deviceinfo.DeviceInfoSettings;
-import com.android.settings.deviceinfo.StorageDashboardFragment;
-import com.android.settings.deviceinfo.StorageSettings;
-import com.android.settings.display.AmbientDisplaySettings;
-import com.android.settings.display.NightDisplaySettings;
-import com.android.settings.display.ScreenZoomSettings;
-import com.android.settings.dream.DreamSettings;
-import com.android.settings.enterprise.EnterprisePrivacySettings;
-import com.android.settings.fuelgauge.BatterySaverSettings;
-import com.android.settings.fuelgauge.PowerUsageAdvanced;
-import com.android.settings.fuelgauge.PowerUsageSummary;
-import com.android.settings.fuelgauge.SmartBatterySettings;
-import com.android.settings.gestures.AssistGestureSettings;
-import com.android.settings.gestures.DoubleTapPowerSettings;
-import com.android.settings.gestures.DoubleTapScreenSettings;
-import com.android.settings.gestures.DoubleTwistGestureSettings;
-import com.android.settings.gestures.GestureSettings;
-import com.android.settings.gestures.PickupGestureSettings;
-import com.android.settings.gestures.SwipeToNotificationSettings;
-import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
-import com.android.settings.inputmethod.PhysicalKeyboardFragment;
-import com.android.settings.inputmethod.VirtualKeyboardFragment;
-import com.android.settings.language.LanguageAndInputSettings;
-import com.android.settings.location.LocationMode;
-import com.android.settings.location.LocationSettings;
-import com.android.settings.location.ScanningSettings;
-import com.android.settings.network.NetworkDashboardFragment;
-import com.android.settings.nfc.PaymentSettings;
-import com.android.settings.notification.ConfigureNotificationSettings;
-import com.android.settings.notification.SoundSettings;
-import com.android.settings.notification.ZenModeAutomationSettings;
-import com.android.settings.notification.ZenModeBehaviorSettings;
-import com.android.settings.notification.ZenModeSettings;
-import com.android.settings.print.PrintSettingsFragment;
-import com.android.settings.security.EncryptionAndCredential;
-import com.android.settings.security.LockscreenDashboardFragment;
-import com.android.settings.security.ScreenPinningSettings;
-import com.android.settings.security.SecuritySettingsV2;
-import com.android.settings.security.screenlock.ScreenLockSettings;
-import com.android.settings.sim.SimSettings;
-import com.android.settings.support.SupportDashboardActivity;
-import com.android.settings.system.ResetDashboardFragment;
-import com.android.settings.system.SystemDashboardFragment;
-import com.android.settings.tts.TextToSpeechSettings;
-import com.android.settings.tts.TtsEnginePreferenceFragment;
-import com.android.settings.users.UserSettings;
-import com.android.settings.wallpaper.WallpaperTypeSettings;
-import com.android.settings.wfd.WifiDisplaySettings;
-import com.android.settings.wifi.ConfigureWifiSettings;
-import com.android.settings.wifi.WifiSettings;
-
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
 
-public final class SearchIndexableResources {
+public interface SearchIndexableResources {
 
-    @VisibleForTesting
-    static final Set<Class> sProviders = new HashSet<>();
-
-    @VisibleForTesting
-    static void addIndex(Class indexClass) {
-        sProviders.add(indexClass);
-    }
-
-    static {
-        addIndex(WifiSettings.class);
-        addIndex(NetworkDashboardFragment.class);
-        addIndex(ConfigureWifiSettings.class);
-        addIndex(BluetoothSettings.class);
-        addIndex(SimSettings.class);
-        addIndex(DataUsageSummary.class);
-        addIndex(ScreenZoomSettings.class);
-        addIndex(DisplaySettings.class);
-        addIndex(AmbientDisplaySettings.class);
-        addIndex(WallpaperTypeSettings.class);
-        addIndex(AppAndNotificationDashboardFragment.class);
-        addIndex(SoundSettings.class);
-        addIndex(ZenModeSettings.class);
-        addIndex(StorageSettings.class);
-        addIndex(PowerUsageAdvanced.class);
-        addIndex(DefaultAppSettings.class);
-        addIndex(ManageAssist.class);
-        addIndex(SpecialAccessSettings.class);
-        addIndex(UserSettings.class);
-        addIndex(AssistGestureSettings.class);
-        addIndex(PickupGestureSettings.class);
-        addIndex(DoubleTapScreenSettings.class);
-        addIndex(DoubleTapPowerSettings.class);
-        addIndex(DoubleTwistGestureSettings.class);
-        addIndex(SwipeToNotificationSettings.class);
-        addIndex(GestureSettings.class);
-        addIndex(LanguageAndInputSettings.class);
-        addIndex(LocationSettings.class);
-        addIndex(LocationMode.class);
-        addIndex(ScanningSettings.class);
-        addIndex(SecuritySettingsV2.class);
-        addIndex(ScreenLockSettings.class);
-        addIndex(EncryptionAndCredential.class);
-        addIndex(ScreenPinningSettings.class);
-        addIndex(UserAndAccountDashboardFragment.class);
-        addIndex(VirtualKeyboardFragment.class);
-        addIndex(AvailableVirtualKeyboardFragment.class);
-        addIndex(PhysicalKeyboardFragment.class);
-        addIndex(BackupSettingsActivity.class);
-        addIndex(BackupSettingsFragment.class);
-        addIndex(DateTimeSettings.class);
-        addIndex(AccessibilitySettings.class);
-        addIndex(PrintSettingsFragment.class);
-        addIndex(DevelopmentSettingsDashboardFragment.class);
-        addIndex(DeviceInfoSettings.class);
-        addIndex(LegalSettings.class);
-        addIndex(SystemDashboardFragment.class);
-        addIndex(ResetDashboardFragment.class);
-        addIndex(StorageDashboardFragment.class);
-        addIndex(ConnectedDeviceDashboardFragment.class);
-        addIndex(ConnectedDeviceDashboardFragmentOld.class);
-        addIndex(AdvancedConnectedDeviceDashboardFragment.class);
-        addIndex(EnterprisePrivacySettings.class);
-        addIndex(PaymentSettings.class);
-        addIndex(TextToSpeechSettings.class);
-        addIndex(TtsEnginePreferenceFragment.class);
-        addIndex(MagnificationPreferenceFragment.class);
-        addIndex(AccessibilityShortcutPreferenceFragment.class);
-        addIndex(DreamSettings.class);
-        addIndex(SupportDashboardActivity.class);
-        addIndex(AutomaticStorageManagerSettings.class);
-        addIndex(ConfigureNotificationSettings.class);
-        addIndex(PowerUsageSummary.class);
-        addIndex(BatterySaverSettings.class);
-        addIndex(LockscreenDashboardFragment.class);
-        addIndex(WifiDisplaySettings.class);
-        addIndex(ZenModeBehaviorSettings.class);
-        addIndex(ZenModeAutomationSettings.class);
-        addIndex(NightDisplaySettings.class);
-        addIndex(SmartBatterySettings.class);
-    }
-
-    private SearchIndexableResources() {
-    }
-
-    public static Collection<Class> providerValues() {
-        return sProviders;
-    }
-}
\ No newline at end of file
+    /**
+     * Returns a collection of classes that should be indexed for search.
+     *
+     * Each class should have the SEARCH_INDEX_DATA_PROVIDER public static member.
+     */
+    Collection<Class> getProviderValues();
+}
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
new file mode 100644
index 0000000..2c20703
--- /dev/null
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -0,0 +1,182 @@
+/*
+ * 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.support.annotation.VisibleForTesting;
+
+import com.android.settings.DateTimeSettings;
+import com.android.settings.DisplaySettings;
+import com.android.settings.LegalSettings;
+import com.android.settings.accessibility.AccessibilitySettings;
+import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
+import com.android.settings.accessibility.MagnificationPreferenceFragment;
+import com.android.settings.accounts.UserAndAccountDashboardFragment;
+import com.android.settings.applications.AppAndNotificationDashboardFragment;
+import com.android.settings.applications.DefaultAppSettings;
+import com.android.settings.applications.SpecialAccessSettings;
+import com.android.settings.applications.assist.ManageAssist;
+import com.android.settings.backup.BackupSettingsActivity;
+import com.android.settings.backup.BackupSettingsFragment;
+import com.android.settings.bluetooth.BluetoothSettings;
+import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
+import com.android.settings.datausage.DataUsageSummary;
+import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.deviceinfo.DeviceInfoSettings;
+import com.android.settings.deviceinfo.StorageDashboardFragment;
+import com.android.settings.deviceinfo.StorageSettings;
+import com.android.settings.display.AmbientDisplaySettings;
+import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.display.ScreenZoomSettings;
+import com.android.settings.dream.DreamSettings;
+import com.android.settings.enterprise.EnterprisePrivacySettings;
+import com.android.settings.fuelgauge.BatterySaverSettings;
+import com.android.settings.fuelgauge.PowerUsageAdvanced;
+import com.android.settings.fuelgauge.PowerUsageSummary;
+import com.android.settings.fuelgauge.SmartBatterySettings;
+import com.android.settings.gestures.AssistGestureSettings;
+import com.android.settings.gestures.DoubleTapPowerSettings;
+import com.android.settings.gestures.DoubleTapScreenSettings;
+import com.android.settings.gestures.DoubleTwistGestureSettings;
+import com.android.settings.gestures.GestureSettings;
+import com.android.settings.gestures.PickupGestureSettings;
+import com.android.settings.gestures.SwipeToNotificationSettings;
+import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
+import com.android.settings.inputmethod.PhysicalKeyboardFragment;
+import com.android.settings.inputmethod.VirtualKeyboardFragment;
+import com.android.settings.language.LanguageAndInputSettings;
+import com.android.settings.location.LocationMode;
+import com.android.settings.location.LocationSettings;
+import com.android.settings.location.ScanningSettings;
+import com.android.settings.network.NetworkDashboardFragment;
+import com.android.settings.nfc.PaymentSettings;
+import com.android.settings.notification.ConfigureNotificationSettings;
+import com.android.settings.notification.SoundSettings;
+import com.android.settings.notification.ZenModeAutomationSettings;
+import com.android.settings.notification.ZenModeBehaviorSettings;
+import com.android.settings.notification.ZenModeSettings;
+import com.android.settings.print.PrintSettingsFragment;
+import com.android.settings.security.EncryptionAndCredential;
+import com.android.settings.security.LockscreenDashboardFragment;
+import com.android.settings.security.ScreenPinningSettings;
+import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settings.sim.SimSettings;
+import com.android.settings.support.SupportDashboardActivity;
+import com.android.settings.system.ResetDashboardFragment;
+import com.android.settings.system.SystemDashboardFragment;
+import com.android.settings.tts.TextToSpeechSettings;
+import com.android.settings.tts.TtsEnginePreferenceFragment;
+import com.android.settings.users.UserSettings;
+import com.android.settings.wallpaper.WallpaperTypeSettings;
+import com.android.settings.wfd.WifiDisplaySettings;
+import com.android.settings.wifi.ConfigureWifiSettings;
+import com.android.settings.wifi.WifiSettings;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class SearchIndexableResourcesImpl implements SearchIndexableResources {
+
+    private final Set<Class> sProviders = new HashSet<>();
+
+    @VisibleForTesting
+    void addIndex(Class indexClass) {
+        sProviders.add(indexClass);
+    }
+
+    public SearchIndexableResourcesImpl() {
+        addIndex(WifiSettings.class);
+        addIndex(NetworkDashboardFragment.class);
+        addIndex(ConfigureWifiSettings.class);
+        addIndex(BluetoothSettings.class);
+        addIndex(SimSettings.class);
+        addIndex(DataUsageSummary.class);
+        addIndex(ScreenZoomSettings.class);
+        addIndex(DisplaySettings.class);
+        addIndex(AmbientDisplaySettings.class);
+        addIndex(WallpaperTypeSettings.class);
+        addIndex(AppAndNotificationDashboardFragment.class);
+        addIndex(SoundSettings.class);
+        addIndex(ZenModeSettings.class);
+        addIndex(StorageSettings.class);
+        addIndex(PowerUsageAdvanced.class);
+        addIndex(DefaultAppSettings.class);
+        addIndex(ManageAssist.class);
+        addIndex(SpecialAccessSettings.class);
+        addIndex(UserSettings.class);
+        addIndex(AssistGestureSettings.class);
+        addIndex(PickupGestureSettings.class);
+        addIndex(DoubleTapScreenSettings.class);
+        addIndex(DoubleTapPowerSettings.class);
+        addIndex(DoubleTwistGestureSettings.class);
+        addIndex(SwipeToNotificationSettings.class);
+        addIndex(GestureSettings.class);
+        addIndex(LanguageAndInputSettings.class);
+        addIndex(LocationSettings.class);
+        addIndex(LocationMode.class);
+        addIndex(ScanningSettings.class);
+        addIndex(SecuritySettingsV2.class);
+        addIndex(ScreenLockSettings.class);
+        addIndex(EncryptionAndCredential.class);
+        addIndex(ScreenPinningSettings.class);
+        addIndex(UserAndAccountDashboardFragment.class);
+        addIndex(VirtualKeyboardFragment.class);
+        addIndex(AvailableVirtualKeyboardFragment.class);
+        addIndex(PhysicalKeyboardFragment.class);
+        addIndex(BackupSettingsActivity.class);
+        addIndex(BackupSettingsFragment.class);
+        addIndex(DateTimeSettings.class);
+        addIndex(AccessibilitySettings.class);
+        addIndex(PrintSettingsFragment.class);
+        addIndex(DevelopmentSettingsDashboardFragment.class);
+        addIndex(DeviceInfoSettings.class);
+        addIndex(LegalSettings.class);
+        addIndex(SystemDashboardFragment.class);
+        addIndex(ResetDashboardFragment.class);
+        addIndex(StorageDashboardFragment.class);
+        addIndex(ConnectedDeviceDashboardFragment.class);
+        addIndex(ConnectedDeviceDashboardFragmentOld.class);
+        addIndex(AdvancedConnectedDeviceDashboardFragment.class);
+        addIndex(EnterprisePrivacySettings.class);
+        addIndex(PaymentSettings.class);
+        addIndex(TextToSpeechSettings.class);
+        addIndex(TtsEnginePreferenceFragment.class);
+        addIndex(MagnificationPreferenceFragment.class);
+        addIndex(AccessibilityShortcutPreferenceFragment.class);
+        addIndex(DreamSettings.class);
+        addIndex(SupportDashboardActivity.class);
+        addIndex(AutomaticStorageManagerSettings.class);
+        addIndex(ConfigureNotificationSettings.class);
+        addIndex(PowerUsageSummary.class);
+        addIndex(BatterySaverSettings.class);
+        addIndex(LockscreenDashboardFragment.class);
+        addIndex(WifiDisplaySettings.class);
+        addIndex(ZenModeBehaviorSettings.class);
+        addIndex(ZenModeAutomationSettings.class);
+        addIndex(NightDisplaySettings.class);
+        addIndex(SmartBatterySettings.class);
+    }
+
+    @Override
+    public Collection<Class> getProviderValues() {
+        return sProviders;
+    }
+}
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index 0c98b9c..3ef1b85 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -175,7 +175,8 @@
     }
 
     private List<String> getNonIndexableKeysFromProvider(Context context) {
-        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final Collection<Class> values = FeatureFactory.getFactory(context)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
         final List<String> nonIndexableKeys = new ArrayList<>();
 
         for (Class<?> clazz : values) {
@@ -209,7 +210,8 @@
     }
 
     private List<SearchIndexableResource> getSearchIndexableResourcesFromProvider(Context context) {
-        Collection<Class> values = SearchIndexableResources.providerValues();
+        Collection<Class> values = FeatureFactory.getFactory(context)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
         List<SearchIndexableResource> resourceList = new ArrayList<>();
 
         for (Class<?> clazz : values) {
@@ -236,7 +238,8 @@
     }
 
     private List<SearchIndexableRaw> getSearchIndexableRawFromProvider(Context context) {
-        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final Collection<Class> values = FeatureFactory.getFactory(context)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
         final List<SearchIndexableRaw> rawList = new ArrayList<>();
 
         for (Class<?> clazz : values) {
diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java
index c10753f..e5a21e4 100644
--- a/src/com/android/settings/slices/SliceDataConverter.java
+++ b/src/com/android/settings/slices/SliceDataConverter.java
@@ -27,9 +27,9 @@
 import android.util.Xml;
 
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable.SearchIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
 import com.android.settings.search.XmlParserUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -62,7 +62,8 @@
      * @return a list of {@link SliceData} to be indexed and later referenced as a Slice.
      *
      * The collection works as follows:
-     * - Collects a list of Fragments from {@link SearchIndexableResources}.
+     * - Collects a list of Fragments from
+     * {@link FeatureFactory#getSearchFeatureProvider()}.
      * - From each fragment, grab a {@link SearchIndexProvider}.
      * - For each provider, collect XML resource layout and a list of
      * {@link com.android.settings.core.BasePreferenceController}.
@@ -72,7 +73,8 @@
             return mSliceData;
         }
 
-        final Collection<Class> indexableClasses = SearchIndexableResources.providerValues();
+        final Collection<Class> indexableClasses = FeatureFactory.getFactory(mContext)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
 
         for (Class clazz : indexableClasses) {
             final String fragmentName = clazz.getName();
diff --git a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
index c561d0d..8ded9d6 100644
--- a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
+++ b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
@@ -2,6 +2,8 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.mockito.Mockito.mock;
+
 import android.content.Context;
 import android.content.res.XmlResourceParser;
 import android.provider.SearchIndexableResource;
@@ -13,10 +15,12 @@
 import com.android.settings.TestConfig;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableResources;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
 import com.android.settings.search.XmlParserUtils;
 import com.android.settings.security.SecuritySettings;
 import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -82,19 +86,21 @@
                     + "IllegalAccessException. Please fix the following classes:\n";
 
     Context mContext;
-
-    private Set<Class> mProviderClassesCopy;
+    SearchFeatureProvider mSearchProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-        mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
+        mSearchProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
@@ -156,7 +162,8 @@
     private Set<Integer> getIndexableXml() {
         Set<Integer> xmlResSet = new HashSet();
 
-        Collection<Class> indexableClasses = SearchIndexableResources.providerValues();
+        Collection<Class> indexableClasses =
+                mSearchProvider.getSearchIndexableResources().getProviderValues();
         indexableClasses.removeAll(illegalClasses);
 
         for (Class clazz : indexableClasses) {
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
index f84f9a2..d610363 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
@@ -121,7 +121,8 @@
                 continue;
             }
             // Must be in SearchProviderRegistry
-            if (!SearchIndexableResources.providerValues().contains(clazz)) {
+            SearchFeatureProvider provider = new SearchFeatureProviderImpl();
+            if (!provider.getSearchIndexableResources().getProviderValues().contains(clazz)) {
                 if (!notInSearchIndexableRegistryGrandfatherList.remove(className)) {
                     notInSearchProviderRegistry.add(className);
                 }
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
index eedb324..72dd94c 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
@@ -21,12 +21,14 @@
 
 import static junit.framework.Assert.fail;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.database.Cursor;
 import android.text.TextUtils;
 
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.wifi.WifiSettings;
 
@@ -36,49 +38,56 @@
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
-import java.util.Set;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SearchIndexableResourcesTest {
 
-    Set<Class> sProviderClassCopy;
+    SearchFeatureProviderImpl mSearchProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
-        sProviderClassCopy = new HashSet<>(SearchIndexableResources.sProviders);
+        mSearchProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.sProviders.addAll(sProviderClassCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
     public void testAddIndex() {
         final Class stringClass = java.lang.String.class;
         // Confirms that String.class isn't contained in SearchIndexableResources.
-        assertThat(SearchIndexableResources.sProviders).doesNotContain(stringClass);
-        final int beforeCount = SearchIndexableResources.providerValues().size();
+        assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+                .doesNotContain(stringClass);
+        final int beforeCount =
+                mSearchProvider.getSearchIndexableResources().getProviderValues().size();
 
-        SearchIndexableResources.addIndex(java.lang.String.class);
+        ( (SearchIndexableResourcesImpl) mSearchProvider.getSearchIndexableResources())
+                .addIndex(java.lang.String.class);
 
-        assertThat(SearchIndexableResources.sProviders).contains(stringClass);
-        final int afterCount = SearchIndexableResources.providerValues().size();
+        assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+                .contains(stringClass);
+        final int afterCount =
+                mSearchProvider.getSearchIndexableResources().getProviderValues().size();
         assertThat(afterCount).isEqualTo(beforeCount + 1);
     }
 
     @Test
     public void testIndexHasWifiSettings() {
-        assertThat(sProviderClassCopy).contains(WifiSettings.class);
+        assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+                .contains(WifiSettings.class);
     }
 
     @Test
     public void testNonIndexableKeys_GetsKeyFromProvider() {
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.addIndex(FakeIndexProvider.class);
+        mSearchProvider.getSearchIndexableResources().getProviderValues().clear();
+        ( (SearchIndexableResourcesImpl) mSearchProvider.getSearchIndexableResources())
+                .addIndex(FakeIndexProvider.class);
 
         SettingsSearchIndexablesProvider provider = spy(new SettingsSearchIndexablesProvider());
 
@@ -97,7 +106,7 @@
 
     @Test
     public void testAllClassNamesHaveProviders() {
-        for (Class clazz: sProviderClassCopy) {
+        for (Class clazz: mSearchProvider.getSearchIndexableResources().getProviderValues()) {
             if(DatabaseIndexingUtils.getSearchIndexProvider(clazz) == null) {
                 fail(clazz.getName() + "is not an index provider");
             }
diff --git a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
index efeaed7..cca2794 100644
--- a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
+++ b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
@@ -2,6 +2,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.Manifest;
@@ -14,6 +15,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.search.indexing.FakeSettingsFragment;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -23,9 +25,6 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
-import java.util.Set;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SettingsSearchIndexablesProviderTest {
@@ -33,8 +32,8 @@
     private final String BASE_AUTHORITY = "com.android.settings";
 
     private SettingsSearchIndexablesProvider mProvider;
-
-    Set<Class> sProviderClasses;
+    private SearchFeatureProvider mFeatureProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
     Context mContext;
 
     @Before
@@ -49,15 +48,18 @@
         info.readPermission = Manifest.permission.READ_SEARCH_INDEXABLES;
         mProvider.attachInfo(mContext, info);
 
-        sProviderClasses = new HashSet<>(SearchIndexableResources.sProviders);
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.sProviders.add(FakeSettingsFragment.class);
+        mFeatureProvider = new SearchFeatureProviderImpl();
+        mFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+        mFeatureProvider.getSearchIndexableResources().getProviderValues()
+                .add(FakeSettingsFragment.class);
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mFeatureProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.sProviders.addAll(sProviderClasses);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index efd1cc5..f5d5ff0 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -19,6 +19,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -26,8 +28,9 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.search.FakeIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
-import com.android.settings.testutils.DatabaseTestUtils;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -37,9 +40,6 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
-import java.util.Set;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SliceBroadcastReceiverTest {
@@ -54,30 +54,30 @@
     private Context mContext;
     private SQLiteDatabase mDb;
     private SliceBroadcastReceiver mReceiver;
-
-    private Set<Class> mProviderClassesCopy;
+    private SearchFeatureProvider mSearchFeatureProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mDb = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase();
         mReceiver = new SliceBroadcastReceiver();
-        mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
         SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext);
         helper.setIndexedState();
+        mSearchFeatureProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchFeatureProvider;
     }
 
     @After
     public void cleanUp() {
-        DatabaseTestUtils.clearDb(mContext);
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(SearchFeatureProvider.class);
     }
 
     @Test
     public void testOnReceive_toggleChanged() {
         String key = "key";
-        SearchIndexableResources.providerValues().clear();
+        mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
         insertSpecialCase(key);
         // Turn on toggle setting
         FakeToggleController fakeToggleController = new FakeToggleController(mContext, key);
diff --git a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
index b5c0b5f..1d0ac41 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
@@ -18,11 +18,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+
 import android.content.Context;
 
 import com.android.settings.TestConfig;
 import com.android.settings.search.FakeIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -32,9 +36,7 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -49,28 +51,31 @@
 
     Context mContext;
 
-    private Set<Class> mProviderClassesCopy;
-
     SliceDataConverter mSliceDataConverter;
+    SearchFeatureProvider mSearchFeatureProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-        mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
         mSliceDataConverter = new SliceDataConverter(mContext);
+        mSearchFeatureProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchFeatureProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
     @Config(qualifiers = "mcc999")
     public void testFakeProvider_convertsFakeData() {
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().add(FakeIndexProvider.class);
+        mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+        mSearchFeatureProvider.getSearchIndexableResources().getProviderValues()
+                .add(FakeIndexProvider.class);
 
         List<SliceData> sliceDataList = mSliceDataConverter.getSliceData();
 
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index b4592b8..3325332 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -55,7 +55,6 @@
     public final LocaleFeatureProvider localeFeatureProvider;
     public final ApplicationFeatureProvider applicationFeatureProvider;
     public final EnterprisePrivacyFeatureProvider enterprisePrivacyFeatureProvider;
-    public final SearchFeatureProvider searchFeatureProvider;
     public final SurveyFeatureProvider surveyFeatureProvider;
     public final SecurityFeatureProvider securityFeatureProvider;
     public final SuggestionFeatureProvider suggestionsFeatureProvider;
@@ -65,6 +64,7 @@
     public final DataPlanFeatureProvider dataPlanFeatureProvider;
     public final SmsMirroringFeatureProvider smsMirroringFeatureProvider;
     public final SlicesFeatureProvider slicesFeatureProvider;
+    public SearchFeatureProvider searchFeatureProvider;
 
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
index 86e8dc1..b16c700 100644
--- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
+++ b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
@@ -26,6 +26,7 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.util.ArraySet;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableResources;
@@ -54,7 +55,10 @@
     public void controllersInSearchShouldImplementPreferenceControllerMixin() {
         final Set<String> errorClasses = new ArraySet<>();
 
-        for (Class clazz : SearchIndexableResources.providerValues()) {
+        final SearchIndexableResources resources =
+                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+                        .getSearchIndexableResources();
+        for (Class<?> clazz : resources.getProviderValues()) {
 
             final Indexable.SearchIndexProvider provider =
                     DatabaseIndexingUtils.getSearchIndexProvider(clazz);
diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
index 36865a4..8fe2358 100644
--- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
+++ b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
@@ -31,6 +31,7 @@
 import android.util.Log;
 import android.util.Xml;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
@@ -100,7 +101,10 @@
         final Set<String> uniqueKeys = new HashSet<>();
         final Set<String> nullKeyClasses = new HashSet<>();
         final Set<String> duplicatedKeys = new HashSet<>();
-        for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+        final SearchIndexableResources resources =
+                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+                        .getSearchIndexableResources();
+        for (Class<?> clazz : resources.getProviderValues()) {
             verifyPreferenceKeys(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz);
         }
 
diff --git a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java b/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
index f37c30b..bf77a5b 100644
--- a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
+++ b/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 import android.util.Xml;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableResources;
@@ -79,7 +80,10 @@
     @Test
     public void userRestrictionAttributeShouldBeValid()
             throws IOException, XmlPullParserException, Resources.NotFoundException {
-        for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+        final SearchIndexableResources resources =
+                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+                        .getSearchIndexableResources();
+        for (Class<?> clazz : resources.getProviderValues()) {
             verifyUserRestriction(clazz);
         }
     }