Merge "TelephonyMonitor: Replace boolean decision with  multiple status." into oc-dev
diff --git a/res/xml/about_legal.xml b/res/xml/about_legal.xml
index 596effe..55faad3 100644
--- a/res/xml/about_legal.xml
+++ b/res/xml/about_legal.xml
@@ -15,7 +15,8 @@
 -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-                  android:title="@string/legal_information">
+                  android:title="@string/legal_information"
+                  android:key="legal_screen">
 
     <!-- Note: The titles given here probably won't be used.  Instead, we programmatically
        fill the title with the label of the activity with the corresponding action.
diff --git a/res/xml/battery_saver_settings.xml b/res/xml/battery_saver_settings.xml
index 52f6793..1720c73 100644
--- a/res/xml/battery_saver_settings.xml
+++ b/res/xml/battery_saver_settings.xml
@@ -22,6 +22,6 @@
     <DropDownPreference
             android:key="turn_on_automatically"
             android:title="@string/battery_saver_turn_on_automatically_title"
-            android:summary="@string/summary_placeholder" />
+            android:summary="%s" />
 
 </PreferenceScreen>
diff --git a/res/xml/reset_dashboard_fragment.xml b/res/xml/reset_dashboard_fragment.xml
index c769d5d..1fd45db 100644
--- a/res/xml/reset_dashboard_fragment.xml
+++ b/res/xml/reset_dashboard_fragment.xml
@@ -18,7 +18,8 @@
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
-    android:title="@string/reset_dashboard_title">
+    android:title="@string/reset_dashboard_title"
+    android:key="reset_dashboard_fragment_screen">
 
     <!-- Network reset -->
     <com.android.settingslib.RestrictedPreference
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 33c1b0a..d288a9d 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -124,7 +124,7 @@
         <DropDownPreference
           android:key="dock_audio_media"
           android:title="@string/dock_audio_media_title"
-          android:summary="@string/summary_placeholder" />
+          android:summary="%s" />
 
         <!-- Boot sounds -->
         <SwitchPreference
@@ -135,7 +135,7 @@
         <DropDownPreference
           android:key="emergency_tone"
           android:title="@string/emergency_tone_title"
-          android:summary="@string/summary_placeholder" />
+          android:summary="%s" />
 
         <com.android.settingslib.RestrictedPreference
           android:key="cell_broadcast_settings"
diff --git a/res/xml/zen_mode_visual_interruptions_settings.xml b/res/xml/zen_mode_visual_interruptions_settings.xml
index 012dd95..64c79ec 100644
--- a/res/xml/zen_mode_visual_interruptions_settings.xml
+++ b/res/xml/zen_mode_visual_interruptions_settings.xml
@@ -16,7 +16,8 @@
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
-                  android:title="@string/zen_mode_visual_interruptions_settings_title" >
+                  android:title="@string/zen_mode_visual_interruptions_settings_title"
+                  android:key="zen_mode_visual_interruptions_screen">
 
     <SwitchPreference android:key="screenOn"
                       android:title="@string/zen_mode_screen_on"
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 546b11e..49784f6 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -722,15 +722,16 @@
                                 @Override
                                 public void onRemovalError(Fingerprint fp, int errMsgId,
                                         CharSequence errString) {
-                                    Log.v(TAG, "Fingerprint removed: " + fp.getFingerId());
-                                    if (fp.getFingerId() == 0) {
-                                        removeManagedProfileFingerprintsAndFinishIfNecessary(userId);
-                                    }
+                                    Log.e(TAG, String.format(
+                                            "Can't remove fingerprint %d in group %d. Reason: %s",
+                                            fp.getFingerId(), fp.getGroupId(), errString));
+                                    // TODO: need to proceed with the removal of managed profile
+                                    // fingerprints and finish() gracefully.
                                 }
 
                                 @Override
-                                public void onRemovalSucceeded(Fingerprint fingerprint) {
-                                    if (fingerprint.getFingerId() == 0) {
+                                public void onRemovalSucceeded(Fingerprint fp, int remaining) {
+                                    if (remaining == 0) {
                                         removeManagedProfileFingerprintsAndFinishIfNecessary(userId);
                                     }
                                 }
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java
index 109fb0e..8dfb02b 100644
--- a/src/com/android/settings/DeviceInfoSettings.java
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -51,6 +51,8 @@
 
     private static final String LOG_TAG = "DeviceInfoSettings";
 
+    private static final String KEY_LEGAL_CONTAINER = "legal_container";
+
     @Override
     public int getMetricsCategory() {
         return MetricsEvent.DEVICEINFO;
@@ -151,5 +153,12 @@
                     return buildPreferenceControllers(context, null /*activity */,
                             null /* fragment */, null /* lifecycle */);
                 }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    List<String> keys = super.getNonIndexableKeys(context);
+                    keys.add(KEY_LEGAL_CONTAINER);
+                    return keys;
+                }
             };
 }
