diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 2f23c84..026853f 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -82,6 +82,7 @@
     public static class PublicVolumeSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiSettings2Activity extends SettingsActivity { /* empty */ }
+    public static class NetworkProviderSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ }
     public static class AvailableVirtualKeyboardActivity extends SettingsActivity { /* empty */ }
     public static class KeyboardLayoutPickerActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 6c6bc90..4a5d71a 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -112,6 +112,7 @@
 import com.android.settings.network.ApnSettings;
 import com.android.settings.network.MobileNetworkListFragment;
 import com.android.settings.network.NetworkDashboardFragment;
+import com.android.settings.network.NetworkProviderSettings;
 import com.android.settings.nfc.AndroidBeam;
 import com.android.settings.nfc.PaymentSettings;
 import com.android.settings.notification.ConfigureNotificationSettings;
@@ -303,7 +304,8 @@
             GestureNavigationSettingsFragment.class.getName(),
             InteractAcrossProfilesSettings.class.getName(),
             InteractAcrossProfilesDetails.class.getName(),
-            MediaControlsSettings.class.getName()
+            MediaControlsSettings.class.getName(),
+            NetworkProviderSettings.class.getName()
     };
 
     public static final String[] SETTINGS_FOR_RESTRICTED = {
@@ -324,6 +326,7 @@
             // Home page > Network & Internet
             Settings.WifiSettingsActivity.class.getName(),
             Settings.DataUsageSummaryActivity.class.getName(),
+            Settings.NetworkProviderSettingsActivity.class.getName(),
             // Home page > Connected devices
             Settings.BluetoothSettingsActivity.class.getName(),
             Settings.WifiDisplaySettingsActivity.class.getName(),
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
new file mode 100644
index 0000000..f6f19b5
--- /dev/null
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -0,0 +1,1149 @@
+/*
+ * Copyright (C) 2020 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.network;
+
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
+import static android.os.UserManager.DISALLOW_CONFIG_WIFI;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
+import android.net.NetworkTemplate;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.SimpleClock;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.LinkifyUtils;
+import com.android.settings.R;
+import com.android.settings.RestrictedSettingsFragment;
+import com.android.settings.SettingsActivity;
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.datausage.DataUsagePreference;
+import com.android.settings.datausage.DataUsageUtils;
+import com.android.settings.location.ScanningSettings;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.SwitchBarController;
+import com.android.settings.wifi.AddNetworkFragment;
+import com.android.settings.wifi.AddWifiNetworkPreference;
+import com.android.settings.wifi.ConfigureWifiEntryFragment;
+import com.android.settings.wifi.ConnectedWifiEntryPreference;
+import com.android.settings.wifi.LinkablePreference;
+import com.android.settings.wifi.WifiConfigUiBase2;
+import com.android.settings.wifi.WifiConnectListener;
+import com.android.settings.wifi.WifiDialog2;
+import com.android.settings.wifi.WifiEnabler;
+import com.android.settings.wifi.WifiUtils;
+import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
+import com.android.settings.wifi.dpp.WifiDppUtils;
+import com.android.settingslib.HelpUtils;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.search.Indexable;
+import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.wifi.LongPressWifiEntryPreference;
+import com.android.settingslib.wifi.WifiSavedConfigUtils;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+import java.time.ZoneOffset;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * UI for Mobile network and Wi-Fi network settings.
+ *
+ * TODO(b/167474581): Define the intent android.settings.NETWORK_PROVIDER_SETTINGS in Settings.java.
+ */
+@SearchIndexable
+public class NetworkProviderSettings extends RestrictedSettingsFragment
+        implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback,
+        WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener {
+
+    private static final String TAG = "NetworkProviderSettings";
+
+    // IDs of context menu
+    static final int MENU_ID_CONNECT = Menu.FIRST + 1;
+    @VisibleForTesting
+    static final int MENU_ID_DISCONNECT = Menu.FIRST + 2;
+    @VisibleForTesting
+    static final int MENU_ID_FORGET = Menu.FIRST + 3;
+    static final int MENU_ID_MODIFY = Menu.FIRST + 4;
+
+    // Max age of tracked WifiEntries
+    private static final long MAX_SCAN_AGE_MILLIS = 15_000;
+    // Interval between initiating WifiPickerTracker scans
+    private static final long SCAN_INTERVAL_MILLIS = 10_000;
+
+    @VisibleForTesting
+    static final int ADD_NETWORK_REQUEST = 2;
+    static final int CONFIG_NETWORK_REQUEST = 3;
+    static final int MANAGE_SUBSCRIPTION = 4;
+
+    private static final String PREF_KEY_EMPTY_WIFI_LIST = "wifi_empty_list";
+    // TODO(b/70983952): Rename these to use WifiEntry instead of AccessPoint.
+    private static final String PREF_KEY_CONNECTED_ACCESS_POINTS = "connected_access_point";
+    private static final String PREF_KEY_ACCESS_POINTS = "access_points";
+    private static final String PREF_KEY_CONFIGURE_WIFI_SETTINGS = "configure_wifi_settings";
+    private static final String PREF_KEY_SAVED_NETWORKS = "saved_networks";
+    private static final String PREF_KEY_STATUS_MESSAGE = "wifi_status_message";
+    @VisibleForTesting
+    static final String PREF_KEY_DATA_USAGE = "wifi_data_usage";
+
+    private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0;
+
+    public static final int WIFI_DIALOG_ID = 1;
+
+    // Instance state keys
+    private static final String SAVE_DIALOG_MODE = "dialog_mode";
+    private static final String SAVE_DIALOG_WIFIENTRY_KEY = "wifi_ap_key";
+
+    // Cache at onCreateContextMenu and use at onContextItemSelected. Don't use it in other methods.
+    private WifiEntry mSelectedWifiEntry;
+
+    // Save the dialog details
+    private int mDialogMode;
+    private String mDialogWifiEntryKey;
+    private WifiEntry mDialogWifiEntry;
+
+    // This boolean extra specifies whether to enable the Next button when connected. Used by
+    // account creation outside of setup wizard.
+    private static final String EXTRA_ENABLE_NEXT_ON_CONNECT = "wifi_enable_next_on_connect";
+
+    // Enable the Next button when a Wi-Fi network is connected.
+    private boolean mEnableNextOnConnection;
+
+    // This string extra specifies a network to open the connect dialog on, so the user can enter
+    // network credentials.  This is used by quick settings for secured networks, among other
+    // things.
+    private static final String EXTRA_START_CONNECT_SSID = "wifi_start_connect_ssid";
+    private String mOpenSsid;
+
+    private static boolean isVerboseLoggingEnabled() {
+        return WifiPickerTracker.isVerboseLoggingEnabled();
+    }
+
+    private final Runnable mUpdateWifiEntryPreferencesRunnable = () -> {
+        updateWifiEntryPreferences();
+    };
+    private final Runnable mHideProgressBarRunnable = () -> {
+        setProgressBarVisible(false);
+    };
+
+    protected WifiManager mWifiManager;
+    private WifiManager.ActionListener mConnectListener;
+    private WifiManager.ActionListener mSaveListener;
+    private WifiManager.ActionListener mForgetListener;
+
+    /**
+     * The state of {@link #isUiRestricted()} at {@link #onCreate(Bundle)}}. This is necessary to
+     * ensure that behavior is consistent if {@link #isUiRestricted()} changes. It could be changed
+     * by the Test DPC tool in AFW mode.
+     */
+    private boolean mIsRestricted;
+
+    private WifiEnabler mWifiEnabler;
+
+    // Worker thread used for WifiPickerTracker work
+    private HandlerThread mWorkerThread;
+
+    @VisibleForTesting
+    WifiPickerTracker mWifiPickerTracker;
+
+    private WifiDialog2 mDialog;
+
+    private View mProgressHeader;
+
+    private PreferenceCategory mConnectedWifiEntryPreferenceCategory;
+    private PreferenceCategory mWifiEntryPreferenceCategory;
+    @VisibleForTesting
+    AddWifiNetworkPreference mAddWifiNetworkPreference;
+    @VisibleForTesting
+    Preference mConfigureWifiSettingsPreference;
+    @VisibleForTesting
+    Preference mSavedNetworksPreference;
+    @VisibleForTesting
+    DataUsagePreference mDataUsagePreference;
+    private LinkablePreference mStatusMessagePreference;
+
+    /**
+     * Tracks whether the user initiated a connection via clicking in order to autoscroll to the
+     * network once connected.
+     */
+    private boolean mClickedConnect;
+
+    public NetworkProviderSettings() {
+        super(DISALLOW_CONFIG_WIFI);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        final Activity activity = getActivity();
+        if (activity != null) {
+            mProgressHeader = setPinnedHeaderView(R.layout.progress_header)
+                    .findViewById(R.id.progress_bar_animation);
+            setProgressBarVisible(false);
+
+            ((SettingsActivity) activity).getSwitchBar().setSwitchBarText(
+                    R.string.wifi_settings_primary_switch_title,
+                    R.string.wifi_settings_primary_switch_title);
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // TODO(b/37429702): Add animations and preference comparator back after initial screen is
+        // loaded (ODR).
+        setAnimationAllowed(false);
+
+        addPreferences();
+
+        mIsRestricted = isUiRestricted();
+    }
+
+    private void addPreferences() {
+        addPreferencesFromResource(R.xml.network_provider_settings);
+
+        mConnectedWifiEntryPreferenceCategory = findPreference(PREF_KEY_CONNECTED_ACCESS_POINTS);
+        mWifiEntryPreferenceCategory = findPreference(PREF_KEY_ACCESS_POINTS);
+        mConfigureWifiSettingsPreference = findPreference(PREF_KEY_CONFIGURE_WIFI_SETTINGS);
+        mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS);
+        mAddWifiNetworkPreference = new AddWifiNetworkPreference(getPrefContext());
+        mStatusMessagePreference = findPreference(PREF_KEY_STATUS_MESSAGE);
+        mDataUsagePreference = findPreference(PREF_KEY_DATA_USAGE);
+        mDataUsagePreference.setVisible(DataUsageUtils.hasWifiRadio(getContext()));
+        mDataUsagePreference.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(),
+                0 /*subId*/,
+                null /*service*/);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        final Context context = getContext();
+        mWorkerThread = new HandlerThread(TAG
+                + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
+                Process.THREAD_PRIORITY_BACKGROUND);
+        mWorkerThread.start();
+        final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) {
+            @Override
+            public long millis() {
+                return SystemClock.elapsedRealtime();
+            }
+        };
+        mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context,
+                context.getSystemService(WifiManager.class),
+                context.getSystemService(ConnectivityManager.class),
+                context.getSystemService(NetworkScoreManager.class),
+                new Handler(Looper.getMainLooper()),
+                mWorkerThread.getThreadHandler(),
+                elapsedRealtimeClock,
+                MAX_SCAN_AGE_MILLIS,
+                SCAN_INTERVAL_MILLIS,
+                this);
+
+        final Activity activity = getActivity();
+
+        if (activity != null) {
+            mWifiManager = getActivity().getSystemService(WifiManager.class);
+        }
+
+        mConnectListener = new WifiConnectListener(getActivity());
+
+        mSaveListener = new WifiManager.ActionListener() {
+            @Override
+            public void onSuccess() {
+            }
+
+            @Override
+            public void onFailure(int reason) {
+                Activity activity = getActivity();
+                if (activity != null) {
+                    Toast.makeText(activity,
+                            R.string.wifi_failed_save_message,
+                            Toast.LENGTH_SHORT).show();
+                }
+            }
+        };
+
+        mForgetListener = new WifiManager.ActionListener() {
+            @Override
+            public void onSuccess() {
+            }
+
+            @Override
+            public void onFailure(int reason) {
+                Activity activity = getActivity();
+                if (activity != null) {
+                    Toast.makeText(activity,
+                            R.string.wifi_failed_forget_message,
+                            Toast.LENGTH_SHORT).show();
+                }
+            }
+        };
+        registerForContextMenu(getListView());
+        setHasOptionsMenu(true);
+
+        if (savedInstanceState != null) {
+            mDialogMode = savedInstanceState.getInt(SAVE_DIALOG_MODE);
+            mDialogWifiEntryKey = savedInstanceState.getString(SAVE_DIALOG_WIFIENTRY_KEY);
+        }
+
+        // If we're supposed to enable/disable the Next button based on our current connection
+        // state, start it off in the right state.
+        final Intent intent = getActivity().getIntent();
+        mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false);
+
+        if (intent.hasExtra(EXTRA_START_CONNECT_SSID)) {
+            mOpenSsid = intent.getStringExtra(EXTRA_START_CONNECT_SSID);
+        }
+    }
+
+    @Override
+    public void onDestroyView() {
+        if (mWifiEnabler != null) {
+            mWifiEnabler.teardownSwitchController();
+        }
+        mWorkerThread.quit();
+
+        super.onDestroyView();
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        mWifiEnabler = createWifiEnabler();
+
+        if (mIsRestricted) {
+            restrictUi();
+        }
+    }
+
+    private void restrictUi() {
+        if (!isUiRestrictedByOnlyAdmin()) {
+            getEmptyTextView().setText(R.string.wifi_empty_list_user_restricted);
+        }
+        getPreferenceScreen().removeAll();
+    }
+
+    /**
+     * @return new WifiEnabler
+     */
+    private WifiEnabler createWifiEnabler() {
+        final SettingsActivity activity = (SettingsActivity) getActivity();
+        return new WifiEnabler(activity, new SwitchBarController(activity.getSwitchBar()),
+                mMetricsFeatureProvider);
+    }
+
+    @Override
+    public void onResume() {
+        final Activity activity = getActivity();
+        super.onResume();
+
+        // Because RestrictedSettingsFragment's onResume potentially requests authorization,
+        // which changes the restriction state, recalculate it.
+        final boolean alreadyImmutablyRestricted = mIsRestricted;
+        mIsRestricted = isUiRestricted();
+        if (!alreadyImmutablyRestricted && mIsRestricted) {
+            restrictUi();
+        }
+
+        if (mWifiEnabler != null) {
+            mWifiEnabler.resume(activity);
+        }
+
+        changeNextButtonState(mWifiPickerTracker.getConnectedWifiEntry() != null);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        if (mWifiEnabler != null) {
+            mWifiEnabler.pause();
+        }
+    }
+
+    @Override
+    public void onStop() {
+        getView().removeCallbacks(mUpdateWifiEntryPreferencesRunnable);
+        getView().removeCallbacks(mHideProgressBarRunnable);
+        super.onStop();
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == ADD_NETWORK_REQUEST) {
+            handleAddNetworkRequest(resultCode, data);
+            return;
+        } else if (requestCode == REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER) {
+            if (resultCode == Activity.RESULT_OK) {
+                if (mDialog != null) {
+                    mDialog.dismiss();
+                }
+            }
+            return;
+        } else if (requestCode == CONFIG_NETWORK_REQUEST) {
+            if (resultCode == Activity.RESULT_OK) {
+                final WifiConfiguration wifiConfiguration = data.getParcelableExtra(
+                        ConfigureWifiEntryFragment.NETWORK_CONFIG_KEY);
+                if (wifiConfiguration != null) {
+                    mWifiManager.connect(wifiConfiguration,
+                            new WifiConnectActionListener());
+                }
+            }
+            return;
+        } else if (requestCode == MANAGE_SUBSCRIPTION) {
+            //Do nothing
+            return;
+        }
+
+        final boolean formerlyRestricted = mIsRestricted;
+        mIsRestricted = isUiRestricted();
+        if (formerlyRestricted && !mIsRestricted
+                && getPreferenceScreen().getPreferenceCount() == 0) {
+            // De-restrict the ui
+            addPreferences();
+        }
+    }
+
+    @Override
+    protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
+        final RecyclerView.Adapter adapter = super.onCreateAdapter(preferenceScreen);
+        adapter.setHasStableIds(true);
+        return adapter;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.WIFI;
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        // If dialog has been shown, save its state.
+        if (mDialog != null) {
+            outState.putInt(SAVE_DIALOG_MODE, mDialogMode);
+            outState.putString(SAVE_DIALOG_WIFIENTRY_KEY, mDialogWifiEntryKey);
+        }
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) {
+        Preference preference = (Preference) view.getTag();
+        if (!(preference instanceof LongPressWifiEntryPreference)) {
+            // Do nothing.
+            return;
+        }
+
+        // Cache the WifiEntry for onContextItemSelected. Don't use it in other methods.
+        mSelectedWifiEntry = ((LongPressWifiEntryPreference) preference).getWifiEntry();
+
+        menu.setHeaderTitle(mSelectedWifiEntry.getTitle());
+        if (mSelectedWifiEntry.canConnect()) {
+            menu.add(Menu.NONE, MENU_ID_CONNECT, 0 /* order */, R.string.wifi_connect);
+        }
+
+        if (mSelectedWifiEntry.canDisconnect()) {
+            menu.add(Menu.NONE, MENU_ID_DISCONNECT, 0 /* order */,
+                    R.string.wifi_disconnect_button_text);
+        }
+
+        // "forget" for normal saved network. And "disconnect" for ephemeral network because it
+        // could only be disconnected and be put in blocklists so it won't be used again.
+        if (canForgetNetwork()) {
+            menu.add(Menu.NONE, MENU_ID_FORGET, 0 /* order */, R.string.forget);
+        }
+
+        WifiConfiguration config = mSelectedWifiEntry.getWifiConfiguration();
+        // Some configs are ineditable
+        if (WifiUtils.isNetworkLockedDown(getActivity(), config)) {
+            return;
+        }
+
+        if (mSelectedWifiEntry.isSaved() && mSelectedWifiEntry.getConnectedState()
+                != WifiEntry.CONNECTED_STATE_CONNECTED) {
+            menu.add(Menu.NONE, MENU_ID_MODIFY, 0 /* order */, R.string.wifi_modify);
+        }
+    }
+
+    private boolean canForgetNetwork() {
+        return mSelectedWifiEntry.canForget() && !WifiUtils.isNetworkLockedDown(getActivity(),
+                mSelectedWifiEntry.getWifiConfiguration());
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_ID_CONNECT:
+                connect(mSelectedWifiEntry, true /* editIfNoConfig */, false /* fullScreenEdit */);
+                return true;
+            case MENU_ID_DISCONNECT:
+                mSelectedWifiEntry.disconnect(null /* callback */);
+                return true;
+            case MENU_ID_FORGET:
+                forget(mSelectedWifiEntry);
+                return true;
+            case MENU_ID_MODIFY:
+                showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY);
+                return true;
+            default:
+                return super.onContextItemSelected(item);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(Preference preference) {
+        // If the preference has a fragment set, open that
+        if (preference.getFragment() != null) {
+            preference.setOnPreferenceClickListener(null);
+            return super.onPreferenceTreeClick(preference);
+        }
+
+        if (preference instanceof LongPressWifiEntryPreference) {
+            final WifiEntry selectedEntry =
+                    ((LongPressWifiEntryPreference) preference).getWifiEntry();
+
+            if (selectedEntry.shouldEditBeforeConnect()) {
+                launchConfigNewNetworkFragment(selectedEntry);
+                return true;
+            }
+
+            connect(selectedEntry, true /* editIfNoConfig */, true /* fullScreenEdit */);
+        } else if (preference == mAddWifiNetworkPreference) {
+            onAddNetworkPressed();
+        } else {
+            return super.onPreferenceTreeClick(preference);
+        }
+        return true;
+    }
+
+    private void showDialog(WifiEntry wifiEntry, int dialogMode) {
+        if (WifiUtils.isNetworkLockedDown(getActivity(), wifiEntry.getWifiConfiguration())
+                && wifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
+            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(),
+                    RestrictedLockUtilsInternal.getDeviceOwner(getActivity()));
+            return;
+        }
+
+        if (mDialog != null) {
+            removeDialog(WIFI_DIALOG_ID);
+            mDialog = null;
+        }
+
+        // Save the access point and edit mode
+        mDialogWifiEntry = wifiEntry;
+        mDialogWifiEntryKey = wifiEntry.getKey();
+        mDialogMode = dialogMode;
+
+        showDialog(WIFI_DIALOG_ID);
+    }
+
+    @Override
+    public Dialog onCreateDialog(int dialogId) {
+        switch (dialogId) {
+            case WIFI_DIALOG_ID:
+                // modify network
+                mDialog = WifiDialog2
+                        .createModal(getActivity(), this, mDialogWifiEntry, mDialogMode);
+                return mDialog;
+            default:
+                return super.onCreateDialog(dialogId);
+        }
+    }
+
+    @Override
+    public void onDialogShowing() {
+        super.onDialogShowing();
+        setOnDismissListener(this);
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        // We don't keep any dialog object when dialog was dismissed.
+        mDialog = null;
+        mDialogWifiEntry = null;
+        mDialogWifiEntryKey = null;
+    }
+
+    @Override
+    public int getDialogMetricsCategory(int dialogId) {
+        switch (dialogId) {
+            case WIFI_DIALOG_ID:
+                return SettingsEnums.DIALOG_WIFI_AP_EDIT;
+            default:
+                return 0;
+        }
+    }
+
+    /** Called when the state of Wifi has changed. */
+    @Override
+    public void onWifiStateChanged() {
+        if (mIsRestricted) {
+            return;
+        }
+        final int wifiState = mWifiPickerTracker.getWifiState();
+
+        if (isVerboseLoggingEnabled()) {
+            Log.i(TAG, "onWifiStateChanged called with wifi state: " + wifiState);
+        }
+
+        switch (wifiState) {
+            case WifiManager.WIFI_STATE_ENABLED:
+                updateWifiEntryPreferences();
+                break;
+
+            case WifiManager.WIFI_STATE_ENABLING:
+                removeConnectedWifiEntryPreference();
+                removeWifiEntryPreference();
+                addMessagePreference(R.string.wifi_starting);
+                setProgressBarVisible(true);
+                break;
+
+            case WifiManager.WIFI_STATE_DISABLING:
+                removeConnectedWifiEntryPreference();
+                removeWifiEntryPreference();
+                addMessagePreference(R.string.wifi_stopping);
+                break;
+
+            case WifiManager.WIFI_STATE_DISABLED:
+                setOffMessage();
+                setAdditionalSettingsSummaries();
+                setProgressBarVisible(false);
+                mClickedConnect = false;
+                break;
+        }
+    }
+
+    @Override
+    public void onWifiEntriesChanged() {
+        updateWifiEntryPreferencesDelayed();
+        changeNextButtonState(mWifiPickerTracker.getConnectedWifiEntry() != null);
+
+        // Edit the Wi-Fi network of specified SSID.
+        if (mOpenSsid != null) {
+            Optional<WifiEntry> matchedWifiEntry = mWifiPickerTracker.getWifiEntries().stream()
+                    .filter(wifiEntry -> TextUtils.equals(mOpenSsid, wifiEntry.getSsid()))
+                    .filter(wifiEntry -> wifiEntry.getSecurity() != WifiEntry.SECURITY_NONE
+                            && wifiEntry.getSecurity() != WifiEntry.SECURITY_OWE)
+                    .filter(wifiEntry -> !wifiEntry.isSaved()
+                            || isDisabledByWrongPassword(wifiEntry))
+                    .findFirst();
+            if (matchedWifiEntry.isPresent()) {
+                mOpenSsid = null;
+                launchConfigNewNetworkFragment(matchedWifiEntry.get());
+            }
+        }
+    }
+
+    @Override
+    public void onNumSavedNetworksChanged() {
+        if (isFinishingOrDestroyed()) {
+            return;
+        }
+        setAdditionalSettingsSummaries();
+    }
+
+    @Override
+    public void onNumSavedSubscriptionsChanged() {
+        if (isFinishingOrDestroyed()) {
+            return;
+        }
+        setAdditionalSettingsSummaries();
+    }
+
+    /**
+     * Updates WifiEntries from {@link WifiPickerTracker#getWifiEntries()}. Adds a delay to have
+     * progress bar displayed before starting to modify entries.
+     */
+    private void updateWifiEntryPreferencesDelayed() {
+        // Safeguard from some delayed event handling
+        if (getActivity() != null && !mIsRestricted
+                && mWifiPickerTracker.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
+            final View view = getView();
+            final Handler handler = view.getHandler();
+            if (handler != null && handler.hasCallbacks(mUpdateWifiEntryPreferencesRunnable)) {
+                return;
+            }
+            setProgressBarVisible(true);
+            view.postDelayed(mUpdateWifiEntryPreferencesRunnable, 300);
+        }
+    }
+
+    private void updateWifiEntryPreferences() {
+        // in case state has changed
+        if (mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED) {
+            return;
+        }
+
+        boolean hasAvailableWifiEntries = false;
+        mStatusMessagePreference.setVisible(false);
+        mWifiEntryPreferenceCategory.setVisible(true);
+
+        final WifiEntry connectedEntry = mWifiPickerTracker.getConnectedWifiEntry();
+        mConnectedWifiEntryPreferenceCategory.setVisible(connectedEntry != null);
+        if (connectedEntry != null) {
+            final LongPressWifiEntryPreference connectedPref =
+                    mConnectedWifiEntryPreferenceCategory.findPreference(connectedEntry.getKey());
+            if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) {
+                mConnectedWifiEntryPreferenceCategory.removeAll();
+                final ConnectedWifiEntryPreference pref =
+                        new ConnectedWifiEntryPreference(getPrefContext(), connectedEntry, this);
+                pref.setKey(connectedEntry.getKey());
+                pref.refresh();
+                mConnectedWifiEntryPreferenceCategory.addPreference(pref);
+                pref.setOnPreferenceClickListener(preference -> {
+                    if (connectedEntry.canSignIn()) {
+                        connectedEntry.signIn(null /* callback */);
+                    } else {
+                        launchNetworkDetailsFragment(pref);
+                    }
+                    return true;
+                });
+                pref.setOnGearClickListener(preference -> {
+                    launchNetworkDetailsFragment(pref);
+                });
+
+                if (mClickedConnect) {
+                    mClickedConnect = false;
+                    scrollToPreference(mConnectedWifiEntryPreferenceCategory);
+                }
+            }
+        } else {
+            mConnectedWifiEntryPreferenceCategory.removeAll();
+        }
+
+        int index = 0;
+        cacheRemoveAllPrefs(mWifiEntryPreferenceCategory);
+        List<WifiEntry> wifiEntries = mWifiPickerTracker.getWifiEntries();
+        for (WifiEntry wifiEntry : wifiEntries) {
+            hasAvailableWifiEntries = true;
+
+            String key = wifiEntry.getKey();
+            LongPressWifiEntryPreference pref =
+                    (LongPressWifiEntryPreference) getCachedPreference(key);
+            if (pref != null) {
+                if (pref.getWifiEntry() == wifiEntry) {
+                    pref.setOrder(index++);
+                    continue;
+                } else {
+                    // Create a new preference if the underlying WifiEntry object has changed
+                    removePreference(key);
+                }
+            }
+
+            pref = createLongPressWifiEntryPreference(wifiEntry);
+            pref.setKey(wifiEntry.getKey());
+            pref.setOrder(index++);
+            pref.refresh();
+
+            if (wifiEntry.getHelpUriString() != null) {
+                pref.setOnButtonClickListener(preference -> {
+                    openSubscriptionHelpPage(wifiEntry);
+                });
+            }
+            mWifiEntryPreferenceCategory.addPreference(pref);
+        }
+        removeCachedPrefs(mWifiEntryPreferenceCategory);
+
+        if (!hasAvailableWifiEntries) {
+            setProgressBarVisible(true);
+            Preference pref = new Preference(getPrefContext());
+            pref.setSelectable(false);
+            pref.setSummary(R.string.wifi_empty_list_wifi_on);
+            pref.setOrder(index++);
+            pref.setKey(PREF_KEY_EMPTY_WIFI_LIST);
+            mWifiEntryPreferenceCategory.addPreference(pref);
+        } else {
+            // Continuing showing progress bar for an additional delay to overlap with animation
+            getView().postDelayed(mHideProgressBarRunnable, 1700 /* delay millis */);
+        }
+
+        mAddWifiNetworkPreference.setOrder(index++);
+        mWifiEntryPreferenceCategory.addPreference(mAddWifiNetworkPreference);
+        setAdditionalSettingsSummaries();
+    }
+
+    private void launchNetworkDetailsFragment(LongPressWifiEntryPreference pref) {
+        final WifiEntry wifiEntry = pref.getWifiEntry();
+        final Context context = getContext();
+        final CharSequence title =
+                FeatureFlagUtils.isEnabled(context, FeatureFlags.WIFI_DETAILS_DATAUSAGE_HEADER)
+                        ? wifiEntry.getTitle()
+                        : context.getText(R.string.pref_title_network_details);
+
+        final Bundle bundle = new Bundle();
+        bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY, wifiEntry.getKey());
+
+        new SubSettingLauncher(context)
+                .setTitleText(title)
+                .setDestination(WifiNetworkDetailsFragment2.class.getName())
+                .setArguments(bundle)
+                .setSourceMetricsCategory(getMetricsCategory())
+                .launch();
+    }
+
+    @VisibleForTesting
+    LongPressWifiEntryPreference createLongPressWifiEntryPreference(WifiEntry wifiEntry) {
+        return new LongPressWifiEntryPreference(getPrefContext(), wifiEntry, this);
+    }
+
+    private void launchAddNetworkFragment() {
+        new SubSettingLauncher(getContext())
+                .setTitleRes(R.string.wifi_add_network)
+                .setDestination(AddNetworkFragment.class.getName())
+                .setSourceMetricsCategory(getMetricsCategory())
+                .setResultListener(this, ADD_NETWORK_REQUEST)
+                .launch();
+    }
+
+    /** Removes all preferences and hide the {@link #mConnectedWifiEntryPreferenceCategory}. */
+    private void removeConnectedWifiEntryPreference() {
+        mConnectedWifiEntryPreferenceCategory.removeAll();
+        mConnectedWifiEntryPreferenceCategory.setVisible(false);
+    }
+
+    private void removeWifiEntryPreference() {
+        mWifiEntryPreferenceCategory.removeAll();
+        mWifiEntryPreferenceCategory.setVisible(false);
+    }
+
+    @VisibleForTesting
+    void setAdditionalSettingsSummaries() {
+        mConfigureWifiSettingsPreference.setSummary(getString(
+                isWifiWakeupEnabled()
+                        ? R.string.wifi_configure_settings_preference_summary_wakeup_on
+                        : R.string.wifi_configure_settings_preference_summary_wakeup_off));
+
+        final int numSavedNetworks = mWifiPickerTracker.getNumSavedNetworks();
+        final int numSavedSubscriptions = mWifiPickerTracker.getNumSavedSubscriptions();
+        if (numSavedNetworks + numSavedSubscriptions > 0) {
+            mSavedNetworksPreference.setVisible(true);
+            mSavedNetworksPreference.setSummary(
+                    getSavedNetworkSettingsSummaryText(numSavedNetworks, numSavedSubscriptions));
+        } else {
+            mSavedNetworksPreference.setVisible(false);
+        }
+    }
+
+    private String getSavedNetworkSettingsSummaryText(
+            int numSavedNetworks, int numSavedSubscriptions) {
+        if (numSavedSubscriptions == 0) {
+            return getResources().getQuantityString(R.plurals.wifi_saved_access_points_summary,
+                    numSavedNetworks, numSavedNetworks);
+        } else if (numSavedNetworks == 0) {
+            return getResources().getQuantityString(
+                    R.plurals.wifi_saved_passpoint_access_points_summary,
+                    numSavedSubscriptions, numSavedSubscriptions);
+        } else {
+            final int numTotalEntries = numSavedNetworks + numSavedSubscriptions;
+            return getResources().getQuantityString(R.plurals.wifi_saved_all_access_points_summary,
+                    numTotalEntries, numTotalEntries);
+        }
+    }
+
+    private boolean isWifiWakeupEnabled() {
+        final Context context = getContext();
+        final PowerManager powerManager = context.getSystemService(PowerManager.class);
+        final ContentResolver contentResolver = context.getContentResolver();
+        return mWifiManager.isAutoWakeupEnabled()
+                && mWifiManager.isScanAlwaysAvailable()
+                && Settings.Global.getInt(contentResolver,
+                Settings.Global.AIRPLANE_MODE_ON, 0) == 0
+                && !powerManager.isPowerSaveMode();
+    }
+
+    private void setOffMessage() {
+        final CharSequence title = getText(R.string.wifi_empty_list_wifi_off);
+        // Don't use WifiManager.isScanAlwaysAvailable() to check the Wi-Fi scanning mode. Instead,
+        // read the system settings directly. Because when the device is in Airplane mode, even if
+        // Wi-Fi scanning mode is on, WifiManager.isScanAlwaysAvailable() still returns "off".
+        // TODO(b/149421497): Fix this?
+        final boolean wifiScanningMode = mWifiManager.isScanAlwaysAvailable();
+        final CharSequence description = wifiScanningMode ? getText(R.string.wifi_scan_notify_text)
+                : getText(R.string.wifi_scan_notify_text_scanning_off);
+        final LinkifyUtils.OnClickListener clickListener =
+                () -> new SubSettingLauncher(getContext())
+                        .setDestination(ScanningSettings.class.getName())
+                        .setTitleRes(R.string.location_scanning_screen_title)
+                        .setSourceMetricsCategory(getMetricsCategory())
+                        .launch();
+        mStatusMessagePreference.setText(title, description, clickListener);
+        removeConnectedWifiEntryPreference();
+        removeWifiEntryPreference();
+        mStatusMessagePreference.setVisible(true);
+    }
+
+    private void addMessagePreference(int messageId) {
+        mStatusMessagePreference.setTitle(messageId);
+        mStatusMessagePreference.setVisible(true);
+
+    }
+
+    protected void setProgressBarVisible(boolean visible) {
+        if (mProgressHeader != null) {
+            mProgressHeader.setVisibility(visible ? View.VISIBLE : View.GONE);
+        }
+    }
+
+    @VisibleForTesting
+    void handleAddNetworkRequest(int result, Intent data) {
+        if (result == Activity.RESULT_OK) {
+            handleAddNetworkSubmitEvent(data);
+        }
+    }
+
+    private void handleAddNetworkSubmitEvent(Intent data) {
+        final WifiConfiguration wifiConfiguration = data.getParcelableExtra(
+                AddNetworkFragment.WIFI_CONFIG_KEY);
+        if (wifiConfiguration != null) {
+            mWifiManager.save(wifiConfiguration, mSaveListener);
+        }
+    }
+
+    /**
+     * Called when "add network" button is pressed.
+     */
+    private void onAddNetworkPressed() {
+        launchAddNetworkFragment();
+    }
+
+    @Override
+    public int getHelpResource() {
+        return R.string.help_url_wifi;
+    }
+
+    /**
+     * Renames/replaces "Next" button when appropriate. "Next" button usually exists in
+     * Wi-Fi setup screens, not in usual wifi settings screen.
+     *
+     * @param enabled true when the device is connected to a wifi network.
+     */
+    @VisibleForTesting
+    void changeNextButtonState(boolean enabled) {
+        if (mEnableNextOnConnection && hasNextButton()) {
+            getNextButton().setEnabled(enabled);
+        }
+    }
+
+    @Override
+    public void onForget(WifiDialog2 dialog) {
+        forget(dialog.getWifiEntry());
+    }
+
+    @Override
+    public void onSubmit(WifiDialog2 dialog) {
+        final int dialogMode = dialog.getMode();
+        final WifiConfiguration config = dialog.getController().getConfig();
+        final WifiEntry wifiEntry = dialog.getWifiEntry();
+
+        if (dialogMode == WifiConfigUiBase2.MODE_MODIFY) {
+            if (config == null) {
+                Toast.makeText(getContext(), R.string.wifi_failed_save_message,
+                        Toast.LENGTH_SHORT).show();
+            } else {
+                mWifiManager.save(config, mSaveListener);
+            }
+        } else if (dialogMode == WifiConfigUiBase2.MODE_CONNECT
+                || (dialogMode == WifiConfigUiBase2.MODE_VIEW && wifiEntry.canConnect())) {
+            if (config == null) {
+                connect(wifiEntry, false /* editIfNoConfig */,
+                        false /* fullScreenEdit*/);
+            } else {
+                mWifiManager.connect(config, new WifiConnectActionListener());
+            }
+        }
+    }
+
+    @Override
+    public void onScan(WifiDialog2 dialog, String ssid) {
+        // Launch QR code scanner to join a network.
+        startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid),
+                REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER);
+    }
+
+    private void forget(WifiEntry wifiEntry) {
+        mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_FORGET);
+        wifiEntry.forget(null /* callback */);
+    }
+
+    @VisibleForTesting
+    void connect(WifiEntry wifiEntry, boolean editIfNoConfig, boolean fullScreenEdit) {
+        mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_CONNECT,
+                wifiEntry.isSaved());
+
+        // If it's an unsaved secure WifiEntry, it will callback
+        // ConnectCallback#onConnectResult with ConnectCallback#CONNECT_STATUS_FAILURE_NO_CONFIG
+        wifiEntry.connect(new WifiEntryConnectCallback(wifiEntry, editIfNoConfig,
+                fullScreenEdit));
+    }
+
+    private class WifiConnectActionListener implements WifiManager.ActionListener {
+        @Override
+        public void onSuccess() {
+            mClickedConnect = true;
+        }
+
+        @Override
+        public void onFailure(int reason) {
+            if (isFinishingOrDestroyed()) {
+                return;
+            }
+            Toast.makeText(getContext(), R.string.wifi_failed_connect_message, Toast.LENGTH_SHORT)
+                    .show();
+        }
+    };
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.network_provider_settings) {
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    final List<String> keys = super.getNonIndexableKeys(context);
+
+                    final WifiManager wifiManager = context.getSystemService(WifiManager.class);
+                    if (WifiSavedConfigUtils.getAllConfigsCount(context, wifiManager) == 0) {
+                        keys.add(PREF_KEY_SAVED_NETWORKS);
+                    }
+
+                    if (!DataUsageUtils.hasWifiRadio(context)) {
+                        keys.add(PREF_KEY_DATA_USAGE);
+                    }
+                    return keys;
+                }
+            };
+
+    private class WifiEntryConnectCallback implements ConnectCallback {
+        final WifiEntry mConnectWifiEntry;
+        final boolean mEditIfNoConfig;
+        final boolean mFullScreenEdit;
+
+        WifiEntryConnectCallback(WifiEntry connectWifiEntry, boolean editIfNoConfig,
+                boolean fullScreenEdit) {
+            mConnectWifiEntry = connectWifiEntry;
+            mEditIfNoConfig = editIfNoConfig;
+            mFullScreenEdit = fullScreenEdit;
+        }
+
+        @Override
+        public void onConnectResult(@ConnectStatus int status) {
+            if (isFinishingOrDestroyed()) {
+                return;
+            }
+
+            if (status == ConnectCallback.CONNECT_STATUS_SUCCESS) {
+                mClickedConnect = true;
+            } else if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
+                if (mEditIfNoConfig) {
+                    // Edit an unsaved secure Wi-Fi network.
+                    if (mFullScreenEdit) {
+                        launchConfigNewNetworkFragment(mConnectWifiEntry);
+                    } else {
+                        showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_CONNECT);
+                    }
+                }
+            } else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {
+                Toast.makeText(getContext(), R.string.wifi_failed_connect_message,
+                        Toast.LENGTH_SHORT).show();
+            }
+        }
+    }
+
+    private void launchConfigNewNetworkFragment(WifiEntry wifiEntry) {
+        final Bundle bundle = new Bundle();
+        bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY,
+                wifiEntry.getKey());
+        new SubSettingLauncher(getContext())
+                .setTitleText(wifiEntry.getTitle())
+                .setDestination(ConfigureWifiEntryFragment.class.getName())
+                .setArguments(bundle)
+                .setSourceMetricsCategory(getMetricsCategory())
+                .setResultListener(NetworkProviderSettings.this, CONFIG_NETWORK_REQUEST)
+                .launch();
+    }
+
+    /** Helper method to return whether a WifiEntry is disabled due to a wrong password */
+    private static boolean isDisabledByWrongPassword(WifiEntry wifiEntry) {
+        WifiConfiguration config = wifiEntry.getWifiConfiguration();
+        if (config == null) {
+            return false;
+        }
+        WifiConfiguration.NetworkSelectionStatus networkStatus =
+                config.getNetworkSelectionStatus();
+        if (networkStatus == null
+                || networkStatus.getNetworkSelectionStatus() == NETWORK_SELECTION_ENABLED) {
+            return false;
+        }
+        int reason = networkStatus.getNetworkSelectionDisableReason();
+        return WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD == reason;
+    }
+
+    @VisibleForTesting
+    void openSubscriptionHelpPage(WifiEntry wifiEntry) {
+        final Intent intent = getHelpIntent(getContext(), wifiEntry.getHelpUriString());
+        if (intent != null) {
+            try {
+                startActivityForResult(intent, MANAGE_SUBSCRIPTION);
+            } catch (ActivityNotFoundException e) {
+                Log.e(TAG, "Activity was not found for intent, " + intent.toString());
+            }
+        }
+    }
+
+    @VisibleForTesting
+    Intent getHelpIntent(Context context, String helpUrlString) {
+        return HelpUtils.getHelpIntent(context, helpUrlString, context.getClass().getName());
+    }
+}
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index 7b86936..2ed213b 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -41,7 +41,7 @@
 public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2,
         View.OnClickListener {
 
-    final static String WIFI_CONFIG_KEY = "wifi_config_key";
+    public static final String WIFI_CONFIG_KEY = "wifi_config_key";
     @VisibleForTesting
     final static int SUBMIT_BUTTON_ID = android.R.id.button1;
     @VisibleForTesting
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 7bc4063..5c7820c 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -88,6 +88,9 @@
 
 /**
  * UI for Wi-Fi settings screen
+ *
+ * TODO(b/167474581): This file will be deprecated at Android S, please merge your WifiSettings
+ * in change in {@link NetworkProviderSettings}.
  */
 @SearchIndexable
 public class WifiSettings extends RestrictedSettingsFragment
@@ -228,6 +231,17 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+            final Intent intent = new Intent("android.settings.NETWORK_PROVIDER_SETTINGS");
+            final Bundle extras = getActivity().getIntent().getExtras();
+            if (extras != null) {
+                intent.putExtras(extras);
+            }
+            getContext().startActivity(intent);
+            finish();
+            return;
+        }
+
         // TODO(b/37429702): Add animations and preference comparator back after initial screen is
         // loaded (ODR).
         setAnimationAllowed(false);
