Change the Auto-select Network UI.
Design doc: https://docs.google.com/document/d/1M0HsnsHnLfp5iroxU7aujhI9pmS3dwHBtws6uTFxogM/edit?usp=sharing
Bug: 70530820,72052945
Test: Telephony sanity, Manual testing
Change-Id: Ie71ac8fc30ad350e45e8b9839b39738147efc9fd
Merged-In: Ie71ac8fc30ad350e45e8b9839b39738147efc9fd
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();
+ }
+ }
+}