diff --git a/res/values/strings.xml b/res/values/strings.xml
index 711d720..f917d81 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8318,9 +8318,6 @@
     <!-- Summary of memory screen [CHAR LIMIT=NONE] -->
     <string name="memory_summary">Avg <xliff:g id="used_memory" example="1.7GB">%1$s</xliff:g> of <xliff:g id="total_memory" example="2GB">%2$s</xliff:g> memory used</string>
 
-    <!-- Summary of Users & accounts setting screen [CHAR LIMIT=NONE] -->
-    <string name="users_and_accounts_summary">Current user: <xliff:g id="user_name" example="Jason">%1$s</xliff:g></string>
-
     <!-- Summary of User settings [CHAR LIMIT=NONE] -->
     <string name="users_summary">Signed in as <xliff:g id="user_name" example="Jason">%1$s</xliff:g></string>
 
@@ -8780,6 +8777,9 @@
     <!-- [CHAR LIMIT=25] Title of developer tile to toggle layer trace -->
     <string name="layer_trace_quick_settings_title">Surface Trace</string>
 
+    <!-- Template for formatting country and language. eg Canada - French [CHAR LIMIT=NONE]-->
+    <string name="support_country_format"><xliff:g id="country" example="Canada">%1$s</xliff:g> - <xliff:g id="language" example="French">%2$s</xliff:g></string>
+
     <!-- [CHAR LIMIT=60] Title of work profile setting page -->
     <string name="managed_profile_settings_title">Work profile settings</string>
     <!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
diff --git a/res/xml/app_data_usage.xml b/res/xml/app_data_usage.xml
index 3e94135..a4b2159 100644
--- a/res/xml/app_data_usage.xml
+++ b/res/xml/app_data_usage.xml
@@ -16,6 +16,8 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="app_data_usage_screen"
     android:title="@string/data_usage_app_summary_title">
 
     <com.android.settings.datausage.SpinnerPreference
@@ -50,15 +52,19 @@
             android:key="app_settings"
             android:title="@string/data_usage_app_settings" />
 
-        <SwitchPreference
+        <com.android.settingslib.RestrictedSwitchPreference
             android:key="restrict_background"
             android:title="@string/data_usage_app_restrict_background"
-            android:summary="@string/data_usage_app_restrict_background_summary" />
+            android:summary="@string/data_usage_app_restrict_background_summary"
+            settings:useAdditionalSummary="true"
+            settings:restrictedSwitchSummary="@string/disabled_by_admin" />
 
-        <SwitchPreference
+        <com.android.settingslib.RestrictedSwitchPreference
             android:key="unrestricted_data_saver"
             android:title="@string/unrestricted_app_title"
-            android:summary="@string/unrestricted_app_summary" />
+            android:summary="@string/unrestricted_app_summary"
+            settings:useAdditionalSummary="true"
+            settings:restrictedSwitchSummary="@string/disabled_by_admin" />
 
     </PreferenceCategory>
 
diff --git a/src/com/android/settings/accounts/AccountDashboardFragment.java b/src/com/android/settings/accounts/AccountDashboardFragment.java
index fe967b8..65a5ff0 100644
--- a/src/com/android/settings/accounts/AccountDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDashboardFragment.java
@@ -19,16 +19,16 @@
 
 import android.app.Activity;
 import android.content.Context;
-import android.content.pm.UserInfo;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.SearchIndexableResource;
+import android.text.BidiFormatter;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.accounts.AuthenticatorHelper;
 import com.android.settingslib.core.AbstractPreferenceController;
 
 import java.util.ArrayList;
