Merge "Revert "Mainline: removed legacy UI for network selection mode."" into rvc-dev am: 518ffd7c76
am: d32cb38e45
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/11837795 Change-Id: Ie3b090330bc2114a67e9229060ba5c6e23b74347
This commit is contained in:
@@ -33,6 +33,9 @@ import android.text.BidiFormatter;
|
|||||||
import android.text.TextDirectionHeuristics;
|
import android.text.TextDirectionHeuristics;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.android.internal.telephony.OperatorInfo;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -99,6 +102,35 @@ public final class CellInfoUtil {
|
|||||||
return cellId;
|
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. */
|
/** Convert a list of cellInfos to readable string without sensitive info. */
|
||||||
public static String cellInfoListToString(List<CellInfo> cellInfos) {
|
public static String cellInfoListToString(List<CellInfo> cellInfos) {
|
||||||
|
@@ -57,6 +57,7 @@ public class NetworkOperatorPreference extends Preference {
|
|||||||
private List<String> mForbiddenPlmns;
|
private List<String> mForbiddenPlmns;
|
||||||
private int mLevel = LEVEL_NONE;
|
private int mLevel = LEVEL_NONE;
|
||||||
private boolean mShow4GForLTE;
|
private boolean mShow4GForLTE;
|
||||||
|
private boolean mUseNewApi;
|
||||||
|
|
||||||
public NetworkOperatorPreference(Context context, CellInfo cellinfo,
|
public NetworkOperatorPreference(Context context, CellInfo cellinfo,
|
||||||
List<String> forbiddenPlmns, boolean show4GForLTE) {
|
List<String> forbiddenPlmns, boolean show4GForLTE) {
|
||||||
@@ -75,6 +76,8 @@ public class NetworkOperatorPreference extends Preference {
|
|||||||
super(context);
|
super(context);
|
||||||
mForbiddenPlmns = forbiddenPlmns;
|
mForbiddenPlmns = forbiddenPlmns;
|
||||||
mShow4GForLTE = show4GForLTE;
|
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) {
|
private void updateIcon(int level) {
|
||||||
if (level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) {
|
if (!mUseNewApi || level < 0 || level >= NUM_SIGNAL_STRENGTH_BINS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.network.telephony;
|
package com.android.settings.network.telephony;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.telephony.AccessNetworkConstants.AccessNetworkType;
|
import android.telephony.AccessNetworkConstants.AccessNetworkType;
|
||||||
import android.telephony.CellInfo;
|
import android.telephony.CellInfo;
|
||||||
import android.telephony.NetworkScan;
|
import android.telephony.NetworkScan;
|
||||||
@@ -25,9 +26,21 @@ import android.telephony.TelephonyManager;
|
|||||||
import android.telephony.TelephonyScanManager;
|
import android.telephony.TelephonyScanManager;
|
||||||
import android.util.Log;
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.Executor;
|
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
|
* 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);
|
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.
|
||||||
|
*
|
||||||
|
* <p> 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)}.
|
||||||
|
*
|
||||||
|
* <p> 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. */
|
/** The constants below are used in the async network scan. */
|
||||||
private static final boolean INCREMENTAL_RESULTS = true;
|
private static final boolean INCREMENTAL_RESULTS = true;
|
||||||
private static final int SEARCH_PERIODICITY_SEC = 5;
|
private static final int SEARCH_PERIODICITY_SEC = 5;
|
||||||
@@ -83,6 +123,9 @@ public class NetworkScanHelper {
|
|||||||
|
|
||||||
private NetworkScan mNetworkScanRequester;
|
private NetworkScan mNetworkScanRequester;
|
||||||
|
|
||||||
|
/** Callbacks for sync network scan */
|
||||||
|
private ListenableFuture<List<CellInfo>> mNetworkScanFuture;
|
||||||
|
|
||||||
public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) {
|
public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) {
|
||||||
mTelephonyManager = tm;
|
mTelephonyManager = tm;
|
||||||
mNetworkScanCallback = callback;
|
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(
|
* @param type used to tell which network scan API should be used.
|
||||||
* 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)}.
|
|
||||||
*/
|
*/
|
||||||
public void startNetworkScan() {
|
public void startNetworkScan(@NetworkQueryType int type) {
|
||||||
if (mNetworkScanRequester != null) {
|
if (type == NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS) {
|
||||||
return;
|
mNetworkScanFuture = SettableFuture.create();
|
||||||
}
|
Futures.addCallback(mNetworkScanFuture, new FutureCallback<List<CellInfo>>() {
|
||||||
mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
|
@Override
|
||||||
createNetworkScanForPreferredAccessNetworks(),
|
public void onSuccess(List<CellInfo> result) {
|
||||||
mExecutor,
|
onResults(result);
|
||||||
mInternalNetworkScanCallback);
|
onComplete();
|
||||||
if (mNetworkScanRequester == null) {
|
}
|
||||||
onError(NetworkScan.ERROR_RADIO_INTERFACE_ERROR);
|
|
||||||
|
@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.
|
* 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
|
||||||
* Use this method to stop an ongoing scan. When user requests a new scan, a {@link NetworkScan}
|
* calling this method.
|
||||||
* object will be returned, and the user can stop the scan by calling this method.
|
|
||||||
*/
|
*/
|
||||||
public void stopNetworkQuery() {
|
public void stopNetworkQuery() {
|
||||||
if (mNetworkScanRequester != null) {
|
if (mNetworkScanRequester != null) {
|
||||||
mNetworkScanRequester.stopScan();
|
mNetworkScanRequester.stopScan();
|
||||||
mNetworkScanRequester = null;
|
mNetworkScanRequester = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mNetworkScanFuture != null) {
|
||||||
|
mNetworkScanFuture.cancel(true /* mayInterruptIfRunning */);
|
||||||
|
mNetworkScanFuture = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onResults(List<CellInfo> cellInfos) {
|
private void onResults(List<CellInfo> cellInfos) {
|
||||||
@@ -185,6 +253,23 @@ public class NetworkScanHelper {
|
|||||||
mNetworkScanCallback.onError(errCode);
|
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 {
|
private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
|
||||||
public void onResults(List<CellInfo> results) {
|
public void onResults(List<CellInfo> results) {
|
||||||
Log.d(TAG, "Async scan onResults() results = "
|
Log.d(TAG, "Async scan onResults() results = "
|
||||||
@@ -202,4 +287,35 @@ public class NetworkScanHelper {
|
|||||||
NetworkScanHelper.this.onError(errCode);
|
NetworkScanHelper.this.onError(errCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class NetworkScanSyncTask implements Runnable {
|
||||||
|
private final SettableFuture<List<CellInfo>> mCallback;
|
||||||
|
private final TelephonyManager mTelephonyManager;
|
||||||
|
|
||||||
|
NetworkScanSyncTask(
|
||||||
|
TelephonyManager telephonyManager, SettableFuture<List<CellInfo>> callback) {
|
||||||
|
mTelephonyManager = telephonyManager;
|
||||||
|
mCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
|
||||||
|
if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) {
|
||||||
|
final List<CellInfo> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -93,6 +93,8 @@ public class NetworkSelectSettings extends DashboardFragment {
|
|||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
|
mUseNewApi = getContext().getResources().getBoolean(
|
||||||
|
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
|
||||||
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID);
|
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID);
|
||||||
|
|
||||||
mPreferenceCategory = findPreference(PREF_KEY_NETWORK_OPERATORS);
|
mPreferenceCategory = findPreference(PREF_KEY_NETWORK_OPERATORS);
|
||||||
@@ -464,7 +466,10 @@ public class NetworkSelectSettings extends DashboardFragment {
|
|||||||
if (mNetworkScanHelper != null) {
|
if (mNetworkScanHelper != null) {
|
||||||
mRequestIdManualNetworkScan = getNewRequestId();
|
mRequestIdManualNetworkScan = getNewRequestId();
|
||||||
mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -164,7 +164,8 @@ public class NetworkScanHelperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startNetworkScan_incremental(boolean waitForCompletion) {
|
private void startNetworkScan_incremental(boolean waitForCompletion) {
|
||||||
mNetworkScanHelper.startNetworkScan();
|
mNetworkScanHelper.startNetworkScan(
|
||||||
|
NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS);
|
||||||
if (!waitForCompletion) {
|
if (!waitForCompletion) {
|
||||||
mNetworkScanHelper.stopNetworkQuery();
|
mNetworkScanHelper.stopNetworkQuery();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user