OSDN Git Service

Move Index provider conversion into Settings provider
authorMatthew Fritze <mfritze@google.com>
Fri, 3 Nov 2017 19:03:59 +0000 (12:03 -0700)
committerMatthew Fritze <mfritze@google.com>
Tue, 7 Nov 2017 19:18:26 +0000 (11:18 -0800)
Pre-patch, settings search provider would push all of its
fragments into to search via SearchIndexableResources with
an implicit contract of if the resource's xml == 0, then
it was a settings fragment with an Index provider.

One, implicit contract is bad. Two, it was messy at indexing time.

So this patch moves htat conversion into the search index provider.
Such that all of the indexables are either real Resources or Raw.

Change-Id: I39f4351c03d123bb9b45edb4df7f924cfaff2b38
Fixes: 65376542
Fixes: 37741509
Test: robotests

src/com/android/settings/search/SearchIndexableResources.java
src/com/android/settings/search/SettingsSearchIndexablesProvider.java
src/com/android/settings/search/indexing/IndexDataConverter.java
tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java
tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
tests/unit/src/com/android/settings/core/UniquePreferenceTest.java

index 69b2f9f..36e4edf 100644 (file)
@@ -16,9 +16,7 @@
 
 package com.android.settings.search;
 
-import android.provider.SearchIndexableResource;
 import android.support.annotation.VisibleForTesting;
-import android.support.annotation.XmlRes;
 
 import com.android.settings.DateTimeSettings;
 import com.android.settings.DeviceInfoSettings;
@@ -88,22 +86,17 @@ import com.android.settings.wifi.ConfigureWifiSettings;
 import com.android.settings.wifi.WifiSettings;
 
 import java.util.Collection;
