Ensure DashboardFragment shares pref controlls with search
Test: make RunSettingsRoboTests
Change-Id: I48be270d9706539925d00874bae29d46406ac491
Fix: 35812240
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index 6c492cc..d6fe1aa 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -67,7 +67,7 @@
super(context);
mActivity = activity;
mFragment = fragment;
- mUm = UserManager.get(context);
+ mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
if (lifecycle != null) {
lifecycle.addObserver(this);
diff --git a/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java b/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java
index 1154493..8f26ed8 100644
--- a/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java
+++ b/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java
@@ -48,7 +48,7 @@
EmergencyBroadcastPreferenceController(Context context, AccountRestrictionHelper helper) {
super(context);
mHelper = helper;
- mUserManager = UserManager.get(context);
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mPm = mContext.getPackageManager();
// Enable link to CMAS app settings depending on the value in config.xml.
mCellBroadcastAppLinkEnabled = isCellBroadcastAppLinkEnabled();
diff --git a/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider b/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
new file mode 100644
index 0000000..cb04679
--- /dev/null
+++ b/tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider
@@ -0,0 +1,11 @@
+com.android.settings.gestures.PickupGestureSettings
+com.android.settings.language.LanguageAndInputSettings
+com.android.settings.enterprise.EnterprisePrivacySettings
+com.android.settings.gestures.DoubleTapScreenSettings
+com.android.settings.applications.AdvancedAppSettings
+com.android.settings.gestures.AssistGestureSettings
+com.android.settings.fuelgauge.PowerUsageSummary
+com.android.settings.gestures.SwipeToNotificationSettings
+com.android.settings.inputmethod.InputMethodAndLanguageSettings
+com.android.settings.gestures.DoubleTapPowerSettings
+com.android.settings.gestures.DoubleTwistGestureSettings
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index 8e46343..5902ec0 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -32,6 +32,7 @@
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.CategoryManager;
import com.android.settingslib.drawer.DashboardCategory;
@@ -62,7 +63,9 @@
import static org.robolectric.Shadows.shadowOf;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH,
+ sdk = TestConfig.SDK_VERSION,
+ shadows = ShadowUserManager.class)
public class DashboardFeatureProviderImplTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java
new file mode 100644
index 0000000..6b22f7b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java
@@ -0,0 +1,74 @@
+/*
+ * 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;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
index 0a74cc4..5455b13 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
@@ -47,6 +47,7 @@
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -117,6 +118,7 @@
mController = new BuildNumberPreferenceController(
context, mActivity, mFragment, mLifecycle);
ReflectionHelpers.setField(mController, "mContext", context);
+ ReflectionHelpers.setField(mController, "mUm", mUserManager);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
verify(mFactory.metricsFeatureProvider).action(
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
index 3c820ec..801b509 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
@@ -21,6 +21,7 @@
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;
@@ -40,6 +41,9 @@
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";
@@ -47,18 +51,22 @@
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
@@ -66,6 +74,7 @@
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)) {
@@ -78,20 +87,36 @@
}
// 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 (hasSearchIndexProvider
- && SearchIndexableResources.getResourceByName(className) == null
- && !notInSearchIndexableRegistryGrandfatherList.contains(className)) {
- notInSearchProviderRegistry.add(className);
+ // 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;
+ }
+ // Must be in SearchProviderRegistry
+ if (SearchIndexableResources.getResourceByName(className) == null) {
+ if (!notInSearchIndexableRegistryGrandfatherList.contains(className)) {
+ notInSearchProviderRegistry.add(className);
+ }
+ continue;
}
}
@@ -100,15 +125,21 @@
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();
}