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;
-        }
-    }
-}
