diff --git a/res/drawable/ic_menu_add_activated_tint.xml b/res/drawable/ic_menu_add_activated_tint.xml
new file mode 100644
index 0000000..e5d1384
--- /dev/null
+++ b/res/drawable/ic_menu_add_activated_tint.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlActivated">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M18,13h-5v5c0,0.55-0.45,1-1,1h0c-0.55,0-1-0.45-1-1v-5H6c-0.55,0-1-0.45-1-1v0c0-0.55,0.45-1,1-1h5V6c0-0.55,0.45-1,1-1h0
+c0.55,0,1,0.45,1,1v5h5c0.55,0,1,0.45,1,1v0C19,12.55,18.55,13,18,13z"/>
+</vector>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e770d3c..93b7fa2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2321,8 +2321,9 @@
         <item quantity="one">1 subscription</item>
         <item quantity="other">%d subscriptions</item>
     </plurals>
-    <!-- Wi-Fi settings screen, Saved networks summary.  This shows below the "Saved networks" item and indicates number of whole kinds networks, if there are both normal saved networks and saved passpoint networks. The number will be at least 2. [CHAR LIMIT=60] -->
+    <!-- Wi-Fi settings screen, Saved networks summary.  This shows below the "Saved networks" item and indicates number of whole kinds networks, if there are both normal saved networks and saved passpoint networks. The number will be at least 2, so the one case is only to prevent lint error. [CHAR LIMIT=60] -->
     <plurals name="wifi_saved_all_access_points_summary">
+        <item quantity="one">1 network &amp; subscription</item>
         <item quantity="other">%d networks &amp; subscriptions</item>
     </plurals>
     <!-- Wi-Fi settings screen, advanced, settings section.  This is a header shown above advanced wifi settings. [CHAR LIMIT=30] -->
@@ -6385,6 +6386,8 @@
 
     <!-- Option for indicating that a network being metered (expensive) should be determined automatically. [CHAR LIMIT=32] -->
     <string name="data_usage_metered_auto">Automatic</string>
+    <!-- Title for Network usage to control whether Wifi is metered or not [CHAR LIMIT=20] -->
+    <string name="wifi_metered_title">Network usage</string>
     <!-- Option for indicating that a network is metered (expensive). [CHAR LIMIT=32] -->
     <string name="data_usage_metered_yes">Metered</string>
     <!-- Option for indicating that a network is not metered (inexpensive). [CHAR LIMIT=32] -->
@@ -11081,9 +11084,9 @@
     <string name="forget_passpoint_dialog_message">You may lose access to any remaining time or data. Check with your provider before removing.</string>
 
     <!-- Keywords for Content Capture feature [CHAR_LIMIT=none] -->
-    <string name="keywords_content_capture">content capture</string>
+    <string name="keywords_content_capture">content capture, app content</string>
     <!-- Title of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=none]-->
-    <string name="content_capture">Content Capture</string>
+    <string name="content_capture">App content</string>
     <!-- Description of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
     <string name="content_capture_summary">Allow apps to send content to the Android system</string>
 
diff --git a/res/xml/mobile_network_list.xml b/res/xml/mobile_network_list.xml
index c2baf46..13f9a59 100644
--- a/res/xml/mobile_network_list.xml
+++ b/res/xml/mobile_network_list.xml
@@ -24,7 +24,7 @@
         android:key="add_more"
         settings:isPreferenceVisible="false"
         android:title="@string/mobile_network_list_add_more"
-        android:icon="@drawable/ic_menu_add"
+        android:icon="@drawable/ic_menu_add_activated_tint"
         android:order="100" >
         <intent android:action="android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION">
             <extra android:name="android.telephony.euicc.extra.FORCE_PROVISION"
diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml
index 3218e0d..d45f9bc 100644
--- a/res/xml/wifi_network_details_fragment.xml
+++ b/res/xml/wifi_network_details_fragment.xml
@@ -58,7 +58,7 @@
     <DropDownPreference
         android:key="metered"
         android:icon="@drawable/ic_attach_money_black_24dp"
