FileDocCategorySizeDatePackage
SmsNumberUtils.javaAPI DocAndroid 5.1 API26204Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony

SmsNumberUtils.java

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import android.content.Context;
import android.os.SystemProperties;
import android.os.Build;
import android.text.TextUtils;
import android.content.ContentResolver;
import android.database.Cursor;
import android.database.SQLException;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.telephony.Rlog;
import com.android.internal.telephony.HbpcdLookup.MccIdd;
import com.android.internal.telephony.HbpcdLookup.MccLookup;


 /**
 * This class implements handle the MO SMS target address before sending.
 * This is special for VZW requirement. Follow the specificaitons of assisted dialing
 * of MO SMS while traveling on VZW CDMA, international CDMA or GSM markets.
 * {@hide}
 */
public class SmsNumberUtils {
    private static final String TAG = "SmsNumberUtils";
    private static final boolean DBG = Build.IS_DEBUGGABLE;

    private static final String PLUS_SIGN = "+";

    private static final int NANP_SHORT_LENGTH = 7;
    private static final int NANP_MEDIUM_LENGTH = 10;
    private static final int NANP_LONG_LENGTH = 11;

    private static final int NANP_CC = 1;
    private static final String NANP_NDD = "1";
    private static final String NANP_IDD = "011";

    private static final int MIN_COUNTRY_AREA_LOCAL_LENGTH = 10;

    private static final int GSM_UMTS_NETWORK = 0;
    private static final int CDMA_HOME_NETWORK = 1;
    private static final int CDMA_ROAMING_NETWORK = 2;

    private static final int NP_NONE = 0;
    private static final int NP_NANP_BEGIN = 1;

    /* <Phone Number>, <NXX>-<XXXX> N[2-9] */
    private static final int NP_NANP_LOCAL = NP_NANP_BEGIN;

    /* <Area_code>-<Phone Number>, <NXX>-<NXX>-<XXXX> N[2-9] */
    private static final int NP_NANP_AREA_LOCAL = NP_NANP_BEGIN + 1;

    /* <1>-<Area_code>-<Phone Number>, 1-<NXX>-<NXX>-<XXXX> N[2-9] */
    private static final int NP_NANP_NDD_AREA_LOCAL = NP_NANP_BEGIN + 2;

    /* <+><U.S.Country_code><Area_code><Phone Number>, +1-<NXX>-<NXX>-<XXXX> N[2-9] */
    private static final int NP_NANP_NBPCD_CC_AREA_LOCAL = NP_NANP_BEGIN + 3;

    /* <Local_IDD><Country_code><Area_code><Phone Number>, 001-1-<NXX>-<NXX>-<XXXX> N[2-9] */
    private static final int NP_NANP_LOCALIDD_CC_AREA_LOCAL = NP_NANP_BEGIN + 4;

    /* <+><Home_IDD><Country_code><Area_code><Phone Number>, +011-1-<NXX>-<NXX>-<XXXX> N[2-9] */
    private static final int NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL = NP_NANP_BEGIN + 5;

    private static final int NP_INTERNATIONAL_BEGIN = 100;
    /* <+>-<Home_IDD>-<Country_code>-<Area_code>-<Phone Number>, +011-86-25-86281234 */
    private static final int NP_NBPCD_HOMEIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN;

    /* <Home_IDD>-<Country_code>-<Area_code>-<Phone Number>, 011-86-25-86281234 */
    private static final int NP_HOMEIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 1;

    /* <NBPCD>-<Country_code>-<Area_code>-<Phone Number>, +1-86-25-86281234 */
    private static final int NP_NBPCD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 2;

    /* <Local_IDD>-<Country_code>-<Area_code>-<Phone Number>, 00-86-25-86281234 */
    private static final int NP_LOCALIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 3;

    /* <Country_code>-<Area_code>-<Phone Number>, 86-25-86281234*/
    private static final int NP_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 4;

    private static int[] ALL_COUNTRY_CODES = null;
    private static int MAX_COUNTRY_CODES_LENGTH;
    private static HashMap<String, ArrayList<String>> IDDS_MAPS =
            new HashMap<String, ArrayList<String>>();