-import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
 
 public final class SearchIndexableResources {
-    @XmlRes
-    public static final int NO_RES_ID = 0;
 
     @VisibleForTesting
-    static final HashMap<String, SearchIndexableResource> sResMap = new HashMap<>();
+    static final Set<Class> sProviders = new HashSet<>();
 
     @VisibleForTesting
-    static void addIndex(Class<?> indexClass) {
-        String className = indexClass.getName();
-        SearchIndexableResource resource = new SearchIndexableResource(
-                0 /* rank */, NO_RES_ID, className, NO_RES_ID);
-
-        sResMap.put(className, resource);
+    static void addIndex(Class indexClass) {
+        sProviders.add(indexClass);
     }
 
     static {
@@ -178,15 +171,5 @@ public final class SearchIndexableResources {
     private SearchIndexableResources() {
     }
 
-    public static int size() {
-        return sResMap.size();
-    }
-
-    public static SearchIndexableResource getResourceByName(String className) {
-        return sResMap.get(className);
-    }
-
-    public static Collection<SearchIndexableResource> values() {
-        return sResMap.values();
-    }
+    public static Collection<Class> providerValues() { return sProviders;}
 }
\ No newline at end of file
index 622378b..968847b 100644 (file)
 package com.android.settings.search;
 
 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE;
+import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_USER_ID;
 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME;
 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID;
 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION;
@@ -33,11 +46,12 @@ import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.provider.SearchIndexableResource;
 import android.provider.SearchIndexablesProvider;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
 
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
 
 public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
@@ -60,8 +74,9 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
     @Override
     public Cursor queryXmlResources(String[] projection) {
         MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
-        Collection<SearchIndexableResource> values = SearchIndexableResources.values();
-        for (SearchIndexableResource val : values) {
+        final List<SearchIndexableResource> resources =
+                getSearchIndexableResourcesFromProvider(getContext());
+        for (SearchIndexableResource val : resources) {
             Object[] ref = new Object[INDEXABLES_XML_RES_COLUMNS.length];
             ref[COLUMN_INDEX_XML_RES_RANK] = val.rank;
             ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId;
@@ -72,13 +87,33 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
             ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class
             cursor.addRow(ref);
         }
+
         return cursor;
     }
 
     @Override
     public Cursor queryRawData(String[] projection) {
-        MatrixCursor result = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
-        return result;
+        MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
+        final List<SearchIndexableRaw> raws = getSearchIndexableRawFromProvider(getContext());
+        for (SearchIndexableRaw val : raws) {
+            Object[] ref = new Object[INDEXABLES_RAW_COLUMNS.length];
+            ref[COLUMN_INDEX_RAW_TITLE] = val.title;
+            ref[COLUMN_INDEX_RAW_SUMMARY_ON] = val.summaryOn;
+            ref[COLUMN_INDEX_RAW_SUMMARY_OFF] = val.summaryOff;
+            ref[COLUMN_INDEX_RAW_ENTRIES] = val.entries;
+            ref[COLUMN_INDEX_RAW_KEYWORDS] = val.keywords;
+            ref[COLUMN_INDEX_RAW_SCREEN_TITLE] = val.screenTitle;
+            ref[COLUMN_INDEX_RAW_CLASS_NAME] = val.className;
+            ref[COLUMN_INDEX_RAW_ICON_RESID] = val.iconResId;
+            ref[COLUMN_INDEX_RAW_INTENT_ACTION] = val.intentAction;
+            ref[COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE] = val.intentTargetPackage;
+            ref[COLUMN_INDEX_RAW_INTENT_TARGET_CLASS] = val.intentTargetClass;
+            ref[COLUMN_INDEX_RAW_KEY] = val.key;
+            ref[COLUMN_INDEX_RAW_USER_ID] = val.userId;
+            cursor.addRow(ref);
+        }
+
+        return cursor;
     }
 
     /**
@@ -89,29 +124,24 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
     @Override
     public Cursor queryNonIndexableKeys(String[] projection) {
         MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
-        final Collection<String> values = new HashSet<>();
-        final Context context = getContext();
-
-        for (SearchIndexableResource sir : SearchIndexableResources.values()) {
-            if (DEBUG) {
-                Log.d(TAG, "Getting non-indexable from " + sir.className);
-            }
-            final long startTime = System.currentTimeMillis();
-            final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(sir.className);
-            if (clazz == null) {
-                Log.d(TAG, "SearchIndexableResource '" + sir.className +
-                        "' should implement the " + Indexable.class.getName() + " interface!");
-                continue;
-            }
+        final List<String> nonIndexableKeys = getNonIndexableKeysFromProvider(getContext());
+        for (String nik : nonIndexableKeys) {
+            final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length];
+            ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = nik;
+            cursor.addRow(ref);
+        }
 
-            final Indexable.SearchIndexProvider provider =
-                    DatabaseIndexingUtils.getSearchIndexProvider(clazz);
+        return cursor;
+    }
 
-            if (provider == null) {
-                Log.d(TAG, "Unable to get SearchIndexableProvider from " + clazz);
-                continue;
-            }
+    private List<String> getNonIndexableKeysFromProvider(Context context) {
+        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final List<String> nonIndexableKeys = new ArrayList<>();
 
+        for (Class<?> clazz : values) {
+            final long startTime = System.currentTimeMillis();
+            Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+                    clazz);
             List<String> providerNonIndexableKeys = provider.getNonIndexableKeys(context);
 
             if (providerNonIndexableKeys == null || providerNonIndexableKeys.isEmpty()) {
@@ -123,22 +153,71 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
             }
 
             if (providerNonIndexableKeys.removeAll(INVALID_KEYS)) {
-                Log.v(TAG, clazz.getName() + " tried to add an empty non-indexable key");
+                Log.v(TAG, provider + " tried to add an empty non-indexable key");
             }
+
             if (DEBUG) {
                 final long totalTime = System.currentTimeMillis() - startTime;
                 Log.d(TAG, "Non-indexables " + providerNonIndexableKeys.size() + ", total time "
                         + totalTime);
             }
-            values.addAll(providerNonIndexableKeys);
+
+            nonIndexableKeys.addAll(providerNonIndexableKeys);
         }
 
-        for (String nik : values) {
+        return nonIndexableKeys;
+    }
 
-            final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length];
-            ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = nik;
-            cursor.addRow(ref);
+    private List<SearchIndexableResource> getSearchIndexableResourcesFromProvider(Context context) {
+        Collection<Class> values = SearchIndexableResources.providerValues();
+        List<SearchIndexableResource> resourceList = new ArrayList<>();
+
+        for (Class<?> clazz : values) {
+            Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+                    clazz);
+
+            final List<SearchIndexableResource> resList =
+                    provider.getXmlResourcesToIndex(context, true);
+
+            if (resList == null) {
+                continue;
+            }
+
+            for (SearchIndexableResource item : resList) {
+                item.className = TextUtils.isEmpty(item.className)
+                        ? clazz.getName()
+                        : item.className;
+            }
+
+            resourceList.addAll(resList);
         }
-        return cursor;
+
+        return resourceList;
+    }
+
+    private List<SearchIndexableRaw> getSearchIndexableRawFromProvider(Context context) {
+        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final List<SearchIndexableRaw> rawList = new ArrayList<>();
+
+        for (Class<?> clazz : values) {
+            Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+                    clazz);
+            final List<SearchIndexableRaw> providerRaws = provider.getRawDataToIndex(context,
+                    true /* enabled */);
+
+            if (providerRaws == null) {
+                continue;
+            }
+
+            for (SearchIndexableRaw raw : providerRaws) {
+                // The classname and intent information comes from the PreIndexData
+                // This will be more clear when provider conversion is done at PreIndex time.
+                raw.className = clazz.getName();
+
+            }
+            rawList.addAll(providerRaws);
+        }
+
+        return rawList;
     }
 }