-        android:title="@string/data_usage_metered_yes"
+        android:title="@string/wifi_metered_title"
         android:entries="@array/wifi_metered_entries"
         android:entryValues="@array/wifi_metered_values"/>
 
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
index 6435468..be23f72 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
@@ -20,12 +20,25 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.provider.SearchIndexableResource;
+import android.text.Annotation;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import android.text.style.URLSpan;
+import android.view.View;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
+import com.android.settingslib.HelpUtils;
 import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.widget.FooterPreference;
 
 import java.util.Arrays;
 import java.util.List;
@@ -36,10 +49,14 @@
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class BatterySaverSettings extends DashboardFragment {
     private static final String TAG = "BatterySaverSettings";
+    public static final String KEY_FOOTER_PREFERENCE = "footer_preference";
+    private SpannableStringBuilder mFooterText;
+    private String mHelpUri;
 
     @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
+    public void onStart() {
+        super.onStart();
+        setupFooter();
     }
 
     @Override
@@ -75,4 +92,82 @@
                     return Arrays.asList(sir);
                 }
             };
+
+    // Updates the footer for this page.
+    @VisibleForTesting
+    void setupFooter() {
+        mFooterText =  new SpannableStringBuilder(getText(
+                com.android.internal.R.string.battery_saver_description_with_learn_more));
+        mHelpUri = getString(R.string.help_url_battery_saver_settings);
+        if (!TextUtils.isEmpty(mHelpUri)) {
+            addHelpLink();
+        }
+    }
+
+    // Changes the text to include a learn more link if possible.
+    @VisibleForTesting
+    void addHelpLink() {
+        FooterPreference pref = getPreferenceScreen().findPreference(KEY_FOOTER_PREFERENCE);
+        if (pref != null) {
+            SupportPageLearnMoreSpan.linkify(mFooterText, this, mHelpUri);
+            pref.setTitle(mFooterText);
+        }
+    }
+
+    /**
+     * A {@link URLSpan} that opens a support page when clicked
+     */
+    public static class SupportPageLearnMoreSpan extends URLSpan {
+
+
+        private static final String ANNOTATION_URL = "url";
+        private final Fragment mFragment;
+        private final String mUriString;
+
+        public SupportPageLearnMoreSpan(Fragment fragment, String uriString) {
+            // sets the url to empty string so we can prevent any other span processing from
+            // from clearing things we need in this string.
+            super("");
+            mFragment = fragment;
+            mUriString = uriString;
+        }
+
+        @Override
+        public void onClick(View widget) {
+            if (mFragment != null) {
+                // launch the support page
+                mFragment.startActivityForResult(HelpUtils.getHelpIntent(mFragment.getContext(),
+                        mUriString, ""), 0);
+            }
+        }
+
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            super.updateDrawState(ds);
+            // remove underline
+            ds.setUnderlineText(false);
+        }
+
+        /**
+         * This method takes a string and turns it into a url span that will launch a support page
+         * @param msg The text to turn into a link
+         * @param fragment The fragment which contains this span
+         * @param uriString The URI string of the help article to open when clicked
+         * @return A CharSequence containing the original text content as a url
+         */
+        public static CharSequence linkify(Spannable msg, Fragment fragment, String uriString) {
+            Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
+            for (Annotation annotation : spans) {
+                int start = msg.getSpanStart(annotation);
+                int end = msg.getSpanEnd(annotation);
+                if (ANNOTATION_URL.equals(annotation.getValue())) {
+                    SupportPageLearnMoreSpan link =
+                            new SupportPageLearnMoreSpan(fragment, uriString);
+                    msg.removeSpan(annotation);
+                    msg.setSpan(link, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                }
+            }
+            return msg;
+        }
+    }
 }
diff --git a/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java b/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java
index 52c5cc1..13bfa92 100644
--- a/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java
+++ b/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java
@@ -17,6 +17,7 @@
 package com.android.settings.network.telephony;
 
 import android.app.Dialog;
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
@@ -77,7 +78,6 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO(b/131519375) - use a real id here once it's been created in the metrics proto
-        return 0;
+        return SettingsEnums.DIALOG_DELETE_SIM_CONFIRMATION;
     }
 }
diff --git a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java b/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java
index 15f4b22..c176f3c 100644
--- a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java
+++ b/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java
@@ -20,6 +20,7 @@
 import android.app.Dialog;
 import android.app.PendingIntent;
 import android.app.ProgressDialog;