    private static class NumberEntry {
        public String number;
        public String IDD;
        public int countryCode;
        public NumberEntry(String number) {
            this.number = number;
        }
    }

    /* Breaks the given number down and formats it according to the rules
     * for different number plans and differnt network.
     *
     * @param number destionation number which need to be format
     * @param activeMcc current network's mcc
     * @param networkType current network type
     *
     * @return the number after fromatting.
     */
    private static String formatNumber(Context context, String number,
                               String activeMcc,
                               int networkType) {
        if (number == null ) {
            throw new IllegalArgumentException("number is null");
        }

        if (activeMcc == null || activeMcc.trim().length() == 0) {
            throw new IllegalArgumentException("activeMcc is null or empty!");
        }

        String networkPortionNumber = PhoneNumberUtils.extractNetworkPortion(number);
        if (networkPortionNumber == null || networkPortionNumber.length() == 0) {
            throw new IllegalArgumentException("Number is invalid!");
        }

        NumberEntry numberEntry = new NumberEntry(networkPortionNumber);
        ArrayList<String> allIDDs = getAllIDDs(context, activeMcc);

        // First check whether the number is a NANP number.
        int nanpState = checkNANP(numberEntry, allIDDs);
        if (DBG) Rlog.d(TAG, "NANP type: " + getNumberPlanType(nanpState));

        if ((nanpState == NP_NANP_LOCAL)
            || (nanpState == NP_NANP_AREA_LOCAL)
            || (nanpState == NP_NANP_NDD_AREA_LOCAL)) {
            return networkPortionNumber;
        } else if (nanpState == NP_NANP_NBPCD_CC_AREA_LOCAL) {
            if (networkType == CDMA_HOME_NETWORK
                    || networkType == CDMA_ROAMING_NETWORK) {
                // Remove "+"
                return networkPortionNumber.substring(1);
            } else {
                return networkPortionNumber;
            }
        } else if (nanpState == NP_NANP_LOCALIDD_CC_AREA_LOCAL) {
            if (networkType == CDMA_HOME_NETWORK) {
                return networkPortionNumber;
            } else if (networkType == GSM_UMTS_NETWORK) {
                // Remove the local IDD and replace with "+"
                int iddLength  =  numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
                return PLUS_SIGN + networkPortionNumber.substring(iddLength);
            } else if (networkType == CDMA_ROAMING_NETWORK) {
                // Remove the local IDD
                int iddLength  =  numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
                return  networkPortionNumber.substring(iddLength);
            }
        }

        int internationalState = checkInternationalNumberPlan(context, numberEntry, allIDDs,
                NANP_IDD);
        if (DBG) Rlog.d(TAG, "International type: " + getNumberPlanType(internationalState));
        String returnNumber = null;

        switch (internationalState) {
            case NP_NBPCD_HOMEIDD_CC_AREA_LOCAL:
                if (networkType == GSM_UMTS_NETWORK) {
                    // Remove "+"
                    returnNumber = networkPortionNumber.substring(1);
                }
                break;

            case NP_NBPCD_CC_AREA_LOCAL:
                // Replace "+" with "011"
                returnNumber = NANP_IDD + networkPortionNumber.substring(1);
                break;

            case NP_LOCALIDD_CC_AREA_LOCAL:
                if (networkType == GSM_UMTS_NETWORK || networkType == CDMA_ROAMING_NETWORK) {
                    int iddLength  =  numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
                    // Replace <Local IDD> to <Home IDD>("011")
                    returnNumber = NANP_IDD + networkPortionNumber.substring(iddLength);
                }
                break;

            case NP_CC_AREA_LOCAL:
                int countryCode = numberEntry.countryCode;

                if (!inExceptionListForNpCcAreaLocal(numberEntry)
                    && networkPortionNumber.length() >= 11 && countryCode != NANP_CC) {
                    // Add "011"
                    returnNumber = NANP_IDD + networkPortionNumber;
                }
                break;

            case NP_HOMEIDD_CC_AREA_LOCAL:
                returnNumber = networkPortionNumber;
                break;

            default:
                // Replace "+" with 011 in CDMA network if the number's country
                // code is not in the HbpcdLookup database.
                if (networkPortionNumber.startsWith(PLUS_SIGN)
                    && (networkType == CDMA_HOME_NETWORK || networkType == CDMA_ROAMING_NETWORK)) {
                    if (networkPortionNumber.startsWith(PLUS_SIGN + NANP_IDD)) {
                        // Only remove "+"
                        returnNumber = networkPortionNumber.substring(1);
                    } else {
                        // Replace "+" with "011"
                        returnNumber = NANP_IDD + networkPortionNumber.substring(1);
                    }
                }
        }

        if (returnNumber == null) {
            returnNumber = networkPortionNumber;
        }
        return returnNumber;
    }