@@ -84,10 +84,27 @@
         @Override
         public void setListening(boolean listening) {
             if (listening) {
-                UserInfo info = mContext.getSystemService(UserManager.class).getUserInfo(
-                        UserHandle.myUserId());
-                mSummaryLoader.setSummary(this,
-                        mContext.getString(R.string.users_and_accounts_summary, info.name));
+                final AuthenticatorHelper authHelper = new AuthenticatorHelper(mContext,
+                        UserHandle.of(UserHandle.myUserId()), null /* OnAccountsUpdateListener */);
+                final String[] types = authHelper.getEnabledAccountTypes();
+
+                final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+
+                CharSequence summary = null;
+
+                // Show up to 3 account types
+                final int size = Math.min(3, types.length);
+
+                for (int i = 0; i < size; i++) {
+                    final CharSequence label = authHelper.getLabelForType(mContext, types[i]);
+                    if (summary == null) {
+                        summary = bidiFormatter.unicodeWrap(label);
+                    } else {
+                        summary = mContext.getString(R.string.join_many_items_middle, summary,
+                                bidiFormatter.unicodeWrap(label));
+                    }
+                }
+                mSummaryLoader.setSummary(this, summary);
             }
         }
     }
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index 5470e63..a0d0ec0 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -33,7 +33,6 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.support.annotation.VisibleForTesting;
-import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceCategory;
 import android.text.format.Formatter;
@@ -48,6 +47,9 @@
 import com.android.settings.applications.AppInfoBase;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.AppItem;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedSwitchPreference;
 import com.android.settingslib.net.ChartData;
 import com.android.settingslib.net.ChartDataLoader;
 import com.android.settingslib.net.UidDetail;
@@ -80,7 +82,7 @@
     private Preference mForegroundUsage;
     private Preference mBackgroundUsage;
     private Preference mAppSettings;
-    private SwitchPreference mRestrictBackground;
+    private RestrictedSwitchPreference mRestrictBackground;
     private PreferenceCategory mAppList;
 
     private Drawable mIcon;
@@ -97,7 +99,7 @@
     private AppItem mAppItem;
     private Intent mAppSettingsIntent;
     private SpinnerPreference mCycle;
-    private SwitchPreference mUnrestrictedData;
+    private RestrictedSwitchPreference mUnrestrictedData;
     private DataSaverBackend mDataSaverBackend;
 
     @Override
@@ -160,9 +162,11 @@
                 removePreference(KEY_UNRESTRICTED_DATA);
                 removePreference(KEY_RESTRICT_BACKGROUND);
             } else {
-                mRestrictBackground = (SwitchPreference) findPreference(KEY_RESTRICT_BACKGROUND);
+                mRestrictBackground = (RestrictedSwitchPreference) findPreference(
+                        KEY_RESTRICT_BACKGROUND);
                 mRestrictBackground.setOnPreferenceChangeListener(this);
-                mUnrestrictedData = (SwitchPreference) findPreference(KEY_UNRESTRICTED_DATA);
+                mUnrestrictedData = (RestrictedSwitchPreference) findPreference(
+                        KEY_UNRESTRICTED_DATA);
                 mUnrestrictedData.setOnPreferenceChangeListener(this);
             }
             mDataSaverBackend = new DataSaverBackend(getContext());
@@ -261,8 +265,11 @@
     }
 
     private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
+        final EnforcedAdmin admin = RestrictedLockUtils.checkIfMeteredDataRestricted(
+                getContext(), mPackageName, UserHandle.getUserId(mAppItem.key));
         if (mRestrictBackground != null) {
             mRestrictBackground.setChecked(!restrictBackground);
+            mRestrictBackground.setDisabledByAdmin(admin);
         }
         if (mUnrestrictedData != null) {
             if (restrictBackground) {
@@ -270,6 +277,7 @@
             } else {
                 mUnrestrictedData.setVisible(true);
                 mUnrestrictedData.setChecked(unrestrictData);
+                mUnrestrictedData.setDisabledByAdmin(admin);
             }
         }
     }
