1 package com.android.settings.search; 2 3 import static com.google.common.truth.Truth.assertThat; 4 5 import android.content.Context; 6 import android.provider.SearchIndexableResource; 7 import android.util.ArraySet; 8 import com.android.settings.DateTimeSettings; 9 import com.android.settings.R; 10 import com.android.settings.SecuritySettings; 11 import com.android.settings.TestConfig; 12 import com.android.settings.core.codeinspection.CodeInspector; 13 import com.android.settings.datausage.DataPlanUsageSummary; 14 import com.android.settings.datausage.DataUsageSummary; 15 import com.android.settings.testutils.SettingsRobolectricTestRunner; 16 import com.android.settings.testutils.XmlTestUtils; 17 import com.android.settings.testutils.shadow.SettingsShadowResources; 18 import java.util.ArrayList; 19 import java.util.List; 20 import java.util.Set; 21 import org.junit.Test; 22 import org.junit.runner.RunWith; 23 import org.robolectric.RuntimeEnvironment; 24 import org.robolectric.annotation.Config; 25 26 @RunWith(SettingsRobolectricTestRunner.class) 27 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, 28 assetDir = "/tests/robotests/assets") 29 public class DataIntegrityTest { 30 31 @Test 32 @Config(shadows = { 33 SettingsShadowResources.class, 34 SettingsShadowResources.SettingsShadowTheme.class, 35 }) testIndexableResources_uniqueKeys()36 public void testIndexableResources_uniqueKeys() { 37 final Context context = RuntimeEnvironment.application; 38 // Aggregation of all keys 39 final Set<String> masterKeys = new ArraySet<>(); 40 // Aggregation of the incorrectly duplicate keys 41 final Set<String> duplicateKeys = new ArraySet<>(); 42 // Keys for a specific page 43 final Set<String> pageKeys = new ArraySet<>(); 44 // List of all Xml preferences 45 final Set<Integer> xmlList = new ArraySet<>(); 46 // Duplicates we know about. 47 List<String> grandfatheredKeys = new ArrayList<>(); 48 CodeInspector.initializeGrandfatherList(grandfatheredKeys, 49 "whitelist_duplicate_index_key"); 50 51 // Get a list of all Xml. 52 for (SearchIndexableResource val : SearchIndexableResources.values()) { 53 final int xmlResId = val.xmlResId; 54 if (xmlResId != 0) { 55 xmlList.add(xmlResId); 56 } else { 57 // Take class and get all keys 58 final Class clazz = DatabaseIndexingUtils.getIndexableClass(val.className); 59 60 // Skip classes that are invalid or cannot be mocked. Add them as special Xml below. 61 if (clazz == null 62 || clazz == DateTimeSettings.class 63 || clazz == DataPlanUsageSummary.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