diff --git a/src/com/android/phone/CellInfoUtil.java b/src/com/android/phone/CellInfoUtil.java
new file mode 100644
index 0000000..c0409d8
--- /dev/null
+++ b/src/com/android/phone/CellInfoUtil.java
@@ -0,0 +1,169 @@
+/*
+ * 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.phone;
+
+import android.telephony.CellIdentity;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.TelephonyManager;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.OperatorInfo;
+
+/**
+ * Add static Utility functions to get information from the CellInfo object.
+ * TODO: Modify {@link CellInfo} for simplify those functions
+ */
+public final class CellInfoUtil {
+    private static final String TAG = "NetworkSelectSetting";
+
+    private CellInfoUtil() {
+    }
+
+    /**
+     * Get the network type from a CellInfo. Network types include
+     * {@link TelephonyManager#NETWORK_TYPE_LTE}, {@link TelephonyManager#NETWORK_TYPE_UMTS},
+     * {@link TelephonyManager#NETWORK_TYPE_GSM}, {@link TelephonyManager#NETWORK_TYPE_CDMA} and
+     * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN}
+     * @return network types
+     */
+    public static int getNetworkType(CellInfo cellInfo) {
+        if (cellInfo instanceof CellInfoLte) {
+            return TelephonyManager.NETWORK_TYPE_LTE;
+        } else if (cellInfo instanceof CellInfoWcdma) {
+            return TelephonyManager.NETWORK_TYPE_UMTS;
+        } else if (cellInfo instanceof CellInfoGsm) {
+            return TelephonyManager.NETWORK_TYPE_GSM;
+        } else if (cellInfo instanceof CellInfoCdma) {
+            return TelephonyManager.NETWORK_TYPE_CDMA;
+        } else {
+            Log.e(TAG, "Invalid CellInfo type");
+            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        }
+    }
+
+    /**
+     * Get signal level as an int from 0..4.
+     * @return Signal strength level
+     */
+    public static int getLevel(CellInfo cellInfo) {
+        if (cellInfo instanceof CellInfoLte) {
+            return ((CellInfoLte) cellInfo).getCellSignalStrength().getLevel();
+        } else if (cellInfo instanceof CellInfoWcdma) {
+            return ((CellInfoWcdma) cellInfo).getCellSignalStrength().getLevel();
+        } else if (cellInfo instanceof CellInfoGsm) {
+            return ((CellInfoGsm) cellInfo).getCellSignalStrength().getLevel();
+        } else if (cellInfo instanceof CellInfoCdma) {
+            return ((CellInfoCdma) cellInfo).getCellSignalStrength().getLevel();
+        } else {
+            Log.e(TAG, "Invalid CellInfo type");
+            return 0;
+        }
+    }
+
+    /**
+     * Wrap a CellIdentity into a CellInfo.
+     */
+    public static CellInfo wrapCellInfoWithCellIdentity(CellIdentity cellIdentity) {
+        if (cellIdentity instanceof CellIdentityLte) {
+            CellInfoLte cellInfo = new CellInfoLte();
+            cellInfo.setCellIdentity((CellIdentityLte) cellIdentity);
+            return cellInfo;
+        } else if (cellIdentity instanceof CellIdentityCdma) {
+            CellInfoCdma cellInfo = new CellInfoCdma();
+            cellInfo.setCellIdentity((CellIdentityCdma) cellIdentity);
+            return cellInfo;
+        }  else if (cellIdentity instanceof CellIdentityWcdma) {
+            CellInfoWcdma cellInfo = new CellInfoWcdma();
+            cellInfo.setCellIdentity((CellIdentityWcdma) cellIdentity);
+            return cellInfo;
+        } else if (cellIdentity instanceof CellIdentityGsm) {
+            CellInfoGsm cellInfo = new CellInfoGsm();
+            cellInfo.setCellIdentity((CellIdentityGsm) cellIdentity);
+            return cellInfo;
+        } else {
+            Log.e(TAG, "Invalid CellInfo type");
+            return null;
+        }
+    }
+
+    /**
+     * Returns the title of the network obtained in the manual search.
+     *
+     * @param cellInfo contains the information of the network.
+     * @return Long Name if not null/empty, otherwise Short Name if not null/empty,
+     * else MCCMNC string.
+     */
+    public static String getNetworkTitle(CellInfo cellInfo) {
+        OperatorInfo oi = getOperatorInfoFromCellInfo(cellInfo);
+
+        if (!TextUtils.isEmpty(oi.getOperatorAlphaLong())) {
+            return oi.getOperatorAlphaLong();
+        } else if (!TextUtils.isEmpty(oi.getOperatorAlphaShort())) {
+            return oi.getOperatorAlphaShort();
+        } else {
+            BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+            return bidiFormatter.unicodeWrap(oi.getOperatorNumeric(), TextDirectionHeuristics.LTR);
+        }
+    }
+
+    /**
+     * Wrap a cell info into an operator info.
+     */
+    public static OperatorInfo getOperatorInfoFromCellInfo(CellInfo cellInfo) {
+        OperatorInfo oi;
+        if (cellInfo instanceof CellInfoLte) {
+            CellInfoLte lte = (CellInfoLte) cellInfo;
+            oi = new OperatorInfo(
+                    (String) lte.getCellIdentity().getOperatorAlphaLong(),
+                    (String) lte.getCellIdentity().getOperatorAlphaShort(),
+                    lte.getCellIdentity().getMobileNetworkOperator());
+        } else if (cellInfo instanceof CellInfoWcdma) {
+            CellInfoWcdma wcdma = (CellInfoWcdma) cellInfo;
+            oi = new OperatorInfo(
+                    (String) wcdma.getCellIdentity().getOperatorAlphaLong(),
+                    (String) wcdma.getCellIdentity().getOperatorAlphaShort(),
+                    wcdma.getCellIdentity().getMobileNetworkOperator());
+        } else if (cellInfo instanceof CellInfoGsm) {
+            CellInfoGsm gsm = (CellInfoGsm) cellInfo;
+            oi = new OperatorInfo(
+                    (String) gsm.getCellIdentity().getOperatorAlphaLong(),
+                    (String) gsm.getCellIdentity().getOperatorAlphaShort(),
+                    gsm.getCellIdentity().getMobileNetworkOperator());
+        } else if (cellInfo instanceof CellInfoCdma) {
+            CellInfoCdma cdma = (CellInfoCdma) cellInfo;
+            oi = new OperatorInfo(
+                    (String) cdma.getCellIdentity().getOperatorAlphaLong(),
+                    (String) cdma.getCellIdentity().getOperatorAlphaShort(),
+                    "" /* operator numeric */);
+        } else {
+            Log.e(TAG, "Invalid CellInfo type");
+            oi = new OperatorInfo("", "", "");
+        }
+        return oi;
+    }
+}
diff --git a/src/com/android/phone/NetworkOperatorPreference.java b/src/com/android/phone/NetworkOperatorPreference.java
new file mode 100644
index 0000000..f29c038
--- /dev/null
+++ b/src/com/android/phone/NetworkOperatorPreference.java
@@ -0,0 +1,127 @@
+/*
+ * 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.phone;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.preference.Preference;
+import android.telephony.CellInfo;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.Gravity;
+
+import com.android.settingslib.graph.SignalDrawable;
+
+/**
+ * A Preference represents a network operator in the NetworkSelectSetting fragment.
+ */
+public class NetworkOperatorPreference extends Preference {
+
+    private static final String TAG = "NetworkOperatorPref";
+    private static final boolean DBG = true;
+    // number of signal strength level
+    public static final int NUMBER_OF_LEVELS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+    private CellInfo mCellInfo;
+    private int mLevel = -1;
+
+    // The following constants are used to draw signal icon.
+    private static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
+    private static final int NO_CELL_DATA_CONNECTED_ICON = 0;
+
+    public NetworkOperatorPreference(CellInfo cellinfo, Context context) {
+        super(context);
+        mCellInfo = cellinfo;
+        refresh();
+    }
+
+    public CellInfo getCellInfo() {
+        return mCellInfo;
+    }
+
+    /**
+     * Refresh the NetworkOperatorPreference by updating the title and the icon.
+     */
+    public void refresh() {
+        if (DBG) Log.d(TAG, "refresh the network: " + CellInfoUtil.getNetworkTitle(mCellInfo));
+        setTitle(CellInfoUtil.getNetworkTitle(mCellInfo));
+        int level = CellInfoUtil.getLevel(mCellInfo);
+        if (DBG) Log.d(TAG, "refresh level: " + String.valueOf(level));
+        if (mLevel != level) {
+            mLevel = level;
+            updateIcon(mLevel);
+        }
+    }
+
+    /**
+     * Update the icon according to the input signal strength level.
+     */
+    public void setIcon(int level) {
+        updateIcon(level);
+    }
+
+    private int getIconId(int networkType) {
+        if (networkType == TelephonyManager.NETWORK_TYPE_CDMA) {
+            return R.drawable.signal_strength_1x;
+        } else if (networkType == TelephonyManager.NETWORK_TYPE_LTE) {
+            return R.drawable.signal_strength_lte;
+        } else if (networkType == TelephonyManager.NETWORK_TYPE_UMTS) {
+            return R.drawable.signal_strength_3g;
+        } else if (networkType == TelephonyManager.NETWORK_TYPE_GSM) {
+            return R.drawable.signal_strength_g;
+        } else {
+            return 0;
+        }
+    }
+
+    private void updateIcon(int level) {
+        if (level < 0 || level >= NUMBER_OF_LEVELS) return;
+        Context context = getContext();
+        // Make the signal strength drawable
+        int iconId = 0;
+        if (DBG) Log.d(TAG, "updateIcon level: " + String.valueOf(level));
+        iconId = SignalDrawable.getState(level, NUMBER_OF_LEVELS, false /* cutOut */);
+
+        SignalDrawable signalDrawable = new SignalDrawable(getContext());
+        signalDrawable.setLevel(iconId);
+        signalDrawable.setDarkIntensity(0);
+
+        // Make the network type drawable
+        int iconType = getIconId(CellInfoUtil.getNetworkType(mCellInfo));
+        Drawable networkDrawable =
+                iconType == NO_CELL_DATA_CONNECTED_ICON
+                        ? EMPTY_DRAWABLE
+                        : getContext()
+                        .getResources().getDrawable(iconType, getContext().getTheme());
+
+        // Overlay the two drawables
+        Drawable[] layers = {networkDrawable, signalDrawable};
+        final int iconSize =
+                context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size);
+
+        LayerDrawable icons = new LayerDrawable(layers);
+        // Set the network type icon at the top left
+        icons.setLayerGravity(0 /* index of networkDrawable */, Gravity.TOP | Gravity.LEFT);
+        // Set the signal strength icon at the bottom right
+        icons.setLayerGravity(1 /* index of SignalDrawable */, Gravity.BOTTOM | Gravity.RIGHT);
+        icons.setLayerSize(1 /* index of SignalDrawable */, iconSize, iconSize);
+        setIcon(icons);
+    }
+}
diff --git a/src/com/android/phone/NetworkOperators.java b/src/com/android/phone/NetworkOperators.java
index c39937e..babd283 100644
--- a/src/com/android/phone/NetworkOperators.java
+++ b/src/com/android/phone/NetworkOperators.java
@@ -18,6 +18,7 @@
 
 import android.app.ProgressDialog;
 import android.content.Context;
