From c3703cb4fe60f17a2ffb8fec6ef98507bf7fd004 Mon Sep 17 00:00:00 2001 From: SongFerng Wang Date: Thu, 11 Jun 2020 08:56:42 +0000 Subject: [PATCH] Revert "Mainline: removed legacy UI for network selection mode." This reverts commit 521ebeafd3dbe88a93645c5a4bee83ffd3661b1f. Reason for revert: to fix b/157880043 Bug: 157880043 Test: test legacy UI. PASS Change-Id: I4116457a1f7fc0a3be142671c5d0439cd6bdf11d --- .../network/telephony/CellInfoUtil.java | 32 ++++ .../telephony/NetworkOperatorPreference.java | 5 +- .../network/telephony/NetworkScanHelper.java | 156 +++++++++++++++--- .../telephony/NetworkSelectSettings.java | 7 +- .../telephony/NetworkScanHelperTest.java | 3 +- 5 files changed, 180 insertions(+), 23 deletions(-) diff --git a/src/com/android/settings/network/telephony/CellInfoUtil.java b/src/com/android/settings/network/telephony/CellInfoUtil.java index 7412428389d..d7d2b18c8d0 100644 --- a/src/com/android/settings/network/telephony/CellInfoUtil.java +++ b/src/com/android/settings/network/telephony/CellInfoUtil.java @@ -33,6 +33,9 @@ import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; +import com.android.internal.telephony.OperatorInfo; + +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -99,6 +102,35 @@ public final class CellInfoUtil { return cellId; } + /** + * Creates a CellInfo object from OperatorInfo. GsmCellInfo is used here only because + * operatorInfo does not contain technology type while CellInfo is an abstract object that + * requires to specify technology type. It doesn't matter which CellInfo type to use here, since + * we only want to wrap the operator info and PLMN to a CellInfo object. + */ + public static CellInfo convertOperatorInfoToCellInfo(OperatorInfo operatorInfo) { + 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); + } + final CellIdentityGsm cig = new CellIdentityGsm( + Integer.MAX_VALUE /* lac */, + Integer.MAX_VALUE /* cid */, + Integer.MAX_VALUE /* arfcn */, + Integer.MAX_VALUE /* bsic */, + mcc, + mnc, + operatorInfo.getOperatorAlphaLong(), + operatorInfo.getOperatorAlphaShort(), + Collections.emptyList()); + + final CellInfoGsm ci = new CellInfoGsm(); + ci.setCellIdentity(cig); + return ci; + } /** Convert a list of cellInfos to readable string without sensitive info. */ public static String cellInfoListToString(List cellInfos) { diff --git a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java index 7173ccccfc8..97894b1aded 100644 --- a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java +++ b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java @@ -57,6 +57,7 @@ public class NetworkOperatorPreference extends Preference { private List mForbiddenPlmns; private int mLevel = LEVEL_NONE; private boolean mShow4GForLTE; + private boolean mUseNewApi; public NetworkOperatorPreference(Context context, CellInfo cellinfo, List forbiddenPlmns, boolean show4GForLTE) { @@ -75,6 +76,8 @@ public class NetworkOperatorPreference extends Preference { super(context); mForbiddenPlmns = forbiddenPlmns; mShow4GForLTE = show4GForLTE; + mUseNewApi = context.getResources().getBoolean( + com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI); } /** @@ -215,7 +218,7 @@ public class NetworkOperatorPreference extends Preference { } private void updateIcon(int level) { - if (level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) { + if (!mUseNewApi || level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) { return; } final Context context = getContext(); diff --git a/src/com/android/settings/network/telephony/NetworkScanHelper.java b/src/com/android/settings/network/telephony/NetworkScanHelper.java index fe5b9e1037c..524a7373de3 100644 --- a/src/com/android/settings/network/telephony/NetworkScanHelper.java +++ b/src/com/android/settings/network/telephony/NetworkScanHelper.java @@ -16,6 +16,7 @@ package com.android.settings.network.telephony; +import android.annotation.IntDef; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.CellInfo; import android.telephony.NetworkScan; @@ -25,9 +26,21 @@ import android.telephony.TelephonyManager; import android.telephony.TelephonyScanManager; import android.util.Log; +import com.android.internal.telephony.CellNetworkScanResult; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CancellationException; import java.util.concurrent.Executor; +import java.util.stream.Collectors; /** * A helper class that builds the common interface and performs the network scan for two different @@ -70,6 +83,33 @@ public class NetworkScanHelper { void onError(int errorCode); } + @Retention(RetentionPolicy.SOURCE) + @IntDef({NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS, NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS}) + public @interface NetworkQueryType {} + + /** + * Performs the network scan using {@link TelephonyManager#getAvailableNetworks()}. The network + * scan results won't be returned to the caller until the network scan is completed. + * + *

This is typically used when the modem doesn't support the new network scan api + * {@link TelephonyManager#requestNetworkScan( + * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}. + */ + public static final int NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS = 1; + + /** + * Performs the network scan using {@link TelephonyManager#requestNetworkScan( + * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan + * results will be returned to the caller periodically in a small time window until the network + * scan is completed. The complete results should be returned in the last called of + * {@link NetworkScanCallback#onResults(List)}. + * + *

This is recommended to be used if modem supports the new network scan api + * {@link TelephonyManager#requestNetworkScan( + * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} + */ + public static final int NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS = 2; + /** The constants below are used in the async network scan. */ private static final boolean INCREMENTAL_RESULTS = true; private static final int SEARCH_PERIODICITY_SEC = 5; @@ -83,6 +123,9 @@ public class NetworkScanHelper { private NetworkScan mNetworkScanRequester; + /** Callbacks for sync network scan */ + private ListenableFuture> mNetworkScanFuture; + public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) { mTelephonyManager = tm; mNetworkScanCallback = callback; @@ -139,38 +182,63 @@ public class NetworkScanHelper { } /** - * Request a network scan. + * Performs a network scan for the given type {@code type}. + * {@link #NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS} is recommended if modem supports + * {@link TelephonyManager#requestNetworkScan( + * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}. * - * Performs the network scan using {@link TelephonyManager#requestNetworkScan( - * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan - * results will be returned to the caller periodically in a small time window until the network - * scan is completed. The complete results should be returned in the last called of - * {@link NetworkScanCallback#onResults(List)}. + * @param type used to tell which network scan API should be used. */ - public void startNetworkScan() { - if (mNetworkScanRequester != null) { - return; - } - mNetworkScanRequester = mTelephonyManager.requestNetworkScan( - createNetworkScanForPreferredAccessNetworks(), - mExecutor, - mInternalNetworkScanCallback); - if (mNetworkScanRequester == null) { - onError(NetworkScan.ERROR_RADIO_INTERFACE_ERROR); + public void startNetworkScan(@NetworkQueryType int type) { + if (type == NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS) { + mNetworkScanFuture = SettableFuture.create(); + Futures.addCallback(mNetworkScanFuture, new FutureCallback>() { + @Override + public void onSuccess(List result) { + onResults(result); + onComplete(); + } + + @Override + public void onFailure(Throwable t) { + if (t instanceof CancellationException) { + return; + } + int errCode = Integer.parseInt(t.getMessage()); + onError(errCode); + } + }, MoreExecutors.directExecutor()); + mExecutor.execute(new NetworkScanSyncTask( + mTelephonyManager, (SettableFuture) mNetworkScanFuture)); + } else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) { + if (mNetworkScanRequester != null) { + return; + } + mNetworkScanRequester = mTelephonyManager.requestNetworkScan( + createNetworkScanForPreferredAccessNetworks(), + mExecutor, + mInternalNetworkScanCallback); + if (mNetworkScanRequester == null) { + onError(NetworkScan.ERROR_RADIO_INTERFACE_ERROR); + } } } /** - * Stops the network scan. - * - * Use this method to stop an ongoing scan. When user requests a new scan, a {@link NetworkScan} - * object will be returned, and the user can stop the scan by calling this method. + * The network scan of type {@link #NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS} can't be stopped, + * however, the result of the current network scan won't be returned to the callback after + * calling this method. */ public void stopNetworkQuery() { if (mNetworkScanRequester != null) { mNetworkScanRequester.stopScan(); mNetworkScanRequester = null; } + + if (mNetworkScanFuture != null) { + mNetworkScanFuture.cancel(true /* mayInterruptIfRunning */); + mNetworkScanFuture = null; + } } private void onResults(List cellInfos) { @@ -185,6 +253,23 @@ public class NetworkScanHelper { mNetworkScanCallback.onError(errCode); } + /** + * Converts the status code of {@link CellNetworkScanResult} to one of the + * {@link NetworkScan.ScanErrorCode}. + * @param errCode status code from {@link CellNetworkScanResult}. + * + * @return one of the scan error code from {@link NetworkScan.ScanErrorCode}. + */ + private static int convertToScanErrorCode(int errCode) { + switch (errCode) { + case CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE: + return NetworkScan.ERROR_RADIO_INTERFACE_ERROR; + case CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE: + default: + return NetworkScan.ERROR_MODEM_ERROR; + } + } + private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback { public void onResults(List results) { Log.d(TAG, "Async scan onResults() results = " @@ -202,4 +287,35 @@ public class NetworkScanHelper { NetworkScanHelper.this.onError(errCode); } } + + private static final class NetworkScanSyncTask implements Runnable { + private final SettableFuture> mCallback; + private final TelephonyManager mTelephonyManager; + + NetworkScanSyncTask( + TelephonyManager telephonyManager, SettableFuture> callback) { + mTelephonyManager = telephonyManager; + mCallback = callback; + } + + @Override + public void run() { + final CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks(); + if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) { + final List cellInfos = result.getOperators() + .stream() + .map(operatorInfo + -> CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo)) + .collect(Collectors.toList()); + Log.d(TAG, "Sync network scan completed, cellInfos = " + + CellInfoUtil.cellInfoListToString(cellInfos)); + mCallback.set(cellInfos); + } else { + final Throwable error = new Throwable( + Integer.toString(convertToScanErrorCode(result.getStatus()))); + mCallback.setException(error); + Log.d(TAG, "Sync network scan error, ex = " + error); + } + } + } } diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java index 787706320a1..3f18928f9a4 100644 --- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java +++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java @@ -93,6 +93,8 @@ public class NetworkSelectSettings extends DashboardFragment { public void onCreate(Bundle icicle) { super.onCreate(icicle); + mUseNewApi = getContext().getResources().getBoolean( + com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI); mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID); mPreferenceCategory = findPreference(PREF_KEY_NETWORK_OPERATORS); @@ -464,7 +466,10 @@ public class NetworkSelectSettings extends DashboardFragment { if (mNetworkScanHelper != null) { mRequestIdManualNetworkScan = getNewRequestId(); mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED; - mNetworkScanHelper.startNetworkScan(); + mNetworkScanHelper.startNetworkScan( + mUseNewApi + ? NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS + : NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS); } } diff --git a/tests/robotests/src/com/android/settings/network/telephony/NetworkScanHelperTest.java b/tests/robotests/src/com/android/settings/network/telephony/NetworkScanHelperTest.java index 19ae6ffc29d..1e7bfaf2f15 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/NetworkScanHelperTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/NetworkScanHelperTest.java @@ -164,7 +164,8 @@ public class NetworkScanHelperTest { } private void startNetworkScan_incremental(boolean waitForCompletion) { - mNetworkScanHelper.startNetworkScan(); + mNetworkScanHelper.startNetworkScan( + NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS); if (!waitForCompletion) { mNetworkScanHelper.stopNetworkQuery(); }