index ab60f62..65fa279 100644 (file)
@@ -31,7 +31,6 @@ import android.util.Xml;
 
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.search.DatabaseIndexingUtils;
-import com.android.settings.search.Indexable;
 import com.android.settings.search.ResultPayload;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settings.search.XmlParserUtils;
@@ -89,21 +88,8 @@ public class IndexDataConverter {
                 final SearchIndexableResource sir = (SearchIndexableResource) data;
                 final Set<String> resourceNonIndexableKeys =
                         getNonIndexableKeysForResource(nonIndexableKeys, sir.packageName);
-
-                if (sir.xmlResId == 0) {
-                    // Index from provider
-                    final Indexable.SearchIndexProvider provider = getSearchProvider(sir);
-                    if (provider == null) {
-                        continue;
-                    }
-                    indexData.addAll(convertIndexProvider(provider, sir, resourceNonIndexableKeys));
-
-                } else {
-                    final List<IndexData> resourceData = convertResource(sir,
-                            resourceNonIndexableKeys);
-                    indexData.addAll(resourceData);
-                }
-
+                final List<IndexData> resourceData = convertResource(sir, resourceNonIndexableKeys);
+                indexData.addAll(resourceData);
             }
         }
 
@@ -305,84 +291,10 @@ public class IndexDataConverter {
         return resourceIndexData;
     }
 
-    private List<IndexData> convertIndexProvider(Indexable.SearchIndexProvider provider,
-            SearchIndexableResource sir, Set<String> nonIndexableKeys) {
-        final List<IndexData> indexData = new ArrayList<>();
-
-        final String className = sir.className;
-        final String intentAction = sir.intentAction;
-        final String intentTargetPackage = sir.intentTargetPackage;
-
-        // TODO (b/65376542) Move provider conversion to PreIndexTime
-        // TODO (b/37741509) Providers don't use general non-indexable keys
-        nonIndexableKeys.addAll(provider.getNonIndexableKeys(mContext));
-
-        final List<SearchIndexableRaw> rawList = provider.getRawDataToIndex(mContext,
-                true /* enabled */);
-
-        if (rawList != null) {
-            for (SearchIndexableRaw raw : rawList) {
-                // The classname and intent information comes from the PreIndexData
-                // This will be more clear when provider conversion is done at PreIndex time.
-                raw.className = className;
-                raw.intentAction = intentAction;
-                raw.intentTargetPackage = intentTargetPackage;
-
-                IndexData.Builder builder = convertRaw(raw, nonIndexableKeys);
-                if (builder != null) {
-                    indexData.add(builder.build(mContext));
-                }
-            }
-        }
-
-        final List<SearchIndexableResource> resList =
-                provider.getXmlResourcesToIndex(mContext, true);
-
-        if (resList != null) {
-            for (SearchIndexableResource item : resList) {
-                item.className = TextUtils.isEmpty(item.className)
-                        ? className
-                        : item.className;
-                item.intentAction = TextUtils.isEmpty(item.intentAction)
-                        ? intentAction
-                        : item.intentAction;
-                item.intentTargetPackage = TextUtils.isEmpty(item.intentTargetPackage)
-                        ? intentTargetPackage
-                        : item.intentTargetPackage;
-
-                indexData.addAll(convertResource(item, nonIndexableKeys));
-            }
-        }
-
-        return indexData;
-    }
-
     private Set<String> getNonIndexableKeysForResource(Map<String, Set<String>> nonIndexableKeys,
             String packageName) {
         return nonIndexableKeys.containsKey(packageName)
                 ? nonIndexableKeys.get(packageName)
                 : new HashSet<>();
     }