    /* Query International direct dialing from HbpcdLookup.db
     * for specified country code
     *
     * @param mcc current network's country code
     *
     * @return the IDD array list.
     */
    private static ArrayList<String> getAllIDDs(Context context, String mcc) {
        ArrayList<String> allIDDs = IDDS_MAPS.get(mcc);
        if (allIDDs != null) {
            return allIDDs;
        } else {
            allIDDs = new ArrayList<String>();
        }

        String projection[] = {MccIdd.IDD, MccIdd.MCC};
        String where = null;

        // if mcc is null         : return all rows
        // if mcc is empty-string : return those rows whose mcc is emptry-string
        String[] selectionArgs = null;
        if (mcc != null) {
            where = MccIdd.MCC + "=?";
            selectionArgs = new String[] {mcc};
        }

        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(MccIdd.CONTENT_URI, projection,
                    where, selectionArgs, null);
            if (cursor.getCount() > 0) {
                while (cursor.moveToNext()) {
                    String idd = cursor.getString(0);
                    if (!allIDDs.contains(idd)) {
                        allIDDs.add(idd);
                    }
                }
            }
        } catch (SQLException e) {
            Rlog.e(TAG, "Can't access HbpcdLookup database", e);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        IDDS_MAPS.put(mcc, allIDDs);

        if (DBG) Rlog.d(TAG, "MCC = " + mcc + ", all IDDs = " + allIDDs);
        return allIDDs;
    }


    /* Verify if the the destination number is a NANP number
     *
     * @param numberEntry including number and IDD array
     * @param allIDDs the IDD array list of the current network's country code
     *
     * @return the number plan type related NANP
     */
    private static int checkNANP(NumberEntry numberEntry, ArrayList<String> allIDDs) {
        boolean isNANP = false;
        String number = numberEntry.number;

        if (number.length() == NANP_SHORT_LENGTH) {
            // 7 digits - Seven digit phone numbers
            char firstChar = number.charAt(0);
            if (firstChar >= '2' && firstChar <= '9') {
                isNANP = true;
                for (int i=1; i< NANP_SHORT_LENGTH; i++ ) {
                    char c= number.charAt(i);
                    if (!PhoneNumberUtils.isISODigit(c)) {
                        isNANP = false;
                        break;
                    }
                }
            }
            if (isNANP) {
                return NP_NANP_LOCAL;
            }
        } else if (number.length() == NANP_MEDIUM_LENGTH) {
            // 10 digits - Three digit area code followed by seven digit phone numbers/
            if (isNANP(number)) {
                return NP_NANP_AREA_LOCAL;
            }
        } else if (number.length() == NANP_LONG_LENGTH) {
            // 11 digits - One digit U.S. NDD(National Direct Dial) prefix '1',
            // followed by three digit area code and seven digit phone numbers
            if (isNANP(number)) {
                return NP_NANP_NDD_AREA_LOCAL;
            }
        } else if (number.startsWith(PLUS_SIGN)) {
            number = number.substring(1);
            if (number.length() == NANP_LONG_LENGTH) {
                // '+' and 11 digits -'+', followed by NANP CC prefix '1' followed by
                // three digit area code and seven digit phone numbers
                if (isNANP(number)) {
                    return NP_NANP_NBPCD_CC_AREA_LOCAL;
                }
            } else if (number.startsWith(NANP_IDD) && number.length() == NANP_LONG_LENGTH + 3) {
                // '+' and 14 digits -'+', followed by NANP IDD "011" followed by NANP CC
                // prefix '1' followed by three digit area code and seven digit phone numbers
                number = number.substring(3);
                if (isNANP(number)) {
                    return NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL;
                }
            }
        } else {
            // Check whether it's NP_NANP_LOCALIDD_CC_AREA_LOCAL
            for (String idd : allIDDs) {
                if (number.startsWith(idd)) {
                    String number2 = number.substring(idd.length());
                    if(number2 !=null && number2.startsWith(String.valueOf(NANP_CC))){
                        if (isNANP(number2)) {
                            numberEntry.IDD = idd;
                            return NP_NANP_LOCALIDD_CC_AREA_LOCAL;
                        }
                    }
                }
            }
        }

        return NP_NONE;
    }