diff --git a/src/com/android/settings/datausage/DataSaverPreference.java b/src/com/android/settings/datausage/DataSaverPreference.java
index 13ef9d7..f1f648a 100644
--- a/src/com/android/settings/datausage/DataSaverPreference.java
+++ b/src/com/android/settings/datausage/DataSaverPreference.java
@@ -37,7 +37,7 @@
     @Override
     public void onDetached() {
         super.onDetached();
-        mDataSaverBackend.addListener(this);
+        mDataSaverBackend.remListener(this);
     }
 
     @Override
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
index e8a7bbf..cff4a50 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
@@ -14,6 +14,8 @@
 
 package com.android.settings.datausage;
 
+import static com.android.settingslib.RestrictedLockUtils.checkIfMeteredDataRestricted;
+
 import android.app.Application;
 import android.content.Context;
 import android.os.Bundle;
@@ -37,6 +39,8 @@
 import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.AppSwitchPreference;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedPreferenceHelper;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
 import com.android.settingslib.applications.ApplicationsState.AppFilter;
@@ -172,6 +176,8 @@
                 preference.setOnPreferenceChangeListener(this);
                 getPreferenceScreen().addPreference(preference);
             } else {
+                preference.setDisabledByAdmin(checkIfMeteredDataRestricted(getContext(),
+                        entry.info.packageName, UserHandle.getUserId(entry.info.uid)));
                 preference.reuse();
             }
             preference.setOrder(i);
@@ -242,16 +248,22 @@
         return app != null && UserHandle.isApp(app.info.uid);
     }
 
-    private class AccessPreference extends AppSwitchPreference
+    @VisibleForTesting
+    class AccessPreference extends AppSwitchPreference
             implements DataSaverBackend.Listener {
         private final AppEntry mEntry;
         private final DataUsageState mState;
+        private final RestrictedPreferenceHelper mHelper;
 
         public AccessPreference(final Context context, AppEntry entry) {
             super(context);
+            setWidgetLayoutResource(R.layout.restricted_switch_widget);
+            mHelper = new RestrictedPreferenceHelper(context, this, null);
             mEntry = entry;
             mState = (DataUsageState) mEntry.extraInfo;
             mEntry.ensureLabel(getContext());
+            setDisabledByAdmin(checkIfMeteredDataRestricted(context, entry.info.packageName,
+                    UserHandle.getUserId(entry.info.uid)));
             setState();
             if (mEntry.icon != null) {
                 setIcon(mEntry.icon);
@@ -291,12 +303,21 @@
             }
         }
 
+        @Override
+        public void performClick() {
+            if (!mHelper.performClick()) {
+                super.performClick();
+            }
+        }
+
         // Sets UI state based on whitelist/blacklist status.
         private void setState() {
             setTitle(mEntry.label);
             if (mState != null) {
                 setChecked(mState.isDataSaverWhitelisted);
-                if (mState.isDataSaverBlacklisted) {
+                if (isDisabledByAdmin()) {
+                    setSummary(R.string.disabled_by_admin);
+                } else if (mState.isDataSaverBlacklisted) {
                     setSummary(R.string.restrict_background_blacklisted);
                 } else {
                     setSummary("");
@@ -323,10 +344,21 @@
                     }
                 });
             }
-            holder.findViewById(android.R.id.widget_frame)
-                    .setVisibility(mState != null && mState.isDataSaverBlacklisted
-                            ? View.INVISIBLE : View.VISIBLE);
+            final boolean disabledByAdmin = isDisabledByAdmin();
+            final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
+            if (disabledByAdmin) {
+                widgetFrame.setVisibility(View.VISIBLE);
+            } else {
+                widgetFrame.setVisibility(mState != null && mState.isDataSaverBlacklisted
+                        ? View.INVISIBLE : View.VISIBLE);
+            }
             super.onBindViewHolder(holder);
+
+            mHelper.onBindViewHolder(holder);
+            holder.findViewById(R.id.restricted_icon).setVisibility(
+                    disabledByAdmin ? View.VISIBLE : View.GONE);
+            holder.findViewById(android.R.id.switch_widget).setVisibility(
+                    disabledByAdmin ? View.GONE : View.VISIBLE);
         }
 
         @Override
