add MVNO check routine

modify createApnList() API as the followings:

1.1 mvno != null (already matched mvno info)
1.2 mvno == cur_mvno_info
1.2.1 result.add
2.1 mvno == null (not yet)
2.2 mvnoMatch check
2.2.1 clear prev results.
2.2.2 result add (mvno)
2.3 mvno_type is null
2.3.1 result add (normal)

match mvno as the followings:
1. if mvno_type is spn, compare spn of SIM
2. if mvno_type is imsi, compare imsi of SIM
3. if mvno_type is gid, compare gid of SIM

Bug: 8143480
Change-Id: Idf0aa1ddf139f80c7d33b1e3315493d32dbf433a
diff --git a/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index ae5fb0f..ba34025 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -951,39 +951,115 @@
         return result;
     }
 
+   private boolean imsiMatches(String imsiDB, String imsiSIM) {
+        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
+        // for MVNO operator. And then digit number is matched at same order and 'x' character
+        // could replace by any digit number.
+        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
+        //     that means first 6 digits, 8th and 9th digit
+        //     should be set in USIM for GG Operator.
+        int len = imsiDB.length();
+        int idxCompare = 0;
+
+        if (len <= 0) return false;
+        if (len > imsiSIM.length()) return false;
+
+        for (int idx=0; idx<len; idx++) {
+            char c = imsiDB.charAt(idx);
+            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean mvnoMatches(IccRecords r, String mvno_type, String mvno_match_data) {
+        if (mvno_type.equalsIgnoreCase("spn")) {
+            if ((r.getServiceProviderName() != null) &&
+                    r.getServiceProviderName().equalsIgnoreCase(mvno_match_data)) {
+                return true;
+            }
+        } else if (mvno_type.equalsIgnoreCase("imsi")) {
+            String imsiSIM = r.getIMSI();
+            if ((imsiSIM != null) && imsiMatches(mvno_match_data, imsiSIM)) {
+                return true;
+            }
+        } else if (mvno_type.equalsIgnoreCase("gid")) {
+            String gid1 = r.getGid1();
+            if ((gid1 != null) && gid1.substring(0,
+                    mvno_match_data.length()).equalsIgnoreCase(mvno_match_data)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private ApnSetting makeApnSetting(Cursor cursor) {
+        String[] types = parseTypes(
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
+        ApnSetting apn = new ApnSetting(
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
+                NetworkUtils.trimV4AddrZeros(
+                        cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
+                NetworkUtils.trimV4AddrZeros(
+                        cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
+                NetworkUtils.trimV4AddrZeros(
+                        cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
+                types,
+                cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
+                cursor.getString(cursor.getColumnIndexOrThrow(
+                        Telephony.Carriers.ROAMING_PROTOCOL)),
+                cursor.getInt(cursor.getColumnIndexOrThrow(
+                        Telephony.Carriers.CARRIER_ENABLED)) == 1,
+                cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
+        return apn;
+    }
+
     private ArrayList<ApnSetting> createApnList(Cursor cursor) {
         ArrayList<ApnSetting> result = new ArrayList<ApnSetting>();
+        IccRecords r = mIccRecords.get();
+
         if (cursor.moveToFirst()) {
+            String mvnoType = null;
+            String mvnoMatchData = null;
             do {
-                String[] types = parseTypes(
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
-                ApnSetting apn = new ApnSetting(
-                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
-                        NetworkUtils.trimV4AddrZeros(
-                                cursor.getString(
-                                cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
-                        NetworkUtils.trimV4AddrZeros(
-                                cursor.getString(
-                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
-                        NetworkUtils.trimV4AddrZeros(
-                                cursor.getString(
-                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
-                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
-                        types,
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(
-                                Telephony.Carriers.ROAMING_PROTOCOL)),
-                        cursor.getInt(cursor.getColumnIndexOrThrow(
-                                Telephony.Carriers.CARRIER_ENABLED)) == 1,
-                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
-                result.add(apn);
+                String cursorMvnoType = cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE));
+                String cursorMvnoMatchData = cursor.getString(
+                        cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA));
+                if (mvnoType != null) {
+                    if (mvnoType.equals(cursorMvnoType) &&
+                            mvnoMatchData.equals(cursorMvnoMatchData)) {
+                        result.add(makeApnSetting(cursor));
+                    }
+                } else {
+                    // no mvno match yet
+                    if (mvnoMatches(r, cursorMvnoType, cursorMvnoMatchData)) {
+                        // first match - toss out non-mvno data
+                        result.clear();
+                        mvnoType = cursorMvnoType;
+                        mvnoMatchData = cursorMvnoMatchData;
+                        result.add(makeApnSetting(cursor));
+                    } else {
+                        // add only non-mvno data
+                        if (cursorMvnoType.equals("")) {
+                            result.add(makeApnSetting(cursor));
+                        }
+                    }
+                }
             } while (cursor.moveToNext());
         }
         if (DBG) log("createApnList: X result=" + result);