From 54828510a0eadfc6ba663a61a2a056ed55ab7e21 Mon Sep 17 00:00:00 2001
From: Mattias Nilsson <mattias.nilsson@sony.com>
Date: Fri, 13 Nov 2020 22:30:08 +0100
Subject: [PATCH] Mcc and mnc from xml in RRO may be integers

Mcc and mnc in an xml from overlays built in current android build
system are integers to the contrary of the apns-full-conf.xml
where they are strings. The telephony provider uses the same parsing
mechanism in both cases which makes the full apn list get
correct values whereas the provider misjudge what it should
insert in the database when there is an apns.xml in an overlay.

For the newly built android RROs mnc="01" becomes mnc="1" and no
match is found when the sim card is inserted.

To not risk the large APN list we only change the behavior for the
overlay handling.

Solution is to format the mcc value to have 3 digits and use the
carrier id table to get correct mnc. Sim cards missing
in the carrier id table need to be added there.

Test: Manual
Test: adb shell content query --uri content://telephony/carriers
Bug: 175620622
Change-Id: I244ad0f76f360a0635343187e455b54c90ec45b4
---
 .../telephony/TelephonyProvider.java          | 35 ++++++++++++-------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 3cb4abeb..b1b3146d 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -128,6 +128,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.Integer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -752,7 +753,7 @@ private void initDatabase(SQLiteDatabase db) {
                 try {
                     XmlUtils.beginDocument(parser, "apns");
                     publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
-                    loadApns(db, parser);
+                    loadApns(db, parser, true);
                 } catch (Exception e) {
                     loge("Got exception while loading APN database." + e);
                 } finally {
@@ -782,7 +783,7 @@ private void initDatabase(SQLiteDatabase db) {
                             + confFile.getAbsolutePath());
                 }
 
-                loadApns(db, confparser);
+                loadApns(db, confparser, false);
             } catch (FileNotFoundException e) {
                 // It's ok if the file isn't found. It means there isn't a confidential file
                 // Log.e(TAG, "File not found: '" + confFile.getAbsolutePath() + "'");
@@ -1665,7 +1666,7 @@ private void deleteMatchingApns(SQLiteDatabase db, XmlPullParser parser) {
                 try {
                     XmlUtils.nextElement(parser);
                     while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
-                        ContentValues row = getRow(parser);
+                        ContentValues row = getRow(parser, false);
                         if (row == null) {
                             throw new XmlPullParserException("Expected 'apn' tag", parser, null);
                         }
@@ -2072,9 +2073,10 @@ private void getBlobValueFromCursor(ContentValues cv, Cursor c, String key) {
          * Gets the next row of apn values.
          *
          * @param parser the parser
+         * @param isOverlay If the xml file comes from an overlay MCC/MNC are treated as integers
          * @return the row or null if it's not an apn
          */
-        private ContentValues getRow(XmlPullParser parser) {
+        private ContentValues getRow(XmlPullParser parser, boolean isOverlay) {
             if (!"apn".equals(parser.getName())) {
                 return null;
             }
@@ -2083,11 +2085,21 @@ private ContentValues getRow(XmlPullParser parser) {
 
             String mcc = parser.getAttributeValue(null, "mcc");
             String mnc = parser.getAttributeValue(null, "mnc");
-            String numeric = mcc + mnc;
-
+            String mccString = mcc;
+            String mncString = mnc;
+            // Since an mnc can have both two and three digits and it is hard to verify
+            // all OEM's Global APN lists we only do this for overlays.
+            if (isOverlay) {
+                mccString = String.format("%03d", Integer.parseInt(mcc));
+                // Looks up a two digit mnc in the carrier id DB
+                // if not found a three digit mnc value is chosen
+                mncString = getBestStringMnc(mContext, mccString, Integer.parseInt(mnc));
+            }
+
+            String numeric = mccString + mncString;
             map.put(NUMERIC, numeric);
-            map.put(MCC, mcc);
-            map.put(MNC, mnc);
+            map.put(MCC, mccString);
+            map.put(MNC, mncString);
             map.put(NAME, parser.getAttributeValue(null, "carrier"));
 
             // do not add NULL to the map so that default values can be inserted in db
@@ -2156,7 +2168,6 @@ private ContentValues getRow(XmlPullParser parser) {
                     map.put(MVNO_MATCH_DATA, mvno_match_data);
                 }
             }
-
             return map;
         }
 
@@ -2189,15 +2200,15 @@ private void addBoolAttribute(XmlPullParser parser, String att,
          *
          * @param db the sqlite database to write to
          * @param parser the xml parser
-         *
+         * @param isOverlay, if we are parsing an xml in an overlay
          */
-        private void loadApns(SQLiteDatabase db, XmlPullParser parser) {
+        private void loadApns(SQLiteDatabase db, XmlPullParser parser, boolean isOverlay) {
             if (parser != null) {
                 try {
                     db.beginTransaction();
                     XmlUtils.nextElement(parser);
                     while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
-                        ContentValues row = getRow(parser);
+                        ContentValues row = getRow(parser, isOverlay);
                         if (row == null) {
                             throw new XmlPullParserException("Expected 'apn' tag", parser, null);
                         }
