From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mattias Nilsson <Mattias.Nilsson@sony.com>
Date: Thu, 15 Apr 2021 17:11:27 +0200
Subject: [PATCH] MNCs not in carrier_list can get the wrong MNC value

Mobile Network Codes that belong to SIM cards not specified
in carrier_list sometimes get the wrong MNC value.

This change aims to improve the likelihood of a
correct MNC.

Test: Install an RRO with apns.xml and look at the DB.
Bug: 186542894
Change-Id: I1dbccf9d75a7a8ae896ca483935bc5e007843e75
---
 .../telephony/TelephonyProvider.java          | 68 ++++++++++++++++---
 1 file changed, 58 insertions(+), 10 deletions(-)

diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index b1b3146d..6bddde93 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -260,6 +260,40 @@ public class TelephonyProvider extends ContentProvider
 
     private boolean mManagedApnEnforced;
 
+    /**
+     * Mobile country codes where there is a high likelyhood that the MNC has 3 digits
+     * and need one more prefix zero to set correct mobile network code value.
+     *
+     * Please note! The best solution is to add the MCCMNC combo to carrier id
+     * carrier_list, this is just a best effort.
+     */
+    private static final String[] COUNTRY_MCC_WITH_THREE_DIGIT_MNC = {
+            "302" // Canada
+           ,"310" // Guam, USA
+           ,"311" // USA
+           ,"312" // USA
+           ,"313" // USA
+           ,"316" // USA
+           ,"334" // Mexico
+           ,"338" // Bermuda, Jamaica
+           ,"342" // Barbados
+           ,"344" // Antigua and Barbuda
+           ,"346" // Cayman Islands
+           ,"348" // British Virgin Islands
+           ,"356" // Saint Kitts and Nevis
+           ,"358" // Saint Lucia
+           ,"360" // Saint Vincent and the Grenadines
+           ,"365" // Anguilla
+           ,"366" // Dominica
+           ,"376" // Turks and Caicos Islands
+           ,"405" // India
+           ,"708" // Honduras
+           ,"722" // Argentina
+           ,"732" // Colombia
+           ,"738" // Guyana
+           ,"750" // Falkland Islands
+            };
+
     /**
      * Available radio technologies for GSM, UMTS and CDMA.
      * Duplicates the constants from hardware/radio/include/ril.h
@@ -4151,18 +4185,32 @@ public class TelephonyProvider extends ContentProvider
         }
         String twoDigitMnc = String.format(Locale.getDefault(), "%02d", mnc);
         String threeDigitMnc = "0" + twoDigitMnc;
+        boolean threeDigitNetworkCode =
+                Arrays.asList(COUNTRY_MCC_WITH_THREE_DIGIT_MNC).contains(mcc);
+        int twoDigitResult = countMccMncInCarrierList(context, mcc + twoDigitMnc);
+        int threeDigitResult = countMccMncInCarrierList(context, mcc + threeDigitMnc);
 
-        try (
-                Cursor twoDigitMncCursor = context.getContentResolver().query(
-                        Telephony.CarrierId.All.CONTENT_URI,
-                        /* projection */ null,
-                        /* selection */ Telephony.CarrierId.All.MCCMNC + "=?",
-                        /* selectionArgs */ new String[]{mcc + twoDigitMnc}, null)
-        ) {
-            if (twoDigitMncCursor.getCount() > 0) {
-                return twoDigitMnc;
-            }
+        if ((threeDigitResult > twoDigitResult) ||
+                (threeDigitNetworkCode && (twoDigitResult == threeDigitResult))) {
             return threeDigitMnc;
+        } else {
+            return twoDigitMnc;
+        }
+    }
+
+    /**
+     * Check carrier_list how many mcc mnc combo matches there are
+     */
+    private static int countMccMncInCarrierList(Context ctx, String mccMncCombo) {
+        try (
+            Cursor mccMncCursor = ctx.getContentResolver().query(
+                    Telephony.CarrierId.All.CONTENT_URI,
+                    /* projection */ null,
+                    /* selection */ Telephony.CarrierId.All.MCCMNC + "=?",
+                    /* selectionArgs */ new String[]{mccMncCombo}, null);
+        )
+        {
+            return mccMncCursor.getCount();
         }
     }
 