diff --git a/src/com/android/settings/LegalSettings.java b/src/com/android/settings/LegalSettings.java
index e40152a..d5b9988 100644
--- a/src/com/android/settings/LegalSettings.java
+++ b/src/com/android/settings/LegalSettings.java
@@ -40,6 +40,7 @@
     private static final String KEY_LICENSE = "license";
     private static final String KEY_COPYRIGHT = "copyright";
     private static final String KEY_WEBVIEW_LICENSE = "webview_license";
+    private static final String KEY_WALLPAPER_ATTRIBUTIONS = "wallpaper_attributions";
 
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -76,7 +77,7 @@
 
             @Override
             public List<String> getNonIndexableKeys(Context context) {
-                final List<String> keys = new ArrayList<String>();
+                final List<String> keys = super.getNonIndexableKeys(context);
                 if (!checkIntentAction(context, "android.settings.TERMS")) {
                     keys.add(KEY_TERMS);
                 }
@@ -89,6 +90,7 @@
                 if (!checkIntentAction(context, "android.settings.WEBVIEW_LICENSE")) {
                     keys.add(KEY_WEBVIEW_LICENSE);
                 }
+                keys.add(KEY_WALLPAPER_ATTRIBUTIONS);
                 return keys;
             }
 
diff --git a/src/com/android/settings/SettingsInitialize.java b/src/com/android/settings/SettingsInitialize.java
index 66fc4d6..6b15770 100644
--- a/src/com/android/settings/SettingsInitialize.java
+++ b/src/com/android/settings/SettingsInitialize.java
@@ -35,7 +35,7 @@
 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
 
 /**
- * Listens to {@link Intent.ACTION_BOOT_COMPLETED} and {@link Intent.ACTION_PRE_BOOT_COMPLETED}
+ * Listens to {@link Intent.ACTION_PRE_BOOT_COMPLETED} and {@link Intent.ACTION_USER_INITIALIZED}
  * performs setup steps for a managed profile (disables the launcher icon of the Settings app,
  * adds cross-profile intent filters for the appropriate Settings activities), and disables the
  * webview setting for non-admin users.
@@ -89,11 +89,13 @@
         }
 
         // Disable launcher icon
-        // Note: This needs to happen after forwarding intents, otherwise the main Settings
-        // intent gets lost
         ComponentName settingsComponentName = new ComponentName(context, Settings.class);
         pm.setComponentEnabledSetting(settingsComponentName,
                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+        // Disable shortcut picker.
+        ComponentName shortcutComponentName = new ComponentName(context, CreateShortcut.class);
+        pm.setComponentEnabledSetting(shortcutComponentName,
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
     }
 
     // Disable WebView Setting if the current user is not an admin
diff --git a/src/com/android/settings/applications/AdvancedAppSettings.java b/src/com/android/settings/applications/AdvancedAppSettings.java
index caa9da1..cce8b7d 100644
--- a/src/com/android/settings/applications/AdvancedAppSettings.java
+++ b/src/com/android/settings/applications/AdvancedAppSettings.java
@@ -43,6 +43,8 @@
 
     static final String TAG = "AdvancedAppSettings";
 
+    private static final String KEY_ASSIST_VOICE_INPUT = "assist_and_voice_input";
+
     @Override
     protected String getLogTag() {
         return TAG;
@@ -80,6 +82,18 @@
                     sir.xmlResId = R.xml.app_default_settings;
                     return Arrays.asList(sir);
                 }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    List<String> keys = super.getNonIndexableKeys(context);
+                    keys.add(KEY_ASSIST_VOICE_INPUT);
+                    // TODO (b/38230148) Remove these keys when we can differentiate work results
+                    keys.add((new DefaultWorkPhonePreferenceController(context))
+                            .getPreferenceKey());
+                    keys.add((new DefaultWorkBrowserPreferenceController(context))
+                            .getPreferenceKey());
+                    return keys;
+                }
             };
 
     static class SummaryProvider implements SummaryLoader.SummaryProvider {
diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
index a6dfa9b..a76ed46 100755
--- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
 import android.text.Html;
 import android.text.TextUtils;
 import android.util.Log;
@@ -37,6 +38,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.bluetooth.A2dpProfile;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -55,6 +57,8 @@
     private static final String KEY_PROFILE_CONTAINER = "profile_container";
     private static final String KEY_UNPAIR = "unpair";
     private static final String KEY_PBAP_SERVER = "PBAP Server";
+    @VisibleForTesting
+    static final String HIGH_QUALITY_AUDIO_PREF_TAG = "A2dpProfileHighQualityAudio";
 
     private CachedBluetoothDevice mCachedDevice;
     private LocalBluetoothManager mManager;
@@ -169,6 +173,21 @@
         for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
             CheckBox pref = createProfilePreference(profile);
             mProfileContainer.addView(pref);
+
+            if (profile instanceof A2dpProfile) {
+                BluetoothDevice device = mCachedDevice.getDevice();
+                A2dpProfile a2dpProfile = (A2dpProfile) profile;
+                if (a2dpProfile.supportsHighQualityAudio(device)) {
+                    CheckBox highQualityPref = new CheckBox(getActivity());
+                    highQualityPref.setTag(HIGH_QUALITY_AUDIO_PREF_TAG);
+                    highQualityPref.setOnClickListener(v -> {
+                        a2dpProfile.setHighQualityAudioEnabled(device, highQualityPref.isChecked());
+                    });
+                    highQualityPref.setVisibility(View.GONE);
+                    mProfileContainer.addView(highQualityPref);
+                }
+                refreshProfilePreference(pref, profile);
+            }
         }
 
         final int pbapPermission = mCachedDevice.getPhonebookPermissionChoice();
@@ -356,6 +375,22 @@
         } else {
             profilePref.setChecked(profile.isPreferred(device));
         }
+        if (profile instanceof A2dpProfile) {
+            A2dpProfile a2dpProfile = (A2dpProfile) profile;
+            View v = mProfileContainer.findViewWithTag(HIGH_QUALITY_AUDIO_PREF_TAG);
+            if (v instanceof CheckBox) {
+                CheckBox highQualityPref = (CheckBox) v;
+                highQualityPref.setText(a2dpProfile.getHighQualityAudioOptionLabel(device));
+                highQualityPref.setChecked(a2dpProfile.isHighQualityAudioEnabled(device));
+
+                if (a2dpProfile.isPreferred(device)) {
+                    v.setVisibility(View.VISIBLE);
+                    v.setEnabled(!mCachedDevice.isBusy());
+                } else {
+                    v.setVisibility(View.GONE);
+                }
+            }
+        }
     }
 
     private LocalBluetoothProfile getProfileOf(View v) {
diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java
index 16172bd..5a84d13 100644
--- a/src/com/android/settings/datausage/DataUsageSummary.java
+++ b/src/com/android/settings/datausage/DataUsageSummary.java
@@ -71,10 +71,11 @@
     public static final boolean TEST_RADIOS = false;
     public static final String TEST_RADIOS_PROP = "test.radios";
 
+    public static final String KEY_RESTRICT_BACKGROUND = "restrict_background";
+    public static final String KEY_NETWORK_RESTRICTIONS = "network_restrictions";
+
     private static final String KEY_STATUS_HEADER = "status_header";
     private static final String KEY_LIMIT_SUMMARY = "limit_summary";
-    private static final String KEY_RESTRICT_BACKGROUND = "restrict_background";
-    private static final String KEY_NETWORK_RESTRICTIONS = "network_restrictions";
     private static final String KEY_WIFI_USAGE_TITLE = "wifi_category";
 
     private DataUsageController mDataUsageController;
@@ -465,7 +466,7 @@
             @Override
             public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
                     boolean enabled) {
-                ArrayList<SearchIndexableResource> resources = new ArrayList<>();
+                List<SearchIndexableResource> resources = new ArrayList<>();
                 SearchIndexableResource resource = new SearchIndexableResource(context);
                 resource.xmlResId = R.xml.data_usage;
                 resources.add(resource);
@@ -485,13 +486,14 @@
 
             @Override
             public List<String> getNonIndexableKeys(Context context) {
-                ArrayList<String> keys = new ArrayList<>();
-                boolean hasMobileData = ConnectivityManager.from(context).isNetworkSupported(
-                        ConnectivityManager.TYPE_MOBILE);
+                List<String> keys = super.getNonIndexableKeys(context);
 
-                if (hasMobileData) {
+                if (hasMobileData(context)) {
                     keys.add(KEY_RESTRICT_BACKGROUND);
                 }
+                if (hasWifiRadio(context)) {
+                    keys.add(KEY_NETWORK_RESTRICTIONS);
+                }
                 keys.add(KEY_WIFI_USAGE_TITLE);
 
                 return keys;
diff --git a/src/com/android/settings/fingerprint/FingerprintRemoveSidecar.java b/src/com/android/settings/fingerprint/FingerprintRemoveSidecar.java
index eda4c82..462d09e 100644
--- a/src/com/android/settings/fingerprint/FingerprintRemoveSidecar.java
+++ b/src/com/android/settings/fingerprint/FingerprintRemoveSidecar.java
@@ -53,7 +53,7 @@
     private FingerprintManager.RemovalCallback
             mRemoveCallback = new FingerprintManager.RemovalCallback() {
         @Override
-        public void onRemovalSucceeded(Fingerprint fingerprint) {
+        public void onRemovalSucceeded(Fingerprint fingerprint, int remaining) {
             if (mListener != null) {
                 mListener.onRemovalSucceeded(fingerprint);
             } else {
diff --git a/src/com/android/settings/fuelgauge/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/BatterySaverSettings.java
index 45d0db2..6b7ddf9 100644
--- a/src/com/android/settings/fuelgauge/BatterySaverSettings.java
+++ b/src/com/android/settings/fuelgauge/BatterySaverSettings.java
@@ -99,6 +99,7 @@
             }
         };
         mTriggerPref.init(this);
+
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
     }
 
diff --git a/src/com/android/settings/notification/SettingPref.java b/src/com/android/settings/notification/SettingPref.java
index cdbd5b3..18efc33 100644
--- a/src/com/android/settings/notification/SettingPref.java
+++ b/src/com/android/settings/notification/SettingPref.java
@@ -121,19 +121,6 @@
         if (mTwoState != null) {
             mTwoState.setChecked(val != 0);
         } else if (mDropDown != null) {
-            if (mValues != null) {
-                int index = 0;
-                for (int len = mValues.length; index < len; index++) {
-                    if (mValues[index] == val) {
-                        break;
-                    }
-                }
-
-                if (index < mValues.length) {
-                    CharSequence entry = mDropDown.getEntries()[index];
-                    mDropDown.setSummary(entry);
-                }
-            }
             mDropDown.setValue(Integer.toString(val));
         }
     }
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index a92c5dd..ec7351a 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -43,6 +43,7 @@
 public class SoundSettings extends DashboardFragment {
     private static final String TAG = "SoundSettings";
 
+    private static final String KEY_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
     private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
     private static final int REQUEST_CODE = 200;
 
@@ -187,7 +188,7 @@
         final List<PreferenceController> controllers = new ArrayList<>();
         controllers.add(new ZenModePreferenceController(context));
         controllers.add(new EmergencyBroadcastPreferenceController(
-                context, "cell_broadcast_settings"));
+                context, KEY_CELL_BROADCAST_SETTINGS));
         controllers.add(new VibrateWhenRingPreferenceController(context));
 
         // === Volumes ===
@@ -236,6 +237,16 @@
                     return buildPreferenceControllers(context, null /* fragment */,
                             null /* callback */, null /* lifecycle */);
                 }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    List<String> keys = super.getNonIndexableKeys(context);
