diff --git a/tests/uitests/Android.mk b/tests/uitests/Android.mk
new file mode 100644
index 0000000..23357e8
--- /dev/null
+++ b/tests/uitests/Android.mk
@@ -0,0 +1,35 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := SettingsUITests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_MODULE_TAGS := tests
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    app-helpers-base \
+    launcher-helper-lib \
+    settings-helper \
+    timeresult-helper-lib \
+    ub-uiautomator \
+    sysui-helper \
+    metrics-helper-lib \
+    platform-test-annotations \
+
+#LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/uitests/AndroidManifest.xml b/tests/uitests/AndroidManifest.xml
new file mode 100644
index 0000000..06d74c6
--- /dev/null
+++ b/tests/uitests/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.settings.ui">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+
+    <instrumentation
+            android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.settings.ui"
+            android:label="Android Settings Functional UI Tests" />
+</manifest>
diff --git a/tests/uitests/AndroidTest.xml b/tests/uitests/AndroidTest.xml
new file mode 100644
index 0000000..fbeea2d
--- /dev/null
+++ b/tests/uitests/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Run Android Settings Functional UI Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="SettingsUITests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="SettingsUITests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.settings.ui" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
diff --git a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
new file mode 100644
index 0000000..57f9bc2
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
@@ -0,0 +1,224 @@
+/*
+ * 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.Intent;
+import android.os.RemoteException;
+import android.provider.Settings;
+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.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+/** Verifies basic functionality of the About Phone screen */
+public class AboutPhoneSettingsTests extends InstrumentationTestCase {
+    private static final boolean LOCAL_LOGV = false;
+    private static final String TAG = "AboutPhoneSettingsTest";
+    private static final int TIMEOUT = 2000;
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+
+    private UiDevice mDevice;
+
+    // TODO: retrieve using name/ids from com.android.settings package
+    private static final String[] sResourceTexts = {
+        "Status",
+        "Legal information",
+        "Regulatory labels",
+        "Model",
+        "Android version",
+        "Android security patch level",
+        "Baseband version",
+        "Kernel version",
+        "Build number"
+    };
+
+    private static final String[] sClickableResourceTexts = {
+        "Status", "Legal information", "Regulatory labels",
+    };
+
+    @Override
+    public void setUp() throws Exception {
+        if (LOCAL_LOGV) {
+            Log.d(TAG, "-------");
+        }
+        super.setUp();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to freeze device orientaion", e);
+        }
+
+        // make sure we are in a clean state before starting the test
+        mDevice.pressHome();
+        Thread.sleep(TIMEOUT * 2);
+        launchAboutPhoneSettings(Settings.ACTION_DEVICE_INFO_SETTINGS);
+        // TODO: make sure we are always at the top of the app
+        // currently this will fail if the user has navigated into submenus
+        UiObject2 view =
+                mDevice.wait(
+                        Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT);
+        assertNotNull("Could not find main About Phone screen", view);
+        view.scroll(Direction.UP, 1.0f);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Adding an extra pressBack so we exit About Phone Settings
+        // and finish the test cleanly
+        mDevice.pressBack();
+        mDevice.pressHome(); // finish settings activity
+        mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
+        super.tearDown();
+    }
+
+    private void launchAboutPhoneSettings(String aboutSetting) throws Exception {
+        Intent aboutIntent = new Intent(aboutSetting);
+        aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getInstrumentation().getContext().startActivity(aboutIntent);
+    }
+
+    /**
+     * Callable actions that can be taken when a UIObject2 is found
+     *
+     * @param device The current UiDevice
+     * @param item The UiObject2 that was found and can be acted on
+     *
+     * @return {@code true} if the call was successful, and {@code false} otherwise
+     */
+    public interface UIObject2Callback {
+        boolean call(UiDevice device, UiObject2 item) throws Exception;
+    }
+
+    /**
+     * Clicks the given item and then presses the Back button
+     *
+     * <p>Used to test whether a given UiObject2 can be successfully clicked.
+     * Presses Back to restore state to the previous screen.
+     *
+     * @param device The device that can be used to press Back
+     * @param item The item to click
+     *
+     * @return {@code true} if clicking the item succeeded, and {@code false} otherwise
+     */
+    public class UiObject2Clicker implements UIObject2Callback {
+        public boolean call(UiDevice device, UiObject2 item) throws Exception {
+            item.click();
+            Thread.sleep(TIMEOUT * 2); // give UI time to finish animating
+            boolean pressWorked = device.pressBack();
+            Thread.sleep(TIMEOUT * 2);
+            return pressWorked;
+        }
+    }
+
+    /**
+     * Removes items found in the view and optionally takes some action.
+     *
+     * @param device The current UiDevice
+     * @param itemsLeftToFind The items to search for in the current view
+     * @param action Action to call on each item that is found; pass {@code null} to take no action
+     */
+    private void removeItemsAndTakeAction(
+            UiDevice device, ArrayList<String> itemsLeftToFind, UIObject2Callback action) throws Exception {
+        for (Iterator<String> iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) {
+            String itemText = iterator.next();
+            UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT);
+            if (item != null) {
+                if (LOCAL_LOGV) {
+                    Log.d(TAG, itemText + " is present");
+                }
+                iterator.remove();
+                if (action != null) {
+                    boolean success = action.call(device, item);
+                    assertTrue("Calling action after " + itemText + " did not work", success);
+                }
+            } else {
+                if (LOCAL_LOGV) {
+                    Log.d(TAG, "Could not find " + itemText);
+                }
+            }
+        }
+    }
+
+    /**
+     * Searches for UI elements in the current view and optionally takes some action.
+     *
+     * <p>Will scroll down the screen until it has found all elements or reached the bottom.
+     * This allows elements to be found and acted on even if they change order.
+     *
+     * @param device The current UiDevice
+     * @param itemsToFind The items to search for in the current view
+     * @param action Action to call on each item that is found; pass {@code null} to take no action
+     */
+    public void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind, UIObject2Callback action)
+            throws Exception {
+
+        ArrayList<String> itemsLeftToFind = new ArrayList<String>(Arrays.asList(itemsToFind));
+        assertFalse(
+                "There must be at least one item to search for on the screen!",
+                itemsLeftToFind.isEmpty());
+
+        if (LOCAL_LOGV) {
+            Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind));
+        }
+        boolean canScrollDown = true;
+        while (canScrollDown && !itemsLeftToFind.isEmpty()) {
+            removeItemsAndTakeAction(device, itemsLeftToFind, action);
+
+            // when we've finished searching the current view, scroll down
+            UiObject2 view =
+                    device.wait(
+                            Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")),
+                            TIMEOUT * 2);
+            if (view != null) {
+                canScrollDown = view.scroll(Direction.DOWN, 1.0f);
+            } else {
+                canScrollDown = false;
+            }
+        }
+        // check the last items once we have reached the bottom of the view
+        removeItemsAndTakeAction(device, itemsLeftToFind, action);
+
+        assertTrue(
+                "The following items were not found on the screen: "
+                        + TextUtils.join(", ", itemsLeftToFind),
+                itemsLeftToFind.isEmpty());
+    }
+
+    @MediumTest // UI interaction
+    public void testAllMenuEntriesExist() throws Exception {
+        searchForItemsAndTakeAction(mDevice, sResourceTexts, null);
+    }
+
+    // Suppressing this test as it might be causing other test failures
+    // Will verify that this test is the cause before proceeding with solution
+    @Suppress
+    @MediumTest // UI interaction
+    public void testClickableEntriesCanBeClicked() throws Exception {
+        searchForItemsAndTakeAction(mDevice, sClickableResourceTexts, new UiObject2Clicker());
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java b/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java
new file mode 100644
index 0000000..83afa65
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java
@@ -0,0 +1,279 @@
+/*
+ * 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.Context;
+import android.net.wifi.WifiManager;
+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 android.metrics.MetricsReader;
+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/AppsSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java
new file mode 100644
index 0000000..6be49d6
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java
@@ -0,0 +1,136 @@
+/*
+ * 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.Intent;
+import android.os.RemoteException;
+import android.provider.Settings;
+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.ActivityHelper;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+/** Verifies basic functionality of the About Phone screen */
+public class AppsSettingsTests extends InstrumentationTestCase {
+    private static final boolean LOCAL_LOGV = false;
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+    private static final String TAG = "AboutPhoneSettingsTest";
+    private static final int TIMEOUT = 2000;
+    private ActivityHelper mActivityHelper = null;
+
+    private UiDevice mDevice;
+
+    private static final String[] sResourceTexts = {
+        "Storage",
+        "Data usage",
+        "Permissions",
+        "App notifications",
+        "Open by default",
+        "Battery",
+        "Memory"
+    };
+
+    @Override
+    public void setUp() throws Exception {
+        if (LOCAL_LOGV) {
+            Log.d(TAG, "-------");
+        }
+        super.setUp();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivityHelper = ActivityHelper.getInstance();
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to freeze device orientaion", e);
+        }
+
+        // make sure we are in a clean state before starting the test
+        mDevice.pressHome();
+        Thread.sleep(TIMEOUT * 2);
+        launchAppsSettings();
+        UiObject2 view =
+                mDevice.wait(
+                        Until.findObject(By.text("All apps")), TIMEOUT);
+        assertNotNull("Could not find Settings > Apps screen", view);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevice.pressBack();
+        mDevice.pressHome(); // finish settings activity
+        mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
+        super.tearDown();
+    }
+
+    @MediumTest
+    public void testAppSettingsListForCalculator() {
+        UiObject2 calculator = mDevice.wait(
+                Until.findObject(By.text("Calculator")), TIMEOUT);
+        calculator.click();
+        for (String setting : sResourceTexts) {
+            UiObject2 appSetting =
+                mDevice.wait(
+                        Until.findObject(By.text(setting)), TIMEOUT);
+            assertNotNull("Missing setting for Calculator: " + setting, appSetting);
+            appSetting.scroll(Direction.DOWN, 10.0f);
+        }
+    }
+
+    @MediumTest
+    public void testDisablingAndEnablingSystemApp() throws Exception {
+        launchAppsSettings();
+        UiObject2 calculator = mDevice.wait(
+                Until.findObject(By.text("Calculator")), TIMEOUT);
+        calculator.click();
+        mDevice.waitForIdle(TIMEOUT);
+        UiObject2 appInfoList = mDevice.wait(
+            Until.findObject(By.res(SETTINGS_PACKAGE, "list")), TIMEOUT);
+        appInfoList.scroll(Direction.DOWN, 100.0f);
+        UiObject2 disableButton = mDevice.wait(
+                Until.findObject(By.text("DISABLE")), TIMEOUT);
+        disableButton.click();
+        mDevice.waitForIdle(TIMEOUT);
+        // Click on "Disable App" on dialog.
+        mDevice.wait(
+                Until.findObject(By.text("DISABLE APP")), TIMEOUT).click();
+        mDevice.waitForIdle(TIMEOUT);
+        UiObject2 enableButton = mDevice.wait(
+                Until.findObject(By.text("ENABLE")), TIMEOUT);
+        assertNotNull("App not disabled successfully", enableButton);
+        enableButton.click();
+        mDevice.waitForIdle(TIMEOUT);
+        disableButton = mDevice.wait(
+                Until.findObject(By.text("DISABLE")), TIMEOUT);
+        assertNotNull("App not enabled successfully", disableButton);
+    }
+
+    private void launchAppsSettings() throws Exception {
+        Intent appsSettingsIntent = new
+                Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
+        mActivityHelper.launchIntent(appsSettingsIntent);
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java
new file mode 100644
index 0000000..d41be9c
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java
@@ -0,0 +1,163 @@
+/*
+ * 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/ConnectedDeviceTests.java b/tests/uitests/src/com/android/settings/ui/ConnectedDeviceTests.java
new file mode 100644
index 0000000..971d724
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/ConnectedDeviceTests.java
@@ -0,0 +1,92 @@
+/*
+ * 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.Context;
+import android.content.Intent;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcManager;
+import android.os.RemoteException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+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 org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class ConnectedDeviceTests {
+
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+    private static final int TIMEOUT = 2000;
+    private UiDevice mDevice;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("failed to freeze device orientation", e);
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mDevice.pressBack();
+        mDevice.pressHome();
+    }
+
+    // This NFC toggle test is set up this way since there's no way to set
+    // the NFC flag to enabled or disabled without touching UI.
+    // This way, we get coverage for whether or not the toggle button works.
+    @Test
+    public void testNFCToggle() throws Exception {
+        NfcManager manager = (NfcManager) InstrumentationRegistry.getTargetContext()
+                .getSystemService(Context.NFC_SERVICE);
+        NfcAdapter nfcAdapter = manager.getDefaultAdapter();
+        boolean nfcInitiallyEnabled = nfcAdapter.isEnabled();
+        InstrumentationRegistry.getContext().startActivity(new Intent()
+                .setClassName(
+                        SETTINGS_PACKAGE,
+                        "com.android.settings.Settings$ConnectedDeviceDashboardActivity"));
+        UiObject2 nfcSetting = mDevice.wait(Until.findObject(By.text("NFC")), TIMEOUT);
+        nfcSetting.click();
+        Thread.sleep(TIMEOUT * 2);
+        if (nfcInitiallyEnabled) {
+            assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled());
+            nfcSetting.click();
+            Thread.sleep(TIMEOUT * 2);
+            assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled());
+        } else {
+            assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled());
+            nfcSetting.click();
+            Thread.sleep(TIMEOUT * 2);
+            assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled());
+        }
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/DataUsageSettingsTests.java b/tests/uitests/src/com/android/settings/ui/DataUsageSettingsTests.java
new file mode 100644
index 0000000..725ba5c
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/DataUsageSettingsTests.java
@@ -0,0 +1,84 @@
+/*
+ * 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.os.RemoteException;
+import android.provider.Settings;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+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;
+
+public class DataUsageSettingsTests extends InstrumentationTestCase {
+
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+    private static final int TIMEOUT = 2000;
+    private UiDevice mDevice;
+
+    @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);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Need to finish settings activity
+        mDevice.pressBack();
+        mDevice.pressHome();
+        super.tearDown();
+    }
+
+    @MediumTest
+    public void testElementsOnDataUsageScreen() throws Exception {
+        launchDataUsageSettings();
+        assertNotNull("Data usage element not found",
+                mDevice.wait(Until.findObject(By.text("Usage")),
+                TIMEOUT));
+        assertNotNull("Data usage bar not found",
+                mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE,
+                "color_bar")), TIMEOUT));
+        assertNotNull("WiFi Data usage element not found",
+                mDevice.wait(Until.findObject(By.text("Wi-Fi data usage")),
+                TIMEOUT));
+        assertNotNull("Network restrictions element not found",
+                mDevice.wait(Until.findObject(By.text("Network restrictions")),
+                TIMEOUT));
+    }
+
+    public void launchDataUsageSettings() throws Exception {
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_SETTINGS);
+        mDevice.wait(Until
+                .findObject(By.text("Network & Internet")), TIMEOUT)
+                .click();
+        Thread.sleep(TIMEOUT * 2);
+        assertNotNull("Network & internet screen not loaded", mDevice.wait(
+                Until.findObject(By.text("Data usage")), TIMEOUT));
+        mDevice.wait(Until
+                .findObject(By.text("Data usage")), TIMEOUT)
+                .click();
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java b/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java
new file mode 100644
index 0000000..0b7402d
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java
@@ -0,0 +1,268 @@
+/*
+ * 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;
+        }
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
new file mode 100644
index 0000000..7931d30
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
@@ -0,0 +1,99 @@
+/*
+ * 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.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+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 com.android.settings.ui.testutils.SettingsTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class HomepageDisplayTests {
+
+    private static final String[] HOMEPAGE_ITEMS = {
+            "Network & internet",
+            "Connected devices",
+            "Apps & notifications",
+            "Battery",
+            "Display",
+            "Sound",
+            "Storage",
+            "Security & location",
+            "Users & accounts",
+            "Accessibility",
+            "System",
+            "Support & tips"
+    };
+
+    private UiDevice mDevice;
+    private SettingsHelper mSettingsHelper;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mSettingsHelper = new SettingsHelper();
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("failed to freeze device orientaion", e);
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Need to finish settings activity
+        mDevice.pressHome();
+    }
+
+    @Presubmit
+    @Test
+    public void testHomepageCategory() throws Exception {
+        // Launch Settings
+        SettingsHelper.launchSettingsPage(
+                InstrumentationRegistry.getContext(), Settings.ACTION_SETTINGS);
+
+        // Scroll to top
+        final UiObject2 view = mDevice.wait(
+                Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
+                TIMEOUT);
+        view.scroll(Direction.UP, 100f);
+
+        // Inspect each item
+        for (String item : HOMEPAGE_ITEMS) {
+            SettingsTestUtils.assertTitleMatch(mDevice, item);
+        }
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/LocationSettingsTests.java b/tests/uitests/src/com/android/settings/ui/LocationSettingsTests.java
new file mode 100644
index 0000000..b4a1baa
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/LocationSettingsTests.java
@@ -0,0 +1,243 @@
+/*
+ * 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.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+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;
+
+
+public class LocationSettingsTests extends InstrumentationTestCase {
+
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+    private static final int TIMEOUT = 2000;
+    private UiDevice mDevice;
+
+    @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);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevice.pressBack();
+        mDevice.pressHome();
+        super.tearDown();
+    }
+
+    @MediumTest
+    public void testLoadingLocationSettings () throws Exception {
+        // Load Security
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_SECURITY_SETTINGS);
+
+        SettingsHelper helper = new SettingsHelper();
+        helper.scrollVert(true);
+        // Tap on location
+        UiObject2 settingsPanel = mDevice.wait(Until.findObject
+                (By.res(SETTINGS_PACKAGE, "main_content")), TIMEOUT);
+        int count = 0;
+        UiObject2 locationTitle = null;
+        while(count < 6 && locationTitle == null) {
+            locationTitle = mDevice.wait(Until.findObject(By.text("Location")), TIMEOUT);
+            if (locationTitle == null) {
+                settingsPanel.scroll(Direction.DOWN, 1.0f);
+            }
+            count++;
+        }
+        // Verify location settings loads.
+        locationTitle.click();
+        Thread.sleep(TIMEOUT);
+        assertNotNull("Location screen has not loaded correctly",
+                mDevice.wait(Until.findObject(By.text("Location services")), TIMEOUT));
+    }
+
+    @Presubmit
+    @MediumTest
+    public void testLocationSettingOn() throws Exception {
+        verifyLocationSettingsOnOrOff(true);
+    }
+
+    @MediumTest
+    public void testLocationSettingOff() throws Exception {
+        verifyLocationSettingsOnOrOff(false);
+    }
+
+    @MediumTest
+    public void testLocationDeviceOnlyMode() throws Exception {
+        // Changing the value from default before testing the toggle to Device only mode
+        Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
+                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+        dismissAlertDialogs();
+        Thread.sleep(TIMEOUT);
+        verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
+    }
+
+    @MediumTest
+    public void testLocationBatterySavingMode() throws Exception {
+        Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
+                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
+        Thread.sleep(TIMEOUT);
+        verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
+    }
+
+    @MediumTest
+    public void testLocationHighAccuracyMode() throws Exception {
+        Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
+                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
+        Thread.sleep(TIMEOUT);
+        verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+    }
+
+    @MediumTest
+    public void testLocationSettingsElements() throws Exception {
+        String[] textElements = {"Location", "Mode", "Recent location requests",
+                "Location services"};
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+        Thread.sleep(TIMEOUT);
+        for (String element : textElements) {
+            assertNotNull(element + " item not found under Location Settings",
+                    mDevice.wait(Until.findObject(By.text(element)), TIMEOUT));
+        }
+    }
+
+    @MediumTest
+    public void testLocationSettingsOverflowMenuElements() throws Exception {
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                            Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+        // Verify help & feedback
+        assertNotNull("Help & feedback item not found under Location Settings",
+                mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT));
+        // Verify scanning
+        assertNotNull("Scanning item not found under Location Settings",
+                mDevice.wait(Until.findObject(By.text("Scanning")), TIMEOUT));
+    }
+
+    private void verifyLocationSettingsMode(int mode) throws Exception {
+        int modeIntValue = 1;
+        String textMode = "Device only";
+        if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) {
+            modeIntValue = 3;
+            textMode = "High accuracy";
+        }
+        else if (mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
+            modeIntValue = 2;
+            textMode = "Battery saving";
+        }
+        // Load location settings
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+        // Tap on mode
+        dismissAlertDialogs();
+        // Load location settings
+        mDevice.wait(Until.findObject(By.text("Mode")), TIMEOUT).click();
+        Thread.sleep(TIMEOUT);
+        assertNotNull("Location mode screen not loaded", mDevice.wait(Until.findObject
+                (By.text("Location mode")), TIMEOUT));
+        // Choose said mode
+        mDevice.wait(Until.findObject(By.text(textMode)), TIMEOUT).click();
+        Thread.sleep(TIMEOUT);
+        dismissAlertDialogs();
+        mDevice.wait(Until.findObject(By.desc("Navigate up")), TIMEOUT).click();
+        Thread.sleep(TIMEOUT);
+        if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY ||
+                mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
+            dismissAlertDialogs();
+        }
+        // get setting and verify value
+        // Verify change of mode
+        int locationSettingMode =
+                Settings.Secure.getInt(getInstrumentation().getContext().getContentResolver(),
+                Settings.Secure.LOCATION_MODE);
+        assertEquals(mode + " value not set correctly for location.", modeIntValue,
+                locationSettingMode);
+    }
+
+    private void verifyLocationSettingsOnOrOff(boolean verifyOn) throws Exception {
+        // Set location flag
+        if (verifyOn) {
+            Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
+                    Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
+        }
+        else {
+            Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
+                    Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
+        }
+        dismissAlertDialogs();
+        // Load location settings
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+        dismissAlertDialogs();
+        // Toggle UI
+        mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT).click();
+        dismissAlertDialogs();
+        Thread.sleep(TIMEOUT);
+        // Verify change in setting
+        int locationEnabled = Settings.Secure.getInt(getInstrumentation()
+                 .getContext().getContentResolver(),
+                 Settings.Secure.LOCATION_MODE);
+        if (verifyOn) {
+            assertFalse("Location not enabled correctly", locationEnabled == 0);
+        }
+        else {
+            assertEquals("Location not disabled correctly", 0, locationEnabled);
+        }
+    }
+
+    // This method dismisses both alert dialogs that might popup and
+    // interfere with the test. Since the order in which the dialog
+    // shows up changes in no specific known way, we're checking for
+    // both dialogs in any order for a robust test. Bug b/36233151
+    // filed against Location team for specifications. This is a
+    // workaround in the meantime to ensure coverage.
+    private void dismissAlertDialogs() throws Exception {
+        for (int count = 0; count < 2; count++) {
+            UiObject2 agreeDialog = mDevice.wait(Until.findObject
+                    (By.text("Improve location accuracy?")), TIMEOUT);
+            UiObject2 previousChoiceYesButton = mDevice.wait(Until.findObject
+                    (By.text("YES")), TIMEOUT);
+            if (agreeDialog != null) {
+                mDevice.wait(Until.findObject
+                        (By.text("AGREE")), TIMEOUT).click();
+                Thread.sleep(TIMEOUT);
+                assertNull("Improve location dialog not dismissed",
+                        mDevice.wait(Until.findObject
+                        (By.text("Improve location accuracy?")), TIMEOUT));
+            }
+            if (previousChoiceYesButton != null) {
+                previousChoiceYesButton.click();
+                // Short sleep to wait for the new screen
+                Thread.sleep(TIMEOUT);
+            }
+        }
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTests.java b/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTests.java
new file mode 100644
index 0000000..2523686
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTests.java
@@ -0,0 +1,126 @@
+/*
+ * 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.os.RemoteException;
+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.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+
+public class MoreWirelessSettingsTests extends InstrumentationTestCase {
+
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+    private static final int TIMEOUT = 2000;
+    private UiDevice mDevice;
+
+    @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);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevice.pressBack();
+        mDevice.pressHome();
+        super.tearDown();
+    }
+
+    @Presubmit
+    @MediumTest
+    public void testAirplaneModeEnabled() throws Exception {
+        verifyAirplaneModeOnOrOff(true);
+        // Toggling this via the wifi network settings page
+        // because of bug b/34858716. Once that is fixed,
+        // we should be able to set this via Settings putString.
+        toggleAirplaneModeSwitch();
+    }
+
+    @Presubmit
+    @MediumTest
+    public void testAirplaneModeDisabled() throws Exception {
+        verifyAirplaneModeOnOrOff(false);
+    }
+
+    @MediumTest
+    public void testTetheringMenuLoad() throws Exception {
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_WIRELESS_SETTINGS);
+        mDevice.wait(Until
+                 .findObject(By.text("Hotspot & tethering")), TIMEOUT)
+                 .click();
+        Thread.sleep(TIMEOUT);
+        UiObject2 usbTethering = mDevice.wait(Until
+                 .findObject(By.text("USB tethering")), TIMEOUT);
+        assertNotNull("Tethering screen did not load correctly", usbTethering);
+    }
+
+    @MediumTest
+    public void testVPNMenuLoad() throws Exception {
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_WIRELESS_SETTINGS);
+        mDevice.wait(Until
+                 .findObject(By.text("VPN")), TIMEOUT)
+                 .click();
+        Thread.sleep(TIMEOUT);
+        UiObject2 usbTethering = mDevice.wait(Until
+                 .findObject(By.res(SETTINGS_PACKAGE, "vpn_create")), TIMEOUT);
+        assertNotNull("VPN screen did not load correctly", usbTethering);
+    }
+
+    private void verifyAirplaneModeOnOrOff(boolean verifyOn) throws Exception {
+        if (verifyOn) {
+            Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+                    Settings.Global.AIRPLANE_MODE_ON, "0");
+        }
+        else {
+            Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+                    Settings.Global.AIRPLANE_MODE_ON, "1");
+        }
+        toggleAirplaneModeSwitch();
+        String airplaneModeValue = Settings.Global
+                .getString(getInstrumentation().getContext().getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON);
+        if (verifyOn) {
+            assertEquals("1", airplaneModeValue);
+        }
+        else {
+            assertEquals("0", airplaneModeValue);
+        }
+    }
+
+    private void toggleAirplaneModeSwitch() throws Exception {
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_WIRELESS_SETTINGS);
+        mDevice.wait(Until
+                .findObject(By.text("Airplane mode")), TIMEOUT)
+                .click();
+        Thread.sleep(TIMEOUT);
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/NotificationSettingsTests.java b/tests/uitests/src/com/android/settings/ui/NotificationSettingsTests.java
new file mode 100644
index 0000000..133332c
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/NotificationSettingsTests.java
@@ -0,0 +1,158 @@
+/*
+ * 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.Intent;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+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.ActivityHelper;
+import android.system.helpers.SettingsHelper;
+import android.widget.ListView;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+/** Verifies that you can get to the notification app listing page from the apps & notifications
+ * page */
+public class NotificationSettingsTests extends InstrumentationTestCase {
+    private static final boolean LOCAL_LOGV = false;
+    private static final String TAG = "NotifiSettingsTests";
+    private static final int TIMEOUT = 2000;
+    private ActivityHelper mActivityHelper = null;
+    private SettingsHelper mSettingsHelper = null;
+
+    private UiDevice mDevice;
+    @Override
+    public void setUp() throws Exception {
+        if (LOCAL_LOGV) {
+            Log.d(TAG, "-------");
+        }
+        super.setUp();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivityHelper = ActivityHelper.getInstance();
+        mSettingsHelper = SettingsHelper.getInstance();
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to freeze device orientaion", e);
+        }
+
+        // make sure we are in a clean state before starting the test
+        mDevice.pressHome();
+        Thread.sleep(TIMEOUT * 2);
+        launchAppsSettings();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevice.pressBack();
+        mDevice.pressHome(); // finish settings activity
+        mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
+        super.tearDown();
+    }
+
+    @MediumTest
+    public void testNotificationsSettingsListForCalculator() {
+        UiObject2 configureNotifications = mDevice.wait(
+                Until.findObject(By.text("Notifications")), TIMEOUT);
+        configureNotifications.click();
+        mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT);
+        UiObject2 appNotifications = mDevice.wait(
+                Until.findObject(By.text("On for all apps")), TIMEOUT);
+        appNotifications.click();
+        UiObject2 view =
+                mDevice.wait(
+                        Until.findObject(By.text("All apps")), TIMEOUT);
+        assertNotNull("Could not find Settings > Apps screen", view);
+        UiObject2 app = mDevice.wait(Until.findObject(By.text("Calculator")), TIMEOUT);
+        assertNotNull("Could not find Calculator notification settings", app);
+    }
+
+
+    @MediumTest
+    public void testNotificationsSettingsListForPhone() {
+        UiObject2 configureNotifications = mDevice.wait(
+                Until.findObject(By.text("Notifications")), TIMEOUT);
+        configureNotifications.click();
+        mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT);
+        UiObject2 appNotifications = mDevice.wait(
+                Until.findObject(By.text("On for all apps")), TIMEOUT);
+        appNotifications.click();
+        UiObject2 view =
+                mDevice.wait(
+                        Until.findObject(By.text("All apps")), TIMEOUT);
+        assertNotNull("Could not find Settings > Apps screen", view);
+
+        final BySelector preferenceListSelector = By.clazz(ListView.class).res("android:id/list");
+        UiObject2 apps = mDevice.wait(Until.findObject(preferenceListSelector), TIMEOUT);
+
+        UiObject2 phone = scrollTo(mDevice, apps, By.text("Phone"), Direction.DOWN);
+        assertNotNull("Could not find Phone notification settings", phone);
+        phone.click();
+        UiObject2 incomingCalls = mDevice.wait(Until.findObject(By.text("Incoming calls")), TIMEOUT);
+        assertNotNull("Could not find incoming calls channel", incomingCalls);
+        incomingCalls.click();
+
+        // here's the meat of this test: make sure that you cannot change
+        // most settings for this channel
+
+        UiObject2 importance = mDevice.wait(Until.findObject(By.text("Importance")), TIMEOUT);
+        assertNotNull("Could not find importance toggle", importance);
+        assertFalse(importance.isEnabled());
+        assertFalse(mDevice.wait(Until.findObject(By.text("Sound")), TIMEOUT).isEnabled());;
+        assertFalse(mDevice.wait(Until.findObject(By.text("Vibrate")), TIMEOUT).isEnabled());
+        assertFalse(mDevice.wait(Until.findObject(By.text("Override Do Not Disturb")), TIMEOUT).isEnabled());
+
+
+
+
+
+
+    }
+
+    private UiObject2 scrollTo(UiDevice device, UiObject2 scrollable,
+                                          BySelector target, Direction direction) {
+        while (!device.hasObject(target) && scrollable.scroll(direction, 1.0f)) {
+            // continue
+        }
+        if (!device.hasObject(target)) {
+            // Scroll once more if not found; in some cases UiObject2.scroll can return false when
+            // the last item is not fully visible yet for list views.
+            scrollable.scroll(direction, 1.0f);
+        }
+        return device.findObject(target);
+    }
+
+
+    private void launchAppsSettings() throws Exception {
+        Intent appsSettingsIntent = new Intent(Settings.ACTION_SETTINGS);
+        mActivityHelper.launchIntent(appsSettingsIntent);
+        mSettingsHelper.flingSettingsToStart();
+        UiObject2 view = mDevice.wait(
+                Until.findObject(By.text("Apps & notifications")), TIMEOUT);
+        view.click();
+        UiObject2 title = mDevice.wait(
+                Until.findObject(By.text("Apps & notifications")), TIMEOUT);
+        assertNotNull("Could not find Settings > Apps & notifications screen", title);
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java b/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java
new file mode 100644
index 0000000..b730690
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/SecuritySettingsLaunchTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.os.RemoteException;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import android.system.helpers.SettingsHelper;
+
+import com.android.settings.ui.testutils.SettingsTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SecuritySettingsLaunchTest {
+
+    // Items we really want to always show
+    private static final String[] CATEGORIES = new String[]{
+            "Security status",
+            "Device security",
+            "Privacy",
+    };
+
+    private UiDevice mDevice;
+    private SettingsHelper mHelper;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mHelper = SettingsHelper.getInstance();
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("failed to freeze device orientaion", e);
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Go back to home for next test.
+        mDevice.pressHome();
+    }
+
+    @Test
+    public void launchSecuritySettings() throws Exception {
+        // Launch Settings
+        SettingsHelper.launchSettingsPage(
+                InstrumentationRegistry.getContext(), Settings.ACTION_SECURITY_SETTINGS);
+        mHelper.scrollVert(false);
+        for (String category : CATEGORIES) {
+            SettingsTestUtils.assertTitleMatch(mDevice, category);
+        }
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java b/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java
new file mode 100644
index 0000000..0aec505
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/SoundSettingsTest.java
@@ -0,0 +1,334 @@
+/*
+ * 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.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.service.notification.ZenModeConfig;
+import android.support.test.uiautomator.UiObject2;
+import android.system.helpers.SettingsHelper;
+import android.system.helpers.SettingsHelper.SettingsType;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
+
+import java.util.HashMap;
+
+public class SoundSettingsTest extends InstrumentationTestCase {
+    private static final String PAGE = Settings.ACTION_SOUND_SETTINGS;
+    private static final int TIMEOUT = 2000;
+
+    private UiDevice mDevice;
+    private ContentResolver mResolver;
+    private SettingsHelper mHelper;
+
+
+    private HashMap ringtoneSounds = new HashMap<String, String>() {{
+        put("angler","Dione");
+        put("bullhead","Dione");
+        put("marlin","Spaceship");
+        put("sailfish","Spaceship");
+        put("walleye","Copycat");
+        put("taimen","Copycat");
+    }};
+
+    private HashMap ringtoneCodes = new HashMap<String, String>() {{
+        put("angler","38");
+        put("bullhead","38");
+        put("marlin","37");
+        put("sailfish","37");
+        put("walleye","26");
+        put("taimen","26");
+    }};
+
+    private HashMap alarmSounds = new HashMap<String, String>() {{
+        put("angler","Awaken");
+        put("bullhead","Awaken");
+        put("marlin","Bounce");
+        put("sailfish","Bounce");
+        put("walleye","Cuckoo clock");
+        put("taimen","Cuckoo clock");
+    }};
+
+    private HashMap alarmCodes = new HashMap<String, String>() {{
+        put("angler","6");
+        put("bullhead","6");
+        put("marlin","49");
+        put("sailfish","49");
+        put("walleye","15");
+        put("taimen","15");
+    }};
+
+    private HashMap notificationSounds = new HashMap<String, String>() {{
+        put("angler","Ceres");
+        put("bullhead","Ceres");
+        put("marlin","Trill");
+        put("sailfish","Trill");
+        put("walleye","Pipes");
+        put("taimen","Pipes");
+    }};
+
+
+    private HashMap notificationCodes = new HashMap<String, String>() {{
+        put("angler","26");
+        put("bullhead","26");
+        put("marlin","57");
+        put("sailfish","57");
+        put("walleye","69");
+        put("taimen","69");
+    }};
+
+    @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 {
+        mDevice.pressBack();
+        mDevice.pressHome();
+        mDevice.waitForIdle();
+        mDevice.unfreezeRotation();
+        super.tearDown();
+    }
+
+    @MediumTest
+    public void testCallVibrate() throws Exception {
+        assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
+                "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING));
+        assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
+                "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING));
+    }
+
+    @MediumTest
+    public void testOtherSoundsDialPadTones() throws Exception {
+        loadOtherSoundsPage();
+        assertTrue("Dial pad tones not toggled", mHelper.verifyToggleSetting(
+                SettingsType.SYSTEM, PAGE, "Dial pad tones",
+                Settings.System.DTMF_TONE_WHEN_DIALING));
+    }
+
+    @MediumTest
+    public void testOtherSoundsScreenLocking() throws Exception {
+        loadOtherSoundsPage();
+        assertTrue("Screen locking sounds not toggled",
+                    mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
+                    "Screen locking sounds", Settings.System.LOCKSCREEN_SOUNDS_ENABLED));
+    }
+
+    @MediumTest
+    public void testOtherSoundsCharging() throws Exception {
+        loadOtherSoundsPage();
+        assertTrue("Charging sounds not toggled",
+                    mHelper.verifyToggleSetting(SettingsType.GLOBAL, PAGE,
+                    "Charging sounds", Settings.Global.CHARGING_SOUNDS_ENABLED));
+    }
+
+    @MediumTest
+    public void testOtherSoundsTouch() throws Exception {
+        loadOtherSoundsPage();
+        assertTrue("Touch sounds not toggled",
+                    mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
+                    "Touch sounds", Settings.System.SOUND_EFFECTS_ENABLED));
+    }
+
+    @MediumTest
+    public void testOtherSoundsVibrateOnTap() throws Exception {
+        loadOtherSoundsPage();
+        assertTrue("Vibrate on tap not toggled",
+                    mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
+                    "Vibrate on tap", Settings.System.HAPTIC_FEEDBACK_ENABLED));
+    }
+
+    private void loadOtherSoundsPage() throws Exception {
+        launchSoundSettings();
+        mHelper.scrollVert(false);
+        Thread.sleep(1000);
+    }
+
+    private void launchSoundSettings() throws Exception {
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
+        mHelper.scrollVert(false);
+        clickMore();
+        Thread.sleep(1000);
+        mHelper.scrollVert(true);
+        Thread.sleep(1000);
+    }
+
+    /*
+     * Rather than verifying every ringtone, verify the ones least likely to change
+     * (None and Hangouts) and an arbitrary one from the ringtone pool.
+     */
+    @MediumTest
+    public void testPhoneRingtoneNone() throws Exception {
+        launchSoundSettings();
+        mHelper.clickSetting("Phone ringtone");
+        verifyRingtone(new RingtoneSetting("None", "null"),
+                Settings.System.RINGTONE);
+    }
+
+    @MediumTest
+    @Suppress
+    public void testPhoneRingtoneHangouts() throws Exception {
+        launchSoundSettings();
+        mHelper.clickSetting("Phone ringtone");
+        verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE);
+    }
+
+    @MediumTest
+    public void testPhoneRingtone() throws Exception {
+        launchSoundSettings();
+        mHelper.clickSetting("Phone ringtone");
+        String ringtone = ringtoneSounds.get(mDevice.getProductName()).toString();
+        String ringtoneSettingValue = ringtoneCodes.get(mDevice.getProductName()).toString();
+        verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue),
+                Settings.System.RINGTONE);
+    }
+
+    @MediumTest
+    public void testNotificationRingtoneNone() throws Exception {
+        launchSoundSettings();
+        mHelper.clickSetting("Default notification sound");
+        verifyRingtone(new RingtoneSetting("None", "null"),
+                Settings.System.NOTIFICATION_SOUND);
+    }
+
+    @MediumTest
+    @Suppress
+    public void testNotificationRingtoneHangouts() throws Exception {
+        launchSoundSettings();
+        mHelper.clickSetting("Default notification sound");
+        verifyRingtone(new RingtoneSetting("Hangouts Message", "30"),
+                Settings.System.NOTIFICATION_SOUND);
+    }
+
+    @MediumTest
+    public void testNotificationRingtone() throws Exception {
+        launchSoundSettings();
+        mHelper.clickSetting("Default notification sound");
+        String notificationRingtone = notificationSounds.get(mDevice.getProductName()).toString();
+        String notificationSettingValue = notificationCodes.get(mDevice.getProductName()).toString();
+        verifyRingtone(new RingtoneSetting(notificationRingtone, notificationSettingValue),
+                Settings.System.NOTIFICATION_SOUND);
+    }
+
+    @MediumTest
+    public void testAlarmRingtoneNone() throws Exception {
+        launchSoundSettings();
+        mHelper.clickSetting("Default alarm sound");
+        verifyRingtone(new RingtoneSetting("None", "null"),
+                Settings.System.ALARM_ALERT);
+    }
+
+    @MediumTest
+    public void testAlarmRingtone() throws Exception {
+        launchSoundSettings();
+        String alarmRingtone = alarmSounds.get(mDevice.getProductName()).toString();
+        String alarmSettingValue = alarmCodes.get(mDevice.getProductName()).toString();
+        mHelper.clickSetting("Default alarm sound");
+        verifyRingtone(new RingtoneSetting(alarmRingtone, alarmSettingValue),
+                Settings.System.ALARM_ALERT);
+    }
+
+    /*
+     * This method verifies that setting a custom ringtone changes the
+     * ringtone code setting on the system. Each ringtone sound corresponds
+     * to an arbitrary code. To see which ringtone code this is on your device, run
+     * adb shell settings get system ringtone
+     * The number you see at the end of the file path is the one you need.
+     * To see alarms and notifications ringtone codes, run the following:
+     * adb shell settings get system alarm_alert
+     * adb shell settings get system notification_sound
+     * @param r Ringtone setting - the name of the ringtone as displayed on device
+     * @param settingName - the code of the ringtone as explained above
+     * @param dir - the direction in which to scroll
+     */
+    private void verifyRingtone(RingtoneSetting r, String settingName) throws Exception {
+        findRingtoneInList(r.getName()).click();
+        if (mDevice.getProductName().equals("walleye") || mDevice.getProductName().equals("taimen")) {
+            mDevice.wait(Until.findObject(By.text("SAVE")), TIMEOUT).click();
+        }
+        else {
+            mDevice.wait(Until.findObject(By.text("OK")), TIMEOUT).click();
+        }
+        SystemClock.sleep(1000);
+        if (r.getVal().equals("null")) {
+            assertEquals(null,
+                    Settings.System.getString(mResolver, settingName));
+        } else if (r.getName().contains("Hangouts")) {
+            assertEquals("content://media/external/audio/media/" + r.getVal(),
+                    Settings.System.getString(mResolver, settingName));
+        } else {
+            assertEquals("content://media/internal/audio/media/" + r.getVal(),
+                    Settings.System.getString(mResolver, settingName));
+        }
+    }
+
+    private enum ScrollDir {
+        UP,
+        DOWN,
+        NOSCROLL
+    }
+
+    class RingtoneSetting {
+        private final String mName;
+        private final String mMediaVal;
+        public RingtoneSetting(String name, String fname) {
+            mName = name;
+            mMediaVal = fname;
+        }
+        public String getName() {
+            return mName;
+        }
+        public String getVal() {
+            return mMediaVal;
+        }
+    }
+
+    private void clickMore() throws InterruptedException {
+        UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT);
+        if (more != null) {
+            more.click();
+            Thread.sleep(TIMEOUT);
+        }
+    }
+
+    private UiObject2 findRingtoneInList(String ringtone) throws Exception {
+        mHelper.scrollVert(false);
+        SystemClock.sleep(1000);
+        UiObject2 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT);
+        int count = 0;
+        while (ringToneObject == null && count < 5) {
+            mHelper.scrollVert(true);
+            SystemClock.sleep(1000);
+            ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT);
+            count++;
+        }
+        return ringToneObject;
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/SyncSettingsTest.java b/tests/uitests/src/com/android/settings/ui/SyncSettingsTest.java
new file mode 100644
index 0000000..3dca424
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/SyncSettingsTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.os.RemoteException;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+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 org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static junit.framework.Assert.assertTrue;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SyncSettingsTest {
+    private static final int TIMEOUT = 2000;
+
+    private UiDevice mDevice;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("failed to freeze device orientaion", e);
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Need to finish settings activity
+        mDevice.pressHome();
+    }
+
+    @Test
+    public void syncPageShouldHaveAddAccountButton() throws Exception {
+        // Launch Settings
+        SettingsHelper.launchSettingsPage(
+                InstrumentationRegistry.getContext(), Settings.ACTION_SYNC_SETTINGS);
+        UiObject2 addAccount = mDevice.wait(
+                Until.findObject(By.text("Add account")), TIMEOUT);
+        assertTrue(addAccount != null);
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
new file mode 100644
index 0000000..1e3b978
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
@@ -0,0 +1,777 @@
+/*
+ * 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.Context;
+import android.content.Intent;
+import android.net.wifi.WifiManager;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.system.helpers.CommandsHelper;
+import android.system.helpers.SettingsHelper;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.StaleObjectException;
+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 android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+import junit.framework.AssertionFailedError;
+
+public class WirelessNetworkSettingsTests extends InstrumentationTestCase {
+    // These back button presses are performed in tearDown() to exit Wifi
+    // Settings sub-menus that a test might finish in. This number should be
+    // high enough to account for the deepest sub-menu a test might enter.
+    private static final int NUM_BACK_BUTTON_PRESSES = 5;
+    private static final int TIMEOUT = 2000;
+    private static final int SLEEP_TIME = 500;
+    private static final String AIRPLANE_MODE_BROADCAST =
+            "am broadcast -a android.intent.action.AIRPLANE_MODE";
+    private static final String TAG="WirelessNetworkSettingsTests";
+
+    // Note: The values of these variables might affect flakiness in tests that involve
+    // scrolling. Adjust where necessary.
+    private static final float SCROLL_UP_PERCENT = 10.0f;
+    private static final float SCROLL_DOWN_PERCENT = 0.5f;
+    private static final int MAX_SCROLL_ATTEMPTS = 10;
+    private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3;
+    private static final int SCROLL_SPEED = 2000;
+
+    private static final String TEST_SSID = "testSsid";
+    private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char";
+    private static final String TEST_PW_LT_8_CHAR = "lt8Char";
+    private static final String TEST_DOMAIN = "testDomain.com";
+
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+
+    private static final String CHECKBOX_CLASS = "android.widget.CheckBox";
+    private static final String SPINNER_CLASS = "android.widget.Spinner";
+    private static final String EDIT_TEXT_CLASS = "android.widget.EditText";
+    private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView";
+    private static final String LISTVIEW_CLASS = "android.widget.ListView";
+
+    private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL";
+    private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE";
+    private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network";
+    private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "Wi‑Fi preferences";
+    private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced";
+    private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select";
+    private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates";
+    private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate";
+    private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select";
+    private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide";
+    private static final String SECURITY_OPTION_NONE_TEXT = "None";
+    private static final String SECURITY_OPTION_WEP_TEXT = "WEP";
+    private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK";
+    private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP";
+    private static final String EAP_METHOD_PEAP_TEXT = "PEAP";
+    private static final String EAP_METHOD_TLS_TEXT = "TLS";
+    private static final String EAP_METHOD_TTLS_TEXT = "TTLS";
+    private static final String EAP_METHOD_PWD_TEXT = "PWD";
+    private static final String EAP_METHOD_SIM_TEXT = "SIM";
+    private static final String EAP_METHOD_AKA_TEXT = "AKA";
+    private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'";
+    private static final String PHASE2_MENU_NONE_TEXT = "None";
+    private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2";
+    private static final String PHASE2_MENU_GTC_TEXT = "GTC";
+
+    private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox";
+    private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings";
+    private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings";
+    private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security";
+    private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method";
+    private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid";
+    private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2";
+    private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert";
+    private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert";
+    private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning";
+    private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning";
+    private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain";
+    private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain";
+    private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity";
+    private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous";
+    private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout";
+    private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID =
+            "show_password_layout";
+    private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password";
+
+    private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR =
+            By.scrollable(true).clazz(SCROLLVIEW_CLASS);
+    private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR =
+            By.scrollable(true).clazz(LISTVIEW_CLASS);
+
+    private UiDevice mDevice;
+    private CommandsHelper mCommandsHelper;
+
+    @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 orientation", e);
+        }
+        // Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager.
+        Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, "0");
+        Log.d(TAG, "sending airplane mode broadcast to device");
+        mCommandsHelper = CommandsHelper.getInstance();
+        mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Exit all settings sub-menus.
+        for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
+            mDevice.pressBack();
+        }
+        mDevice.pressHome();
+        super.tearDown();
+    }
+
+    @Presubmit
+    @MediumTest
+    public void testWiFiEnabled() throws Exception {
+        verifyWiFiOnOrOff(true);
+    }
+
+    @Presubmit
+    @MediumTest
+    public void testWiFiDisabled() throws Exception {
+        verifyWiFiOnOrOff(false);
+    }
+
+    @MediumTest
+    public void testWifiMenuLoadConfigure() throws Exception {
+        loadWiFiConfigureMenu();
+        Thread.sleep(SLEEP_TIME);
+        UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject
+                (By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT);
+        assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading);
+    }
+
+    @MediumTest
+    public void testNetworkNotificationsOn() throws Exception {
+        verifyNetworkNotificationsOnOrOff(true);
+    }
+
+    @MediumTest
+    public void testNetworkNotificationsOff() throws Exception {
+        verifyNetworkNotificationsOnOrOff(false);
+    }
+
+    @MediumTest
+    public void testAddNetworkMenu_Default() throws Exception {
+        loadAddNetworkMenu();
+
+        // Submit button should be disabled by default, while cancel button should be enabled.
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Check that the SSID field is defaults to the hint.
+        assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By
+                .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID)
+                .clazz(EDIT_TEXT_CLASS)), TIMEOUT*2)
+                .getText());
+
+        // Check Security defaults to None.
+        assertEquals("None", mDevice.wait(Until.findObject(By
+                .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
+                .clazz(SPINNER_CLASS)), TIMEOUT)
+                .getChildren().get(0).getText());
+
+        // Check advanced options are collapsed by default.
+        assertFalse(mDevice.wait(Until.findObject(By
+                .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
+                .clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked());
+
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetworkMenu_Proxy() throws Exception {
+        loadAddNetworkMenu();
+
+        // Toggle advanced options.
+        mDevice.wait(Until.findObject(By
+                .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
+                .clazz(CHECKBOX_CLASS)), TIMEOUT).click();
+
+        // Verify Proxy defaults to None.
+        BySelector proxySettingsBySelector =
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID)
+                .clazz(SPINNER_CLASS);
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
+        assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT)
+                .getChildren().get(0).getText());
+
+        // Verify that Proxy Manual fields appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
+        mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
+        mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click();
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support"));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "proxy_hostname"));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "proxy_exclusionlist"));
+
+        // Verify that Proxy Auto-Config options appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
+        mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
+        mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click();
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "proxy_pac"));
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetworkMenu_IpSettings() throws Exception {
+        loadAddNetworkMenu();
+
+        // Toggle advanced options.
+        mDevice.wait(Until.findObject(By
+                .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
+                .clazz(CHECKBOX_CLASS)), TIMEOUT).click();
+
+        // Verify IP settings defaults to DHCP.
+        BySelector ipSettingsBySelector =
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS);
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector);
+        assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT)
+                .getChildren().get(0).getText());
+
+        // Verify that Static IP settings options appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click();
+        mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click();
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "ipaddress"));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "gateway"));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "network_prefix_length"));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "dns1"));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, "dns2"));
+    }
+
+    @Suppress
+    @MediumTest
+    public void testPhase2Settings() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+
+        BySelector phase2SettingsBySelector =
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS);
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector);
+        assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until
+                .findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText());
+        mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click();
+        Thread.sleep(SLEEP_TIME);
+
+        // Verify Phase 2 authentication spinner options.
+        assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT));
+        assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT));
+        assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT));
+    }
+
+    @Suppress
+    @MediumTest
+    public void testCaCertSettings() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+
+        BySelector caCertSettingsBySelector =
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS);
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector);
+        assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until
+                .findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText());
+        mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
+        Thread.sleep(SLEEP_TIME);
+
+        // Verify CA certificate spinner options.
+        assertNotNull(mDevice.wait(Until.findObject(
+                By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT));
+        assertNotNull(mDevice.wait(Until.findObject(
+                By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT));
+        assertNotNull(mDevice.wait(Until.findObject(
+                By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT));
+
+        // Verify that a domain field and warning appear when the user selects the
+        // "Use system certificates" option.
+        mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click();
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID));
+
+        // Verify that a warning appears when the user chooses the "Do Not Validate" option.
+        mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
+        mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click();
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID));
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_NoSecurity() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_NONE_TEXT);
+
+        // Entering an SSID is enough to enable the submit button. // TODO THIS GUY
+        enterSSID(TEST_SSID);
+        assertTrue(mDevice.wait(Until
+                .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_WEP() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_WEP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Verify that WEP fields appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
+
+        // Entering an SSID alone does not enable the submit button.
+        enterSSID(TEST_SSID);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Submit button is only enabled after a password is entered.
+        enterPassword(TEST_PW_GE_8_CHAR);
+        assertTrue(mDevice.wait(Until
+                .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_PSK() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_PSK_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Verify that PSK fields appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
+
+        // Entering an SSID alone does not enable the submit button.
+        enterSSID(TEST_SSID);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Entering an password that is too short does not enable submit button.
+        enterPassword(TEST_PW_LT_8_CHAR);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Submit button is only enabled after a password of valid length is entered.
+        enterPassword(TEST_PW_GE_8_CHAR);
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_EAP_PEAP() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        selectEAPMethod(EAP_METHOD_PEAP_TEXT);
+
+        // Verify that EAP-PEAP fields appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
+
+        // Entering an SSID alone does not enable the submit button.
+        enterSSID(TEST_SSID);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        verifyCaCertificateSubmitConditions();
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_EAP_TLS() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        selectEAPMethod(EAP_METHOD_TLS_TEXT);
+
+        // Verify that EAP-TLS fields appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+
+        // Entering an SSID alone does not enable the submit button.
+        enterSSID(TEST_SSID);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Selecting the User certificate "Do not provide" option alone does not enable the submit
+        // button.
+        selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        verifyCaCertificateSubmitConditions();
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_EAP_TTLS() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        selectEAPMethod(EAP_METHOD_TTLS_TEXT);
+
+        // Verify that EAP-TLS fields appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+
+        // Entering an SSID alone does not enable the submit button.
+        enterSSID(TEST_SSID);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        verifyCaCertificateSubmitConditions();
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_EAP_PWD() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        selectEAPMethod(EAP_METHOD_PWD_TEXT);
+
+        // Verify that EAP-TLS fields appear.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
+
+        // Entering an SSID alone enables the submit button.
+        enterSSID(TEST_SSID);
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_EAP_SIM() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        selectEAPMethod(EAP_METHOD_SIM_TEXT);
+
+        // Entering an SSID alone enables the submit button.
+        enterSSID(TEST_SSID);
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_EAP_AKA() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        selectEAPMethod(EAP_METHOD_AKA_TEXT);
+
+        // Entering an SSID alone enables the submit button.
+        enterSSID(TEST_SSID);
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    @Suppress
+    @MediumTest
+    public void testAddNetwork_EAP_AKA_PRIME() throws Exception {
+        loadAddNetworkMenu();
+        selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT);
+
+        // Entering an SSID alone enables the submit button.
+        enterSSID(TEST_SSID);
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue)
+            throws Exception {
+        loadWiFiConfigureMenu();
+        mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT)
+                .click();
+        mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView")
+                .text(settingToBeVerified)), TIMEOUT).click();
+        Thread.sleep(SLEEP_TIME);
+        int keepWiFiOnSetting =
+                Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
+                Settings.Global.WIFI_SLEEP_POLICY);
+        assertEquals(settingValue, keepWiFiOnSetting);
+    }
+
+    private void verifyNetworkNotificationsOnOrOff(boolean verifyOn)
+            throws Exception {
+        // Enable network recommendations to enable the toggle switch for Network
+        // notifications
+        Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+                Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1");
+        if (verifyOn) {
+            Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0");
+        }
+        else {
+            Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
+                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
+        }
+        loadWiFiConfigureMenu();
+        mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT)
+                .click();
+        Thread.sleep(SLEEP_TIME);
+        String wifiNotificationValue =
+                Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
+                Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
+        if (verifyOn) {
+            assertEquals("1", wifiNotificationValue);
+        }
+        else {
+            assertEquals("0", wifiNotificationValue);
+        }
+    }
+
+    private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception {
+         String switchText = "On";
+         if (verifyOn) {
+             switchText = "Off";
+         }
+         loadWiFiSettingsPage(!verifyOn);
+         mDevice.wait(Until
+                 .findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT)
+                 .click();
+         Thread.sleep(SLEEP_TIME);
+         String wifiValue =
+                 Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
+                 Settings.Global.WIFI_ON);
+         if (verifyOn) {
+             // 1 is Enabled, 2 is Enabled while airplane mode is ON.
+             assertTrue(wifiValue.equals("1") || wifiValue.equals("2"));
+         }
+         else {
+             assertEquals("0", wifiValue);
+         }
+    }
+
+    private void verifyCaCertificateSubmitConditions() throws Exception {
+        // Selecting the CA certificate "Do not validate" option enables the submit button.
+        selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT);
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // However, selecting the CA certificate "Use system certificates option" is not enough to
+        // enable the submit button.
+        selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT);
+        assertFalse(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+
+        // Submit button is only enabled after a domain is entered as well.
+        enterDomain(TEST_DOMAIN);
+        assertTrue(mDevice.wait(Until.findObject(
+                By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
+    }
+
+    private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
+        WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
+                .getSystemService(Context.WIFI_SERVICE);
+        wifiManager.setWifiEnabled(wifiEnabled);
+        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+                Settings.ACTION_WIFI_SETTINGS);
+    }
+
+    private void loadWiFiConfigureMenu() throws Exception {
+        loadWiFiSettingsPage(false);
+        Thread.sleep(TIMEOUT);
+        mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click();
+        mDevice.wait(Until.findObject(
+                By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click();
+    }
+
+    private void loadAddNetworkMenu() throws Exception {
+        loadWiFiSettingsPage(true);
+        for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) {
+            try {
+                findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT))
+                        .click();
+            } catch (StaleObjectException e) {
+                // The network list might have been updated between when the Add network button was
+                // found, and when it UI automator attempted to click on it. Retry.
+                continue;
+            }
+            // If we get here, we successfully clicked on the Add network button, so we are done.
+            Thread.sleep(SLEEP_TIME*5);
+            return;
+        }
+
+        fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS
+                + " retries");
+    }
+
+    private void selectSecurityOption(String securityOption) throws Exception {
+        // We might not need to scroll to the security options if not enough add network menu
+        // options are visible.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
+                .clazz(SPINNER_CLASS)).click();
+        Thread.sleep(SLEEP_TIME);
+        mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click();
+    }
+
+    private void selectEAPMethod(String eapMethod) throws Exception {
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS))
+                .click();
+        Thread.sleep(SLEEP_TIME);
+        findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click();
+    }
+
+    private void selectUserCertificateOption(String userCertificateOption) throws Exception {
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS))
+                .click();
+        mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click();
+    }
+
+    private void selectCaCertificateOption(String caCertificateOption) throws Exception {
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS))
+                .click();
+        mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click();
+    }
+
+    private void enterSSID(String ssid) throws Exception {
+        // We might not need to scroll to the SSID option if not enough add network menu options
+        // are visible.
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS))
+                .setText(ssid);
+    }
+
+    private void enterPassword(String password) throws Exception {
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS))
+                .setText(password);
+    }
+
+    private void enterDomain(String domain) throws Exception {
+        findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
+                By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain);
+    }
+
+    // Use this if the UI object might or might not need to be scrolled to.
+    private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector)
+            throws Exception {
+        UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT);
+        if (object == null) {
+            object = scrollToObject(scrollableSelector, objectSelector);
+        }
+        return object;
+    }
+
+    private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector)
+            throws Exception {
+        UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT);
+        if (scrollable == null) {
+            fail("Could not find scrollable UI object identified by " + scrollableSelector);
+        }
+        UiObject2 found = null;
+        // Scroll all the way up first, then all the way down.
+        while (true) {
+            // Optimization: terminate if we find the object while scrolling up to reset, so
+            // we save the time spent scrolling down again.
+            boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT,
+                    SCROLL_SPEED);
+            found = mDevice.findObject(objectSelector);
+            if (found != null) return found;
+            if (!canScrollAgain) break;
+        }
+        for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) {
+            // Return value of UiObject2.scroll() is not reliable, so do not use it in loop
+            // condition, in case it causes this loop to terminate prematurely.
+            scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED);
+            found = mDevice.findObject(objectSelector);
+        }
+        if (found == null) {
+            fail("Could not scroll to UI object identified by " + objectSelector);
+        }
+        return found;
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java b/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java
new file mode 100644
index 0000000..9b1be14
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java
@@ -0,0 +1,61 @@
+/*
+ * 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.testutils;
+
+import static org.junit.Assert.assertNotNull;
+
+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;
+
+public class SettingsTestUtils {
+
+    public static final String SETTINGS_PACKAGE = "com.android.settings";
+    public static final int TIMEOUT = 2000;
+
+    private void scrollToTop(UiDevice device) throws Exception {
+        int count = 5;
+        UiObject2 view = null;
+        while (count >= 0) {
+            view = device.wait(
+                    Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
+                    TIMEOUT);
+            view.scroll(Direction.UP, 1.0f);
+            count--;
+        }
+    }
+
+    public static void assertTitleMatch(UiDevice device, String title) {
+        int maxAttempt = 5;
+        UiObject2 item = null;
+        UiObject2 view = null;
+        while (maxAttempt-- > 0) {
+            item = device.wait(Until.findObject(By.res("android:id/title").text(title)), TIMEOUT);
+            if (item == null) {
+                view = device.wait(
+                        Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
+                        TIMEOUT);
+                view.scroll(Direction.DOWN, 1.0f);
+            } else {
+                return;
+            }
+        }
+        assertNotNull(String.format("%s in Setting has not been loaded correctly", title), item);
+    }
+}