    private static boolean isNANP(String number) {
        if (number.length() == NANP_MEDIUM_LENGTH
            || (number.length() == NANP_LONG_LENGTH  && number.startsWith(NANP_NDD))) {
            if (number.length() == NANP_LONG_LENGTH) {
                number = number.substring(1);
            }
            return (PhoneNumberUtils.isNanp(number));
        }
        return false;
    }

    /* Verify if the the destination number is an internal number
     *
     * @param numberEntry including number and IDD array
     * @param allIDDs the IDD array list of the current network's country code
     *
     * @return the number plan type related international number
     */
    private static int checkInternationalNumberPlan(Context context, NumberEntry numberEntry,
            ArrayList<String> allIDDs,String homeIDD) {
        String number = numberEntry.number;
        int countryCode = -1;

        if (number.startsWith(PLUS_SIGN)) {
            // +xxxxxxxxxx
            String numberNoNBPCD = number.substring(1);
            if (numberNoNBPCD.startsWith(homeIDD)) {
                // +011xxxxxxxx
                String numberCountryAreaLocal = numberNoNBPCD.substring(homeIDD.length());
                if ((countryCode = getCountryCode(context, numberCountryAreaLocal)) > 0) {
                    numberEntry.countryCode = countryCode;
                    return NP_NBPCD_HOMEIDD_CC_AREA_LOCAL;
                }
            } else if ((countryCode = getCountryCode(context, numberNoNBPCD)) > 0) {
                numberEntry.countryCode = countryCode;
                return NP_NBPCD_CC_AREA_LOCAL;
            }

        } else if (number.startsWith(homeIDD)) {
            // 011xxxxxxxxx
            String numberCountryAreaLocal = number.substring(homeIDD.length());
            if ((countryCode = getCountryCode(context, numberCountryAreaLocal)) > 0) {
                numberEntry.countryCode = countryCode;
                return NP_HOMEIDD_CC_AREA_LOCAL;
            }
        } else {
            for (String exitCode : allIDDs) {
                if (number.startsWith(exitCode)) {
                    String numberNoIDD = number.substring(exitCode.length());
                    if ((countryCode = getCountryCode(context, numberNoIDD)) > 0) {
                        numberEntry.countryCode = countryCode;
                        numberEntry.IDD = exitCode;
                        return NP_LOCALIDD_CC_AREA_LOCAL;
                    }
                }
            }

            if (!number.startsWith("0") && (countryCode = getCountryCode(context, number)) > 0) {
                numberEntry.countryCode = countryCode;
                return NP_CC_AREA_LOCAL;
            }
        }
        return NP_NONE;
    }

    /**
     *  Returns the country code from the given number.
     */
    private static int getCountryCode(Context context, String number) {
        int countryCode = -1;
        if (number.length() >= MIN_COUNTRY_AREA_LOCAL_LENGTH) {
            // Check Country code
            int[] allCCs = getAllCountryCodes(context);
            if (allCCs == null) {
                return countryCode;
            }

            int[] ccArray = new int[MAX_COUNTRY_CODES_LENGTH];
            for (int i = 0; i < MAX_COUNTRY_CODES_LENGTH; i ++) {
                ccArray[i] = Integer.valueOf(number.substring(0, i+1));
            }

            for (int i = 0; i < allCCs.length; i ++) {
                int tempCC = allCCs[i];
                for (int j = 0; j < MAX_COUNTRY_CODES_LENGTH; j ++) {
                    if (tempCC == ccArray[j]) {
                        if (DBG) Rlog.d(TAG, "Country code = " + tempCC);
                        return tempCC;
                    }
                }
            }
        }

        return countryCode;
    }

