1 package com.android.settings.search; 2 3 import android.content.Context; 4 import android.provider.SearchIndexableResource; 5 import android.util.ArraySet; 6 import com.android.settings.DateTimeSettings; 7 import com.android.settings.R; 8 import com.android.settings.SecuritySettings; 9 import com.android.settings.SettingsRobolectricTestRunner; 10 import com.android.settings.TestConfig; 11 import com.android.settings.core.codeinspection.CodeInspector; 12 import com.android.settings.datausage.DataUsageSummary; 13 import com.android.settings.search2.DatabaseIndexingUtils; 14 import com.android.settings.testutils.XmlTestUtils; 15 import com.android.settings.testutils.shadow.SettingsShadowResources; 16 import org.junit.Test; 17 import org.junit.runner.RunWith; 18 import org.robolectric.RuntimeEnvironment; 19 import org.robolectric.annotation.Config; 20 21 import java.util.ArrayList; 22 import java.util.List; 23 import java.util.Set; 24 25 import static com.google.common.truth.Truth.assertThat; 26 27 @RunWith(SettingsRobolectricTestRunner.class) 28 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, 29 assetDir = "/tests/robotests/assets") 30 public class DataIntegrityTest { 31 32 @Test 33 @Config(shadows = { 34 SettingsShadowResources.class, 35 SettingsShadowResources.SettingsShadowTheme.class, 36 }) testIndexableResources_uniqueKeys()37 public void testIndexableResources_uniqueKeys() { 38 final Context context = RuntimeEnvironment.application; 39 // Aggregation of all keys 40 final Set<String> masterKeys = new ArraySet<>(); 41 // Aggregation of the incorrectly duplicate keys 42 final Set<String> duplicateKeys = new ArraySet<>(); 43 // Keys for a specific page 44 final Set<String> pageKeys = new ArraySet<>(); 45 // List of all Xml preferences 46 final Set<Integer> xmlList = new ArraySet<>(); 47 // Duplicates we know about. 48 List<String> grandfatheredKeys = new ArrayList<>(); 49 CodeInspector.initializeGrandfatherList(grandfatheredKeys, 50 "whitelist_duplicate_index_key"); 51 52 // Get a list of all Xml. 53 for (SearchIndexableResource val : SearchIndexableResources.values()) { 54 final int xmlResId = val.xmlResId; 55 if (xmlResId != 0) { 56 xmlList.add(xmlResId); 57 } else { 58 // Take class and get all keys 59 final Class clazz = DatabaseIndexingUtils.getIndexableClass(val.className); 60 61 // Skip classes that are invalid or cannot be mocked. Add them as special Xml below. 62 if (clazz == null 63 || clazz == DateTimeSettings.class 64 || clazz == DataUsageSummary.class 65 || clazz == SecuritySettings.class) { 66 continue; 67 } 68 69 Indexable.SearchIndexProvider provider = DatabaseIndexingUtils 70 .getSearchIndexProvider(clazz); 71 72 if (provider == null) { 73 continue; 74 } 75 76 List<SearchIndexableResource> subXml = 77 provider.getXmlResourcesToIndex(context, true); 78 79 if (subXml == null) { 80 continue; 81 } 82 for (SearchIndexableResource resource : subXml) { 83 final int subXmlResId = resource.xmlResId; 84 if (subXmlResId != 0) { 85 xmlList.add(subXmlResId); 86 } 87 } 88 } 89 } 90 addSpecialXml(xmlList); 91 92 // Get keys from all Xml and check for duplicates. 93 for (Integer xmlResId : xmlList) { 94 // Get all keys to be indexed 95 final List<String> prefKeys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlResId); 96 pageKeys.addAll(prefKeys); 97 // Find all already-existing keys. 98 pageKeys.retainAll(masterKeys); 99 // Keep list of offending duplicate keys. 100 duplicateKeys.addAll(pageKeys); 101 // Add all keys to master key list. 102 masterKeys.addAll(prefKeys); 103 pageKeys.clear(); 104 } 105 assertThat(duplicateKeys).containsExactlyElementsIn(grandfatheredKeys); 106 } 107 108 /** 109 * Add XML preferences from Fragments which have issues being instantiated in robolectric. 110 */ addSpecialXml(Set<Integer> xmlList)111 private void addSpecialXml(Set<Integer> xmlList) { 112 xmlList.add(R.xml.date_time_prefs); 113 xmlList.add(R.xml.data_usage); 114 xmlList.add(R.xml.data_usage_cellular); 115 xmlList.add(R.xml.data_usage_wifi); 116 xmlList.add(R.xml.security_settings_misc); 117 } 118 119 120 } 121