-
-    /**
-     * @return Return the {@link Indexable.SearchIndexProvider} corresponding to the
-     * class specified by the Class name specified by {@param sir}.
-     */
-    private Indexable.SearchIndexProvider getSearchProvider(SearchIndexableResource sir) {
-        if (TextUtils.isEmpty(sir.className)) {
-            Log.w(LOG_TAG, "Cannot index an empty Search Provider name!");
-            return null;
-        }
-
-        final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(sir.className);
-        if (clazz == null) {
-            Log.d(LOG_TAG, "SearchIndexableResource '" + sir.className +
-                    "' should implement the " + Indexable.class.getName() + " interface!");
-            return null;
-        }
-
-        // Will be non null only for a Local provider implementing a
-        // SEARCH_INDEX_DATA_PROVIDER field
-        return DatabaseIndexingUtils.getSearchIndexProvider(clazz);
-    }
 }
index b4a91c5..3c51a90 100644 (file)
@@ -114,11 +114,10 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
                 continue;
             }
             // Must be in SearchProviderRegistry
-            if (SearchIndexableResources.getResourceByName(className) == null) {
+            if (!SearchIndexableResources.providerValues().contains(clazz)) {
                 if (!notInSearchIndexableRegistryGrandfatherList.remove(className)) {
                     notInSearchProviderRegistry.add(className);
                 }
-                continue;
             }
         }
 
index 0e3ce50..eedb324 100644 (file)
 package com.android.settings.search;
 
 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
-import static com.android.settings.search.SearchIndexableResources.NO_RES_ID;
 import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.fail;
+
 import static org.mockito.Mockito.spy;
 
 import android.database.Cursor;
-import android.provider.SearchIndexableResource;
 import android.text.TextUtils;
 
 import com.android.settings.TestConfig;