+import android.app.settings.SettingsEnums;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -114,7 +115,6 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO(b/131519375) - use a real id here once it's been created in the metrics proto
-        return 0;
+        return SettingsEnums.DIALOG_DELETE_SIM_PROGRESS;
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettingsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettingsTest.java
new file mode 100644
index 0000000..7cb57a3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettingsTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 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.fuelgauge.batterysaver;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import androidx.preference.PreferenceScreen;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class BatterySaverSettingsTest {
+    BatterySaverSettings mFragment;
+    @Mock
+    PreferenceScreen mScreen;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mFragment = spy(new BatterySaverSettings());
+        doReturn(mScreen).when(mFragment).getPreferenceScreen();
+    }
+
+
+    @Test
+    public void setupFooter_linkAddedWhenAppropriate() {
+        doReturn("").when(mFragment).getText(anyInt());
+        doReturn("").when(mFragment).getString(anyInt());
+        mFragment.setupFooter();
+        verify(mFragment, never()).addHelpLink();
+
+        doReturn("testString").when(mFragment).getText(anyInt());
+        doReturn("testString").when(mFragment).getString(anyInt());
+        mFragment.setupFooter();
+        verify(mFragment, atLeastOnce()).addHelpLink();
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java b/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java
deleted file mode 100644
index 2fdee5c..0000000
--- a/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2018 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.ui;
-
-import android.metrics.MetricsReader;
-import android.os.RemoteException;
-import android.platform.test.annotations.Presubmit;
-import android.provider.Settings;
-import android.support.test.metricshelper.MetricsAsserts;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Direction;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.system.helpers.SettingsHelper;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class AccessibilitySettingsTests extends InstrumentationTestCase {
-
-    private static final String SETTINGS_PACKAGE = "com.android.settings";
-    private static final int TIMEOUT = 2000;
-    private UiDevice mDevice;
-    private MetricsReader mMetricsReader;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        try {
-            mDevice.setOrientationNatural();
-        } catch (RemoteException e) {
-            throw new RuntimeException("failed to freeze device orientaion", e);
-        }
-        mMetricsReader = new MetricsReader();
-        // Clear out old logs
-        mMetricsReader.checkpoint();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Need to finish settings activity
-        mDevice.pressBack();
-        mDevice.pressHome();
-        mDevice.waitForIdle();
-        super.tearDown();
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testHighContrastTextOn() throws Exception {
-        verifyAccessibilitySettingOnOrOff("High contrast text",
-                Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0, 1);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testHighContrastTextOff() throws Exception {
-        verifyAccessibilitySettingOnOrOff("High contrast text",
-               Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 1, 0);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testPowerButtonEndsCallOn() throws Exception {
-        verifyAccessibilitySettingOnOrOff("Power button ends call",
-                Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 1, 2);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testPowerButtonEndsCallOff() throws Exception {
-        verifyAccessibilitySettingOnOrOff("Power button ends call",
-                Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 2, 1);
-    }
-
-    /* Suppressing these four tests. The settings don't play
-     * nice with Settings.System.putInt or Settings.Secure.putInt.
-     * Need further clarification. Filed bug b/27792029
-     */
-    @Suppress
-    @MediumTest
-    public void testAutoRotateScreenOn() throws Exception {
-        verifyAccessibilitySettingOnOrOff("Auto-rotate screen",
-               Settings.System.ACCELEROMETER_ROTATION, 0, 1);
-    }
-
-    @Suppress
-    @MediumTest
-    public void testAutoRotateScreenOff() throws Exception {
-       verifyAccessibilitySettingOnOrOff("Auto-rotate screen",
-               Settings.System.ACCELEROMETER_ROTATION, 1, 0);
-    }
-
-    @Suppress
-    @MediumTest
-    public void testMonoAudioOn() throws Exception {
-        verifyAccessibilitySettingOnOrOff("Mono audio",
-               Settings.System.MASTER_MONO, 0, 1);
-    }
-
-    @Suppress
-    @MediumTest
-    public void testMonoAudioOff() throws Exception {
-         verifyAccessibilitySettingOnOrOff("Mono audio",
-                Settings.System.MASTER_MONO, 1, 0);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testLargeMousePointerOn() throws Exception {
-         verifyAccessibilitySettingOnOrOff("Large mouse pointer",
-                 Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0, 1);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testLargeMousePointerOff() throws Exception {
-         verifyAccessibilitySettingOnOrOff("Large mouse pointer",
-                 Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 1, 0);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testColorCorrection() throws Exception {
-        verifySettingToggleAfterScreenLoad("Color correction",
-                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
-        MetricsAsserts.assertHasVisibilityLog("Missing color correction log",
-                mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_DALTONIZER, true);
-    }
-
-    // Suppressing this test, since UiAutomator + talkback don't play nice
-    @Suppress
-    @MediumTest
-    public void testTalkback() throws Exception {
-        verifySettingToggleAfterScreenLoad("TalkBack",
-                Settings.Secure.ACCESSIBILITY_ENABLED);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testCaptions() throws Exception {
-         verifySettingToggleAfterScreenLoad("Captions",
-                 Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
-        MetricsAsserts.assertHasVisibilityLog("Missing captions log",
-                mMetricsReader, MetricsEvent.ACCESSIBILITY_CAPTION_PROPERTIES, true);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testMagnificationGesture() throws Exception {
-        verifySettingToggleAfterScreenLoad("Magnification", "Magnify with triple-tap",
-                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
-        MetricsAsserts.assertHasVisibilityLog("Missing magnification log",
-                mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION, true);
-    }
-
-    @MediumTest
-    public void testClickAfterPointerStopsMoving() throws Exception {
-         verifySettingToggleAfterScreenLoad("Click after pointer stops moving",
-                  Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED);
-    }
-
-    @MediumTest
-    public void testAccessibilitySettingsLoadLog() throws Exception {
-        launchAccessibilitySettings();
-        MetricsAsserts.assertHasVisibilityLog("Missing accessibility settings load log",
-                mMetricsReader, MetricsEvent.ACCESSIBILITY, true);
-    }
-
-    public void launchAccessibilitySettings() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
-                Settings.ACTION_ACCESSIBILITY_SETTINGS);
-    }
-
-    private void verifyAccessibilitySettingOnOrOff(String settingText,
-            String settingFlag, int initialFlagValue, int expectedFlagValue)
-            throws Exception {
-        Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
-                settingFlag, initialFlagValue);
-        launchAccessibilitySettings();
-        UiObject2 settingsTitle = findItemOnScreen(settingText);
-        settingsTitle.click();
-        Thread.sleep(TIMEOUT);
-        int settingValue = Settings.Secure
-                .getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
-        assertEquals(settingText + " not correctly set after toggle",
-                expectedFlagValue, settingValue);
-    }
-
-    private void verifySettingToggleAfterScreenLoad(String settingText, String settingFlag)
-            throws Exception {
-        verifySettingToggleAfterScreenLoad(settingText, null, settingFlag);
-    }
-
-    private void verifySettingToggleAfterScreenLoad
-            (String settingText, String subSetting, String settingFlag) throws Exception {
-        // Load accessibility settings
-        launchAccessibilitySettings();
-        Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
-                settingFlag, 0);
-        Thread.sleep(TIMEOUT);
-        // Tap on setting required
-        UiObject2 settingTitle = findItemOnScreen(settingText);
-        // Load screen
-        settingTitle.click();
-        Thread.sleep(TIMEOUT);
-        if (subSetting != null) {
-            UiObject2 subSettingObject = findItemOnScreen(subSetting);
-            subSettingObject.click();
-            Thread.sleep(TIMEOUT);
-        }
-        // Toggle value
-        UiObject2 settingToggle =  mDevice.wait(Until.findObject(By.text("Off")),
-                            TIMEOUT);
-        settingToggle.click();
-        dismissOpenDialog();
-        Thread.sleep(TIMEOUT);
-        // Assert new value
-        int settingValue = Settings.Secure.
-                getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
-        assertEquals(settingText + " value not set correctly", 1, settingValue);
-        // Toogle value
-        settingToggle.click();
-        dismissOpenDialog();
-        mDevice.pressBack();
-        Thread.sleep(TIMEOUT);
-        // Assert reset to old value
-        settingValue = Settings.Secure.
-                getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
-        assertEquals(settingText + " value not set correctly", 0, settingValue);
-    }
-
-    private UiObject2 findItemOnScreen(String item) throws Exception {
-        int count = 0;
-        UiObject2 settingsPanel = mDevice.wait(Until.findObject
-                (By.res(SETTINGS_PACKAGE, "list")), TIMEOUT);
-        while (settingsPanel.fling(Direction.UP) && count < 3) {
-            count++;
-        }
-        count = 0;
-        UiObject2 setting = null;
-        while(count < 3 && setting == null) {
-            setting = mDevice.wait(Until.findObject(By.text(item)), TIMEOUT);
-            if (setting == null) {
-                settingsPanel.scroll(Direction.DOWN, 1.0f);
-            }
-            count++;
-        }
-        return setting;
-    }
-
-    private void dismissOpenDialog() throws Exception {
-        UiObject2 okButton = mDevice.wait(Until.findObject
-                (By.res("android:id/button1")), TIMEOUT*2);
-        if (okButton != null) {
-            okButton.click();
-        }
-    }
-}
diff --git a/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java
deleted file mode 100644
index d41be9c..0000000
--- a/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2018 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.ui;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothManager;
-import android.content.Context;
-import android.content.Intent;
-import android.metrics.MetricsReader;
-import android.os.RemoteException;
-import android.platform.test.annotations.Presubmit;
-import android.provider.Settings;
-import android.support.test.metricshelper.MetricsAsserts;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class BluetoothNetworkSettingsTests extends InstrumentationTestCase {
-
-    private static final String SETTINGS_PACKAGE = "com.android.settings";
-    private static final int TIMEOUT = 2000;
-    private static final int LONG_TIMEOUT = 40000;
-    private UiDevice mDevice;
-    private MetricsReader mMetricsReader;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        try {
-            mDevice.setOrientationNatural();
-        } catch (RemoteException e) {
-            throw new RuntimeException("failed to freeze device orientaion", e);
-        }
-        mMetricsReader = new MetricsReader();
-        // Clear out old logs
-        mMetricsReader.checkpoint();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mDevice.pressBack();
-        mDevice.pressHome();
-        mDevice.waitForIdle();
-        super.tearDown();
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testBluetoothEnabled() throws Exception {
-        verifyBluetoothOnOrOff(true);
-        MetricsAsserts.assertHasActionLog("missing bluetooth toggle log",
-                mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testBluetoothDisabled() throws Exception {
-        verifyBluetoothOnOrOff(false);
-        MetricsAsserts.assertHasActionLog("missing bluetooth toggle log",
-                mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
-    }
-
-    @MediumTest
-    public void testRenameOption() throws Exception {
-        launchBluetoothSettings();
-        verifyUiObjectClicked(By.text("Device name"), "Rename preference");
-        verifyUiObjectClicked(By.text("CANCEL"), "CANCEL button");
-
-        MetricsAsserts.assertHasActionLog("missing bluetooth rename device log",
-                mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_RENAME);
-        MetricsAsserts.assertHasVisibilityLog("missing bluetooth rename dialog log",
-                mMetricsReader, MetricsEvent.DIALOG_BLUETOOTH_RENAME, true);
-    }
-
-    @MediumTest
-    public void testReceivedFilesOption() throws Exception {
-        launchBluetoothSettings();
-        verifyUiObjectClicked(By.text("Received files"), "Received files preference");
-
-        MetricsAsserts.assertHasActionLog("missing bluetooth received files log",
-                mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_FILES);
-    }
-
-    @MediumTest
-    public void testHelpFeedbackOverflowOption() throws Exception {
-        launchBluetoothSettings();
-
-        // Verify help & feedback
-        assertNotNull("Help & feedback item not found under Bluetooth Settings",
-                mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT));
-    }
-
-    public void launchBluetoothSettings() throws Exception {
-        Intent btIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
-        btIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getInstrumentation().getContext().startActivity(btIntent);
-        Thread.sleep(TIMEOUT * 2);
-    }
-
-    /**
-     * Find the {@link UiObject2} by {@code itemSelector} and try to click it if possible.
-     *
-     * If not find, throw assertion error
-     * @param itemSelector used to find the {@link UiObject2}
-     * @param text the description of the {@link UiObject2}
-     */
-    private void verifyUiObjectClicked(BySelector itemSelector, String text) throws Exception {
-        UiObject2 uiObject2 = mDevice.wait(Until.findObject(itemSelector), TIMEOUT);
-        assertNotNull(text + "is not present in bluetooth settings page", uiObject2);
-        uiObject2.click();
-    }
-
-    /**
-     * Toggles the Bluetooth switch and verifies that the change is reflected in Settings
-     *
-     * @param verifyOn set to whether you want the setting turned On or Off
-     */
-    private void verifyBluetoothOnOrOff(boolean verifyOn) throws Exception {
-        String switchText = "ON";
-        BluetoothAdapter bluetoothAdapter = ((BluetoothManager) getInstrumentation().getContext()
-                .getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
-        if (verifyOn) {
-            switchText = "OFF";
-            bluetoothAdapter.disable();
-        } else {
-            bluetoothAdapter.enable();
-        }
-        launchBluetoothSettings();
-        mDevice.wait(Until
-                .findObject(By.res(SETTINGS_PACKAGE, "switch_widget").text(switchText)), TIMEOUT)
-                .click();
-        Thread.sleep(TIMEOUT);
-        String bluetoothValue =
-                Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
-                        Settings.Global.BLUETOOTH_ON);
-        if (verifyOn) {
-            assertEquals("1", bluetoothValue);
-        } else {
-            assertEquals("0", bluetoothValue);
-        }
-    }
-}
diff --git a/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java b/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java
deleted file mode 100644
index 0b7402d..0000000
--- a/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2018 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.ui;
-
-import android.content.ContentResolver;
-import android.platform.test.annotations.Presubmit;
-import android.provider.Settings;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.system.helpers.SettingsHelper;
-import android.system.helpers.SettingsHelper.SettingsType;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.regex.Pattern;
-
-public class DisplaySettingsTest extends InstrumentationTestCase {
-
-    private static final String PAGE = Settings.ACTION_DISPLAY_SETTINGS;
-    private static final int TIMEOUT = 2000;
-    private static final FontSetting FONT_SMALL = new FontSetting("Small", 0.85f);
-    private static final FontSetting FONT_NORMAL = new FontSetting("Default", 1.00f);
-    private static final FontSetting FONT_LARGE = new FontSetting("Large", 1.15f);
-    private static final FontSetting FONT_HUGE = new FontSetting("Largest", 1.30f);
-
-    private UiDevice mDevice;
-    private ContentResolver mResolver;
-    private SettingsHelper mHelper;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mDevice.setOrientationNatural();
-        mResolver = getInstrumentation().getContext().getContentResolver();
-        mHelper = new SettingsHelper();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        // reset settings we touched that may impact others
-        Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
-        mDevice.waitForIdle();
-        super.tearDown();
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testAdaptiveBrightness() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        Thread.sleep(1000);
-
-        assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness",
-                Settings.System.SCREEN_BRIGHTNESS_MODE));
-        assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness",
-                Settings.System.SCREEN_BRIGHTNESS_MODE));
-    }
-
-
-    // blocked on b/27487224
-    @MediumTest
-    @Suppress
-    public void testDaydreamToggle() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        clickMore();
-        Pattern p = Pattern.compile("On|Off");
-        mHelper.clickSetting("Screen saver");
-        Thread.sleep(1000);
-        try {
-            assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p,
-                    Settings.Secure.SCREENSAVER_ENABLED, false));
-            assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p,
-                    Settings.Secure.SCREENSAVER_ENABLED, false));
-        } finally {
-            mDevice.pressBack();
-        }
-    }
-
-    @MediumTest
-    public void testAccelRotation() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        clickMore();
-        Thread.sleep(4000);
-        int currentAccelSetting = Settings.System.getInt(
-                mResolver, Settings.System.ACCELEROMETER_ROTATION);
-        mHelper.clickSetting("Auto-rotate screen");
-        int newAccelSetting = Settings.System.getInt(
-                mResolver, Settings.System.ACCELEROMETER_ROTATION);
-        assertTrue("Accelorometer setting unchanged after toggle", currentAccelSetting != newAccelSetting);
-        mHelper.clickSetting("Auto-rotate screen");
-        int revertedAccelSetting = Settings.System.getInt(
-                mResolver, Settings.System.ACCELEROMETER_ROTATION);
-        assertTrue("Accelorometer setting unchanged after toggle", revertedAccelSetting != newAccelSetting);
-    }
-
-    @MediumTest
-    public void testDaydream() throws Exception {
-        Settings.Secure.putInt(mResolver, Settings.Secure.SCREENSAVER_ENABLED, 1);
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        clickMore();
-        mHelper.scrollVert(false);
-        mDevice.wait(Until.findObject(By.text("Screen saver")), TIMEOUT).click();
-        try {
-            assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
-                    "Current screen saver", "Clock", Settings.Secure.SCREENSAVER_COMPONENTS,
-                    "com.google.android.deskclock/com.android.deskclock.Screensaver"));
-            assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
-                    "Current screen saver", "Colors", Settings.Secure.SCREENSAVER_COMPONENTS,
-                    "com.android.dreams.basic/com.android.dreams.basic.Colors"));
-            assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
-                    "Current screen saver", "Photos", Settings.Secure.SCREENSAVER_COMPONENTS,
-                    "com.google.android.apps.photos/com.google.android.apps.photos.daydream"
-                            + ".PhotosDreamService"));
-        } finally {
-            mDevice.pressBack();
-            Thread.sleep(2000);
-        }
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testSleep15Seconds() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
-                "Sleep", "15 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "15000"));
-    }
-
-    @MediumTest
-    public void testSleep30Seconds() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
-                "Sleep", "30 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "30000"));
-    }
-
-    @MediumTest
-    public void testSleep1Minute() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
-                "Sleep", "1 minute", Settings.System.SCREEN_OFF_TIMEOUT, "60000"));
-    }
-
-    @MediumTest
-    public void testSleep2Minutes() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
-                "Sleep", "2 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "120000"));
-    }
-
-    @MediumTest
-    public void testSleep5Minutes() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
-                "Sleep", "5 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "300000"));
-    }
-
-    @MediumTest
-    public void testSleep10Minutes() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
-                "Sleep", "10 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "600000"));
-    }
-
-    @MediumTest
-    public void testSleep30Minutes() throws Exception {
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        mHelper.scrollVert(true);
-        assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
-                "Sleep", "30 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "1800000"));
-    }
-
-    @Presubmit
-    @MediumTest
-    public void testFontSizeLarge() throws Exception {
-        verifyFontSizeSetting(1.00f, FONT_LARGE);
-        // Leaving the font size at large can make later tests fail, so reset it
-        Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
-        // It takes a second for the new font size to be picked up
-        Thread.sleep(2000);
-    }
-
-    @MediumTest
-    public void testFontSizeDefault() throws Exception {
-        verifyFontSizeSetting(1.15f, FONT_NORMAL);
-    }
-
-    @MediumTest
-    public void testFontSizeLargest() throws Exception {
-        verifyFontSizeSetting(1.00f, FONT_HUGE);
-        // Leaving the font size at huge can make later tests fail, so reset it
-        Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
-        // It takes a second for the new font size to be picked up
-        Thread.sleep(2000);
-    }
-
-    @MediumTest
-    public void testFontSizeSmall() throws Exception {
-        verifyFontSizeSetting(1.00f, FONT_SMALL);
-    }
-
-    private void verifyFontSizeSetting(float resetValue, FontSetting setting)
-            throws Exception {
-        Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, resetValue);
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
-        clickMore();
-        mHelper.clickSetting("Font size");
-        try {
-            mDevice.wait(Until.findObject(By.desc(setting.getName())), TIMEOUT).click();
-            Thread.sleep(1000);
-            float changedValue = Settings.System.getFloat(
-                    mResolver, Settings.System.FONT_SCALE);
-            assertEquals(setting.getSize(), changedValue, 0.0001);
-        } finally {
-            // Make sure to back out of the font menu
-            mDevice.pressBack();
-        }
-    }
-
-    private void clickMore() throws InterruptedException {
-        UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT);
-        if (more != null) {
-            more.click();
-            Thread.sleep(TIMEOUT);
-        }
-    }
-
-    private static class FontSetting {
-        private final String mSizeName;
-        private final float mSizeVal;
-
-        public FontSetting(String sizeName, float sizeVal) {
-            mSizeName = sizeName;
-            mSizeVal = sizeVal;
-        }
-
-        public String getName() {
-            return mSizeName;
-        }
-
-        public float getSize() {
-            return mSizeVal;
-        }
-    }
-}