@@ -348,6 +380,19 @@
                 reuse();
             }
         }
+
+        public void setDisabledByAdmin(EnforcedAdmin admin) {
+            mHelper.setDisabledByAdmin(admin);
+        }
+
+        public boolean isDisabledByAdmin() {
+            return mHelper.isDisabledByAdmin();
+        }
+
+        @VisibleForTesting
+        public AppEntry getEntryForTest() {
+            return mEntry;
+        }
     }
 
 }
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java
index dff82aa..aeffd20 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java
@@ -15,42 +15,40 @@
  */
 package com.android.settings.accounts;
 
-import android.app.Activity;
-import android.content.pm.UserInfo;
-import android.os.UserManager;
-import android.provider.SearchIndexableResource;
+import static com.android.settings.accounts.AccountDashboardFragmentTest
+        .ShadowAuthenticationHelper.LABELS;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
-import com.android.settings.R;
+import android.app.Activity;
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.SearchIndexableResource;
+import android.text.TextUtils;
+
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.SummaryLoader;
+import com.android.settingslib.accounts.AuthenticatorHelper;
 import com.android.settingslib.drawer.CategoryKey;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 import org.robolectric.shadows.ShadowApplication;
 
 import java.util.List;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 @RunWith(RobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class AccountDashboardFragmentTest {
 
-    private static final String METADATA_CATEGORY = "com.android.settings.category";
-    private static final String METADATA_ACCOUNT_TYPE = "com.android.settings.ia.account";
-
-    @Mock
-    private UserManager mUserManager;
     private AccountDashboardFragment mFragment;
 
     @Before
@@ -65,21 +63,18 @@
     }
 
     @Test
-    public void updateSummary_shouldDisplaySignedInUser() {
-        final Activity activity = mock(Activity.class);
+    @Config(shadows = {
+            ShadowAuthenticationHelper.class
+    })
+    public void updateSummary_shouldDisplayUpTo3AccountTypes() {
         final SummaryLoader loader = mock(SummaryLoader.class);
-        final UserInfo userInfo = new UserInfo();
-        userInfo.name = "test_name";
-
-        when(activity.getSystemService(UserManager.class)).thenReturn(mUserManager);
-        when(mUserManager.getUserInfo(anyInt())).thenReturn(userInfo);
+        final Activity activity = Robolectric.buildActivity(Activity.class).setup().get();
 
         final SummaryLoader.SummaryProvider provider = mFragment.SUMMARY_PROVIDER_FACTORY
                 .createSummaryProvider(activity, loader);
         provider.setListening(true);
 
-        verify(activity).getString(R.string.users_and_accounts_summary,
-                userInfo.name);
+        verify(loader).setSummary(provider, LABELS[0] + ", " + LABELS[1] + ", " + LABELS[2]);
     }
 
     @Test
@@ -92,4 +87,36 @@
         assertThat(indexRes).isNotNull();
         assertThat(indexRes.get(0).xmlResId).isEqualTo(mFragment.getPreferenceScreenResId());
     }
+
+    @Implements(AuthenticatorHelper.class)
+    public static class ShadowAuthenticationHelper {
+
+        static final String[] TYPES = new String[] {"type1", "type2", "type3", "type4"};
+        static final String[] LABELS = new String[] {"LABEL1", "LABEL2",
+                "LABEL3", "LABEL4"};
+
+        public void __constructor__(Context context, UserHandle userHandle,
+                AuthenticatorHelper.OnAccountsUpdateListener listener) {
+
+        }
+
+        @Implementation
+        public String[] getEnabledAccountTypes() {
+            return TYPES;
+        }
+
+        @Implementation
+        public CharSequence getLabelForType(Context context, final String accountType) {
+            if (TextUtils.equals(accountType, TYPES[0])) {
+                return LABELS[0];
+            } else if (TextUtils.equals(accountType, TYPES[1])) {
+                return LABELS[1];
+            } else if (TextUtils.equals(accountType, TYPES[2])) {
+                return LABELS[2];
+            } else if (TextUtils.equals(accountType, TYPES[3])) {
+                return LABELS[3];
+            }
+            return "no_label";
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
index 7cd09de..58643b6 100644
--- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
@@ -29,8 +29,8 @@
 import static org.mockito.Mockito.when;
 
 import android.content.pm.PackageManager;
+import android.net.NetworkPolicyManager;
 import android.os.Bundle;
-import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.PreferenceManager;
 import android.support.v7.preference.PreferenceScreen;
 import android.util.ArraySet;
@@ -40,8 +40,11 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.AppItem;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedSwitchPreference;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 import org.junit.After;
@@ -57,7 +60,10 @@
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
-        shadows = ShadowEntityHeaderController.class)
+        shadows = {
+                ShadowEntityHeaderController.class,
+                ShadowRestrictedLockUtils.class
+        })
 public class AppDataUsageTest {
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -134,7 +140,7 @@
     public void changePreference_backgroundData_shouldUpdateUI() {
         mFragment = spy(new AppDataUsage());
         final AppItem appItem = new AppItem(123456789);
-        final SwitchPreference pref = mock(SwitchPreference.class);
+        final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class);
         final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
         ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
         ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
@@ -146,4 +152,31 @@
 
         verify(mFragment).updatePrefs();
     }
+
+    @Test
+    public void updatePrefs_restrictedByAdmin_shouldDisablePreference() {
+        mFragment = spy(new AppDataUsage());
+        final int testUid = 123123;
+        final AppItem appItem = new AppItem(testUid);
+        final RestrictedSwitchPreference restrictBackgroundPref
+                = mock(RestrictedSwitchPreference.class);
+        final RestrictedSwitchPreference unrestrictedDataPref
+                = mock(RestrictedSwitchPreference.class);
+        final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
+        final NetworkPolicyManager networkPolicyManager = mock(NetworkPolicyManager.class);
+        ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
+        ReflectionHelpers.setField(mFragment, "mRestrictBackground", restrictBackgroundPref);
+        ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref);
+        ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
+        ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
+
+        ShadowRestrictedLockUtils.setRestricted(true);
+        doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
+                .getUidPolicy(testUid);
+
+        mFragment.updatePrefs();
+
+        verify(restrictBackgroundPref).setDisabledByAdmin(any(EnforcedAdmin.class));
+        verify(unrestrictedDataPref).setDisabledByAdmin(any(EnforcedAdmin.class));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
index 53cb7ed..fff879f 100644
--- a/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/UnrestrictedDataAccessTest.java
@@ -16,41 +16,68 @@
 package com.android.settings.datausage;
 
 import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.os.Process;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
 
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
 import com.android.settings.TestConfig;
+import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
+import com.android.settings.datausage.UnrestrictedDataAccess.AccessPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.applications.ApplicationsState;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.ArrayList;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+        shadows = {
+                ShadowRestrictedLockUtils.class
+        })
 public class UnrestrictedDataAccessTest {
 
     @Mock
-    private ApplicationsState.AppEntry mAppEntry;
+    private AppEntry mAppEntry;
     private UnrestrictedDataAccess mFragment;
     private FakeFeatureFactory mFeatureFactory;
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+    @Mock
+    private PreferenceManager mPreferenceManager;
+    @Mock
+    private DataSaverBackend mDataSaverBackend;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mFeatureFactory = FakeFeatureFactory.setupForTest();
-        mFragment = new UnrestrictedDataAccess();
+        mFragment = spy(new UnrestrictedDataAccess());
     }
 
     @Test