@@ -35,60 +36,48 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.Set;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SearchIndexableResourcesTest {
 
-    Map<String, SearchIndexableResource> sResMapCopy;
+    Set<Class> sProviderClassCopy;
 
     @Before
     public void setUp() {
-        sResMapCopy = new HashMap<>(SearchIndexableResources.sResMap);
+        sProviderClassCopy = new HashSet<>(SearchIndexableResources.sProviders);
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.sResMap.clear();
-        for (String key : sResMapCopy.keySet()) {
-            SearchIndexableResources.sResMap.put(key, sResMapCopy.get(key));
-        }
+        SearchIndexableResources.sProviders.clear();
+        SearchIndexableResources.sProviders.addAll(sProviderClassCopy);
     }
 
     @Test
     public void testAddIndex() {
+        final Class stringClass = java.lang.String.class;
         // Confirms that String.class isn't contained in SearchIndexableResources.
-        assertThat(SearchIndexableResources.getResourceByName("java.lang.String")).isNull();
-        final int beforeCount = SearchIndexableResources.values().size();
+        assertThat(SearchIndexableResources.sProviders).doesNotContain(stringClass);
+        final int beforeCount = SearchIndexableResources.providerValues().size();
 
         SearchIndexableResources.addIndex(java.lang.String.class);
-        final SearchIndexableResource index = SearchIndexableResources
-                .getResourceByName("java.lang.String");
-
-        assertThat(index).isNotNull();
-        assertThat(index.className).isEqualTo("java.lang.String");
-        assertThat(index.xmlResId).isEqualTo(NO_RES_ID);
-        assertThat(index.iconResId).isEqualTo(NO_RES_ID);
-        final int afterCount = SearchIndexableResources.values().size();
+
+        assertThat(SearchIndexableResources.sProviders).contains(stringClass);
+        final int afterCount = SearchIndexableResources.providerValues().size();
         assertThat(afterCount).isEqualTo(beforeCount + 1);
     }
 
     @Test
     public void testIndexHasWifiSettings() {
-        final SearchIndexableResource index = SearchIndexableResources
-                .getResourceByName(WifiSettings.class.getName());
-
-        assertThat(index).isNotNull();
-        assertThat(index.className).isEqualTo(WifiSettings.class.getName());
-        assertThat(index.xmlResId).isEqualTo(NO_RES_ID);
-        assertThat(index.iconResId).isEqualTo(NO_RES_ID);
+        assertThat(sProviderClassCopy).contains(WifiSettings.class);
     }
 
     @Test
     public void testNonIndexableKeys_GetsKeyFromProvider() {
-        SearchIndexableResources.sResMap.clear();
+        SearchIndexableResources.sProviders.clear();
         SearchIndexableResources.addIndex(FakeIndexProvider.class);
 
         SettingsSearchIndexablesProvider provider = spy(new SettingsSearchIndexablesProvider());
@@ -105,4 +94,13 @@ public class SearchIndexableResourcesTest {
 
         assertThat(hasTestKey).isTrue();
     }
+
+    @Test
+    public void testAllClassNamesHaveProviders() {
+        for (Class clazz: sProviderClassCopy) {
+            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
new file mode 100644 (file)
index 0000000..efeaed7
--- /dev/null
@@ -0,0 +1,119 @@
+package com.android.settings.search;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.ProviderInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.SearchIndexablesContract;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.search.indexing.FakeSettingsFragment;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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 {
+
+    private final String BASE_AUTHORITY = "com.android.settings";
+
+    private SettingsSearchIndexablesProvider mProvider;
+
+    Set<Class> sProviderClasses;
+    Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+
+        mProvider = spy(new SettingsSearchIndexablesProvider());
+        ProviderInfo info = new ProviderInfo();
+        info.exported = true;
+        info.grantUriPermissions = true;
+        info.authority = BASE_AUTHORITY;
+        info.readPermission = Manifest.permission.READ_SEARCH_INDEXABLES;
+        mProvider.attachInfo(mContext, info);
+
+        sProviderClasses = new HashSet<>(SearchIndexableResources.sProviders);
+        SearchIndexableResources.sProviders.clear();
+        SearchIndexableResources.sProviders.add(FakeSettingsFragment.class);
+    }
+
+    @After
+    public void cleanUp() {
+        SearchIndexableResources.sProviders.clear();
+        SearchIndexableResources.sProviders.addAll(sProviderClasses);
+    }
+
+    @Test
+    public void testRawColumnFetched() {
+        Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
+                SearchIndexablesContract.INDEXABLES_RAW_PATH);
+
+        final Cursor cursor = mProvider.query(rawUri,
+                SearchIndexablesContract.INDEXABLES_RAW_COLUMNS, null, null, null);
+
+        cursor.moveToFirst();
+        assertThat(cursor.getString(1)).isEqualTo(FakeSettingsFragment.TITLE);
+        assertThat(cursor.getString(2)).isEqualTo(FakeSettingsFragment.SUMMARY_ON);
+        assertThat(cursor.getString(3)).isEqualTo(FakeSettingsFragment.SUMMARY_OFF);
+        assertThat(cursor.getString(4)).isEqualTo(FakeSettingsFragment.ENTRIES);
+        assertThat(cursor.getString(5)).isEqualTo(FakeSettingsFragment.KEYWORDS);
+        assertThat(cursor.getString(6)).isEqualTo(FakeSettingsFragment.SCREEN_TITLE);
+        assertThat(cursor.getString(7)).isEqualTo(FakeSettingsFragment.CLASS_NAME);
+        assertThat(cursor.getInt(8)).isEqualTo(FakeSettingsFragment.ICON);
+        assertThat(cursor.getString(9)).isEqualTo(FakeSettingsFragment.INTENT_ACTION);
+        assertThat(cursor.getString(10)).isEqualTo(FakeSettingsFragment.TARGET_PACKAGE);
+        assertThat(cursor.getString(11)).isEqualTo(FakeSettingsFragment.TARGET_CLASS);
+        assertThat(cursor.getString(12)).isEqualTo(FakeSettingsFragment.KEY);
+    }
+
+    @Test
+    public void testResourcesColumnFetched() {
+        Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
+                SearchIndexablesContract.INDEXABLES_XML_RES_PATH);
+
+        final Cursor cursor = mProvider.query(rawUri,
+                SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS, null, null, null);
+
+        cursor.moveToFirst();
+        assertThat(cursor.getCount()).isEqualTo(1);
+        assertThat(cursor.getInt(1)).isEqualTo(R.xml.display_settings);
+        assertThat(cursor.getString(2)).isEqualTo(FakeSettingsFragment.CLASS_NAME);
+        assertThat(cursor.getInt(3)).isEqualTo(0);
+        assertThat(cursor.getString(4)).isNull();
+        assertThat(cursor.getString(5)).isNull();
+        assertThat(cursor.getString(6)).isNull();
+    }
+
+    @Test
+    public void testNonIndexablesColumnFetched() {
+        Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
+                SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH);
+        //final ContentResolver resolver = mContext.getContentResolver();
+
+        final Cursor cursor = mProvider.query(rawUri,
+                SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS, null, null, null);
+
+        cursor.moveToFirst();
+        assertThat(cursor.getCount()).isEqualTo(2);
+        assertThat(cursor.getString(0)).isEqualTo("pref_key_1");
+        cursor.moveToNext();
+        assertThat(cursor.getString(0)).isEqualTo("pref_key_3");
+    }
+}
index b95bfe8..0f2ab56 100644 (file)
@@ -266,55 +266,6 @@ public class IndexDataConverterTest {
         assertThat(row.iconResId).isGreaterThan(0);
     }
 