+                    // Duplicate results
+                    keys.add((new ZenModePreferenceController(context)).getPreferenceKey());
+                    keys.add(ZenModeSettings.KEY_VISUAL_SETTINGS);
+                    keys.add(KEY_CELL_BROADCAST_SETTINGS);
+                    return keys;
+                }
             };
 
     // === Work Sound Settings ===
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index bbcaa9c..854857a 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -53,8 +53,10 @@
 import java.util.Map.Entry;
 
 public class ZenModeSettings extends ZenModeSettingsBase {
+
+    public static final String KEY_VISUAL_SETTINGS = "visual_interruptions_settings";
+
     private static final String KEY_PRIORITY_SETTINGS = "priority_settings";
-    private static final String KEY_VISUAL_SETTINGS = "visual_interruptions_settings";
     private static final String KEY_AUTOMATIC_RULES = "automatic_rules";
 
     static final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java
index 8732227..f5e06ca 100644
--- a/src/com/android/settings/search/BaseSearchIndexProvider.java
+++ b/src/com/android/settings/search/BaseSearchIndexProvider.java
@@ -72,7 +72,7 @@
             }
             return nonIndexableKeys;
         } else {
-            return EMPTY_LIST;
+            return new ArrayList<>();
         }
     }
 
diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java
index 4c4ed21..1a5a182 100644
--- a/src/com/android/settings/system/SystemDashboardFragment.java
+++ b/src/com/android/settings/system/SystemDashboardFragment.java
@@ -37,6 +37,8 @@
 
     private static final String TAG = "SystemDashboardFrag";
 
