Merge "Apply color extraction for vision settings" into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2637acc..a21c4bb 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -678,7 +678,8 @@
         <activity android:name=".localepicker.LocalePickerWithRegionActivity"
                   android:excludeFromRecents="true"
                   android:configChanges="orientation|keyboardHidden|screenSize"
-                  android:exported="false">
+                  android:exported="false"
+                  android:theme="@style/Theme.LocalePickerWithRegionActivity">
         </activity>
 
         <activity
diff --git a/res/layout/preference_balance_slider.xml b/res/layout/preference_balance_slider.xml
index 43cd86f..93e192a 100644
--- a/res/layout/preference_balance_slider.xml
+++ b/res/layout/preference_balance_slider.xml
@@ -91,6 +91,8 @@
                 <TextView
                     android:id="@+id/left_text"
                     android:text="@string/accessibility_toggle_primary_balance_left_label"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:textColor="?android:attr/textColorSecondary"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
@@ -99,6 +101,8 @@
                 <TextView
                     android:id="@+id/right_text"
                     android:text="@string/accessibility_toggle_primary_balance_right_label"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:textColor="?android:attr/textColorSecondary"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index cfa0e3b..c72b3a5 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -145,6 +145,7 @@
         <item name="android:layout_marginStart">4dip</item>
         <item name="android:textAlignment">viewStart</item>
         <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
+        <item name="android:textColorHint">?android:attr/textColorSecondary</item>
         <item name="android:minHeight">@dimen/min_tap_target_size</item>
     </style>
 
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 555a045..9681b03 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -32,7 +32,6 @@
         <item name="android:navigationBarColor">@android:color/transparent</item>
         <item name="android:datePickerDialogTheme">@style/PickerDialogTheme.Settings</item>
         <item name="android:progressBarStyleHorizontal">@style/HorizontalProgressBarStyle</item>
-        <item name="android:textColorHint">?android:attr/textColorSecondary</item>
 
         <item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
         <item name="face_layout_theme">@style/FaceLayoutTheme</item>
@@ -93,6 +92,10 @@
         <item name="android:backgroundDimEnabled">false</item>
     </style>
 
+    <style name="Theme.LocalePickerWithRegionActivity" parent="Theme.Settings">
+        <item name="android:textColorHint">?android:attr/textColorSecondary</item>
+    </style>
+
     <style name="ThemeOverlay.SwitchBar.Settings.Base" parent="@*android:style/ThemeOverlay.DeviceDefault.ActionBar">
         <item name="android:elevation">1dp</item>
         <item name="switchBarMarginStart">@dimen/switchbar_subsettings_margin_start</item>
diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
index b5496a8..4e8be42 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java
@@ -28,13 +28,11 @@
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
+import android.widget.LinearLayout;
 
 import androidx.preference.Preference;
 import androidx.recyclerview.widget.RecyclerView;
@@ -44,6 +42,7 @@
 import com.android.settingslib.RestrictedPreference;
 
 import com.google.android.setupdesign.GlifPreferenceLayout;
+import com.google.android.setupdesign.util.ThemeHelper;
 
 import java.util.List;
 
@@ -85,14 +84,13 @@
         layout.setDividerInsets(Integer.MAX_VALUE, 0);
         layout.setDescriptionText(R.string.vision_settings_description);
         layout.setHeaderText(R.string.vision_settings_title);
-        layout.setIcon(getResources().getDrawable(R.drawable.ic_accessibility_visibility));
+        layout.setIcon(getPrefContext().getDrawable(R.drawable.ic_accessibility_visibility));
 
