Add search providers for Connected Devices in new IA
Also add code inspection tests to ensure search provider is added properly. Bug: 33252252 Test: make RunSettingsRoboTests Change-Id: I192e1d9fe0498b76013c4d43b5624d1ef2beb6f9
This commit is contained in:
@@ -4517,7 +4517,7 @@
|
|||||||
<string name="battery_saver_turn_on_automatically_never">Never</string>
|
<string name="battery_saver_turn_on_automatically_never">Never</string>
|
||||||
|
|
||||||
<!-- [CHAR_LIMIT=40] Battery saver: Value for automatic entry option: pct% battery -->
|
<!-- [CHAR_LIMIT=40] Battery saver: Value for automatic entry option: pct% battery -->
|
||||||
<string name="battery_saver_turn_on_automatically_pct">at <xliff:g id="percent">%1$s</xliff:g>battery</string>
|
<string name="battery_saver_turn_on_automatically_pct">at <xliff:g id="percent">%1$s</xliff:g> battery</string>
|
||||||
|
|
||||||
<!-- Process Stats strings -->
|
<!-- Process Stats strings -->
|
||||||
<skip />
|
<skip />
|
||||||
|
@@ -14,7 +14,9 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:title="@string/connected_devices_dashboard_title">
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="toggle_nfc"
|
android:key="toggle_nfc"
|
||||||
|
@@ -16,15 +16,20 @@
|
|||||||
package com.android.settings.connecteddevice;
|
package com.android.settings.connecteddevice;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.provider.SearchIndexableResource;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.PreferenceController;
|
import com.android.settings.core.PreferenceController;
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.deviceinfo.UsbBackend;
|
import com.android.settings.deviceinfo.UsbBackend;
|
||||||
import com.android.settings.nfc.NfcPreferenceController;
|
import com.android.settings.nfc.NfcPreferenceController;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
|
import com.android.settings.search.Indexable;
|
||||||
import com.android.settingslib.drawer.CategoryKey;
|
import com.android.settingslib.drawer.CategoryKey;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||||
@@ -65,4 +70,21 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
|||||||
return controllers;
|
return controllers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For Search.
|
||||||
|
*/
|
||||||
|
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||||
|
new BaseSearchIndexProvider() {
|
||||||
|
@Override
|
||||||
|
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||||
|
Context context, boolean enabled) {
|
||||||
|
if (!FeatureFactory.getFactory(context).getDashboardFeatureProvider(context)
|
||||||
|
.isEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||||
|
sir.xmlResId = R.xml.connected_devices;
|
||||||
|
return Arrays.asList(sir);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
@@ -16,7 +16,6 @@
|
|||||||
package com.android.settings.core.instrumentation;
|
package com.android.settings.core.instrumentation;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -92,9 +91,4 @@ public class MetricsFeatureProviderImpl implements MetricsFeatureProvider {
|
|||||||
writer.histogram(context, name, bucket);
|
writer.histogram(context, name, bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void addLogWriter(LogWriter logWriter) {
|
|
||||||
mLoggerWriters.add(logWriter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ import com.android.settings.accounts.AccountSettings;
|
|||||||
import com.android.settings.applications.AdvancedAppSettings;
|
import com.android.settings.applications.AdvancedAppSettings;
|
||||||
import com.android.settings.applications.SpecialAccessSettings;
|
import com.android.settings.applications.SpecialAccessSettings;
|
||||||
import com.android.settings.bluetooth.BluetoothSettings;
|
import com.android.settings.bluetooth.BluetoothSettings;
|
||||||
|
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
|
||||||
import com.android.settings.datausage.DataUsageMeteredSettings;
|
import com.android.settings.datausage.DataUsageMeteredSettings;
|
||||||
import com.android.settings.datausage.DataUsageSummary;
|
import com.android.settings.datausage.DataUsageSummary;
|
||||||
import com.android.settings.deviceinfo.StorageDashboardFragment;
|
import com.android.settings.deviceinfo.StorageDashboardFragment;
|
||||||
@@ -108,6 +109,7 @@ public final class Ranking {
|
|||||||
|
|
||||||
// BT
|
// BT
|
||||||
sRankMap.put(BluetoothSettings.class.getName(), RANK_BT);
|
sRankMap.put(BluetoothSettings.class.getName(), RANK_BT);
|
||||||
|
sRankMap.put(ConnectedDeviceDashboardFragment.class.getName(), RANK_BT);
|
||||||
|
|
||||||
// SIM Cards
|
// SIM Cards
|
||||||
sRankMap.put(SimSettings.class.getName(), RANK_SIM);
|
sRankMap.put(SimSettings.class.getName(), RANK_SIM);
|
||||||
|
@@ -20,6 +20,7 @@ import android.provider.SearchIndexableResource;
|
|||||||
import android.support.annotation.DrawableRes;
|
import android.support.annotation.DrawableRes;
|
||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.annotation.XmlRes;
|
import android.support.annotation.XmlRes;
|
||||||
|
|
||||||
import com.android.settings.DateTimeSettings;
|
import com.android.settings.DateTimeSettings;
|
||||||
import com.android.settings.DevelopmentSettings;
|
import com.android.settings.DevelopmentSettings;
|
||||||
import com.android.settings.DeviceInfoSettings;
|
import com.android.settings.DeviceInfoSettings;
|
||||||
@@ -36,6 +37,7 @@ import com.android.settings.accounts.AccountSettings;
|
|||||||
import com.android.settings.applications.AdvancedAppSettings;
|
import com.android.settings.applications.AdvancedAppSettings;
|
||||||
import com.android.settings.applications.SpecialAccessSettings;
|
import com.android.settings.applications.SpecialAccessSettings;
|
||||||
import com.android.settings.bluetooth.BluetoothSettings;
|
import com.android.settings.bluetooth.BluetoothSettings;
|
||||||
|
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
|
||||||
import com.android.settings.datausage.DataUsageMeteredSettings;
|
import com.android.settings.datausage.DataUsageMeteredSettings;
|
||||||
import com.android.settings.datausage.DataUsageSummary;
|
import com.android.settings.datausage.DataUsageSummary;
|
||||||
import com.android.settings.deviceinfo.StorageDashboardFragment;
|
import com.android.settings.deviceinfo.StorageDashboardFragment;
|
||||||
@@ -131,6 +133,7 @@ public final class SearchIndexableResources {
|
|||||||
R.drawable.ic_settings_notifications);
|
R.drawable.ic_settings_notifications);
|
||||||
addIndex(SystemDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_about);
|
addIndex(SystemDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_about);
|
||||||
addIndex(StorageDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_storage);
|
addIndex(StorageDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_storage);
|
||||||
|
addIndex(ConnectedDeviceDashboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_bt_laptop);
|
||||||
addIndex(EnterprisePrivacySettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_about);
|
addIndex(EnterprisePrivacySettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_about);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,3 @@
|
|||||||
|
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
|
||||||
|
com.android.settings.wifi.WifiSettingsForSetupWizard
|
||||||
|
com.android.settings.print.PrintServiceSettingsFragment
|
@@ -16,10 +16,13 @@
|
|||||||
package com.android.settings.connecteddevice;
|
package com.android.settings.connecteddevice;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.provider.SearchIndexableResource;
|
||||||
|
|
||||||
import com.android.settings.SettingsRobolectricTestRunner;
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settingslib.drawer.CategoryKey;
|
import com.android.settingslib.drawer.CategoryKey;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -27,8 +30,12 @@ import org.mockito.Answers;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
@@ -43,6 +50,9 @@ public class ConnectedDeviceDashboardFragmentTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
FakeFeatureFactory.setupForTest(mContext);
|
FakeFeatureFactory.setupForTest(mContext);
|
||||||
|
final FakeFeatureFactory factory =
|
||||||
|
(FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
|
||||||
|
when(factory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
|
||||||
mFragment = new ConnectedDeviceDashboardFragment();
|
mFragment = new ConnectedDeviceDashboardFragment();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,4 +61,14 @@ public class ConnectedDeviceDashboardFragmentTest {
|
|||||||
assertThat(mFragment.getCategoryKey()).isEqualTo(CategoryKey.CATEGORY_DEVICE);
|
assertThat(mFragment.getCategoryKey()).isEqualTo(CategoryKey.CATEGORY_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchIndexProvider_shouldIndexResource() {
|
||||||
|
final List<SearchIndexableResource> indexRes =
|
||||||
|
ConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
|
||||||
|
ShadowApplication.getInstance().getApplicationContext(),
|
||||||
|
true /* enabled */);
|
||||||
|
|
||||||
|
assertThat(indexRes).isNotNull();
|
||||||
|
assertThat(indexRes.get(0).xmlResId).isEqualTo(mFragment.getPreferenceScreenResId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,12 +32,12 @@ import static com.google.common.truth.Truth.assertWithMessage;
|
|||||||
*/
|
*/
|
||||||
public class InstrumentableFragmentCodeInspector extends CodeInspector {
|
public class InstrumentableFragmentCodeInspector extends CodeInspector {
|
||||||
|
|
||||||
private final List<String> grandfather_notImplmentingInstrumentable;
|
private final List<String> grandfather_notImplementingInstrumentable;
|
||||||
|
|
||||||
public InstrumentableFragmentCodeInspector(List<Class<?>> classes) {
|
public InstrumentableFragmentCodeInspector(List<Class<?>> classes) {
|
||||||
super(classes);
|
super(classes);
|
||||||
grandfather_notImplmentingInstrumentable = new ArrayList<>();
|
grandfather_notImplementingInstrumentable = new ArrayList<>();
|
||||||
initializeGrandfatherList(grandfather_notImplmentingInstrumentable,
|
initializeGrandfatherList(grandfather_notImplementingInstrumentable,
|
||||||
"grandfather_not_implementing_instrumentable");
|
"grandfather_not_implementing_instrumentable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ public class InstrumentableFragmentCodeInspector extends CodeInspector {
|
|||||||
// If it's a fragment, it must also be instrumentable.
|
// If it's a fragment, it must also be instrumentable.
|
||||||
if (Fragment.class.isAssignableFrom(clazz)
|
if (Fragment.class.isAssignableFrom(clazz)
|
||||||
&& !Instrumentable.class.isAssignableFrom(clazz)
|
&& !Instrumentable.class.isAssignableFrom(clazz)
|
||||||
&& !grandfather_notImplmentingInstrumentable.contains(className)) {
|
&& !grandfather_notImplementingInstrumentable.contains(className)) {
|
||||||
broken.add(className);
|
broken.add(className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,16 +17,18 @@ package com.android.settings.core.instrumentation;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
import com.android.settings.SettingsRobolectricTestRunner;
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Answers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowApplication;
|
|
||||||
|
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
@@ -41,23 +43,21 @@ public class SharedPreferenceLoggerTest {
|
|||||||
private static final String TEST_TAG = "tag";
|
private static final String TEST_TAG = "tag";
|
||||||
private static final String TEST_KEY = "key";
|
private static final String TEST_KEY = "key";
|
||||||
|
|
||||||
@Mock
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
private LogWriter mLogWriter;
|
private Context mContext;
|
||||||
|
|
||||||
|
private FakeFeatureFactory mFactory;
|
||||||
private MetricsFeatureProvider mMetricsFeature;
|
private MetricsFeatureProvider mMetricsFeature;
|
||||||
private ShadowApplication mApplication;
|
|
||||||
private SharedPreferencesLogger mSharedPrefLogger;
|
private SharedPreferencesLogger mSharedPrefLogger;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() {
|
public void init() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mApplication = ShadowApplication.getInstance();
|
FakeFeatureFactory.setupForTest(mContext);
|
||||||
Context context = mApplication.getApplicationContext();
|
mFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
|
||||||
mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
mMetricsFeature = mFactory.metricsFeatureProvider;
|
||||||
((MetricsFeatureProviderImpl) mMetricsFeature).addLogWriter(mLogWriter);
|
|
||||||
|
|
||||||
mSharedPrefLogger = new SharedPreferencesLogger(
|
mSharedPrefLogger = new SharedPreferencesLogger(mContext, TEST_TAG);
|
||||||
mApplication.getApplicationContext(), TEST_TAG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -71,7 +71,7 @@ public class SharedPreferenceLoggerTest {
|
|||||||
editor.putInt(TEST_KEY, 2);
|
editor.putInt(TEST_KEY, 2);
|
||||||
editor.putInt(TEST_KEY, 2);
|
editor.putInt(TEST_KEY, 2);
|
||||||
|
|
||||||
verify(mLogWriter, times(6)).count(any(Context.class), anyString(), anyInt());
|
verify(mMetricsFeature, times(6)).count(any(Context.class), anyString(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -83,7 +83,7 @@ public class SharedPreferenceLoggerTest {
|
|||||||
editor.putBoolean(TEST_KEY, false);
|
editor.putBoolean(TEST_KEY, false);
|
||||||
editor.putBoolean(TEST_KEY, false);
|
editor.putBoolean(TEST_KEY, false);
|
||||||
|
|
||||||
verify(mLogWriter, times(4)).count(any(Context.class), anyString(), anyInt());
|
verify(mMetricsFeature, times(4)).count(any(Context.class), anyString(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -95,7 +95,7 @@ public class SharedPreferenceLoggerTest {
|
|||||||
editor.putLong(TEST_KEY, 1);
|
editor.putLong(TEST_KEY, 1);
|
||||||
editor.putLong(TEST_KEY, 2);
|
editor.putLong(TEST_KEY, 2);
|
||||||
|
|
||||||
verify(mLogWriter, times(4)).count(any(Context.class), anyString(), anyInt());
|
verify(mMetricsFeature, times(4)).count(any(Context.class), anyString(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -107,7 +107,7 @@ public class SharedPreferenceLoggerTest {
|
|||||||
editor.putFloat(TEST_KEY, 1);
|
editor.putFloat(TEST_KEY, 1);
|
||||||
editor.putFloat(TEST_KEY, 2);
|
editor.putFloat(TEST_KEY, 2);
|
||||||
|
|
||||||
verify(mLogWriter, times(4)).count(any(Context.class), anyString(), anyInt());
|
verify(mMetricsFeature, times(4)).count(any(Context.class), anyString(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -35,23 +35,37 @@ import static com.google.common.truth.Truth.assertWithMessage;
|
|||||||
public class SearchIndexProviderCodeInspector extends CodeInspector {
|
public class SearchIndexProviderCodeInspector extends CodeInspector {
|
||||||
private static final String TAG = "SearchCodeInspector";
|
private static final String TAG = "SearchCodeInspector";
|
||||||
|
|
||||||
private final List<String> notImplementingIndexableWhitelist;
|
private static final String NOT_IMPLEMENTING_INDEXABLE_ERROR =
|
||||||
private final List<String> notImplementingIndexProviderWhitelist;
|
"SettingsPreferenceFragment should implement Indexable, but these are not:\n";
|
||||||
|
private static final String NOT_CONTAINING_PROVIDER_OBJECT_ERROR =
|
||||||
|
"Indexable should have public field " + Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
|
||||||
|
+ " but these are not:\n";
|
||||||
|
private static final String NOT_IN_INDEXABLE_PROVIDER_REGISTRY =
|
||||||
|
"Class containing " + Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + " must be added to "
|
||||||
|
+ SearchIndexableResources.class.getName() + " but these are not: \n";
|
||||||
|
|
||||||
|
private final List<String> notImplementingIndexableGrandfatherList;
|
||||||
|
private final List<String> notImplementingIndexProviderGrandfatherList;
|
||||||
|
private final List<String> notInSearchIndexableRegistryGrandfatherList;
|
||||||
|
|
||||||
public SearchIndexProviderCodeInspector(List<Class<?>> classes) {
|
public SearchIndexProviderCodeInspector(List<Class<?>> classes) {
|
||||||
super(classes);
|
super(classes);
|
||||||
notImplementingIndexableWhitelist = new ArrayList<>();
|
notImplementingIndexableGrandfatherList = new ArrayList<>();
|
||||||
notImplementingIndexProviderWhitelist = new ArrayList<>();
|
notImplementingIndexProviderGrandfatherList = new ArrayList<>();
|
||||||
initializeGrandfatherList(notImplementingIndexableWhitelist,
|
notInSearchIndexableRegistryGrandfatherList = new ArrayList<>();
|
||||||
|
initializeGrandfatherList(notImplementingIndexableGrandfatherList,
|
||||||
"grandfather_not_implementing_indexable");
|
"grandfather_not_implementing_indexable");
|
||||||
initializeGrandfatherList(notImplementingIndexProviderWhitelist,
|
initializeGrandfatherList(notImplementingIndexProviderGrandfatherList,
|
||||||
"grandfather_not_implementing_index_provider");
|
"grandfather_not_implementing_index_provider");
|
||||||
|
initializeGrandfatherList(notInSearchIndexableRegistryGrandfatherList,
|
||||||
|
"grandfather_not_in_search_index_provider_registry");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final Set<String> notImplementingIndexable = new ArraySet<>();
|
final Set<String> notImplementingIndexable = new ArraySet<>();
|
||||||
final Set<String> notImplementingIndexProvider = new ArraySet<>();
|
final Set<String> notImplementingIndexProvider = new ArraySet<>();
|
||||||
|
final Set<String> notInSearchProviderRegistry = new ArraySet<>();
|
||||||
|
|
||||||
for (Class clazz : mClasses) {
|
for (Class clazz : mClasses) {
|
||||||
if (!isConcreteSettingsClass(clazz)) {
|
if (!isConcreteSettingsClass(clazz)) {
|
||||||
@@ -64,44 +78,59 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
|
|||||||
}
|
}
|
||||||
// If it's a SettingsPreferenceFragment, it must also be Indexable.
|
// If it's a SettingsPreferenceFragment, it must also be Indexable.
|
||||||
final boolean implementsIndexable = Indexable.class.isAssignableFrom(clazz);
|
final boolean implementsIndexable = Indexable.class.isAssignableFrom(clazz);
|
||||||
if (!implementsIndexable && !notImplementingIndexableWhitelist.contains(className)) {
|
if (!implementsIndexable
|
||||||
|
&& !notImplementingIndexableGrandfatherList.contains(className)) {
|
||||||
notImplementingIndexable.add(className);
|
notImplementingIndexable.add(className);
|
||||||
}
|
}
|
||||||
|
final boolean hasSearchIndexProvider = hasSearchIndexProvider(clazz);
|
||||||
// If it implements Indexable, it must also implement the index provider field.
|
// If it implements Indexable, it must also implement the index provider field.
|
||||||
if (implementsIndexable && !hasSearchIndexProvider(clazz)
|
if (implementsIndexable && !hasSearchIndexProvider
|
||||||
&& !notImplementingIndexProviderWhitelist.contains(className)) {
|
&& !notImplementingIndexProviderGrandfatherList.contains(className)) {
|
||||||
notImplementingIndexProvider.add(className);
|
notImplementingIndexProvider.add(className);
|
||||||
}
|
}
|
||||||
|
if (hasSearchIndexProvider
|
||||||
|
&& SearchIndexableResources.getResourceByName(className) == null
|
||||||
|
&& !notInSearchIndexableRegistryGrandfatherList.contains(className)) {
|
||||||
|
notInSearchProviderRegistry.add(className);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build error messages
|
// Build error messages
|
||||||
final StringBuilder indexableError = new StringBuilder(
|
final String indexableError = buildErrorMessage(NOT_IMPLEMENTING_INDEXABLE_ERROR,
|
||||||
"SettingsPreferenceFragment should implement Indexable, but these are not:\n");
|
notImplementingIndexable);
|
||||||
for (String c : notImplementingIndexable) {
|
final String indexProviderError = buildErrorMessage(NOT_CONTAINING_PROVIDER_OBJECT_ERROR,
|
||||||
indexableError.append(c).append("\n");
|
notImplementingIndexProvider);
|
||||||
}
|
final String notInProviderRegistryError =
|
||||||
final StringBuilder indexProviderError = new StringBuilder(
|
buildErrorMessage(NOT_IN_INDEXABLE_PROVIDER_REGISTRY, notInSearchProviderRegistry);
|
||||||
"Indexable should have public field " + Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
|
assertWithMessage(indexableError)
|
||||||
+ " but these are not:\n");
|
.that(notImplementingIndexable)
|
||||||
for (String c : notImplementingIndexProvider) {
|
.isEmpty();
|
||||||
indexProviderError.append(c).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
assertWithMessage(indexableError.toString())
|
|
||||||
.that(notImplementingIndexable.isEmpty())
|
|
||||||
.isTrue();
|
|
||||||
assertWithMessage(indexProviderError.toString())
|
assertWithMessage(indexProviderError.toString())
|
||||||
.that(notImplementingIndexProvider.isEmpty())
|
.that(notImplementingIndexProvider)
|
||||||
.isTrue();
|
.isEmpty();
|
||||||
|
assertWithMessage(notInProviderRegistryError.toString())
|
||||||
|
.that(notInSearchProviderRegistry)
|
||||||
|
.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasSearchIndexProvider(Class clazz) {
|
private boolean hasSearchIndexProvider(Class clazz) {
|
||||||
try {
|
try {
|
||||||
final Field f = clazz.getField(Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
|
final Field f = clazz.getField(Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
|
||||||
return f != null;
|
return f != null;
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
|
// Cannot find class def, ignore
|
||||||
|
return true;
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
Log.e(TAG, "error fetching search provider from class " + clazz.getName());
|
Log.e(TAG, "error fetching search provider from class " + clazz.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String buildErrorMessage(String errorSummary, Set<String> errorClasses) {
|
||||||
|
final StringBuilder error = new StringBuilder(errorSummary);
|
||||||
|
for (String c : errorClasses) {
|
||||||
|
error.append(c).append("\n");
|
||||||
|
}
|
||||||
|
return error.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user