+import android.content.Intent;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
@@ -51,6 +52,7 @@
     //String keys for preference lookup
     public static final String BUTTON_NETWORK_SELECT_KEY = "button_network_select_key";
     public static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
+    public static final String BUTTON_CHOOSE_NETWORK_KEY = "button_choose_network_key";
     public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
 
     int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
@@ -59,10 +61,15 @@
     //preference objects
     private NetworkSelectListPreference mNetworkSelect;
     private TwoStatePreference mAutoSelect;
+    private Preference mChooseNetwork;
 
     private int mSubId;
     private ProgressDialog mProgressDialog;
 
+    // There's two sets of Auto-Select UI in this class. {@link mNetworkSelect} is used for all
+    // pre-Pixel 3 devices, while {@link mChooseNetwork} is used for all devices after Pixel3.
+    boolean mEnableNewManualSelectNetworkUI;
+
     public NetworkOperators(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -75,10 +82,16 @@
      * Initialize NetworkOperators instance.
      */
     public void initialize() {
-        mNetworkSelect =
-                (NetworkSelectListPreference) findPreference(BUTTON_NETWORK_SELECT_KEY);
-        mAutoSelect =
-                (TwoStatePreference) findPreference(BUTTON_AUTO_SELECT_KEY);
+        mEnableNewManualSelectNetworkUI = getContext().getResources().getBoolean(
+                com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
+        mAutoSelect = (TwoStatePreference) findPreference(BUTTON_AUTO_SELECT_KEY);
+        mChooseNetwork = findPreference(BUTTON_CHOOSE_NETWORK_KEY);
+        mNetworkSelect = (NetworkSelectListPreference) findPreference(BUTTON_NETWORK_SELECT_KEY);
+        if (mEnableNewManualSelectNetworkUI) {
+            this.removePreference(mNetworkSelect);
+        } else {
+            this.removePreference(mChooseNetwork);
+        }
         mProgressDialog = new ProgressDialog(getContext());
     }
 
@@ -96,10 +109,22 @@
             mAutoSelect.setOnPreferenceChangeListener(this);
         }
 
-        if (mNetworkSelect != null) {
-            mNetworkSelect.initialize(mSubId, queryService, this, mProgressDialog);
+        if (mEnableNewManualSelectNetworkUI) {
+            if (mChooseNetwork != null) {
+                TelephonyManager telephonyManager = (TelephonyManager)
+                        getContext().getSystemService(Context.TELEPHONY_SERVICE);
+                logd("data connection status " + telephonyManager.getDataState());
+                if (telephonyManager.getDataState() == telephonyManager.DATA_CONNECTED) {
+                    mChooseNetwork.setSummary(telephonyManager.getNetworkOperatorName());
+                } else {
+                    mChooseNetwork.setSummary(R.string.network_disconnected);
+                }
+            }
+        } else {
+            if (mNetworkSelect != null) {
+                mNetworkSelect.initialize(mSubId, queryService, this, mProgressDialog);
+            }
         }
-
         getNetworkSelectionMode();
     }
 
@@ -114,6 +139,7 @@
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         if (preference == mAutoSelect) {
             boolean autoSelect = (Boolean) newValue;
+            logd("onPreferenceChange autoSelect: " + String.valueOf(autoSelect));
             selectNetworkAutomatic(autoSelect);
             MetricsLogger.action(getContext(),
                     MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE, autoSelect);
@@ -156,8 +182,14 @@
                             if (mAutoSelect != null) {
                                 mAutoSelect.setChecked(autoSelect);
                             }
-                            if (mNetworkSelect != null) {
-                                mNetworkSelect.setEnabled(!autoSelect);
+                            if (mEnableNewManualSelectNetworkUI) {
+                                if (mChooseNetwork != null) {
+                                    mChooseNetwork.setEnabled(!autoSelect);
+                                }
+                            } else {
+                                if (mNetworkSelect != null) {
+                                    mNetworkSelect.setEnabled(!autoSelect);
+                                }
                             }
                         } catch (Exception e) {
                             if (DBG) loge("get network selection mode: unable to parse result.");
@@ -172,10 +204,9 @@
     // Used by both mAutoSelect and mNetworkSelect buttons.
     protected void displayNetworkSelectionFailed(Throwable ex) {
         String status;
-
         if ((ex != null && ex instanceof CommandException)
                 && ((CommandException) ex).getCommandError()
-                        == CommandException.Error.ILLEGAL_SIM_OR_ME) {
+                == CommandException.Error.ILLEGAL_SIM_OR_ME) {
             status = getContext().getResources().getString(R.string.not_allowed);
         } else {
             status = getContext().getResources().getString(R.string.connect_later);
@@ -210,9 +241,17 @@
     }
 
     private void selectNetworkAutomatic(boolean autoSelect) {
-        if (mNetworkSelect != null) {
-            mNetworkSelect.setEnabled(!autoSelect);
+        logd("selectNetworkAutomatic: " + String.valueOf(autoSelect));
+        if (mEnableNewManualSelectNetworkUI) {
+            if (mChooseNetwork != null) {
+                mChooseNetwork.setEnabled(!autoSelect);
+            }
+        } else {
+            if (mNetworkSelect != null) {
+                mNetworkSelect.setEnabled(!autoSelect);
+            }
         }
+
         if (autoSelect) {
             if (DBG) logd("select network automatically...");
             showAutoSelectProgressBar();
@@ -222,8 +261,17 @@
             if (phone != null) {
                 phone.setNetworkSelectionModeAutomatic(msg);
             }
-        } else if (mNetworkSelect != null) {
-            mNetworkSelect.onClick();
+        } else {
+            if (mEnableNewManualSelectNetworkUI) {
+                if (mChooseNetwork != null) {
+                    // Open the choose Network page automatically when user turn off the auto-select
+                    openChooseNetworkPage();
+                }
+            } else {
+                if (mNetworkSelect != null) {
+                    mNetworkSelect.onClick();
+                }
+            }
         }
     }
 
@@ -251,8 +299,24 @@
         mProgressDialog.show();
     }
 
+    /**
+     * Open the Choose netwotk page via {@alink NetworkSelectSettingActivity}
+     */
+    public void openChooseNetworkPage() {
+        Intent intent = NetworkSelectSettingActivity.getIntent(getContext(), mPhoneId);
+        getContext().startActivity(intent);
+    }
+
     protected boolean preferenceTreeClick(Preference preference) {
-        return (preference == mAutoSelect || preference == mNetworkSelect);
+        if (mEnableNewManualSelectNetworkUI) {
+            logd("enable New AutoSelectNetwork UI");
+            if (preference == mChooseNetwork) {
+                openChooseNetworkPage();
+            }
+            return (preference == mAutoSelect || preference == mChooseNetwork);
+        } else {
+            return (preference == mAutoSelect || preference == mNetworkSelect);
+        }
     }
 
     private void logd(String msg) {
@@ -262,4 +326,4 @@
     private void loge(String msg) {
         Log.e(LOG_TAG, "[NetworksList] " + msg);
     }
-}
+}
\ No newline at end of file
diff --git a/src/com/android/phone/NetworkSelectSetting.java b/src/com/android/phone/NetworkSelectSetting.java
new file mode 100644
index 0000000..7ef3dea
--- /dev/null
+++ b/src/com/android/phone/NetworkSelectSetting.java
@@ -0,0 +1,634 @@
+/*
+ * 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.phone;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.metrics.LogMaker;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.CellIdentity;
+import android.telephony.CellInfo;
+import android.telephony.NetworkRegistrationState;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.telephony.OperatorInfo;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * "Choose network" settings UI for the Phone app.
+ */
+public class NetworkSelectSetting extends PreferenceFragment {
+
+    private static final String TAG = "NetworkSelectSetting";
+    private static final boolean DBG = true;
+
+    private static final int EVENT_NETWORK_SELECTION_DONE = 1;
+    private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
+    private static final int EVENT_NETWORK_SCAN_ERROR = 3;
+    private static final int EVENT_NETWORK_SCAN_COMPLETED = 4;
+
+    private static final String PREF_KEY_CONNECTED_NETWORK_OPERATOR =
+            "connected_network_operator_preference";
+    private static final String PREF_KEY_NETWORK_OPERATORS = "network_operators_preference";
+
+    // used to add/remove NetworkOperatorsPreference.
+    private PreferenceCategory mNetworkOperatorsPreferences;
+    // used to add/remove connected NetworkOperatorPreference.
+    private PreferenceCategory mConnectedNetworkOperatorsPreference;
+    // manage the progress bar on the top of the page.
+    private View mProgressHeader;
+    private Preference mStatusMessagePreference;
+    private List<CellInfo> mCellInfoList;
+    private int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
+    private ViewGroup mFrameLayout;
+    private NetworkOperatorPreference mSelectedNetworkOperatorPreference;
+    private TelephonyManager mTelephonyManager;
+    private NetworkOperators mNetworkOperators;
+
+    private final Runnable mUpdateNetworkOperatorsRunnable = () -> {
+        updateNetworkOperatorsPreferenceCategory();
+    };
+
+    /**
+     * Create a new instance of this fragment.
+     */
+    public static NetworkSelectSetting newInstance(int phoneId) {
+        Bundle args = new Bundle();
+        args.putInt(NetworkSelectSettingActivity.KEY_PHONE_ID, phoneId);
+        NetworkSelectSetting fragment = new NetworkSelectSetting();
+        fragment.setArguments(args);
+
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        logd("onCreate");
+        super.onCreate(icicle);
+
+        mPhoneId = getArguments().getInt(NetworkSelectSettingActivity.KEY_PHONE_ID);
+
+        addPreferencesFromResource(R.xml.choose_network);
+        mConnectedNetworkOperatorsPreference =
+                (PreferenceCategory) findPreference(PREF_KEY_CONNECTED_NETWORK_OPERATOR);
+        mNetworkOperatorsPreferences =
+                (PreferenceCategory) findPreference(PREF_KEY_NETWORK_OPERATORS);
+        mStatusMessagePreference = new Preference(getContext());
+        mSelectedNetworkOperatorPreference = null;
+        mTelephonyManager = (TelephonyManager)
+                getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mNetworkOperators = new NetworkOperators(getContext());
+        setRetainInstance(true);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        logd("onViewCreated");
+        super.onViewCreated(view, savedInstanceState);
+
+        if (getListView() != null) {
+            getListView().setDivider(null);
+        }
+        // Inflate progress bar
+        final Activity activity = getActivity();
+        if (activity != null) {
+            mFrameLayout = activity.findViewById(R.id.choose_network_content);
+            final LayoutInflater inflater = activity.getLayoutInflater();
+            final View pinnedHeader =
+                    inflater.inflate(R.layout.choose_network_progress_header, mFrameLayout, false);
+            mFrameLayout.addView(pinnedHeader);
+            mFrameLayout.setVisibility(View.VISIBLE);
+            mProgressHeader = pinnedHeader.findViewById(R.id.progress_bar_animation);
+            setProgressBarVisible(false);
+        }
+        forceConfigConnectedNetworkOperatorsPreferenceCategory();
+    }
+
+    @Override
+    public void onStart() {
+        if (DBG) logd("onStart");
+        super.onStart();
+
+        // Bind the NetworkQueryService
+        bindNetworkQueryService();
+    }
+
+    /**
+     * Invoked on each preference click in this hierarchy, overrides
+     * PreferenceActivity's implementation.  Used to make sure we track the
+     * preference click events.
+     * Since the connected network operator is either faked (when no data connection) or already
+     * connected, we do not allow user to click the connected network operator.
+     */
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+                                         Preference preference) {
+        if (DBG) logd("User clicked the screen");
+        stopNetworkQuery();
+        setProgressBarVisible(false);
+        if (preference instanceof  NetworkOperatorPreference) {
+            // Refresh the last selected item in case users reselect network.
+            if (mSelectedNetworkOperatorPreference != null) {
+                mSelectedNetworkOperatorPreference.setSummary("");
+            }
+
+            mSelectedNetworkOperatorPreference = (NetworkOperatorPreference) preference;
+            CellInfo cellInfo = mSelectedNetworkOperatorPreference.getCellInfo();
+            if (DBG) logd("User click a NetworkOperatorPreference: " + cellInfo.toString());
+
+            // Send metrics event
+            final LogMaker logMaker = new LogMaker(
+                    MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK)
+                    .setType(MetricsProto.MetricsEvent.TYPE_ACTION);
+            if (CellInfoUtil.getNetworkTitle(cellInfo) != null) {
+                // Since operator list is loaded dynamically from modem, we cannot know which
+                // network user chooses if we only record integer index of newValue. So a new tag
+                // and a string value (network) is added in this MetricsEvent.
+                logMaker.addTaggedData(MetricsProto.MetricsEvent.FIELD_MOBILE_NETWORK,
+                        CellInfoUtil.getNetworkTitle(cellInfo));
+            }
+            MetricsLogger.action(logMaker);
+
+            // Connect to the network
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
+            Phone phone = PhoneFactory.getPhone(mPhoneId);
+            if (phone != null) {
+                if (DBG) {
+                    logd("Connect to the network: " + CellInfoUtil.getNetworkTitle(cellInfo));
+                }
+                // Set summary as "Connecting" to the selected network.
+                mSelectedNetworkOperatorPreference.setSummary(R.string.network_connecting);
+
+                // Set summary as "Disconnected" to the previously connected network
+                if (mConnectedNetworkOperatorsPreference.getPreferenceCount() > 0) {
+                    NetworkOperatorPreference connectedNetworkOperator = (NetworkOperatorPreference)
+                            (mConnectedNetworkOperatorsPreference.getPreference(0));
+                    if (!CellInfoUtil.getNetworkTitle(cellInfo).equals(
+                            CellInfoUtil.getNetworkTitle(connectedNetworkOperator.getCellInfo()))) {
+                        connectedNetworkOperator.setSummary(R.string.network_disconnected);
+                    }
+                }
+
+                // Select network manually via Phone
+                OperatorInfo operatorInfo = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo);
+                if (DBG) logd("manually selected network operator: " + operatorInfo.toString());
+                phone.selectNetworkManually(operatorInfo, true, msg);
+                setProgressBarVisible(true);
+                return true;
+            } else {
+                loge("Error selecting network. phone is null.");
+                mSelectedNetworkOperatorPreference = null;
+                return false;
+            }
+
+        } else {
+            preferenceScreen.setEnabled(false);
+            return false;
+        }
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        if (!(getActivity() instanceof NetworkSelectSettingActivity)) {
+            throw new IllegalStateException("Parent activity is not NetworkSelectSettingActivity");
+        }
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        if (DBG) logd("onStop");
+        getView().removeCallbacks(mUpdateNetworkOperatorsRunnable);
+        stopNetworkQuery();
+        // Unbind the NetworkQueryService
+        unbindNetworkQueryService();
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_NETWORK_SELECTION_DONE:
+                    if (DBG) logd("network selection done: hide the progress header");
+                    setProgressBarVisible(false);
+
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        mNetworkOperators.displayNetworkSelectionFailed(ar.exception);
+                        // Set summary as "Couldn't connect" to the selected network.
+                        mSelectedNetworkOperatorPreference.setSummary(
+                                R.string.network_could_not_connect);
+                    } else {
+                        if (DBG) logd("manual network selection: succeeded! ");
+                        mNetworkOperators.displayNetworkSelectionSucceeded(msg.arg1);
+                        // Set summary as "Connected" to the selected network.
+                        mSelectedNetworkOperatorPreference.setSummary(R.string.network_connected);
+                    }
+                    break;
+
+                case EVENT_NETWORK_SCAN_RESULTS:
+                    List<CellInfo> results = aggregateCellInfoList((List<CellInfo>) msg.obj);
+                    mCellInfoList = new ArrayList<>(results);
+                    if (DBG) logd("after aggregate: " + mCellInfoList.toString());
+                    if (mCellInfoList != null && mCellInfoList.size() != 0) {
+                        updateNetworkOperators();
+                    } else {
+                        addMessagePreference(R.string.empty_networks_list);
+                    }
+
+                    break;
+
+                case EVENT_NETWORK_SCAN_ERROR:
+                    int error = msg.arg1;
+                    if (DBG) logd("error while querying available networks " + error);
+                    stopNetworkQuery();
+                    addMessagePreference(R.string.network_query_error);
+                    break;
+
+                case EVENT_NETWORK_SCAN_COMPLETED:
+                    stopNetworkQuery();
+                    if (DBG) logd("scan complete");
+                    setProgressBarVisible(false);
+                    if (mCellInfoList == null) {
+                        // In case the scan timeout before getting any results
+                        addMessagePreference(R.string.empty_networks_list);
+                    }
+                    break;
+            }
+            return;
+        }
+    };
+
+    private void loadNetworksList() {
+        if (DBG) logd("load networks list...");
+        setProgressBarVisible(true);
+        try {
+            if (mNetworkQueryService != null) {
+                if (DBG) logd("start network query");
+                mNetworkQueryService
+                        .startNetworkQuery(mCallback, mPhoneId, true /* is incremental result */);
+            } else {
+                if (DBG) logd("unable to start network query, mNetworkQueryService is null");
+                addMessagePreference(R.string.network_query_error);
+            }
+        } catch (RemoteException e) {
+            loge("loadNetworksList: exception from startNetworkQuery " + e);
+            addMessagePreference(R.string.network_query_error);
+        }
+    }
+
+    /**
+     * This implementation of INetworkQueryServiceCallback is used to receive
+     * callback notifications from the network query service.
+     */
+    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
+
+        /** Returns the scan results to the user, this callback will be called at lease one time. */
+        public void onResults(List<CellInfo> results) {
+            if (DBG) logd("get scan results.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
+            msg.sendToTarget();
+        }
+
+        /**
+         * Informs the user that the scan has stopped.
+         *
+         * This callback will be called when the scan is finished or cancelled by the user.
+         * The related NetworkScanRequest will be deleted after this callback.
+         */
+        public void onComplete() {
+            if (DBG) logd("network scan completed.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
+            msg.sendToTarget();
+        }
+
+        /**
+         * Informs the user that there is some error about the scan.
+         *
+         * This callback will be called whenever there is any error about the scan, and the scan
+         * will be terminated. onComplete() will NOT be called.
+         */
+        public void onError(int error) {
+            if (DBG) logd("get onError callback with error code: " + error);
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR, error, 0 /* arg2 */);
+            msg.sendToTarget();
+        }
+    };
+
+    /**
+     * Updates network operators from {@link INetworkQueryServiceCallback#onResults()}.
+     */
+    private void updateNetworkOperators() {
+        if (DBG) logd("updateNetworkOperators");
+        if (getActivity() != null) {
+            final View view = getView();
+            final Handler handler = view.getHandler();
+            if (handler != null && handler.hasCallbacks(mUpdateNetworkOperatorsRunnable)) {
+                return;
+            }
+            view.post(mUpdateNetworkOperatorsRunnable);
+        }
+    }
+
+    /**
+     * Update the currently available network operators list, which only contains the unregistered
+     * network operators. So if the device has no data and the network operator in the connected
+     * network operator category shows "Disconnected", it will also exist in the available network
+     * operator category for user to select. On the other hand, if the device has data and the
+     * network operator in the connected network operator category shows "Connected", it will not
+     * exist in the available network category.
+     */
+    private void updateNetworkOperatorsPreferenceCategory() {
+        mNetworkOperatorsPreferences.removeAll();
+
+        configConnectedNetworkOperatorsPreferenceCategory();
+        for (int index = 0; index < mCellInfoList.size(); index++) {
+            if (!mCellInfoList.get(index).isRegistered()) {
+                NetworkOperatorPreference pref =
+                        new NetworkOperatorPreference(mCellInfoList.get(index), getContext());
+                pref.setKey(CellInfoUtil.getNetworkTitle(mCellInfoList.get(index)));
+                pref.setOrder(index);
+                mNetworkOperatorsPreferences.addPreference(pref);
+            }
+        }
+    }
+
+    /**
+     * Config the connected network operator preference when the page was created. When user get
+     * into this page, the device might or might not have data connection.
+     *   - If the device has data:
+     *     1. use {@code ServiceState#getNetworkRegistrationStates()} to get the currently
+     *        registered cellIdentity, wrap it into a CellInfo;
+     *     2. set the signal strength level as strong;
+     *     3. use {@link TelephonyManager#getNetworkOperatorName()} to get the title of the
+     *        previously connected network operator, since the CellIdentity got from step 1 only has
+     *        PLMN.
+     *   - If the device has no data, we will remove the connected network operators list from the
+     *     screen.
+     */
+    private void forceConfigConnectedNetworkOperatorsPreferenceCategory() {
+        if (DBG) logd("Force config ConnectedNetworkOperatorsPreferenceCategory");
+        if (mTelephonyManager.getDataState() == mTelephonyManager.DATA_CONNECTED) {
+            // Try to get the network registration states
+            ServiceState ss = mTelephonyManager.getServiceStateForSubscriber(mPhoneId);
+            List<NetworkRegistrationState> networkList =
+                    ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WWAN);
+            if (networkList == null || networkList.size() == 0) {
+                loge("getNetworkRegistrationStates return null");
+                // Remove the connected network operators category
+                removeConnectedNetworkOperatorPreference();
+                return;
+            }
+            CellIdentity cellIdentity = networkList.get(0).getCellIdentity();
+            CellInfo cellInfo = CellInfoUtil.wrapCellInfoWithCellIdentity(cellIdentity);
+            if (cellInfo != null) {
+                if (DBG) logd("Currently registered cell: " + cellInfo.toString());
+                NetworkOperatorPreference pref =
+                        new NetworkOperatorPreference(cellInfo, getContext());
+                pref.setTitle(mTelephonyManager.getNetworkOperatorName());
+                pref.setSummary(R.string.network_connected);
+                // Update the signal strength icon, since the default signalStrength value would be
+                // zero (it would be quite confusing why the connected network has no signal)
+                pref.setIcon(NetworkOperatorPreference.NUMBER_OF_LEVELS - 1);
+
+                mConnectedNetworkOperatorsPreference.addPreference(pref);
+            } else {
+                loge("Invalid CellIfno: " + cellInfo.toString());
+                // Remove the connected network operators category
+                removeConnectedNetworkOperatorPreference();
+            }
+        } else {
+            if (DBG) logd("No currently registered cell");
+            // Remove the connected network operators category
+            removeConnectedNetworkOperatorPreference();
+        }
+    }
+
+    /**
+     * Configure the ConnectedNetworkOperatorsPreferenceCategory. The category only need to be
+     * configured if the category is currently empty or the operator network title of the previous
+     * connected network is different from the new one.
+     */
+    private void configConnectedNetworkOperatorsPreferenceCategory() {
+        if (DBG) logd("config ConnectedNetworkOperatorsPreferenceCategory");
+        // Remove the category if the CellInfo list is empty or does not have registered cell.
+        if (mCellInfoList.size() == 0) {
+            if (DBG) logd("empty cellinfo list");
+            removeConnectedNetworkOperatorPreference();
+        }
+        CellInfo connectedNetworkOperator = null;
+        for (CellInfo cellInfo: mCellInfoList) {
+            if (cellInfo.isRegistered()) {
+                connectedNetworkOperator = cellInfo;
+                break;
+            }
+        }
+        if (connectedNetworkOperator == null) {
+            if (DBG) logd("no registered network");
+            removeConnectedNetworkOperatorPreference();
+            return;
+        }
+
+        // config the category if it is empty.
+        if (mConnectedNetworkOperatorsPreference.getPreferenceCount() == 0) {
+            if (DBG) logd("ConnectedNetworkSelectList is empty, add one");
+            addConnectedNetworkOperatorPreference(connectedNetworkOperator);
+            return;
+        }
+        NetworkOperatorPreference previousConnectedNetworkOperator = (NetworkOperatorPreference)
+                (mConnectedNetworkOperatorsPreference.getPreference(0));
+
+        // config the category if the network title of the previous connected network is different
+        // from the new one.
+        String cTitle = CellInfoUtil.getNetworkTitle(connectedNetworkOperator);
+        String pTitle = CellInfoUtil.getNetworkTitle(
+                previousConnectedNetworkOperator.getCellInfo());
+        if (!cTitle.equals(pTitle)) {
+            if (DBG) logd("reconfig the category: connected network changed");
+            addConnectedNetworkOperatorPreference(connectedNetworkOperator);
+            return;
+        }
+        if (DBG) logd("same network operator is connected, only refresh the connected network");
+        // Otherwise same network operator is connected, only refresh the connected network
+        // operator preference (first and the only one in this category).
+        ((NetworkOperatorPreference) mConnectedNetworkOperatorsPreference.getPreference(0))
+                .refresh();
+        return;
+    }
+
+    /**
+     * Creates a Preference for the given {@link CellInfo} and adds it to the
+     * {@link #mConnectedNetworkOperatorsPreference}.
+     */
+    private void addConnectedNetworkOperatorPreference(CellInfo cellInfo) {
+        if (DBG) logd("addConnectedNetworkOperatorPreference");
+        // Remove the current ConnectedNetworkOperatorsPreference
+        removeConnectedNetworkOperatorPreference();
+        final NetworkOperatorPreference pref =
+                new NetworkOperatorPreference(cellInfo, getContext());
+        pref.setSummary(R.string.network_connected);
+        mConnectedNetworkOperatorsPreference.addPreference(pref);
+        PreferenceScreen preferenceScreen = getPreferenceScreen();
+        preferenceScreen.addPreference(mConnectedNetworkOperatorsPreference);
+    }
+
+    /** Removes all preferences and hide the {@link #mConnectedNetworkOperatorsPreference}. */
+    private void removeConnectedNetworkOperatorPreference() {
+        mConnectedNetworkOperatorsPreference.removeAll();
+        PreferenceScreen preferenceScreen = getPreferenceScreen();
+        preferenceScreen.removePreference(mConnectedNetworkOperatorsPreference);
+    }
+
+    protected void setProgressBarVisible(boolean visible) {
+        if (mProgressHeader != null) {
+            mProgressHeader.setVisibility(visible ? View.VISIBLE : View.GONE);
+        }
+    }
+
+    private void addMessagePreference(int messageId) {
+        if (DBG) logd("remove callback");
+        getView().removeCallbacks(mUpdateNetworkOperatorsRunnable);
+        setProgressBarVisible(false);
+        if (DBG) logd("addMessagePreference");
+        mStatusMessagePreference.setTitle(messageId);
+        removeConnectedNetworkOperatorPreference();
+        mNetworkOperatorsPreferences.removeAll();
+        mNetworkOperatorsPreferences.addPreference(mStatusMessagePreference);
+    }
+
+    /**
+     * The Scan results may contains several cell infos with different radio technologies and signal
+     * strength for one network operator. Aggregate the CellInfoList by retaining only the cell info
+     * with the strongest signal strength.
+     */
+    private List<CellInfo> aggregateCellInfoList(List<CellInfo> cellInfoList) {
+        if (DBG) logd("before aggregate: " + cellInfoList.toString());
+        Map<String, CellInfo> map = new HashMap<>();
+        for (CellInfo cellInfo: cellInfoList) {
+            String networkTitle = CellInfoUtil.getNetworkTitle(cellInfo);
+            if (cellInfo.isRegistered() || !map.containsKey(networkTitle)) {
+                map.put(networkTitle, cellInfo);
+            } else {
+                if (map.get(networkTitle).isRegistered()
+                        || CellInfoUtil.getLevel(map.get(networkTitle))
+                        > CellInfoUtil.getLevel(cellInfo)) {
+                    // Skip if the stored cellInfo is registered or has higher signal strength level
+                    continue;
+                }
+                // Otherwise replace it with the new CellInfo
+                map.put(networkTitle, cellInfo);
+            }
+        }
+        return new ArrayList<>(map.values());
+    }
+
+    /**
+     * Service connection code for the NetworkQueryService.
+     * Handles the work of binding to a local object so that we can make
+     * the appropriate service calls.
+     */
+
+    /** Local service interface */
+    private INetworkQueryService mNetworkQueryService = null;
+    /** Flag indicating whether we have called bind on the service. */
+    boolean mShouldUnbind;
+
+    /** Service connection */
+    private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
+
+        /** Handle the task of binding the local object to the service */
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) logd("connection created, binding local service.");
+            mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
+            // Load the network list only when the service is well connected.
+            loadNetworksList();
+        }
+
+        /** Handle the task of cleaning up the local binding */
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) logd("connection disconnected, cleaning local binding.");
+            mNetworkQueryService = null;
+        }
+    };
+
+    private void bindNetworkQueryService() {
+        if (DBG) logd("bindNetworkQueryService");
+        getContext().bindService(new Intent(getContext(), NetworkQueryService.class).setAction(
+                NetworkQueryService.ACTION_LOCAL_BINDER),
+                mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
+        mShouldUnbind = true;
+    }
+
+    private void unbindNetworkQueryService() {
+        if (DBG) logd("unbindNetworkQueryService");
+        if (mShouldUnbind) {
+            if (DBG) logd("mShouldUnbind is true");
+            // unbind the service.
+            getContext().unbindService(mNetworkQueryServiceConnection);
+            mShouldUnbind = false;
+        }
+    }
+
+    private void stopNetworkQuery() {
+        // Stop the network query process
+        try {
+            if (mNetworkQueryService != null) {
+                if (DBG) logd("Stop network query");
+                mNetworkQueryService.stopNetworkQuery();
+                mNetworkQueryService.unregisterCallback(mCallback);
+            }
+        } catch (RemoteException e) {
+            loge("Exception from stopNetworkQuery " + e);
+        }
+    }
+
+    private void logd(String msg) {
+        Log.d(TAG, msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/NetworkSelectSettingActivity.java b/src/com/android/phone/NetworkSelectSettingActivity.java
new file mode 100644
index 0000000..2f730ad
--- /dev/null
+++ b/src/com/android/phone/NetworkSelectSettingActivity.java
@@ -0,0 +1,60 @@
+/*
+ * 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.phone;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+
+/**
+ * Activity associated with NetworkSelectSetting fragment
+ */
+public class NetworkSelectSettingActivity extends Activity {
+    private static final String TAG = "NetworkSelectSettingActivity";
+    public static final String KEY_PHONE_ID = "phone_id";
+
+    /**
+     * Returns the Android Intent that led to this Activity being created.
+     */
+    public static Intent getIntent(Context context, int phoneId) {
+        Intent intent = new Intent(context, NetworkSelectSettingActivity.class);
+        intent.putExtra(KEY_PHONE_ID, phoneId);
+        return intent;
+    }
+
+    @Override
+    public void onCreate(Bundle savedState) {
+        Log.d(TAG, "onCreate()");
+        super.onCreate(savedState);
+        int phoneId = getIntent().getExtras().getInt(KEY_PHONE_ID);
+        setContentView(R.layout.choose_network);
+
+        FragmentManager fragmentManager = getFragmentManager();
+        Fragment fragment = fragmentManager.findFragmentById(R.id.choose_network_content);
+        if (fragment == null) {
+            fragmentManager.beginTransaction()
+                    .add(R.id.choose_network_content,
+                            NetworkSelectSetting.newInstance(phoneId), TAG)
+                    .commit();
+        }
+    }
+}