-        final ImageView iconView = layout.findManagedViewById(R.id.sud_layout_icon);
-        final FrameLayout.LayoutParams params =
-                (FrameLayout.LayoutParams) iconView.getLayoutParams();
-        params.gravity = Gravity.START;
-        layout.getHeaderTextView().setGravity(Gravity.START);
-        layout.getDescriptionTextView().setGravity(Gravity.START);
+        if (ThemeHelper.shouldApplyExtendedPartnerConfig(getActivity())) {
+            final LinearLayout headerLayout = layout.findManagedViewById(R.id.sud_layout_header);
+            headerLayout.setPadding(0, headerLayout.getPaddingTop(), 0,
+                    headerLayout.getPaddingBottom());
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
index 7501897..1e9c240 100644
--- a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
+++ b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 
 import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
 import com.android.settings.widget.SettingsMainSwitchPreferenceController;
 
 /**
@@ -33,9 +32,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return OneHandedSettingsUtils.isSupportOneHandedMode()
-                ? BasePreferenceController.AVAILABLE
-                : BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+        return OneHandedSettingsUtils.isFeatureAvailable(mContext)
+                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
index 5de02db..21998a6 100644
--- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java
+++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java
@@ -177,6 +177,28 @@
     }
 
     /**
+     * Get NavigationBar mode flag from Settings provider.
+     * @param context App context
+     * @return Navigation bar mode:
+     *  0 = 3 button
+     *  1 = 2 button
+     *  2 = fully gestural
+     */
+    public static int getNavigationBarMode(Context context) {
+        return Settings.Secure.getIntForUser(context.getContentResolver(),
+                Settings.Secure.NAVIGATION_MODE, 2 /* fully gestural */, sCurrentUserId);
+    }
+
+    /**
+     *
+     * @param context App context
+     * @return Support One-Handed mode feature or not.
+     */
+    public static boolean isFeatureAvailable(Context context) {
+        return isSupportOneHandedMode() && getNavigationBarMode(context) != 0;
+    }
+
+    /**
      * Registers callback for observing Settings.Secure.ONE_HANDED_MODE_ENABLED state.
      * @param callback for state changes
      */
diff --git a/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java
index 320d006..ec81482 100644
--- a/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java
@@ -33,7 +33,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return OneHandedSettingsUtils.isSupportOneHandedMode() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return OneHandedSettingsUtils.isFeatureAvailable(mContext)
+                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java
index 3c2df96..581eb2e 100644
--- a/src/com/android/settings/search/BaseSearchIndexProvider.java
+++ b/src/com/android/settings/search/BaseSearchIndexProvider.java
@@ -80,6 +80,10 @@
     @CallSuper
     public List<SearchIndexableRaw> getDynamicRawDataToIndex(Context context, boolean enabled) {
         final List<SearchIndexableRaw> dynamicRaws = new ArrayList<>();
+        if (!isPageSearchEnabled(context)) {
+            // Entire page should be suppressed, do not add dynamic raw data.
+            return dynamicRaws;
+        }
         final List<AbstractPreferenceController> controllers = getPreferenceControllers(context);
         if (controllers == null || controllers.isEmpty()) {
             return dynamicRaws;
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index 736a270..feb9510 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -55,20 +55,22 @@
 import android.provider.SearchIndexablesProvider;
 import android.provider.SettingsSlicesContract;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.slice.SliceViewManager;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.dashboard.CategoryManager;
 import com.android.settings.dashboard.DashboardFeatureProvider;
+import com.android.settings.dashboard.DashboardFragmentRegistry;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.slices.SettingsSliceProvider;
 import com.android.settingslib.drawer.ActivityTile;
-import com.android.settingslib.drawer.CategoryKey;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
 import com.android.settingslib.search.Indexable;
@@ -78,6 +80,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
 
@@ -94,6 +97,9 @@
 
     private static final Collection<String> INVALID_KEYS;
 
+    // Search enabled states for injection (key: category key, value: search enabled)
+    private Map<String, Boolean> mSearchEnabledByCategoryKeyMap;
+
     static {
         INVALID_KEYS = new ArraySet<>();
         INVALID_KEYS.add(null);
@@ -102,6 +108,7 @@
 
     @Override
     public boolean onCreate() {
+        mSearchEnabledByCategoryKeyMap = new ArrayMap<>();
         return true;
     }
 
@@ -166,7 +173,18 @@
     public Cursor queryDynamicRawData(String[] projection) {
         final Context context = getContext();
         final List<SearchIndexableRaw> rawList = new ArrayList<>();
-        rawList.addAll(getDynamicSearchIndexableRawFromProvider(context));
+        final Collection<SearchIndexableData> bundles = FeatureFactory.getFactory(context)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
+
+        for (SearchIndexableData bundle : bundles) {
+            rawList.addAll(getDynamicSearchIndexableRawData(context, bundle));
+
+            // Refresh the search enabled state for indexing injection raw data
+            final Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
+            if (provider instanceof BaseSearchIndexProvider) {
+                refreshSearchEnabledState(context, (BaseSearchIndexProvider) provider);
+            }
+        }
         rawList.addAll(getInjectionIndexableRawData(context));
 
         final MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
@@ -355,39 +373,35 @@
         return rawList;
     }
 
-    private List<SearchIndexableRaw> getDynamicSearchIndexableRawFromProvider(Context context) {
-        final Collection<SearchIndexableData> bundles = FeatureFactory.getFactory(context)
-                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
-        final List<SearchIndexableRaw> rawList = new ArrayList<>();
-
-        for (SearchIndexableData bundle : bundles) {
-            final Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
-            final List<SearchIndexableRaw> providerRaws =
-                    provider.getDynamicRawDataToIndex(context, true /* enabled */);
-
-            if (providerRaws == null) {
-                continue;
-            }
-
-            for (SearchIndexableRaw raw : providerRaws) {
-                // The classname and intent information comes from the PreIndexData
-                // This will be more clear when provider conversion is done at PreIndex time.
-                raw.className = bundle.getTargetClass().getName();
-
-            }
-            rawList.addAll(providerRaws);
+    private List<SearchIndexableRaw> getDynamicSearchIndexableRawData(Context context,
+            SearchIndexableData bundle) {
+        final Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
+        final List<SearchIndexableRaw> providerRaws =
+                provider.getDynamicRawDataToIndex(context, true /* enabled */);
+        if (providerRaws == null) {
+            return new ArrayList<>();
         }
 
-        return rawList;
+        for (SearchIndexableRaw raw : providerRaws) {
+            // The classname and intent information comes from the PreIndexData
+            // This will be more clear when provider conversion is done at PreIndex time.
+            raw.className = bundle.getTargetClass().getName();
+        }
+        return providerRaws;
     }
 
-    private List<SearchIndexableRaw> getInjectionIndexableRawData(Context context) {
+    @VisibleForTesting
+    List<SearchIndexableRaw> getInjectionIndexableRawData(Context context) {
         final DashboardFeatureProvider dashboardFeatureProvider =
                 FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
-
         final List<SearchIndexableRaw> rawList = new ArrayList<>();
         final String currentPackageName = context.getPackageName();
         for (DashboardCategory category : dashboardFeatureProvider.getAllCategories()) {
+            if (mSearchEnabledByCategoryKeyMap.containsKey(category.key)
+                    && !mSearchEnabledByCategoryKeyMap.get(category.key)) {
+                Log.i(TAG, "Skip indexing category: " + category.key);
+                continue;
+            }
             for (Tile tile : category.getTiles()) {
                 if (!isEligibleForIndexing(currentPackageName, tile)) {
                     continue;
@@ -411,16 +425,36 @@
     }
 
     @VisibleForTesting
+    void refreshSearchEnabledState(Context context, BaseSearchIndexProvider provider) {
+        // Provider's class name is like "com.android.settings.Settings$1"
+        String className = provider.getClass().getName();
+        final int delimiter = className.lastIndexOf("$");
+        if (delimiter > 0) {
+            // Parse the outer class name of this provider
+            className = className.substring(0, delimiter);
+        }
+
+        // Lookup the category key by the class name
+        final String categoryKey = DashboardFragmentRegistry.PARENT_TO_CATEGORY_KEY_MAP
+                .get(className);
+        if (categoryKey == null) {
+            return;
+        }
+
+        final DashboardCategory category = CategoryManager.get(context)
+                .getTilesByCategory(context, categoryKey);
+        if (category != null) {
+            mSearchEnabledByCategoryKeyMap.put(category.key, provider.isPageSearchEnabled(context));
+        }
+    }
+
+    @VisibleForTesting
     boolean isEligibleForIndexing(String packageName, Tile tile) {
         if (TextUtils.equals(packageName, tile.getPackageName())
                 && tile instanceof ActivityTile) {
             // Skip Settings injected items because they should be indexed in the sub-pages.
             return false;
         }
-        if (TextUtils.equals(tile.getCategory(), CategoryKey.CATEGORY_HOMEPAGE)) {
-            // Skip homepage injected items since we would like to index their target activity.
-            return false;
-        }
         return true;
     }
 
diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
index ac2beb3..e5b8688 100644
--- a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.provider.Settings;
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
@@ -60,6 +61,7 @@
     @Test
     public void getAvailabilityStatus_setSupportOneHandedModeProperty_shouldAvailable() {
         SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
+        setNavigationBarMode(mContext, "2" /* fully gestural */);
 
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.AVAILABLE);
@@ -68,6 +70,16 @@
     @Test
     public void getAvailabilityStatus_unsetSupportOneHandedModeProperty_shouldUnsupported() {
         SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false");
+        setNavigationBarMode(mContext, "2" /* fully gestural */);
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_set3ButtonModeProperty_shouldUnsupported() {
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
+        setNavigationBarMode(mContext, "0" /* 3-button */);
 
         assertThat(mController.getAvailabilityStatus())
                 .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
@@ -88,4 +100,18 @@
         assertThat(mController.getSummary())
                 .isEqualTo(mContext.getText(R.string.switch_off_text));
     }
+
+    /**
+     * Set NavigationBar mode flag to Settings provider.
+     * @param context App context
+     * @param value Navigation bar mode:
+     *  0 = 3 button
+     *  1 = 2 button
+     *  2 = fully gestural
+     * @return true if the value was set, false on database errors.
+     */
+    private boolean setNavigationBarMode(Context context, String value) {
+        return Settings.Secure.putStringForUser(context.getContentResolver(),
+                Settings.Secure.NAVIGATION_MODE, value, UserHandle.myUserId());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java
index 9f76800..8f50006 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java
@@ -22,6 +22,7 @@
 
 import android.content.Context;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.provider.Settings;
 
 import com.android.settings.R;
@@ -69,6 +70,7 @@
     @Test
     public void getAvailabilityStatus_oneHandedUnsupported_returnsUnsupport() {
         SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false");
+        setNavigationBarMode(mContext, "2" /* fully gestural */);
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.UNSUPPORTED_ON_DEVICE);
@@ -77,11 +79,21 @@
     @Test
     public void getAvailabilityStatus_oneHandedSupported_returnsAvailable() {
         SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
+        setNavigationBarMode(mContext, "2" /* fully gestural */);
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
     }
 
     @Test
+    public void getAvailabilityStatus_set3ButtonModeProperty_returnsUnsupport() {
+        SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true");
+        setNavigationBarMode(mContext, "0" /* 3-button */);
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
     public void getSummary_gestureEnabled_returnsOnSummary() {
         mController.setChecked(true);
 
@@ -105,4 +117,18 @@
 
         assertThat(mController.isChecked()).isFalse();
     }
+
+    /**
+     * Set NavigationBar mode flag to Settings provider.
+     * @param context App context
+     * @param value Navigation bar mode:
+     *  0 = 3 button
+     *  1 = 2 button
+     *  2 = fully gestural
+     * @return true if the value was set, false on database errors.
+     */
+    private boolean setNavigationBarMode(Context context, String value) {
+        return Settings.Secure.putStringForUser(context.getContentResolver(),
+                Settings.Secure.NAVIGATION_MODE, value, UserHandle.myUserId());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/search/BaseSearchIndexProviderTest.java b/tests/robotests/src/com/android/settings/search/BaseSearchIndexProviderTest.java
index 5221630..09b1ea9 100644
--- a/tests/robotests/src/com/android/settings/search/BaseSearchIndexProviderTest.java
+++ b/tests/robotests/src/com/android/settings/search/BaseSearchIndexProviderTest.java
@@ -204,6 +204,16 @@
     }
 
     @Test
+    public void getDynamicRawDataToIndex_disablePageSearch_shouldReturnEmptyList() {
+        List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new AvailablePreferenceController(mContext));
+        doReturn(controllers).when(mIndexProvider).createPreferenceControllers(mContext);
+        doReturn(false).when(mIndexProvider).isPageSearchEnabled(mContext);
+
+        assertThat(mIndexProvider.getDynamicRawDataToIndex(mContext, true)).isEmpty();
+    }
+
+    @Test
     public void getDynamicRawDataToIndex_hasDynamicRaw_shouldNotEmpty() {
         List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new AvailablePreferenceController(mContext));
diff --git a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
index 1fc0230..21b00a3 100644
--- a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
+++ b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
@@ -1,21 +1,31 @@
 package com.android.settings.search;
 
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import android.Manifest;
+import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Bundle;
 import android.provider.SearchIndexablesContract;
 
 import com.android.settings.R;
+import com.android.settings.accounts.ManagedProfileSettings;
+import com.android.settings.dashboard.CategoryManager;
+import com.android.settings.homepage.TopLevelSettings;
+import com.android.settings.network.NetworkDashboardFragment;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.drawer.ActivityTile;
 import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.search.SearchIndexableData;
 
 import org.junit.After;
@@ -25,21 +35,28 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = SettingsSearchIndexablesProviderTest.ShadowCategoryManager.class)
 public class SettingsSearchIndexablesProviderTest {
 
     private static final String PACKAGE_NAME = "com.android.settings";
     private static final String BASE_AUTHORITY = "content://" + PACKAGE_NAME + "/";
 
+    private Context mContext;
     private SettingsSearchIndexablesProvider mProvider;
     private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
+        mContext = RuntimeEnvironment.application;
         mProvider = spy(new SettingsSearchIndexablesProvider());
         ProviderInfo info = new ProviderInfo();
         info.exported = true;
@@ -55,10 +72,22 @@
                         FakeSettingsFragment.SEARCH_INDEX_DATA_PROVIDER));
         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
         mFakeFeatureFactory.searchFeatureProvider = featureProvider;
+
+        final ActivityInfo activityInfo = new ActivityInfo();
+        activityInfo.packageName = "pkg";
+        activityInfo.name = "class";
+        activityInfo.metaData = new Bundle();
+        activityInfo.metaData.putString(META_DATA_PREFERENCE_TITLE, "title");
+        final DashboardCategory category = new DashboardCategory("key");
+        when(mFakeFeatureFactory.dashboardFeatureProvider.getAllCategories())
+                .thenReturn(Arrays.asList(category));
+        category.addTile(new ActivityTile(activityInfo, category.key));
+        ShadowCategoryManager.setDashboardCategory(category);
     }
 
     @After
     public void cleanUp() {
+        ShadowCategoryManager.reset();
         mFakeFeatureFactory.searchFeatureProvider = mock(SearchFeatureProvider.class);
     }
 
@@ -121,7 +150,41 @@
     }
 
     @Test
-    public void testIsEligibleForIndexing_isSettingsInjectedItem_ShouldBeFalse() {
+    public void refreshSearchEnabledState_classNotFoundInCategoryMap_hasInjectionRawData() {
+        mProvider.refreshSearchEnabledState(mContext,
+                ManagedProfileSettings.SEARCH_INDEX_DATA_PROVIDER);
+
+        assertThat(mProvider.getInjectionIndexableRawData(mContext)).isNotEmpty();
+    }
+
+    @Test
+    public void refreshSearchEnabledState_noDashboardCategory_hasInjectionRawData() {
+        ShadowCategoryManager.setDashboardCategory(null);
+
+        mProvider.refreshSearchEnabledState(mContext,
+                TopLevelSettings.SEARCH_INDEX_DATA_PROVIDER);
+
+        assertThat(mProvider.getInjectionIndexableRawData(mContext)).isNotEmpty();
+    }
+
+    @Test
+    public void refreshSearchEnabledState_pageSearchEnabled_hasInjectionRawData() {
+        mProvider.refreshSearchEnabledState(mContext,
+                NetworkDashboardFragment.SEARCH_INDEX_DATA_PROVIDER);
+
+        assertThat(mProvider.getInjectionIndexableRawData(mContext)).isNotEmpty();
+    }
+
+    @Test
+    public void refreshSearchEnabledState_pageSearchDisable_noInjectionRawData() {
+        mProvider.refreshSearchEnabledState(mContext,
+                TopLevelSettings.SEARCH_INDEX_DATA_PROVIDER);
+
+        assertThat(mProvider.getInjectionIndexableRawData(mContext)).isEmpty();
+    }
+
+    @Test
+    public void isEligibleForIndexing_isSettingsInjectedItem_shouldReturnFalse() {
         final ActivityInfo activityInfo = new ActivityInfo();
         activityInfo.packageName = PACKAGE_NAME;
         activityInfo.name = "class";
@@ -132,18 +195,7 @@
     }
 
     @Test
-    public void testIsEligibleForIndexing_isHomepageInjectedItem_ShouldBeFalse() {
-        final ActivityInfo activityInfo = new ActivityInfo();
-        activityInfo.packageName = "pkg";
-        activityInfo.name = "class";
-        final ActivityTile activityTile = new ActivityTile(activityInfo,
-                CategoryKey.CATEGORY_HOMEPAGE);
-
-        assertThat(mProvider.isEligibleForIndexing(PACKAGE_NAME, activityTile)).isFalse();
-    }
-
-    @Test
-    public void testIsEligibleForIndexing_normalInjectedItem_ShouldBeTrue() {
+    public void isEligibleForIndexing_normalInjectedItem_shouldReturnTrue() {
         final ActivityInfo activityInfo = new ActivityInfo();
         activityInfo.packageName = "pkg";
         activityInfo.name = "class";
@@ -152,4 +204,24 @@
 
         assertThat(mProvider.isEligibleForIndexing(PACKAGE_NAME, activityTile)).isTrue();
     }
+
+    @Implements(CategoryManager.class)
+    public static class ShadowCategoryManager {
+
+        private static DashboardCategory sCategory;
+
+        @Resetter
+        static void reset() {
+            sCategory = null;
+        }
+
+        @Implementation
+        public DashboardCategory getTilesByCategory(Context context, String categoryKey) {
+            return sCategory;
+        }
+
+        static void setDashboardCategory(DashboardCategory category) {
+            sCategory = category;
+        }
+    }
 }