Merge "Optimize NetworkScan for only User-Enabled RANs" into rvc-dev
diff --git a/src/com/android/settings/network/telephony/NetworkScanHelper.java b/src/com/android/settings/network/telephony/NetworkScanHelper.java
index eb0d020..6d3cdbb 100644
--- a/src/com/android/settings/network/telephony/NetworkScanHelper.java
+++ b/src/com/android/settings/network/telephony/NetworkScanHelper.java
@@ -25,6 +25,7 @@
 import android.telephony.TelephonyScanManager;
 import android.util.Log;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executor;
 
@@ -75,37 +76,6 @@
     private static final int MAX_SEARCH_TIME_SEC = 300;
     private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
 
-    private static final NetworkScanRequest NETWORK_SCAN_REQUEST =
-            new NetworkScanRequest(
-                    NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
-                    new RadioAccessSpecifier[]{
-                            // GSM
-                            new RadioAccessSpecifier(
-                                    AccessNetworkType.GERAN,
-                                    null /* bands */,
-                                    null /* channels */),
-                            // LTE
-                            new RadioAccessSpecifier(
-                                    AccessNetworkType.EUTRAN,
-                                    null /* bands */,
-                                    null /* channels */),
-                            // WCDMA
-                            new RadioAccessSpecifier(
-                                    AccessNetworkType.UTRAN,
-                                    null /* bands */,
-                                    null /* channels */),
-                            // NR
-                            new RadioAccessSpecifier(
-                                    AccessNetworkType.NGRAN,
-                                    null /* bands */,
-                                    null /* channels */)
-                    },
-                    SEARCH_PERIODICITY_SEC,
-                    MAX_SEARCH_TIME_SEC,
-                    INCREMENTAL_RESULTS,
-                    INCREMENTAL_RESULTS_PERIODICITY_SEC,
-                    null /* List of PLMN ids (MCC-MNC) */);
-
     private final NetworkScanCallback mNetworkScanCallback;
     private final TelephonyManager mTelephonyManager;
     private final TelephonyScanManager.NetworkScanCallback mInternalNetworkScanCallback;
@@ -120,6 +90,47 @@
         mExecutor = executor;
     }
 
+    private NetworkScanRequest createNetworkScanForPreferredAccessNetworks() {
+        long networkTypeBitmap3gpp = mTelephonyManager.getPreferredNetworkTypeBitmask()
+                & TelephonyManager.NETWORK_STANDARDS_FAMILY_BITMASK_3GPP;
+
+        List<RadioAccessSpecifier> radioAccessSpecifiers = new ArrayList<>();
+        // If the allowed network types are unknown or if they are of the right class, scan for
+        // them; otherwise, skip them to save scan time and prevent users from being shown networks
+        // that they can't connect to.
+        if (networkTypeBitmap3gpp == 0
+                || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_2G) != 0) {
+            radioAccessSpecifiers.add(
+                    new RadioAccessSpecifier(AccessNetworkType.GERAN, null, null));
+        }
+        if (networkTypeBitmap3gpp == 0
+                || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_3G) != 0) {
+            radioAccessSpecifiers.add(
+                    new RadioAccessSpecifier(AccessNetworkType.UTRAN, null, null));
+        }
+        if (networkTypeBitmap3gpp == 0
+                || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_4G) != 0) {
+            radioAccessSpecifiers.add(
+                    new RadioAccessSpecifier(AccessNetworkType.EUTRAN, null, null));
+        }
+        if (networkTypeBitmap3gpp == 0
+                || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_5G) != 0) {
+            radioAccessSpecifiers.add(
+                    new RadioAccessSpecifier(AccessNetworkType.NGRAN, null, null));
+        }
+
+
+        return new NetworkScanRequest(
+                NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
+                radioAccessSpecifiers.toArray(
+                        new RadioAccessSpecifier[radioAccessSpecifiers.size()]),
+                SEARCH_PERIODICITY_SEC,
+                MAX_SEARCH_TIME_SEC,
+                INCREMENTAL_RESULTS,
+                INCREMENTAL_RESULTS_PERIODICITY_SEC,
+                null /* List of PLMN ids (MCC-MNC) */);
+    }
+
     /**
      * Request a network scan.
      *
@@ -134,7 +145,7 @@
             return;
         }
         mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
-                NETWORK_SCAN_REQUEST,
+                createNetworkScanForPreferredAccessNetworks(),
                 mExecutor,
                 mInternalNetworkScanCallback);
         if (mNetworkScanRequester == null) {