-    // Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource ->
-    //                     UpdateOneRowWithFilteredData -> UpdateOneRow
-
-    @Test
-    public void testAddProviderWithResource_rowInserted() {
-        final SearchIndexableResource resource = getFakeResource(0 /* xml */);
-        resource.className = FAKE_CLASS_NAME;
-        final PreIndexData preIndexData = new PreIndexData();
-        preIndexData.dataToUpdate.add(resource);
-
-        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData);
-
-        assertThat(indexData.size()).isEqualTo(NUM_FAKE_FRAGMENT_ENTRIES);
-        assertThat(findIndexDataForTitle(indexData, PAGE_TITLE)).isNotNull();
-        assertThat(findIndexDataForTitle(indexData, TITLE_ONE)).isNotNull();
-        assertThat(findIndexDataForTitle(indexData, TITLE_TWO)).isNotNull();
-        assertThat(findIndexDataForTitle(indexData, TITLE_THREE)).isNotNull();
-        assertThat(findIndexDataForTitle(indexData, TITLE_FOUR)).isNotNull();
-        assertThat(findIndexDataForTitle(indexData, TITLE_FIVE)).isNotNull();
-        assertThat(findIndexDataForTitle(indexData, FakeSettingsFragment.TITLE)).isNotNull();
-    }
-
-    @Test
-    public void testAddProviderWithRaw_rowInserted() {
-        final SearchIndexableResource resource = getFakeResource(0 /* xml */);
-        resource.className = FAKE_CLASS_NAME;
-        final PreIndexData preIndexData = new PreIndexData();
-        preIndexData.dataToUpdate.add(resource);
-
-        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData);
-
-        final IndexData data = findIndexDataForTitle(indexData, FakeSettingsFragment.TITLE);
-        assertFakeFragment(data);
-    }
-
-    @Test
-    public void testAddProvider_disabledRows() {
-        // Note that in FakeSettingsFragment, preferences 1 and 3 are disabled.
-        final SearchIndexableResource resource = getFakeResource(0 /* xml */);
-        resource.className = FAKE_CLASS_NAME;
-
-        final PreIndexData preIndexData = new PreIndexData();
-        preIndexData.dataToUpdate.add(resource);
-
-        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData);
-
-        assertThat(getEnabledResultCount(indexData)).isEqualTo(NUM_ENABLED_FAKE_FRAGMENT_ENTRIES);
-    }
-
     @Test
     public void testResource_sameTitleForSettingAndPage_titleNotInserted() {
         final SearchIndexableResource resource = getFakeResource(R.xml.about_legal);
index c75ca13..bc82125 100644 (file)
@@ -54,8 +54,7 @@ public class PreferenceControllerContractTest {
     public void controllersInSearchShouldImplementPreferenceControllerMixin() {
         final Set<String> errorClasses = new ArraySet<>();
 
-        for (SearchIndexableResource page : SearchIndexableResources.values()) {
-            final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(page.className);
+        for (Class clazz: SearchIndexableResources.providerValues()) {
 
             final Indexable.SearchIndexProvider provider =
                     DatabaseIndexingUtils.getSearchIndexProvider(clazz);
index 4c51772..5f3e512 100644 (file)
@@ -90,8 +90,8 @@ public class UniquePreferenceTest {
         final Set<String> uniqueKeys = new HashSet<>();
         final Set<String> nullKeyClasses = new HashSet<>();
         final Set<String> duplicatedKeys = new HashSet<>();
-        for (SearchIndexableResource sir : SearchIndexableResources.values()) {
-            verifyPreferenceIdInXml(uniqueKeys, duplicatedKeys, nullKeyClasses, sir);
+        for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+            verifyPreferenceIdInXml(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz);
         }
 
         if (!nullKeyClasses.isEmpty()) {
@@ -115,22 +115,24 @@ public class UniquePreferenceTest {
     }
 
     private void verifyPreferenceIdInXml(Set<String> uniqueKeys, Set<String> duplicatedKeys,
-            Set<String> nullKeyClasses, SearchIndexableResource page)
+            Set<String> nullKeyClasses, Class<?> clazz)
             throws IOException, XmlPullParserException, Resources.NotFoundException {
-        final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(page.className);
-
+        if (clazz == null) {
+            return;
+        }
+        final String className = clazz.getName();
         final Indexable.SearchIndexProvider provider =
                 DatabaseIndexingUtils.getSearchIndexProvider(clazz);
         final List<SearchIndexableResource> resourcesToIndex =
                 provider.getXmlResourcesToIndex(mContext, true);
         if (resourcesToIndex == null) {
-            Log.d(TAG, page.className + "is not providing SearchIndexableResource, skipping");
+            Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
             return;
         }
 
         for (SearchIndexableResource sir : resourcesToIndex) {
             if (sir.xmlResId <= 0) {
-                Log.d(TAG, page.className + " doesn't have a valid xml to index.");
+                Log.d(TAG, className + " doesn't have a valid xml to index.");
                 continue;
             }
             final XmlResourceParser parser = mContext.getResources().getXml(sir.xmlResId);
@@ -154,14 +156,14 @@ public class UniquePreferenceTest {
                 final String key = XmlParserUtils.getDataKey(mContext, attrs);
                 if (TextUtils.isEmpty(key)) {
                     Log.e(TAG, "Every preference must have an key; found null key"
-                            + " in " + page.className
+                            + " in " + className
                             + " at " + parser.getPositionDescription());
-                    nullKeyClasses.add(page.className);
+                    nullKeyClasses.add(className);
                     continue;
                 }
                 if (uniqueKeys.contains(key) && !WHITELISTED_DUPLICATE_KEYS.contains(key)) {
                     Log.e(TAG, "Every preference key must unique; found " + nodeName
-                            + " in " + page.className
+                            + " in " + className
                             + " at " + parser.getPositionDescription());
                     duplicatedKeys.add(key);
                 }