    /**
     *  Gets all country Codes information with given MCC.
     */
    private static int[] getAllCountryCodes(Context context) {
        if (ALL_COUNTRY_CODES != null) {
            return ALL_COUNTRY_CODES;
        }

        Cursor cursor = null;
        try {
            String projection[] = {MccLookup.COUNTRY_CODE};
            cursor = context.getContentResolver().query(MccLookup.CONTENT_URI,
                    projection, null, null, null);

            if (cursor.getCount() > 0) {
                ALL_COUNTRY_CODES = new int[cursor.getCount()];
                int i = 0;
                while (cursor.moveToNext()) {
                    int countryCode = cursor.getInt(0);
                    ALL_COUNTRY_CODES[i++] = countryCode;
                    int length = String.valueOf(countryCode).trim().length();
                    if (length > MAX_COUNTRY_CODES_LENGTH) {
                        MAX_COUNTRY_CODES_LENGTH = length;
                    }
                }
            }
        } catch (SQLException e) {
            Rlog.e(TAG, "Can't access HbpcdLookup database", e);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return ALL_COUNTRY_CODES;
    }

    private static boolean inExceptionListForNpCcAreaLocal(NumberEntry numberEntry) {
        int countryCode = numberEntry.countryCode;
        boolean result = (numberEntry.number.length() == 12
                          && (countryCode == 7 || countryCode == 20
                              || countryCode == 65 || countryCode == 90));
        return result;
    }

    private static String getNumberPlanType(int state) {
        String numberPlanType = "Number Plan type (" + state + "): ";

        if (state == NP_NANP_LOCAL) {
            numberPlanType = "NP_NANP_LOCAL";
        } else if (state == NP_NANP_AREA_LOCAL) {
            numberPlanType = "NP_NANP_AREA_LOCAL";
        } else if (state  == NP_NANP_NDD_AREA_LOCAL) {
            numberPlanType = "NP_NANP_NDD_AREA_LOCAL";
        } else if (state == NP_NANP_NBPCD_CC_AREA_LOCAL) {
            numberPlanType = "NP_NANP_NBPCD_CC_AREA_LOCAL";
        } else if (state == NP_NANP_LOCALIDD_CC_AREA_LOCAL) {
            numberPlanType = "NP_NANP_LOCALIDD_CC_AREA_LOCAL";
        } else if (state == NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL) {
            numberPlanType = "NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL";
        } else if (state == NP_NBPCD_HOMEIDD_CC_AREA_LOCAL) {
            numberPlanType = "NP_NBPCD_IDD_CC_AREA_LOCAL";
        } else if (state == NP_HOMEIDD_CC_AREA_LOCAL) {
            numberPlanType = "NP_IDD_CC_AREA_LOCAL";
        } else if (state == NP_NBPCD_CC_AREA_LOCAL) {
            numberPlanType = "NP_NBPCD_CC_AREA_LOCAL";
        } else if (state == NP_LOCALIDD_CC_AREA_LOCAL) {
            numberPlanType = "NP_IDD_CC_AREA_LOCAL";
        } else if (state == NP_CC_AREA_LOCAL) {
            numberPlanType = "NP_CC_AREA_LOCAL";
        } else {
            numberPlanType = "Unknown type";
        }
        return numberPlanType;
    }

    /**
     *  Filter the destination number if using VZW sim card.
     */
    public static String filterDestAddr(PhoneBase phoneBase, String destAddr) {
        if (DBG) Rlog.d(TAG, "enter filterDestAddr. destAddr=\"" + destAddr + "\"" );

        if (destAddr == null || !PhoneNumberUtils.isGlobalPhoneNumber(destAddr)) {
            Rlog.w(TAG, "destAddr" + destAddr + " is not a global phone number!");
            return destAddr;
        }

        final String networkOperator = TelephonyManager.getDefault().getNetworkOperator();
        String result = null;

        if (needToConvert(phoneBase)) {
            final int networkType = getNetworkType(phoneBase);
            if (networkType != -1 && !TextUtils.isEmpty(networkOperator)) {
                String networkMcc = networkOperator.substring(0, 3);
                if (networkMcc != null && networkMcc.trim().length() > 0) {
                    result = formatNumber(phoneBase.getContext(), destAddr, networkMcc, networkType);
                }
            }
        }

        if (DBG) Rlog.d(TAG, "leave filterDestAddr, new destAddr=\"" + result + "\"" );
        return result != null ? result : destAddr;
    }

    /**
     * Returns the current network type
     */
    private static int getNetworkType(PhoneBase phoneBase) {
        int networkType = -1;
        int phoneType = TelephonyManager.getDefault().getPhoneType();

        if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
            networkType = GSM_UMTS_NETWORK;
        } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
            if (isInternationalRoaming(phoneBase)) {
                networkType = CDMA_ROAMING_NETWORK;
            } else {
                networkType = CDMA_HOME_NETWORK;
            }
        } else {
            if (DBG) Rlog.w(TAG, "warning! unknown mPhoneType value=" + phoneType);
        }

