operator: Virgin: Set proper SPN for Virgin [1/2]

Affected MCCMNC: 23438 and conditionally 23430

Use SPN as "Virgin" whenever a Virgin SIM is used.

SPN of 23430 is EE, unless GID1 is 2800000000000000, in which case it
belongs to Virgin as well.

Squashed changes and fixup:
* f89d53db "Distinguish between Virgin and EE [1/2]"
* e14a90f9 "Address third party app crash due to missing GID [1/2]"
* 627f4ba4 "Address third party app crash due to missing GID [2/2]"

Issue: PRJ8901-830
Issue: PRJ8901-1544
Issue: PRJ8901-1577
Issue: PRJ8901-1568
Issue: FP3-A11#185
Issue: FP3-A11#231
Change-Id: Id52e35be79b6a7131f467df1b8d41eb926485c3e
(cherry picked from commit 435ba7bc24acbacac71c212b3270ed872375998f)
(cherry picked from commit da8ab1676f0f58893addb957f169890e0a323432)
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3798def..bbf989c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -337,6 +337,8 @@
         UNKNOWN
     };
 
+    private static final String VIRGIN_OPERATOR_NAME = "Virgin";
+
     /** @hide */
     @UnsupportedAppUsage
     public TelephonyManager(Context context) {
@@ -3817,6 +3819,20 @@
         return getSimOperatorNameForPhone(phoneId);
     }
 
+    private static boolean isVirginSIM(String voiceOperatorNumeric, String gid1) {
+        if (voiceOperatorNumeric == null || voiceOperatorNumeric.length() < 5 || gid1 == null) {
+            return false;
+        }
+        if ("23438".equals(voiceOperatorNumeric.substring(0, 5))) {
+            return true;
+        }
+        if ("23430".equals(voiceOperatorNumeric.substring(0, 5))) {
+            // GID1: 28000000...00
+            return gid1.matches("^280+$");
+        }
+        return false;
+    }
+
     /**
      * Returns the Service Provider Name (SPN).
      *
@@ -3824,7 +3840,31 @@
      */
     @UnsupportedAppUsage
     public String getSimOperatorNameForPhone(int phoneId) {
-        return getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_alpha(), "");
+        if (!isSystemProcess()) {
+            return getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_alpha(), "");
+        }
+
+        final String simNumber =
+                getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_numeric(), "");
+        final String spn =
+                getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_alpha(), "");
+        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
+            return spn;
+        }
+        final int[] subIds = mSubscriptionManager.getSubId(phoneId);
+        if (subIds == null) {
+            return spn;
+        }
+        String gid1;
+        try {
+            gid1 = getGroupIdLevel1(subIds[0]);
+        } catch (SecurityException se) {
+            gid1 = null;
+        }
+        if (isVirginSIM(simNumber, gid1)) {
+            return VIRGIN_OPERATOR_NAME;
+        }
+        return spn;
     }
 
     /**
@@ -9948,6 +9988,36 @@
                     TelephonyProperties.icc_operator_numeric(), phoneId, numeric);
             TelephonyProperties.icc_operator_numeric(newList);
         }
+
+        if (!isSystemProcess()) {
+            return;
+        }
+
+        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
+            return;
+        }
+        final int[] subIds = mSubscriptionManager.getSubId(phoneId);
+        if (subIds == null) {
+            return;
+        }
+        String gid1;
+        try {
+            gid1 = getGroupIdLevel1(subIds[0]);
+        } catch (SecurityException se) {
+            gid1 = null;
+        }
+        if (isVirginSIM(numeric, gid1)) {
+            final String operatorName =
+                    getTelephonyProperty(phoneId, TelephonyProperties.icc_operator_alpha(), "");
+            if (!VIRGIN_OPERATOR_NAME.equals(operatorName)) {
+                List<String> newList =
+                        updateTelephonyProperty(
+                                TelephonyProperties.icc_operator_alpha(),
+                                phoneId,
+                                VIRGIN_OPERATOR_NAME);
+                TelephonyProperties.icc_operator_alpha(newList);
+            }
+        }
     }
 
     /**