+    private static final String KEY_RESET = "reset_dashboard";
+
     @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.SETTINGS_SYSTEM_CATEGORY;
@@ -82,5 +84,14 @@
                 public List<PreferenceController> getPreferenceControllers(Context context) {
                     return buildPreferenceControllers(context);
                 }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    List<String> keys = super.getNonIndexableKeys(context);
+                    keys.add((new BackupSettingsActivityPreferenceController(context)
+                            .getPreferenceKey()));
+                    keys.add(KEY_RESET);
+                    return keys;
+                }
             };
 }
diff --git a/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java b/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java
new file mode 100644
index 0000000..40b76df
--- /dev/null
+++ b/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java
@@ -0,0 +1,23 @@
+/*
+ * 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 android.bluetooth;
+
+/**
+ * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility.
+ */
+public class BluetoothCodecConfig {
+}
diff --git a/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java b/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
index c43ad3c..c64e582 100644
--- a/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
@@ -28,6 +28,8 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.dashboard.SummaryLoader;
+import com.android.settings.testutils.XmlTestUtils;
+import com.android.settings.testutils.shadow.ShadowUtils;
 import com.android.settingslib.DeviceInfoUtils;
 
 import org.junit.Before;
@@ -36,8 +38,11 @@
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
+import java.util.List;
+
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class DeviceInfoSettingsTest {
@@ -75,4 +80,17 @@
 
         verify(mSummaryLoader).setSummary(mProvider, Build.MODEL + DeviceInfoUtils.getMsvSuffix());
     }