        return networkType;
    }

    private static boolean isInternationalRoaming(PhoneBase phoneBase) {
        String operatorIsoCountry = TelephonyManager.getDefault().getNetworkCountryIsoForPhone(
                phoneBase.getPhoneId());
        String simIsoCountry = TelephonyManager.getDefault().getSimCountryIsoForPhone(
                phoneBase.getPhoneId());
        boolean internationalRoaming = !TextUtils.isEmpty(operatorIsoCountry)
                && !TextUtils.isEmpty(simIsoCountry)
                && !simIsoCountry.equals(operatorIsoCountry);
        if (internationalRoaming) {
            if ("us".equals(simIsoCountry)) {
                internationalRoaming = !"vi".equals(operatorIsoCountry);
            } else if ("vi".equals(simIsoCountry)) {
                internationalRoaming = !"us".equals(operatorIsoCountry);
            }
        }
        return internationalRoaming;
    }

    private static boolean needToConvert(PhoneBase phoneBase) {
        boolean bNeedToConvert  = false;
        String[] listArray = phoneBase.getContext().getResources()
                .getStringArray(com.android.internal.R.array
                .config_sms_convert_destination_number_support);
        if (listArray != null && listArray.length > 0) {
            for (int i=0; i<listArray.length; i++) {
                if (!TextUtils.isEmpty(listArray[i])) {
                    String[] needToConvertArray = listArray[i].split(";");
                    if (needToConvertArray != null && needToConvertArray.length > 0) {
                        if (needToConvertArray.length == 1) {
                            bNeedToConvert = "true".equalsIgnoreCase(needToConvertArray[0]);
                        } else if (needToConvertArray.length == 2 &&
                                !TextUtils.isEmpty(needToConvertArray[1]) &&
                                compareGid1(phoneBase, needToConvertArray[1])) {
                            bNeedToConvert = "true".equalsIgnoreCase(needToConvertArray[0]);
                            break;
                        }
                    }
                }
            }
        }
        return bNeedToConvert;
    }

    private static boolean compareGid1(PhoneBase phoneBase, String serviceGid1) {
        String gid1 = phoneBase.getGroupIdLevel1();
        boolean ret = true;

        if (TextUtils.isEmpty(serviceGid1)) {
            if (DBG) Rlog.d(TAG, "compareGid1 serviceGid is empty, return " + ret);
            return ret;
        }

        int gid_length = serviceGid1.length();
        // Check if gid1 match service GID1
        if (!((gid1 != null) && (gid1.length() >= gid_length) &&
                gid1.substring(0, gid_length).equalsIgnoreCase(serviceGid1))) {
            if (DBG) Rlog.d(TAG, " gid1 " + gid1 + " serviceGid1 " + serviceGid1);
            ret = false;
        }
        if (DBG) Rlog.d(TAG, "compareGid1 is " + (ret?"Same":"Different"));
        return ret;
    }
}