diff --git a/res/xml/choose_network.xml b/res/xml/choose_network.xml
index 97ea9be2fd5..4ae1ffb9364 100644
--- a/res/xml/choose_network.xml
+++ b/res/xml/choose_network.xml
@@ -19,10 +19,7 @@
android:key="mobile_choose_network_pref_screen"
android:title="@string/choose_network_title">
-
-
-
\ No newline at end of file
+
diff --git a/src/com/android/settings/network/telephony/CellInfoUtil.java b/src/com/android/settings/network/telephony/CellInfoUtil.java
index def81a10c64..31296945ff7 100644
--- a/src/com/android/settings/network/telephony/CellInfoUtil.java
+++ b/src/com/android/settings/network/telephony/CellInfoUtil.java
@@ -17,23 +17,26 @@
package com.android.settings.network.telephony;
import android.telephony.CellIdentity;
-import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellIdentityTdscdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
+import android.telephony.CellInfoNr;
+import android.telephony.CellInfoTdscdma;
import android.telephony.CellInfoWcdma;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
-import android.util.Log;
import com.android.internal.telephony.OperatorInfo;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -46,86 +49,56 @@ public final class CellInfoUtil {
private CellInfoUtil() {
}
- /**
- * 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.
+ * @param cellId contains the information of the network.
+ * @param networkMccMnc contains the MCCMNC string 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);
+ public static String getNetworkTitle(CellIdentity cellId, String networkMccMnc) {
+ if (cellId != null) {
+ String title = Objects.toString(cellId.getOperatorAlphaLong(), "");
+ if (TextUtils.isEmpty(title)) {
+ title = Objects.toString(cellId.getOperatorAlphaShort(), "");
+ }
+ if (!TextUtils.isEmpty(title)) {
+ return title;
+ }
}
+ if (TextUtils.isEmpty(networkMccMnc)) {
+ return "";
+ }
+ final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+ return bidiFormatter.unicodeWrap(networkMccMnc, TextDirectionHeuristics.LTR);
}
/**
- * Wrap a cell info into an operator info.
+ * Returns the CellIdentity from CellInfo
+ *
+ * @param cellInfo contains the information of the network.
+ * @return CellIdentity within CellInfo
*/
- 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("", "", "");
+ public static CellIdentity getCellIdentity(CellInfo cellInfo) {
+ if (cellInfo == null) {
+ return null;
}
- return oi;
+ CellIdentity cellId = null;
+ if (cellInfo instanceof CellInfoGsm) {
+ cellId = ((CellInfoGsm) cellInfo).getCellIdentity();
+ } else if (cellInfo instanceof CellInfoCdma) {
+ cellId = ((CellInfoCdma) cellInfo).getCellIdentity();
+ } else if (cellInfo instanceof CellInfoWcdma) {
+ cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
+ } else if (cellInfo instanceof CellInfoTdscdma) {
+ cellId = ((CellInfoTdscdma) cellInfo).getCellIdentity();
+ } else if (cellInfo instanceof CellInfoLte) {
+ cellId = ((CellInfoLte) cellInfo).getCellIdentity();
+ } else if (cellInfo instanceof CellInfoNr) {
+ cellId = ((CellInfoNr) cellInfo).getCellIdentity();
+ }
+ return cellId;
}
/**
@@ -135,14 +108,14 @@ public final class CellInfoUtil {
* we only want to wrap the operator info and PLMN to a CellInfo object.
*/
public static CellInfo convertOperatorInfoToCellInfo(OperatorInfo operatorInfo) {
- String operatorNumeric = operatorInfo.getOperatorNumeric();
+ final String operatorNumeric = operatorInfo.getOperatorNumeric();
String mcc = null;
String mnc = null;
if (operatorNumeric != null && operatorNumeric.matches("^[0-9]{5,6}$")) {
mcc = operatorNumeric.substring(0, 3);
mnc = operatorNumeric.substring(3);
}
- CellIdentityGsm cig = new CellIdentityGsm(
+ final CellIdentityGsm cig = new CellIdentityGsm(
Integer.MAX_VALUE /* lac */,
Integer.MAX_VALUE /* cid */,
Integer.MAX_VALUE /* arfcn */,
@@ -152,17 +125,11 @@ public final class CellInfoUtil {
operatorInfo.getOperatorAlphaLong(),
operatorInfo.getOperatorAlphaShort());
- CellInfoGsm ci = new CellInfoGsm();
+ final CellInfoGsm ci = new CellInfoGsm();
ci.setCellIdentity(cig);
return ci;
}
- /** Checks whether the network operator is forbidden. */
- public static boolean isForbidden(CellInfo cellInfo, List forbiddenPlmns) {
- String plmn = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
- return forbiddenPlmns != null && forbiddenPlmns.contains(plmn);
- }
-
/** Convert a list of cellInfos to readable string without sensitive info. */
public static String cellInfoListToString(List cellInfos) {
return cellInfos.stream()
@@ -172,11 +139,31 @@ public final class CellInfoUtil {
/** Convert {@code cellInfo} to a readable string without sensitive info. */
public static String cellInfoToString(CellInfo cellInfo) {
- String cellType = cellInfo.getClass().getSimpleName();
- CellIdentity cid = cellInfo.getCellIdentity();
+ final String cellType = cellInfo.getClass().getSimpleName();
+ final CellIdentity cid = getCellIdentity(cellInfo);
+ String mcc = null;
+ String mnc = null;
+ if (cid != null) {
+ if (cid instanceof CellIdentityGsm) {
+ mcc = ((CellIdentityGsm) cid).getMccString();
+ mnc = ((CellIdentityGsm) cid).getMncString();
+ } else if (cid instanceof CellIdentityWcdma) {
+ mcc = ((CellIdentityWcdma) cid).getMccString();
+ mnc = ((CellIdentityWcdma) cid).getMncString();
+ } else if (cid instanceof CellIdentityTdscdma) {
+ mcc = ((CellIdentityTdscdma) cid).getMccString();
+ mnc = ((CellIdentityTdscdma) cid).getMncString();
+ } else if (cid instanceof CellIdentityLte) {
+ mcc = ((CellIdentityLte) cid).getMccString();
+ mnc = ((CellIdentityLte) cid).getMncString();
+ } else if (cid instanceof CellIdentityNr) {
+ mcc = ((CellIdentityNr) cid).getMccString();
+ mnc = ((CellIdentityNr) cid).getMncString();
+ }
+ }
return String.format(
"{CellType = %s, isRegistered = %b, mcc = %s, mnc = %s, alphaL = %s, alphaS = %s}",
- cellType, cellInfo.isRegistered(), cid.getMccString(), cid.getMncString(),
+ cellType, cellInfo.isRegistered(), mcc, mnc,
cid.getOperatorAlphaLong(), cid.getOperatorAlphaShort());
}
}
diff --git a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
index 77f40da7f17..db7c8644d8a 100644
--- a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
+++ b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
@@ -19,16 +19,28 @@ package com.android.settings.network.telephony;
import static android.telephony.SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
import android.content.Context;
+import android.telephony.CellIdentity;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellIdentityTdscdma;
+import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoNr;
+import android.telephony.CellInfoTdscdma;
+import android.telephony.CellInfoWcdma;
import android.telephony.CellSignalStrength;
import android.util.Log;
import androidx.preference.Preference;
import com.android.settings.R;
-import com.android.settings.Utils;
import java.util.List;
+import java.util.Objects;
/**
* A Preference represents a network operator in the NetworkSelectSetting fragment.
@@ -41,38 +53,74 @@ public class NetworkOperatorPreference extends Preference {
private static final int LEVEL_NONE = -1;
private CellInfo mCellInfo;
+ private CellIdentity mCellId;
private List mForbiddenPlmns;
private int mLevel = LEVEL_NONE;
private boolean mShow4GForLTE;
private boolean mUseNewApi;
- public NetworkOperatorPreference(
- CellInfo cellinfo, Context context, List forbiddenPlmns, boolean show4GForLTE) {
+ public NetworkOperatorPreference(Context context, CellInfo cellinfo,
+ List forbiddenPlmns, boolean show4GForLTE) {
+ this(context, forbiddenPlmns, show4GForLTE);
+ updateCell(cellinfo);
+ }
+
+ public NetworkOperatorPreference(Context context, CellIdentity connectedCellId,
+ List forbiddenPlmns, boolean show4GForLTE) {
+ this(context, forbiddenPlmns, show4GForLTE);
+ mCellInfo = null;
+ mCellId = connectedCellId;
+ refresh();
+ }
+
+ private NetworkOperatorPreference(
+ Context context, List forbiddenPlmns, boolean show4GForLTE) {
super(context);
- mCellInfo = cellinfo;
mForbiddenPlmns = forbiddenPlmns;
mShow4GForLTE = show4GForLTE;
mUseNewApi = context.getResources().getBoolean(
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
+ }
+
+ /**
+ * Change cell information
+ */
+ public void updateCell(CellInfo cellinfo) {
+ mCellInfo = cellinfo;
+ mCellId = CellInfoUtil.getCellIdentity(cellinfo);
refresh();
}
- public CellInfo getCellInfo() {
- return mCellInfo;
+ /**
+ * Compare cell within preference
+ */
+ public boolean isSameCell(CellInfo cellinfo) {
+ if (cellinfo == null) {
+ return false;
+ }
+ return mCellId.equals(CellInfoUtil.getCellIdentity(cellinfo));
}
/**
* Refresh the NetworkOperatorPreference by updating the title and the icon.
*/
public void refresh() {
- if (DBG) Log.d(TAG, "refresh the network: " + CellInfoUtil.getNetworkTitle(mCellInfo));
- String networkTitle = CellInfoUtil.getNetworkTitle(mCellInfo);
- if (CellInfoUtil.isForbidden(mCellInfo, mForbiddenPlmns)) {
- networkTitle += " " + getContext().getResources().getString(R.string.forbidden_network);
- }
- setTitle(networkTitle);
+ String networkTitle = getOperatorName();
- final CellSignalStrength signalStrength = mCellInfo.getCellSignalStrength();
+ if ((mForbiddenPlmns != null) && mForbiddenPlmns.contains(getOperatorNumeric())) {
+ if (DBG) Log.d(TAG, "refresh forbidden network: " + networkTitle);
+ networkTitle += " "
+ + getContext().getResources().getString(R.string.forbidden_network);
+ } else {
+ if (DBG) Log.d(TAG, "refresh the network: " + networkTitle);
+ }
+ setTitle(Objects.toString(networkTitle, ""));
+
+ if (mCellInfo == null) {
+ return;
+ }
+
+ final CellSignalStrength signalStrength = getCellSignalStrength(mCellInfo);
final int level = signalStrength != null ? signalStrength.getLevel() : LEVEL_NONE;
if (DBG) Log.d(TAG, "refresh level: " + String.valueOf(level));
if (mLevel != level) {
@@ -88,29 +136,87 @@ public class NetworkOperatorPreference extends Preference {
updateIcon(level);
}
- private int getIconIdForCell(CellInfo ci) {
- final int type = ci.getCellIdentity().getType();
- switch (type) {
- case CellInfo.TYPE_GSM:
- return R.drawable.signal_strength_g;
- case CellInfo.TYPE_WCDMA: // fall through
- case CellInfo.TYPE_TDSCDMA:
- return R.drawable.signal_strength_3g;
- case CellInfo.TYPE_LTE:
- return mShow4GForLTE
- ? R.drawable.ic_signal_strength_4g : R.drawable.signal_strength_lte;
- case CellInfo.TYPE_CDMA:
- return R.drawable.signal_strength_1x;
- default:
- return MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
+ /**
+ * Operator numeric of this cell
+ */
+ public String getOperatorNumeric() {
+ final CellIdentity cellId = mCellId;
+ if (cellId == null) {
+ return null;
}
+ if (cellId instanceof CellIdentityGsm) {
+ return ((CellIdentityGsm) cellId).getMobileNetworkOperator();
+ }
+ if (cellId instanceof CellIdentityWcdma) {
+ return ((CellIdentityWcdma) cellId).getMobileNetworkOperator();
+ }
+ if (cellId instanceof CellIdentityTdscdma) {
+ return ((CellIdentityTdscdma) cellId).getMobileNetworkOperator();
+ }
+ if (cellId instanceof CellIdentityLte) {
+ return ((CellIdentityLte) cellId).getMobileNetworkOperator();
+ }
+ if (cellId instanceof CellIdentityNr) {
+ final String mcc = ((CellIdentityNr) cellId).getMccString();
+ if (mcc == null) {
+ return null;
+ }
+ return mcc.concat(((CellIdentityNr) cellId).getMncString());
+ }
+ return null;
+ }
+
+ /**
+ * Operator name of this cell
+ */
+ public String getOperatorName() {
+ return CellInfoUtil.getNetworkTitle(mCellId, getOperatorNumeric());
+ }
+
+ private int getIconIdForCell(CellInfo ci) {
+ if (ci instanceof CellInfoGsm) {
+ return R.drawable.signal_strength_g;
+ }
+ if (ci instanceof CellInfoCdma) {
+ return R.drawable.signal_strength_1x;
+ }
+ if ((ci instanceof CellInfoWcdma) || (ci instanceof CellInfoTdscdma)) {
+ return R.drawable.signal_strength_3g;
+ }
+ if (ci instanceof CellInfoLte) {
+ return mShow4GForLTE
+ ? R.drawable.ic_signal_strength_4g : R.drawable.signal_strength_lte;
+ }
+ return MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
+ }
+
+ private CellSignalStrength getCellSignalStrength(CellInfo ci) {
+ if (ci instanceof CellInfoGsm) {
+ return ((CellInfoGsm) ci).getCellSignalStrength();
+ }
+ if (ci instanceof CellInfoCdma) {
+ return ((CellInfoCdma) ci).getCellSignalStrength();
+ }
+ if (ci instanceof CellInfoWcdma) {
+ return ((CellInfoWcdma) ci).getCellSignalStrength();
+ }
+ if (ci instanceof CellInfoTdscdma) {
+ return ((CellInfoTdscdma) ci).getCellSignalStrength();
+ }
+ if (ci instanceof CellInfoLte) {
+ return ((CellInfoLte) ci).getCellSignalStrength();
+ }
+ if (ci instanceof CellInfoNr) {
+ return ((CellInfoNr) ci).getCellSignalStrength();
+ }
+ return null;
}
private void updateIcon(int level) {
if (!mUseNewApi || level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) {
return;
}
- Context context = getContext();
+ final Context context = getContext();
setIcon(MobileNetworkUtils.getSignalStrengthIcon(context, level, NUM_SIGNAL_STRENGTH_BINS,
getIconIdForCell(mCellInfo), false));
}
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index 4c62de2b5a8..2835b6e96f0 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.settings.network.telephony;
import android.app.Activity;
@@ -39,7 +40,6 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
-import com.android.internal.telephony.OperatorInfo;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory;
@@ -48,14 +48,12 @@ import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
- * "Choose network" settings UI for the Phone app.
+ * "Choose network" settings UI for the Settings app.
*/
public class NetworkSelectSettings extends DashboardFragment {
@@ -66,15 +64,11 @@ public class NetworkSelectSettings extends DashboardFragment {
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";
@VisibleForTesting
PreferenceCategory mPreferenceCategory;
@VisibleForTesting
- PreferenceCategory mConnectedPreferenceCategory;
- @VisibleForTesting
NetworkOperatorPreference mSelectedPreference;
private View mProgressHeader;
private Preference mStatusMessagePreference;
@@ -89,6 +83,12 @@ public class NetworkSelectSettings extends DashboardFragment {
private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
private MetricsFeatureProvider mMetricsFeatureProvider;
private boolean mUseNewApi;
+ private long mRequestIdManualNetworkSelect;
+ private long mRequestIdManualNetworkScan;
+ private boolean mScreenIsOn;
+ private long mWaitingForNumberOfScanResults;
+
+ private static final int MIN_NUMBER_OF_SCAN_REQUIRED = 2;
@Override
public void onCreate(Bundle icicle) {
@@ -98,12 +98,12 @@ public class NetworkSelectSettings extends DashboardFragment {
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID);
- mConnectedPreferenceCategory = findPreference(PREF_KEY_CONNECTED_NETWORK_OPERATOR);
mPreferenceCategory = findPreference(PREF_KEY_NETWORK_OPERATORS);
mStatusMessagePreference = new Preference(getContext());
mStatusMessagePreference.setSelectable(false);
mSelectedPreference = null;
- mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+ mTelephonyManager = getContext().getSystemService(TelephonyManager.class)
+ .createForSubscriptionId(mSubId);
mNetworkScanHelper = new NetworkScanHelper(
mTelephonyManager, mCallback, mNetworkScanExecutor);
PersistableBundle bundle = ((CarrierConfigManager) getContext().getSystemService(
@@ -138,12 +138,10 @@ public class NetworkSelectSettings extends DashboardFragment {
if (isProgressBarVisible()) {
return;
}
- setProgressBarVisible(true);
-
- mNetworkScanHelper.startNetworkScan(
- mUseNewApi
- ? NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS
- : NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
+ mScreenIsOn = true;
+ if (mWaitingForNumberOfScanResults <= 0) {
+ startNetworkQuery();
+ }
}
/**
@@ -160,43 +158,42 @@ public class NetworkSelectSettings extends DashboardFragment {
@Override
public void onStop() {
super.onStop();
+ mScreenIsOn = false;
+ if (mWaitingForNumberOfScanResults <= 0) {
+ stopNetworkQuery();
+ }
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (preference != mSelectedPreference) {
stopNetworkQuery();
+
// Refresh the last selected item in case users reselect network.
+ clearPreferenceSummary();
if (mSelectedPreference != null) {
- mSelectedPreference.setSummary(null);
+ // Set summary as "Disconnected" to the previously connected network
+ mSelectedPreference.setSummary(R.string.network_disconnected);
}
mSelectedPreference = (NetworkOperatorPreference) preference;
- CellInfo cellInfo = mSelectedPreference.getCellInfo();
mSelectedPreference.setSummary(R.string.network_connecting);
mMetricsFeatureProvider.action(getContext(),
SettingsEnums.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK);
- // Set summary as "Disconnected" to the previously connected network
- if (mConnectedPreferenceCategory.getPreferenceCount() > 0) {
- NetworkOperatorPreference connectedNetworkOperator = (NetworkOperatorPreference)
- (mConnectedPreferenceCategory.getPreference(0));
- if (!CellInfoUtil.getNetworkTitle(cellInfo).equals(
- CellInfoUtil.getNetworkTitle(connectedNetworkOperator.getCellInfo()))) {
- connectedNetworkOperator.setSummary(R.string.network_disconnected);
- }
- }
-
setProgressBarVisible(true);
// Disable the screen until network is manually set
getPreferenceScreen().setEnabled(false);
- final OperatorInfo operatorInfo = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo);
+ mRequestIdManualNetworkSelect = getNewRequestId();
+ mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED;
+ final String operatorNumeric = mSelectedPreference.getOperatorNumeric();
ThreadUtils.postOnBackgroundThread(() -> {
- Message msg = mHandler.obtainMessage(EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE);
+ final Message msg = mHandler.obtainMessage(
+ EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE);
msg.obj = mTelephonyManager.setNetworkSelectionModeManual(
- operatorInfo, true /* persistSelection */);
+ operatorNumeric, true /* persistSelection */);
msg.sendToTarget();
});
}
@@ -224,35 +221,85 @@ public class NetworkSelectSettings extends DashboardFragment {
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE:
- setProgressBarVisible(false);
- getPreferenceScreen().setEnabled(true);
-
- boolean isSucceed = (boolean) msg.obj;
- mSelectedPreference.setSummary(isSucceed
- ? R.string.network_connected
- : R.string.network_could_not_connect);
+ final boolean isSucceed = (boolean) msg.obj;
+ if (isSucceed) {
+ // Don't enable screen here. Wait until result of network re-scan.
+ startNetworkQuery();
+ } else {
+ stopNetworkQuery();
+ setProgressBarVisible(false);
+ getPreferenceScreen().setEnabled(true);
+ // For failure case, only update the summary of selected item.
+ mSelectedPreference.setSummary(R.string.network_could_not_connect);
+ }
break;
case EVENT_NETWORK_SCAN_RESULTS:
- List results = aggregateCellInfoList((List) msg.obj);
- Log.d(TAG, "CellInfoList after aggregation: "
- + CellInfoUtil.cellInfoListToString(results));
- mCellInfoList = new ArrayList<>(results);
- if (mCellInfoList != null && mCellInfoList.size() != 0) {
- updateAllPreferenceCategory();
- } else {
- addMessagePreference(R.string.empty_networks_list);
+ final List results = (List) msg.obj;
+ if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
+ Log.d(TAG, "CellInfoList (drop): "
+ + CellInfoUtil.cellInfoListToString(new ArrayList<>(results)));
+ break;
+ }
+ mWaitingForNumberOfScanResults--;
+ if ((!mScreenIsOn) && (mWaitingForNumberOfScanResults <= 0)) {
+ stopNetworkQuery();
}
+ mCellInfoList = new ArrayList<>(results);
+ Log.d(TAG, "CellInfoList: " + CellInfoUtil.cellInfoListToString(mCellInfoList));
+ if (mCellInfoList != null && mCellInfoList.size() != 0) {
+ final NetworkOperatorPreference connectedPref =
+ updateAllPreferenceCategory();
+ if (connectedPref != null) {
+ // update selected preference instance into connected preference
+ if (mSelectedPreference != null) {
+ mSelectedPreference = connectedPref;
+ }
+ } else if (!getPreferenceScreen().isEnabled()) {
+ if (connectedPref == null) {
+ mSelectedPreference.setSummary(R.string.network_connecting);
+ }
+ }
+ getPreferenceScreen().setEnabled(true);
+ } else if (getPreferenceScreen().isEnabled()) {
+ addMessagePreference(R.string.empty_networks_list);
+ // keep showing progress bar, it will be stopped when error or completed
+ setProgressBarVisible(true);
+ }
break;
case EVENT_NETWORK_SCAN_ERROR:
stopNetworkQuery();
- addMessagePreference(R.string.network_query_error);
+ Log.i(TAG, "Network scan failure " + msg.arg1 + ":"
+ + " scan request 0x" + Long.toHexString(mRequestIdManualNetworkScan)
+ + ", waiting for scan results = " + mWaitingForNumberOfScanResults
+ + ", select request 0x"
+ + Long.toHexString(mRequestIdManualNetworkSelect));
+ if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
+ break;
+ }
+ if (!getPreferenceScreen().isEnabled()) {
+ clearPreferenceSummary();
+ getPreferenceScreen().setEnabled(true);
+ } else {
+ addMessagePreference(R.string.network_query_error);
+ }
break;
case EVENT_NETWORK_SCAN_COMPLETED:
stopNetworkQuery();
- if (mCellInfoList == null) {
+ Log.d(TAG, "Network scan complete:"
+ + " scan request 0x" + Long.toHexString(mRequestIdManualNetworkScan)
+ + ", waiting for scan results = " + mWaitingForNumberOfScanResults
+ + ", select request 0x"
+ + Long.toHexString(mRequestIdManualNetworkSelect));
+ if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
+ break;
+ }
+ if (!getPreferenceScreen().isEnabled()) {
+ clearPreferenceSummary();
+ getPreferenceScreen().setEnabled(true);
+ } else if (mCellInfoList == null) {
// In case the scan timeout before getting any results
addMessagePreference(R.string.empty_networks_list);
}
@@ -265,48 +312,86 @@ public class NetworkSelectSettings extends DashboardFragment {
private final NetworkScanHelper.NetworkScanCallback mCallback =
new NetworkScanHelper.NetworkScanCallback() {
public void onResults(List results) {
- Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
+ final Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
msg.sendToTarget();
}
public void onComplete() {
- Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
+ final Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
msg.sendToTarget();
}
public void onError(int error) {
- Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR, error,
+ final Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR, error,
0 /* arg2 */);
msg.sendToTarget();
}
};
/**
- * 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.
+ * Update the content of network operators list.
+ *
+ * @return preference which shows connected
*/
@VisibleForTesting
- void updateAllPreferenceCategory() {
- updateConnectedPreferenceCategory();
+ NetworkOperatorPreference updateAllPreferenceCategory() {
+ int numberOfPreferences = mPreferenceCategory.getPreferenceCount();
- mPreferenceCategory.removeAll();
+ // remove unused preferences
+ while (numberOfPreferences > mCellInfoList.size()) {
+ numberOfPreferences--;
+ mPreferenceCategory.removePreference(
+ mPreferenceCategory.getPreference(numberOfPreferences));
+ }
+
+ // update selected preference instance by index
for (int index = 0; index < mCellInfoList.size(); index++) {
- if (!mCellInfoList.get(index).isRegistered()) {
- NetworkOperatorPreference pref = new NetworkOperatorPreference(
- mCellInfoList.get(index), getPrefContext(), mForbiddenPlmns, mShow4GForLTE);
- pref.setKey(CellInfoUtil.getNetworkTitle(mCellInfoList.get(index)));
+ final CellInfo cellInfo = mCellInfoList.get(index);
+
+ if ((mSelectedPreference != null) && mSelectedPreference.isSameCell(cellInfo)) {
+ mSelectedPreference = (NetworkOperatorPreference)
+ (mPreferenceCategory.getPreference(index));
+ }
+ }
+
+ // update the content of preference
+ NetworkOperatorPreference connectedPref = null;
+ for (int index = 0; index < mCellInfoList.size(); index++) {
+ final CellInfo cellInfo = mCellInfoList.get(index);
+
+ NetworkOperatorPreference pref = null;
+ if (index < numberOfPreferences) {
+ final Preference rawPref = mPreferenceCategory.getPreference(index);
+ if (rawPref instanceof NetworkOperatorPreference) {
+ // replace existing preference
+ pref = (NetworkOperatorPreference) rawPref;
+ pref.updateCell(cellInfo);
+ } else {
+ mPreferenceCategory.removePreference(rawPref);
+ }
+ }
+ if (pref == null) {
+ // add new preference
+ pref = new NetworkOperatorPreference(getPrefContext(),
+ cellInfo, mForbiddenPlmns, mShow4GForLTE);
pref.setOrder(index);
mPreferenceCategory.addPreference(pref);
}
+ pref.setKey(pref.getOperatorName());
+
+ if (mCellInfoList.get(index).isRegistered()) {
+ pref.setSummary(R.string.network_connected);
+ connectedPref = pref;
+ } else {
+ pref.setSummary(null);
+ }
}
+
+ return connectedPref;
}
/**
- * Config the connected network operator preference when the page was created. When user get
+ * Config the network operator list 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#getNetworkRegistrationInfoList()} to get the currently
@@ -320,63 +405,45 @@ public class NetworkSelectSettings extends DashboardFragment {
private void forceUpdateConnectedPreferenceCategory() {
if (mTelephonyManager.getDataState() == mTelephonyManager.DATA_CONNECTED) {
// Try to get the network registration states
- ServiceState ss = mTelephonyManager.getServiceState();
- List networkList =
+ final ServiceState ss = mTelephonyManager.getServiceState();
+ final List networkList =
ss.getNetworkRegistrationInfoListForTransportType(
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
if (networkList == null || networkList.size() == 0) {
- // Remove the connected network operators category
- mConnectedPreferenceCategory.setVisible(false);
return;
}
- CellIdentity cellIdentity = networkList.get(0).getCellIdentity();
- CellInfo cellInfo = CellInfoUtil.wrapCellInfoWithCellIdentity(cellIdentity);
- if (cellInfo != null) {
- NetworkOperatorPreference pref = new NetworkOperatorPreference(
- cellInfo, getPrefContext(), mForbiddenPlmns, mShow4GForLTE);
- pref.setTitle(MobileNetworkUtils.getCurrentCarrierNameForDisplay(
- getPrefContext(), mSubId));
- 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(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
- mConnectedPreferenceCategory.addPreference(pref);
- } else {
- // Remove the connected network operators category
- mConnectedPreferenceCategory.setVisible(false);
+ for (NetworkRegistrationInfo regInfo : networkList) {
+ final CellIdentity cellIdentity = regInfo.getCellIdentity();
+ if (cellIdentity != null) {
+ final NetworkOperatorPreference pref = new NetworkOperatorPreference(
+ getPrefContext(), cellIdentity, mForbiddenPlmns, mShow4GForLTE);
+ 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(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
+ mPreferenceCategory.addPreference(pref);
+ }
}
- } else {
- // Remove the connected network operators category
- mConnectedPreferenceCategory.setVisible(false);
}
}
/**
- * 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.
+ * Clear all of the preference summary
*/
- private void updateConnectedPreferenceCategory() {
- CellInfo connectedNetworkOperator = null;
- for (CellInfo cellInfo : mCellInfoList) {
- if (cellInfo.isRegistered()) {
- connectedNetworkOperator = cellInfo;
- break;
- }
- }
-
- if (connectedNetworkOperator != null) {
- addConnectedNetworkOperatorPreference(connectedNetworkOperator);
+ private void clearPreferenceSummary() {
+ int idxPreference = mPreferenceCategory.getPreferenceCount();
+ while (idxPreference > 0) {
+ idxPreference--;
+ final NetworkOperatorPreference networkOperator = (NetworkOperatorPreference)
+ (mPreferenceCategory.getPreference(idxPreference));
+ networkOperator.setSummary(null);
}
}
- private void addConnectedNetworkOperatorPreference(CellInfo cellInfo) {
- mConnectedPreferenceCategory.removeAll();
- final NetworkOperatorPreference pref = new NetworkOperatorPreference(
- cellInfo, getPrefContext(), mForbiddenPlmns, mShow4GForLTE);
- pref.setSummary(R.string.network_connected);
- mConnectedPreferenceCategory.addPreference(pref);
- mConnectedPreferenceCategory.setVisible(true);
+ private long getNewRequestId() {
+ return Math.max(mRequestIdManualNetworkSelect,
+ mRequestIdManualNetworkScan) + 1;
}
private boolean isProgressBarVisible() {
@@ -395,39 +462,26 @@ public class NetworkSelectSettings extends DashboardFragment {
private void addMessagePreference(int messageId) {
setProgressBarVisible(false);
mStatusMessagePreference.setTitle(messageId);
- mConnectedPreferenceCategory.setVisible(false);
mPreferenceCategory.removeAll();
mPreferenceCategory.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 aggregateCellInfoList(List cellInfoList) {
- Map map = new HashMap<>();
- for (CellInfo cellInfo : cellInfoList) {
- String plmn = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
- if (cellInfo.isRegistered() || !map.containsKey(plmn)) {
- map.put(plmn, cellInfo);
- } else {
- if (map.get(plmn).isRegistered()
- || map.get(plmn).getCellSignalStrength().getLevel()
- > cellInfo.getCellSignalStrength().getLevel()) {
- // Skip if the stored cellInfo is registered or has higher signal strength level
- continue;
- }
- // Otherwise replace it with the new CellInfo
- map.put(plmn, cellInfo);
- }
+ private void startNetworkQuery() {
+ setProgressBarVisible(true);
+ if (mNetworkScanHelper != null) {
+ mRequestIdManualNetworkScan = getNewRequestId();
+ mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED;
+ mNetworkScanHelper.startNetworkScan(
+ mUseNewApi
+ ? NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS
+ : NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
}
- return new ArrayList<>(map.values());
}
private void stopNetworkQuery() {
setProgressBarVisible(false);
if (mNetworkScanHelper != null) {
+ mWaitingForNumberOfScanResults = 0;
mNetworkScanHelper.stopNetworkQuery();
}
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/NetworkOperatorPreferenceTest.java b/tests/robotests/src/com/android/settings/network/telephony/NetworkOperatorPreferenceTest.java
index 704dd95f00c..3a61195018c 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/NetworkOperatorPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/NetworkOperatorPreferenceTest.java
@@ -60,7 +60,7 @@ public class NetworkOperatorPreferenceTest {
when(mResources.getBoolean(com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI))
.thenReturn(false);
final NetworkOperatorPreference preference = spy(
- new NetworkOperatorPreference(mCellInfo, mContext,
+ new NetworkOperatorPreference(mContext, mCellInfo,
new ArrayList<>() /* forbiddenPlmns */, false /* show4GForLTE */));
preference.setIcon(LEVEL);
diff --git a/tests/robotests/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/robotests/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
index 7dfc8a35323..6bee38fba9e 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
@@ -23,7 +23,11 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.telephony.CellInfo;
+import android.content.SharedPreferences;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -43,20 +47,27 @@ import java.util.Arrays;
@RunWith(RobolectricTestRunner.class)
public class NetworkSelectSettingsTest {
private static final int SUB_ID = 2;
+ private static final String CARRIER_NAME1 = "CarrierName1";
+ private static final String CARRIER_NAME2 = "CarrierName2";
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionManager mSubscriptionManager;
@Mock
- private CellInfo mCellInfo1;
+ private CellInfoWcdma mCellInfo1;
@Mock
- private CellInfo mCellInfo2;
+ private CellIdentityWcdma mCellId1;
+ @Mock
+ private CellInfoLte mCellInfo2;
+ @Mock
+ private CellIdentityLte mCellId2;
@Mock
private PreferenceManager mPreferenceManager;
+ @Mock
+ private SharedPreferences mSharedPreferences;
private Context mContext;
- private PreferenceCategory mConnectedPreferenceCategory;
private PreferenceCategory mPreferenceCategory;
private NetworkSelectSettings mNetworkSelectSettings;
@@ -71,10 +82,13 @@ public class NetworkSelectSettingsTest {
when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
when(mCellInfo1.isRegistered()).thenReturn(true);
+ when(mCellInfo1.getCellIdentity()).thenReturn(mCellId1);
+ when(mCellId1.getOperatorAlphaLong()).thenReturn(CARRIER_NAME1);
when(mCellInfo2.isRegistered()).thenReturn(false);
+ when(mCellInfo2.getCellIdentity()).thenReturn(mCellId2);
+ when(mCellId2.getOperatorAlphaLong()).thenReturn(CARRIER_NAME2);
- mConnectedPreferenceCategory = spy(new PreferenceCategory(mContext));
- doReturn(mPreferenceManager).when(mConnectedPreferenceCategory).getPreferenceManager();
+ doReturn(mSharedPreferences).when(mPreferenceManager).getSharedPreferences();
mPreferenceCategory = spy(new PreferenceCategory(mContext));
doReturn(mPreferenceManager).when(mPreferenceCategory).getPreferenceManager();
@@ -84,23 +98,18 @@ public class NetworkSelectSettingsTest {
doReturn(mContext).when(mPreferenceManager).getContext();
mNetworkSelectSettings.mTelephonyManager = mTelephonyManager;
- mNetworkSelectSettings.mConnectedPreferenceCategory = mConnectedPreferenceCategory;
mNetworkSelectSettings.mPreferenceCategory = mPreferenceCategory;
mNetworkSelectSettings.mCellInfoList = Arrays.asList(mCellInfo1, mCellInfo2);
}
@Test
- public void updateAllPreferenceCategory_containCorrectPreference() {
+ public void updateAllPreferenceCategory_correctOrderingPreference() {
mNetworkSelectSettings.updateAllPreferenceCategory();
- assertThat(mConnectedPreferenceCategory.getPreferenceCount()).isEqualTo(1);
- final NetworkOperatorPreference connectedPreference =
- (NetworkOperatorPreference) mConnectedPreferenceCategory.getPreference(0);
- assertThat(connectedPreference.getCellInfo()).isEqualTo(mCellInfo1);
- assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(1);
+ assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
final NetworkOperatorPreference preference =
- (NetworkOperatorPreference) mPreferenceCategory.getPreference(0);
- assertThat(preference.getCellInfo()).isEqualTo(mCellInfo2);
+ (NetworkOperatorPreference) mPreferenceCategory.getPreference(1);
+ assertThat(preference.getOperatorName()).isEqualTo(mCellId2.getOperatorAlphaLong());
}
@Test