+
+    @Test
+    @Config(shadows = ShadowUtils.class)
+    public void testNonIndexableKeys_existInXmlLayout() {
+        final Context context = RuntimeEnvironment.application;
+        final List<String> niks = DeviceInfoSettings.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(context);
+        final int xmlId = (new DeviceInfoSettings()).getPreferenceScreenResId();
+
+        final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
+
+        assertThat(keys).containsAllIn(niks);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/LegalSettingsTest.java b/tests/robotests/src/com/android/settings/LegalSettingsTest.java
new file mode 100644
index 0000000..6cfe211
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/LegalSettingsTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+import android.content.Context;
+
+import com.android.settings.testutils.XmlTestUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class LegalSettingsTest {
+
+    @Test
+    public void testNonIndexableKeys_existInXmlLayout() {
+        final Context context = RuntimeEnvironment.application;
+        final List<String> niks = LegalSettings.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(context);
+
+        final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context,
+                R.xml.about_legal);
+
+        assertThat(keys).containsAllIn(niks);
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java b/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java
index bedb0a5..0c3c160 100644
--- a/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java
@@ -26,6 +26,7 @@
 import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController;
 import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
 import com.android.settings.dashboard.SummaryLoader;
+import com.android.settings.testutils.XmlTestUtils;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -34,11 +35,14 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
+import java.util.List;
+
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -136,4 +140,16 @@
 
     }
 
+
+    @Test
+    public void testNonIndexableKeys_existInXmlLayout() {
+        final Context context = spy(RuntimeEnvironment.application);
+        final List<String> niks = AdvancedAppSettings.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(context);
+        final int xmlId = (new AdvancedAppSettings()).getPreferenceScreenResId();
+
+        final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
+
+        assertThat(keys).containsAllIn(niks);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/DeviceProfilesSettingsTest.java b/tests/robotests/src/com/android/settings/bluetooth/DeviceProfilesSettingsTest.java
new file mode 100644
index 0000000..c61823c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/DeviceProfilesSettingsTest.java
@@ -0,0 +1,206 @@
+/*
+ * 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.bluetooth;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.shadow.ShadowEventLogWriter;
+import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.FragmentTestUtil;
+import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.RuntimeEnvironment;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import java.util.ArrayList;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = {
+        ShadowEventLogWriter.class
+})
+public class DeviceProfilesSettingsTest {
+    Context mContext;
+    @Mock Activity mActivity;
+    @Mock LocalBluetoothManager mManager;
+    @Mock LocalBluetoothAdapter mAdapter;
+    @Mock LocalBluetoothProfileManager mProfileManager;
+    @Mock CachedBluetoothDeviceManager mDeviceManager;
+    @Mock CachedBluetoothDevice mCachedDevice;
+    @Mock A2dpProfile mProfile;
+
+    ArrayList<LocalBluetoothProfile> mProfiles;
+    DeviceProfilesSettings mFragment;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        when(mProfile.getNameResource(any())).thenReturn(R.string.bluetooth_profile_a2dp);
+        mProfiles = new ArrayList<>();
+        mProfiles.add(mProfile);
+        when(mCachedDevice.getConnectableProfiles()).thenReturn(mProfiles);
+
+        mFragment = new DeviceProfilesSettings();
+        mFragment.setArguments(new Bundle());
+
+        ReflectionHelpers.setStaticField(LocalBluetoothManager.class, "sInstance", mManager);
+        when(mManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+        when(mManager.getBluetoothAdapter()).thenReturn(mAdapter);
+        when(mManager.getProfileManager()).thenReturn(mProfileManager);
+        when(mProfileManager.getMapProfile()).thenReturn(null);
+        when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
+    }
+
+    @Test
+    public void deviceHasHighQualityAudio() {
+        when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
+        when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
+        when(mProfile.isPreferred(any())).thenReturn(true);
+        FragmentTestUtil.startFragment(mFragment);
+
+        ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
+        CheckBox box = (CheckBox) profilesGroup.findViewWithTag(
+                DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
+        assertThat(box).isNotNull();
+        assertThat(box.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(box.isEnabled()).isTrue();
+        assertThat(box.isChecked()).isTrue();
+
+        box.performClick();
+        verify(mProfile).setHighQualityAudioEnabled(any(), eq(false));
+        box.performClick();
+        verify(mProfile).setHighQualityAudioEnabled(any(), eq(true));
+    }
+
+    @Test
+    public void busyDeviceDisablesControl() {
+        when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
+        when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
+        when(mProfile.isPreferred(any())).thenReturn(true);
+        when(mCachedDevice.isBusy()).thenReturn(true);
+        FragmentTestUtil.startFragment(mFragment);
+
+        // Make sure that the high quality audio option is present but disabled when the device
+        // is busy.
+        ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
+        CheckBox box = (CheckBox) profilesGroup.findViewWithTag(
+                DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
+        assertThat(box).isNotNull();
+        assertThat(box.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(box.isEnabled()).isFalse();
+    }
+
+    @Test
+    public void mediaAudioGetsDisabledAndReEnabled() {
+        when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
+        when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
+        when(mProfile.isPreferred(any())).thenReturn(true);
+        FragmentTestUtil.startFragment(mFragment);
+
+        ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
+        CheckBox audioBox = profilesGroup.findViewWithTag(mProfile.toString());
+        CheckBox highQualityAudioBox = profilesGroup.findViewWithTag(
+                DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
+        assertThat(audioBox).isNotNull();
+        assertThat(audioBox.isChecked()).isTrue();
+        assertThat(highQualityAudioBox).isNotNull();
+        assertThat(highQualityAudioBox.isChecked()).isTrue();
+
+        // Disabling media audio should cause the high quality audio box to disappear.
+        when(mProfile.isPreferred(any())).thenReturn(false);
+        mFragment.onDeviceAttributesChanged();
+        audioBox = profilesGroup.findViewWithTag(mProfile.toString());
+        highQualityAudioBox = profilesGroup.findViewWithTag(
+                DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
+        assertThat(audioBox).isNotNull();
+        assertThat(audioBox.isChecked()).isFalse();
+        assertThat(highQualityAudioBox).isNotNull();
+        assertThat(highQualityAudioBox.getVisibility()).isEqualTo(View.GONE);
+
+        // And re-enabling media audio should make it reappear.
+        when(mProfile.isPreferred(any())).thenReturn(true);
+        mFragment.onDeviceAttributesChanged();
+        audioBox = profilesGroup.findViewWithTag(mProfile.toString());
+        highQualityAudioBox = profilesGroup.findViewWithTag(
+                DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
+        assertThat(audioBox).isNotNull();
+        assertThat(audioBox.isChecked()).isTrue();
+        assertThat(highQualityAudioBox).isNotNull();
+        assertThat(highQualityAudioBox.isChecked()).isTrue();
+    }
+
+    @Test
+    public void mediaAudioStartsDisabled() {
+        when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
+        when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
+        when(mProfile.isPreferred(any())).thenReturn(false);
+
+        FragmentTestUtil.startFragment(mFragment);
+        ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
+        CheckBox audioBox = profilesGroup.findViewWithTag(mProfile.toString());
+        CheckBox highQualityAudioBox = profilesGroup.findViewWithTag(
+                DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
+
+        assertThat(audioBox).isNotNull();
+        assertThat(audioBox.isChecked()).isFalse();
+        assertThat(highQualityAudioBox).isNotNull();
+        assertThat(highQualityAudioBox.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void deviceDoesntHaveHighQualityAudio() {
+        when(mProfile.supportsHighQualityAudio(any())).thenReturn(false);
+        when(mProfile.isPreferred(any())).thenReturn(true);
+        FragmentTestUtil.startFragment(mFragment);
+
+        // A device that doesn't support high quality audio shouldn't have the checkbox for
+        // high quality audio support.
+        ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
+        CheckBox box = (CheckBox) profilesGroup.findViewWithTag(
+                DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
+        assertThat(box).isNull();
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
index e1572ab..92ded0d 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
@@ -25,8 +25,8 @@
 import com.android.settings.R;
 import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
 import com.android.settings.testutils.XmlTestUtils;
+import com.android.settings.testutils.shadow.ShadowConnectivityManager;
 import com.android.settingslib.NetworkPolicyEditor;
 
 import org.junit.Before;
@@ -160,4 +160,16 @@
 
         assertThat(keys).containsAllIn(niks);
     }
+
+    @Test
+    @Config(shadows = ShadowConnectivityManager.class)
+    public void testNonIndexableKeys_hasMobileData_restrictedAccessesAdded() {
+        ShadowConnectivityManager.setIsNetworkSupported(true);
+        List<String> keys = DataUsageSummary.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(mContext);
+
+        assertThat(keys).contains(DataUsageSummary.KEY_RESTRICT_BACKGROUND);
+        assertThat(keys).contains(DataUsageSummary.KEY_NETWORK_RESTRICTIONS);
+        ShadowConnectivityManager.setIsNetworkSupported(false);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/SettingPrefTest.java b/tests/robotests/src/com/android/settings/notification/SettingPrefTest.java
deleted file mode 100644
index 39f1377..0000000
--- a/tests/robotests/src/com/android/settings/notification/SettingPrefTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.android.settings.notification;
-
-import android.content.res.Resources;
-
-import android.content.Context;
-import android.provider.Settings;
-import android.support.v7.preference.DropDownPreference;
-import com.android.settings.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.spy;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SettingPrefTest {
-
-    @Test
-    public void update_setsDropDownSummaryText() {
-        Context context = RuntimeEnvironment.application;
-        String testSetting = "test_setting";
-        int[] values = new int[] {1,2,3};
-        String[] entries = new String[] {"one", "two", "three"};
-        SettingPref settingPref =
-                spy(new SettingPref(SettingPref.TYPE_GLOBAL, "key", testSetting, 0, values) {
-                    @Override
-                    protected String getCaption(Resources res, int value) {
-                        return "temp";
-                    }
-                });
-        DropDownPreference dropdownPref = spy(new DropDownPreference(context));
-        dropdownPref.setEntries(entries);
-        settingPref.mDropDown = dropdownPref;
-        Settings.Global.putInt(context.getContentResolver(), testSetting, values[2]);
-
-        settingPref.update(context);
-
-        assertThat(settingPref.mDropDown.getSummary()).isEqualTo(entries[2]);
-    }
-
-    @Test
-    public void update_setsDropDownSummaryText_noMatch_noError() {
-        Context context = RuntimeEnvironment.application;
-        String testSetting = "test_setting";
-        int[] values = new int[] {1,2,3};
-        String[] entries = new String[] {"one", "two", "three"};
-        SettingPref settingPref =
-                spy(new SettingPref(SettingPref.TYPE_GLOBAL, "key", testSetting, 0, values) {
-                    @Override
-                    protected String getCaption(Resources res, int value) {
-                        return "temp";
-                    }
-                });
-        DropDownPreference dropdownPref = spy(new DropDownPreference(context));
-        dropdownPref.setEntries(entries);
-        settingPref.mDropDown = dropdownPref;
-        Settings.Global.putInt(context.getContentResolver(), testSetting, -1);
-
-        settingPref.update(context);
-
-        assertThat(settingPref.mDropDown.getSummary()).isNull();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java b/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java
new file mode 100644
index 0000000..547117b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.notification;
+
+import android.content.Context;
+
+import android.media.AudioManager;
+import android.os.UserManager;
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.XmlTestUtils;
+import com.android.settings.testutils.shadow.ShadowAudioHelper;
+import com.android.settings.testutils.shadow.ShadowUserManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SoundSettingsTest {
+
+    @Test
+    @Config( shadows = {
+            ShadowUserManager.class,
+            ShadowAudioHelper.class,
+    })
+    public void testNonIndexableKeys_existInXmlLayout() {
+        final Context context = spy(RuntimeEnvironment.application);
+        AudioManager audioManager = mock(AudioManager.class);
+        doReturn(audioManager).when(context).getSystemService(Context.AUDIO_SERVICE);
+
+        UserManager userManager = mock(UserManager.class);
+        when(userManager.isAdminUser()).thenReturn(false);
+        doReturn(userManager).when(context).getSystemService(Context.USER_SERVICE);
+
+        final List<String> niks = SoundSettings.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(context);
+        final int xmlId = (new SoundSettings()).getPreferenceScreenResId();
+        final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
+        keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context,
+                R.xml.zen_mode_settings));
+        // Add keys with hidden resources
+        keys.add("alarm_volume");
+        keys.add("ring_volume");
+        keys.add("notification_volume");
+
+        assertThat(keys).containsAllIn(niks);
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java
index b76feff1..6844be5 100644
--- a/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java
+++ b/tests/robotests/src/com/android/settings/search2/DatabaseIndexingManagerTest.java
@@ -671,9 +671,9 @@
                 new HashMap<String, Set<String>>());
 
         Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null);
-        assertThat(cursor.getCount()).isEqualTo(2);
+        assertThat(cursor.getCount()).isEqualTo(1);
         cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null);
-        assertThat(cursor.getCount()).isEqualTo(4);
+        assertThat(cursor.getCount()).isEqualTo(5);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java
new file mode 100644
index 0000000..65b39e6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.system;
+
+import android.content.Context;
+
+import android.os.UserManager;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.XmlTestUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SystemDashboardFragmentTest {
+
+    @Test
+    public void testNonIndexableKeys_existInXmlLayout() {
+        final Context context = spy(RuntimeEnvironment.application);
+        UserManager manager = mock(UserManager.class);
+        when(manager.isAdminUser()).thenReturn(false);
+        doReturn(manager).when(context).getSystemService(Context.USER_SERVICE);
+        final List<String> niks = SystemDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(context);
+        final int xmlId = (new SystemDashboardFragment()).getPreferenceScreenResId();
+
+        final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
+
+        assertThat(keys).containsAllIn(niks);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioHelper.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioHelper.java
new file mode 100644
index 0000000..886f941
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAudioHelper.java
@@ -0,0 +1,37 @@
+/*
+ * 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.testutils.shadow;
+
+import android.os.UserHandle;
+import android.os.UserManager;
+import com.android.settings.notification.AudioHelper;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(AudioHelper.class)
+public class ShadowAudioHelper {
+
+    @Implementation
+    public boolean isSingleVolume() {
+        return true;
+    }
+
+    @Implementation
+    public int getManagedProfileId(UserManager um) {
+        return UserHandle.USER_CURRENT;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java
index dbf1a65..4c05665 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowConnectivityManager.java
@@ -24,9 +24,14 @@
 @Implements(ConnectivityManager.class)
 public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowConnectivityManager {
 
+    private static boolean mIsNetworkSupported;
+
     @Implementation
     public boolean isNetworkSupported(int networkType) {
-        return false;
+        return mIsNetworkSupported;
     }
 
+    public static void setIsNetworkSupported(boolean isNetworkSupported) {
+        mIsNetworkSupported = isNetworkSupported;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
index eb82362..87b9103 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java
@@ -46,4 +46,9 @@
     public static void reset() {
         sFingerprintManager = null;
     }
+
+    @Implementation
+    public static boolean isWifiOnly(Context context) {
+        return true;
+    }
 }