--- /dev/null
+/*
+ * Copyright (C) 2017 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.dashboard;
+
+import android.app.Fragment;
+import android.content.Context;
+
+import com.android.settings.core.PreferenceController;
+import com.android.settings.search.Indexable;
+import com.android.settings.search2.DatabaseIndexingUtils;
+
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+public class DashboardFragmentSearchIndexProviderInspector {
+
+ public static boolean isSharingPreferenceControllers(Class clazz) {
+ final Context context = RuntimeEnvironment.application;
+ final Fragment fragment;
+ try {
+ fragment = Fragment.instantiate(context, clazz.getName());
+ } catch (Throwable e) {
+ // Can't do much with exception, assume the test passed.
+ return true;
+ }
+ if (!(fragment instanceof DashboardFragment)) {
+ return true;
+ }
+
+ final Indexable.SearchIndexProvider provider =
+ DatabaseIndexingUtils.getSearchIndexProvider(clazz);
+ if (provider == null) {
+ return true;
+ }
+ final List<PreferenceController> controllersFromSearchIndexProvider;
+ final List<PreferenceController> controllersFromFragment;
+ try {
+ controllersFromSearchIndexProvider = provider.getPreferenceControllers(context);
+ } catch (Throwable e) {
+ // Can't do much with exception, assume the test passed.
+ return true;
+ }
+ try {
+ controllersFromFragment =
+ ((DashboardFragment) fragment).getPreferenceControllers(context);
+ } catch (Throwable e) {
+ // Can't do much with exception, assume the test passed.
+ return true;
+ }
+
+ if (controllersFromFragment == controllersFromSearchIndexProvider) {
+ return true;
+ } else if (controllersFromFragment != null && controllersFromSearchIndexProvider != null) {
+ return controllersFromFragment.size() == controllersFromSearchIndexProvider.size();
+ } else {
+ return false;
+ }
+ }
+}
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.core.codeinspection.CodeInspector;
+import com.android.settings.dashboard.DashboardFragmentSearchIndexProviderInspector;
import java.lang.reflect.Field;
import java.util.ArrayList;
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_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER =
+ "DashboardFragment should share pref controllers with its SearchIndexProvider, 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;
+ private final List<String> notSharingPrefControllersGrandfatherList;
public SearchIndexProviderCodeInspector(List<Class<?>> classes) {
super(classes);
notImplementingIndexableGrandfatherList = new ArrayList<>();
notImplementingIndexProviderGrandfatherList = new ArrayList<>();
notInSearchIndexableRegistryGrandfatherList = new ArrayList<>();
+ notSharingPrefControllersGrandfatherList = new ArrayList<>();
initializeGrandfatherList(notImplementingIndexableGrandfatherList,
"grandfather_not_implementing_indexable");
initializeGrandfatherList(notImplementingIndexProviderGrandfatherList,
"grandfather_not_implementing_index_provider");
initializeGrandfatherList(notInSearchIndexableRegistryGrandfatherList,
"grandfather_not_in_search_index_provider_registry");
+ initializeGrandfatherList(notSharingPrefControllersGrandfatherList,
+ "grandfather_not_sharing_pref_controllers_with_search_provider");
}
@Override
final Set<String> notImplementingIndexable = new ArraySet<>();
final Set<String> notImplementingIndexProvider = new ArraySet<>();
final Set<String> notInSearchProviderRegistry = new ArraySet<>();
+ final Set<String> notSharingPreferenceControllers = new ArraySet<>();
for (Class clazz : mClasses) {
if (!isConcreteSettingsClass(clazz)) {
}
// If it's a SettingsPreferenceFragment, it must also be Indexable.
final boolean implementsIndexable = Indexable.class.isAssignableFrom(clazz);
- if (!implementsIndexable
- && !notImplementingIndexableGrandfatherList.contains(className)) {
- notImplementingIndexable.add(className);
+ if (!implementsIndexable) {
+ if (!notImplementingIndexableGrandfatherList.contains(className)) {
+ notImplementingIndexable.add(className);
+ }
+ continue;
}
final boolean hasSearchIndexProvider = hasSearchIndexProvider(clazz);
// If it implements Indexable, it must also implement the index provider field.
- if (implementsIndexable && !hasSearchIndexProvider
- && !notImplementingIndexProviderGrandfatherList.contains(className)) {
- notImplementingIndexProvider.add(className);
+ if (!hasSearchIndexProvider) {
+ if (!notImplementingIndexProviderGrandfatherList.contains(className)) {
+ notImplementingIndexProvider.add(className);
+ }
+ continue;
+ }
+ // If it implements index provider field AND it's a DashboardFragment, its fragment and
+ // search provider must share the same set of PreferenceControllers.
+ final boolean isSharingPrefControllers = DashboardFragmentSearchIndexProviderInspector
+ .isSharingPreferenceControllers(clazz);
+ if (!isSharingPrefControllers) {
+ if (!notSharingPrefControllersGrandfatherList.contains(className)) {
+ notSharingPreferenceControllers.add(className);
+ }
+ continue;
}
- if (hasSearchIndexProvider
- && SearchIndexableResources.getResourceByName(className) == null
- && !notInSearchIndexableRegistryGrandfatherList.contains(className)) {
- notInSearchProviderRegistry.add(className);
+ // Must be in SearchProviderRegistry
+ if (SearchIndexableResources.getResourceByName(className) == null) {
+ if (!notInSearchIndexableRegistryGrandfatherList.contains(className)) {
+ notInSearchProviderRegistry.add(className);
+ }
+ continue;
}
}
notImplementingIndexable);
final String indexProviderError = buildErrorMessage(NOT_CONTAINING_PROVIDER_OBJECT_ERROR,
notImplementingIndexProvider);
+ final String notSharingPrefControllerError = buildErrorMessage(
+ NOT_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER,
+ notSharingPreferenceControllers);
final String notInProviderRegistryError =
buildErrorMessage(NOT_IN_INDEXABLE_PROVIDER_REGISTRY, notInSearchProviderRegistry);
assertWithMessage(indexableError)
.that(notImplementingIndexable)
.isEmpty();
- assertWithMessage(indexProviderError.toString())
+ assertWithMessage(indexProviderError)
.that(notImplementingIndexProvider)
.isEmpty();
- assertWithMessage(notInProviderRegistryError.toString())
+ assertWithMessage(notSharingPrefControllerError)
+ .that(notSharingPreferenceControllers)
+ .isEmpty();
+ assertWithMessage(notInProviderRegistryError)
.that(notInSearchProviderRegistry)
.isEmpty();
}