OSDN Git Service

Ensure DashboardFragment shares pref controlls with search
authorFan Zhang <zhfan@google.com>
Wed, 1 Mar 2017 19:48:27 +0000 (11:48 -0800)
committerFan Zhang <zhfan@google.com>
Wed, 1 Mar 2017 21:29:11 +0000 (13:29 -0800)
Test: make RunSettingsRoboTests
Change-Id: I48be270d9706539925d00874bae29d46406ac491
Fix: 35812240

src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java
tests/robotests/assets/grandfather_not_sharing_pref_controllers_with_search_provider [new file with mode: 0644]
tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java

index 6c492cc..d6fe1aa 100644 (file)
@@ -67,7 +67,7 @@ public class BuildNumberPreferenceController extends PreferenceController
         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);
index 1154493..8f26ed8 100644 (file)
@@ -48,7 +48,7 @@ public class EmergencyBroadcastPreferenceController extends PreferenceController
     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 (file)
index 0000000..cb04679
--- /dev/null
@@ -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
index 8e46343..5902ec0 100644 (file)
@@ -32,6 +32,7 @@ import com.android.settings.SettingsActivity;
 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.mockito.Mockito.when;
 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 (file)
index 0000000..6b22f7b
--- /dev/null
@@ -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;
+        }
+    }
+}
index 0a74cc4..5455b13 100644 (file)
@@ -47,6 +47,7 @@ import static com.google.common.truth.Truth.assertThat;
 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 @@ public class BuildNumberPreferenceControllerTest {
         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(
index 3c820ec..801b509 100644 (file)
@@ -21,6 +21,7 @@ import android.util.Log;
 
 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 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
     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 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
     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 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
         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 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
             }
             // 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;
             }
         }
 
@@ -100,15 +125,21 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
                 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();
     }