@@ -80,4 +107,66 @@
                 eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_DENY), eq("app"));
     }
 
+    @Test
+    public void testOnRebuildComplete_restricted_shouldBeDisabled() {
+        final Context context = RuntimeEnvironment.application;
+        doReturn(context).when(mFragment).getContext();
+        doReturn(context).when(mPreferenceManager).getContext();
+        doReturn(true).when(mFragment).shouldAddPreference(any(AppEntry.class));
+        doNothing().when(mFragment).setLoading(anyBoolean(), anyBoolean());
+        doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
+        doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
+        ReflectionHelpers.setField(mFragment, "mDataSaverBackend", mDataSaverBackend);
+
+        final String testPkg1 = "com.example.one";
+        final String testPkg2 = "com.example.two";
+        ShadowRestrictedLockUtils.setRestrictedPkgs(testPkg2);
+
+        doAnswer((invocation) -> {
+            final AccessPreference preference = invocation.getArgument(0);
+            final AppEntry entry = preference.getEntryForTest();
+            // Verify preference is disabled by admin and the summary is changed accordingly.
+            if (testPkg1.equals(entry.info.packageName)) {
+                assertThat(preference.isDisabledByAdmin()).isFalse();
+                assertThat(preference.getSummary()).isEqualTo("");
+            } else if (testPkg2.equals(entry.info.packageName)) {
+                assertThat(preference.isDisabledByAdmin()).isTrue();
+                assertThat(preference.getSummary()).isEqualTo(
+                        context.getString(R.string.disabled_by_admin));
+            }
+            assertThat(preference.isChecked()).isFalse();
+            preference.performClick();
+            // Verify that when the preference is clicked, support details intent is launched
+            // if the preference is disabled by admin, otherwise the switch is toggled.
+            if (testPkg1.equals(entry.info.packageName)) {
+                assertThat(preference.isChecked()).isTrue();
+                assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
+                        .isFalse();
+            } else if (testPkg2.equals(entry.info.packageName)) {
+                assertThat(preference.isChecked()).isFalse();
+                assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
+                        .isTrue();
+            }
+            ShadowRestrictedLockUtils.clearAdminSupportDetailsIntentLaunch();
+            return null;
+        }).when(mPreferenceScreen).addPreference(any(AccessPreference.class));
+        mFragment.onRebuildComplete(createAppEntries(testPkg1, testPkg2));
+    }
+
+    private ArrayList<AppEntry> createAppEntries(String... packageNames) {
+        final ArrayList<AppEntry> appEntries = new ArrayList<>();
+        for (int i = 0; i < packageNames.length; ++i) {
+            final ApplicationInfo info = new ApplicationInfo();
+            info.packageName = packageNames[i];
+            info.uid = Process.FIRST_APPLICATION_UID + i;
+            info.sourceDir = info.packageName;
+            final AppEntry appEntry = spy(new AppEntry(RuntimeEnvironment.application,
+                    info, i));
+            appEntry.extraInfo = new DataUsageState(false, false);
+            doNothing().when(appEntry).ensureLabel(any(Context.class));
+            ReflectionHelpers.setField(appEntry, "info", info);
+            appEntries.add(appEntry);
+        }
+        return appEntries;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java
new file mode 100644
index 0000000..afede1a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtils.java
@@ -0,0 +1,65 @@
+/*
+ * 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.testutils.shadow;
+
+import android.content.Context;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(RestrictedLockUtils.class)
+public class ShadowRestrictedLockUtils {
+    private static boolean isRestricted;
+    private static String[] restrictedPkgs;
+    private static boolean adminSupportDetailsIntentLaunched;
+
+    @Implementation
+    public static RestrictedLockUtils.EnforcedAdmin checkIfMeteredDataRestricted(Context context,
+            String packageName, int userId) {
+        if (isRestricted) {
+            return new EnforcedAdmin();
+        }
+        if (ArrayUtils.contains(restrictedPkgs, packageName)) {
+            return new EnforcedAdmin();
+        }
+        return null;
+    }
+
+    @Implementation
+    public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
+        adminSupportDetailsIntentLaunched = true;
+    }
+
+    public static boolean hasAdminSupportDetailsIntentLaunched() {
+        return adminSupportDetailsIntentLaunched;
+    }
+
+    public static void clearAdminSupportDetailsIntentLaunch() {
+        adminSupportDetailsIntentLaunched = false;
+    }
+
+    public static void setRestricted(boolean restricted) {
+        isRestricted = restricted;
+    }
+
+    public static void setRestrictedPkgs(String... pkgs) {
+        restrictedPkgs = pkgs;
+    }
+}
diff --git a/tests/uitests/Android.mk b/tests/uitests/Android.mk
index 870f59c..d52911d 100644
--- a/tests/uitests/Android.mk
+++ b/tests/uitests/Android.mk
@@ -19,16 +19,22 @@
 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_JAVA_LIBRARIES := \
+    android.test.runner \
+    android.test.base
+
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
     app-helpers-core \
     launcher-helper-lib \
-    settings-helper \
-    timeresult-helper-lib \
-    ub-uiautomator \
-    sysui-helper \
     metrics-helper-lib \
     platform-test-annotations \
+    settings-helper \
+    sysui-helper \
+    timeresult-helper-lib \
+    truth-prebuilt \
+    ub-uiautomator \
 
 #LOCAL_SDK_VERSION := current
 
diff --git a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
index 57f9bc2..b92a707 100644
--- a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
+++ b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java
@@ -16,57 +16,55 @@
 
 package com.android.settings.ui;
 
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.Instrumentation;
 import android.content.Intent;
 import android.os.RemoteException;
 import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+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.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.text.TextUtils;
-import android.util.Log;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 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";
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AboutPhoneSettingsTests {
     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"
+            "Phone number",
+            "SIM status",
+            "Model & hardware",
+            "MEID",
+            "Android version"
     };
 
-    private static final String[] sClickableResourceTexts = {
-        "Status", "Legal information", "Regulatory labels",
-    };
+    private UiDevice mDevice;
+    private Instrumentation mInstrumentation;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        if (LOCAL_LOGV) {
-            Log.d(TAG, "-------");
-        }
-        super.setUp();
-        mDevice = UiDevice.getInstance(getInstrumentation());
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mDevice = UiDevice.getInstance(mInstrumentation);
         try {
             mDevice.setOrientationNatural();
         } catch (RemoteException e) {
@@ -82,84 +80,40 @@
         UiObject2 view =
                 mDevice.wait(
                         Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT);
-        assertNotNull("Could not find main About Phone screen", view);
+        assertThat(view).isNotNull();
         view.scroll(Direction.UP, 1.0f);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public 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();
+    }
+
+    @Test
+    public void testAllMenuEntriesExist() throws Exception {
+        searchForItemsAndTakeAction(mDevice, sResourceTexts);
     }
 
     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;
-        }
+        InstrumentationRegistry.getTargetContext().startActivity(aboutIntent);
     }
 
     /**
      * 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 {
+    private void removeItemsAndTakeAction(UiDevice device, ArrayList<String> itemsLeftToFind)
+            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);
-                }
             }
         }
     }
@@ -169,25 +123,18 @@
      *
      * <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)
+    private void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind)
             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());
+        ArrayList<String> itemsLeftToFind = new ArrayList<>(Arrays.asList(itemsToFind));
+        assertWithMessage("There must be at least one item to search for on the screen!")
+                .that(itemsLeftToFind)
+                .isNotEmpty();
 
-        if (LOCAL_LOGV) {
-            Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind));
-        }
         boolean canScrollDown = true;
         while (canScrollDown && !itemsLeftToFind.isEmpty()) {
-            removeItemsAndTakeAction(device, itemsLeftToFind, action);
+            removeItemsAndTakeAction(device, itemsLeftToFind);
 
             // when we've finished searching the current view, scroll down
             UiObject2 view =
@@ -201,24 +148,11 @@
             }
         }
         // check the last items once we have reached the bottom of the view
-        removeItemsAndTakeAction(device, itemsLeftToFind, action);
+        removeItemsAndTakeAction(device, itemsLeftToFind);
 
-        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());
+        assertWithMessage("The following items were not found on the screen: "
+                + TextUtils.join(", ", itemsLeftToFind))
+                .that(itemsLeftToFind)
+                .isEmpty();
     }
 }
diff --git a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
index 7931d30..3b7b006 100644
--- a/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
+++ b/tests/uitests/src/com/android/settings/ui/HomepageDisplayTests.java
@@ -16,6 +16,9 @@
 
 package com.android.settings.ui;
 
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
+
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
@@ -36,9 +39,6 @@
 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 {
@@ -52,19 +52,17 @@
             "Sound",
             "Storage",
             "Security & location",
-            "Users & accounts",
+            "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) {
diff --git a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java
new file mode 100644
index 0000000..4ed2a1d
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java
@@ -0,0 +1,766 @@
+/*
+ * 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.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.system.helpers.CommandsHelper;
+import android.system.helpers.SettingsHelper;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+
+/**
+ * Additional tests for Wifi Settings.
+ */
+public class WirelessNetworkSettingsAdditionalTests 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();
+    }
+
+    @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/WirelessNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
index 1e3b978..64fa5fd 100644
--- a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
+++ b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
@@ -16,762 +16,109 @@
 
 package com.android.settings.ui;
 
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.google.common.truth.Truth.assertThat;
+
 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.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
 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 {
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Core tests for Wifi Settings.
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class WirelessNetworkSettingsTests {
     // 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 TIMEOUT = 20000;
     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";
+    private static final String TAG = "WirelessNetworkTests";
 
-    // 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
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        mDevice = UiDevice.getInstance(getInstrumentation());
+
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.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.putString(InstrumentationRegistry.getTargetContext().getContentResolver(),
                 Settings.Global.AIRPLANE_MODE_ON, "0");
+
         Log.d(TAG, "sending airplane mode broadcast to device");
-        mCommandsHelper = CommandsHelper.getInstance();
+        mCommandsHelper = CommandsHelper.getInstance(InstrumentationRegistry.getInstrumentation());
         mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() {
         // Exit all settings sub-menus.
         for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
             mDevice.pressBack();
         }
         mDevice.pressHome();
-        super.tearDown();
     }
 
     @Presubmit
-    @MediumTest
+    @Test
     public void testWiFiEnabled() throws Exception {
         verifyWiFiOnOrOff(true);
     }
 
     @Presubmit
-    @MediumTest
+    @Test
     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());
+        loadWiFiSettingsPage(!verifyOn);
+        mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT)
+                .click();
+        Thread.sleep(SLEEP_TIME);
+        final String wifiValue = Settings.Global.getString(
+                InstrumentationRegistry.getTargetContext().getContentResolver(),
+                Settings.Global.WIFI_ON);
+        if (verifyOn) {
+            // 1 is Enabled, 2 is Enabled while airplane mode is ON.
+            assertThat(wifiValue).isAnyOf("1", "2");
+        } else {
+            assertThat(wifiValue).isEqualTo("0");
+        }
     }
 
     private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
-        WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
+        WifiManager wifiManager = (WifiManager) InstrumentationRegistry.getTargetContext()
                 .getSystemService(Context.WIFI_SERVICE);
         wifiManager.setWifiEnabled(wifiEnabled);
-        SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
+        SettingsHelper.launchSettingsPage(InstrumentationRegistry.getTargetContext(),
                 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;
-    }
 }
