10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
174918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savillepackage com.android.internal.telephony.dataconnection;
184918296afe1c667e9523cdfc799f558f7ebc2bfbWink Saville
198b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yuimport android.content.Context;
208e9d1e601dce62cd0328701d7054e03db24727c7Jack Yuimport android.hardware.radio.V1_0.ApnTypes;
218b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yuimport android.os.PersistableBundle;
2221f6e74b368a7045981cdb718570bf872471ac0bJordan Liuimport android.provider.Telephony.Carriers;
238b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yuimport android.telephony.CarrierConfigManager;
240e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yuimport android.telephony.Rlog;
25aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajanimport android.telephony.ServiceState;
263262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawalimport android.text.TextUtils;
273fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamalaimport android.util.Log;
283262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
299fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yuimport com.android.internal.annotations.VisibleForTesting;
3050734be549285702de00295778b8c2a4360215a0Jack Yuimport com.android.internal.telephony.Phone;
314918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.PhoneConstants;
324918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savilleimport com.android.internal.telephony.RILConstants;
3363913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajanimport com.android.internal.telephony.uicc.IccRecords;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
353262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawalimport java.util.ArrayList;
360e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yuimport java.util.Arrays;
378b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yuimport java.util.HashSet;
383262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawalimport java.util.List;
399fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yuimport java.util.Objects;
403ae69aa0ef2e02f140a2229e6a31cfd291528295Robert Greenwalt
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This class represents a apn setting for create PDP link
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class ApnSetting {
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
468b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu    static final String LOG_TAG = "ApnSetting";
478b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
488b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu    private static final boolean DBG = false;
499fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    private static final boolean VDBG = false;
508b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*";
529d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan    static final String V3_FORMAT_REGEX = "^\\[ApnSettingV3\\]\\s*";
53176f28521fd45bb739709d309e7970b1558c9f61Cassie    static final String V4_FORMAT_REGEX = "^\\[ApnSettingV4\\]\\s*";
5421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu    static final String V5_FORMAT_REGEX = "^\\[ApnSettingV5\\]\\s*";
553fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala    static final String TAG = "ApnSetting";
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String carrier;
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String apn;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String proxy;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String port;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String mmsc;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String mmsProxy;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String mmsPort;
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String user;
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String password;
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final int authType;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String[] types;
688e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu    public final int typesBitmap;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final int id;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String numeric;
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String protocol;
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final String roamingProtocol;
73e9701717e43cc5aacbcf624f77a53be92350662cw    public final int mtu;
74e9701717e43cc5aacbcf624f77a53be92350662cw
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville      * Current status of APN
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville      * true : enabled APN, false : disabled APN.
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville      */
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public final boolean carrierEnabled;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
81aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan     * Radio Access Technology info
82aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan     * To check what values can hold, refer to ServiceState.java.
83aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan     * This should be spread to other technologies,
84aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan     * but currently only used for LTE(14) and EHRPD(13).
85176f28521fd45bb739709d309e7970b1558c9f61Cassie     *
86176f28521fd45bb739709d309e7970b1558c9f61Cassie     * @deprecated use {@code networkTypeBitmask} instead
87aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan     */
88176f28521fd45bb739709d309e7970b1558c9f61Cassie    @Deprecated
89aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan    private final int bearer;
90aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan    /**
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville      * Radio Access Technology info
92aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan      * To check what values can hold, refer to ServiceState.java. This is a bitmask of radio
93aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan      * technologies in ServiceState.
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville      * This should be spread to other technologies,
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville      * but currently only used for LTE(14) and EHRPD(13).
96176f28521fd45bb739709d309e7970b1558c9f61Cassie      *
97176f28521fd45bb739709d309e7970b1558c9f61Cassie      * @deprecated use {@code networkTypeBitmask} instead
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville      */
99176f28521fd45bb739709d309e7970b1558c9f61Cassie    @Deprecated
100aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan    public final int bearerBitmask;
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
102176f28521fd45bb739709d309e7970b1558c9f61Cassie    /**
103176f28521fd45bb739709d309e7970b1558c9f61Cassie     * Radio Technology (Network Type) info
104176f28521fd45bb739709d309e7970b1558c9f61Cassie     * To check what values can hold, refer to TelephonyManager.java. This is a bitmask of radio
105176f28521fd45bb739709d309e7970b1558c9f61Cassie     * technologies ({@code NETWORK_TYPE_} constants) in {@link TelephonyManager}.
106176f28521fd45bb739709d309e7970b1558c9f61Cassie     */
107176f28521fd45bb739709d309e7970b1558c9f61Cassie    public final int networkTypeBitmask;
108176f28521fd45bb739709d309e7970b1558c9f61Cassie
1099d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan    /* ID of the profile in the modem */
1109d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan    public final int profileId;
1119d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan    public final boolean modemCognitive;
1129d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan    public final int maxConns;
1139d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan    public final int waitTime;
1149d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan    public final int maxConnsTime;
1159d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan
1163262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    /**
1173262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      * MVNO match type. Possible values:
1183262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      *   "spn": Service provider name.
1193262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      *   "imsi": IMSI.
1203262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      *   "gid": Group identifier level 1.
1213fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala      *   "iccid": ICCID
1223262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      */
1233262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    public final String mvnoType;
1243262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    /**
1253262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      * MVNO data. Examples:
1263262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      *   "spn": A MOBILE, BEN NL
1273262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      *   "imsi": 302720x94, 2060188
1283262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      *   "gid": 4E, 33
1293fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala      *   "iccid": 898603 etc.
1303262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal      */
1313262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    public final String mvnoMatchData;
1323262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
1330e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    /**
13421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     * The APN set id.
13521f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *
13621f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     * APNs that are part of the same set should be preferred together, e.g. if the
13721f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     * user selects a default APN with apnSetId=1, then we will prefer all APNs with apnSetId=1.
13821f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *
13921f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     * If the apnSetId=Carriers.NO_SET_SET (=0) then the APN is not part of a set.
14021f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     */
14121f6e74b368a7045981cdb718570bf872471ac0bJordan Liu    public final int apnSetId;
14221f6e74b368a7045981cdb718570bf872471ac0bJordan Liu
14321f6e74b368a7045981cdb718570bf872471ac0bJordan Liu    /**
1440e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * Indicates this APN setting is permanently failed and cannot be
1450e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * retried by the retry manager anymore.
1460e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu     * */
1470e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public boolean permanentFailed = false;
1480e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
149176f28521fd45bb739709d309e7970b1558c9f61Cassie    /**
150176f28521fd45bb739709d309e7970b1558c9f61Cassie     * @deprecated this constructor is no longer supported. Use the other constructor which takes
151176f28521fd45bb739709d309e7970b1558c9f61Cassie     * a network type bitmask instead of the deprecated bearer bitmask and bearer field.
152176f28521fd45bb739709d309e7970b1558c9f61Cassie     * */
153176f28521fd45bb739709d309e7970b1558c9f61Cassie    @Deprecated
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public ApnSetting(int id, String numeric, String carrier, String apn,
1558e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                      String proxy, String port,
1568e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                      String mmsc, String mmsProxy, String mmsPort,
1578e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                      String user, String password, int authType, String[] types,
1588e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                      String protocol, String roamingProtocol, boolean carrierEnabled, int bearer,
1598e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                      int bearerBitmask, int profileId, boolean modemCognitive, int maxConns,
1608e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                      int waitTime, int maxConnsTime, int mtu, String mvnoType,
1618e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                      String mvnoMatchData) {
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.id = id;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.numeric = numeric;
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.carrier = carrier;
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.apn = apn;
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.proxy = proxy;
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.port = port;
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.mmsc = mmsc;
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.mmsProxy = mmsProxy;
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.mmsPort = mmsPort;
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.user = user;
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.password = password;
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.authType = authType;
1743ae69aa0ef2e02f140a2229e6a31cfd291528295Robert Greenwalt        this.types = new String[types.length];
1758e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        int apnBitmap = 0;
1763ae69aa0ef2e02f140a2229e6a31cfd291528295Robert Greenwalt        for (int i = 0; i < types.length; i++) {
1778e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            this.types[i] = types[i].toLowerCase();
1788e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            apnBitmap |= getApnBitmask(this.types[i]);
1793ae69aa0ef2e02f140a2229e6a31cfd291528295Robert Greenwalt        }
1808e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        this.typesBitmap = apnBitmap;
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.protocol = protocol;
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.roamingProtocol = roamingProtocol;
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.carrierEnabled = carrierEnabled;
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.bearer = bearer;
185aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        this.bearerBitmask = (bearerBitmask | ServiceState.getBitmaskForTech(bearer));
1869d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        this.profileId = profileId;
1879d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        this.modemCognitive = modemCognitive;
1889d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        this.maxConns = maxConns;
1899d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        this.waitTime = waitTime;
1909d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        this.maxConnsTime = maxConnsTime;
191e9701717e43cc5aacbcf624f77a53be92350662cw        this.mtu = mtu;
1923262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        this.mvnoType = mvnoType;
1933262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        this.mvnoMatchData = mvnoMatchData;
19421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        this.apnSetId = Carriers.NO_SET_SET;
195176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
196176f28521fd45bb739709d309e7970b1558c9f61Cassie                this.bearerBitmask);
197176f28521fd45bb739709d309e7970b1558c9f61Cassie    }
1983262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
19921f6e74b368a7045981cdb718570bf872471ac0bJordan Liu    // Constructor with default apn set id
200176f28521fd45bb739709d309e7970b1558c9f61Cassie    public ApnSetting(int id, String numeric, String carrier, String apn,
201176f28521fd45bb739709d309e7970b1558c9f61Cassie                      String proxy, String port,
202176f28521fd45bb739709d309e7970b1558c9f61Cassie                      String mmsc, String mmsProxy, String mmsPort,
203176f28521fd45bb739709d309e7970b1558c9f61Cassie                      String user, String password, int authType, String[] types,
204176f28521fd45bb739709d309e7970b1558c9f61Cassie                      String protocol, String roamingProtocol, boolean carrierEnabled,
205176f28521fd45bb739709d309e7970b1558c9f61Cassie                      int networkTypeBitmask, int profileId, boolean modemCognitive, int maxConns,
206176f28521fd45bb739709d309e7970b1558c9f61Cassie                      int waitTime, int maxConnsTime, int mtu, String mvnoType,
207176f28521fd45bb739709d309e7970b1558c9f61Cassie                      String mvnoMatchData) {
20821f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        this(id, numeric, carrier, apn, proxy, port, mmsc, mmsProxy, mmsPort, user, password,
20921f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                authType, types, protocol, roamingProtocol, carrierEnabled, networkTypeBitmask,
21021f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                profileId, modemCognitive, maxConns, waitTime, maxConnsTime, mtu, mvnoType,
21121f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                mvnoMatchData, Carriers.NO_SET_SET);
21221f6e74b368a7045981cdb718570bf872471ac0bJordan Liu    }
21321f6e74b368a7045981cdb718570bf872471ac0bJordan Liu
21421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu    public ApnSetting(int id, String numeric, String carrier, String apn,
21521f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                      String proxy, String port,
21621f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                      String mmsc, String mmsProxy, String mmsPort,
21721f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                      String user, String password, int authType, String[] types,
21821f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                      String protocol, String roamingProtocol, boolean carrierEnabled,
21921f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                      int networkTypeBitmask, int profileId, boolean modemCognitive, int maxConns,
22021f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                      int waitTime, int maxConnsTime, int mtu, String mvnoType,
22121f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                      String mvnoMatchData, int apnSetId) {
222176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.id = id;
223176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.numeric = numeric;
224176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.carrier = carrier;
225176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.apn = apn;
226176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.proxy = proxy;
227176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.port = port;
228176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.mmsc = mmsc;
229176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.mmsProxy = mmsProxy;
230176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.mmsPort = mmsPort;
231176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.user = user;
232176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.password = password;
233176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.authType = authType;
234176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.types = new String[types.length];
235176f28521fd45bb739709d309e7970b1558c9f61Cassie        int apnBitmap = 0;
236176f28521fd45bb739709d309e7970b1558c9f61Cassie        for (int i = 0; i < types.length; i++) {
237176f28521fd45bb739709d309e7970b1558c9f61Cassie            this.types[i] = types[i].toLowerCase();
238176f28521fd45bb739709d309e7970b1558c9f61Cassie            apnBitmap |= getApnBitmask(this.types[i]);
239176f28521fd45bb739709d309e7970b1558c9f61Cassie        }
240176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.typesBitmap = apnBitmap;
241176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.protocol = protocol;
242176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.roamingProtocol = roamingProtocol;
243176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.carrierEnabled = carrierEnabled;
244176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.bearer = 0;
245176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.bearerBitmask =
246176f28521fd45bb739709d309e7970b1558c9f61Cassie                ServiceState.convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask);
247176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.networkTypeBitmask = networkTypeBitmask;
248176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.profileId = profileId;
249176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.modemCognitive = modemCognitive;
250176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.maxConns = maxConns;
251176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.waitTime = waitTime;
252176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.maxConnsTime = maxConnsTime;
253176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.mtu = mtu;
254176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.mvnoType = mvnoType;
255176f28521fd45bb739709d309e7970b1558c9f61Cassie        this.mvnoMatchData = mvnoMatchData;
25621f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        this.apnSetId = apnSetId;
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2590e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    public ApnSetting(ApnSetting apn) {
2600e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        this(apn.id, apn.numeric, apn.carrier, apn.apn, apn.proxy, apn.port, apn.mmsc, apn.mmsProxy,
2610e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu                apn.mmsPort, apn.user, apn.password, apn.authType, apn.types, apn.protocol,
262176f28521fd45bb739709d309e7970b1558c9f61Cassie                apn.roamingProtocol, apn.carrierEnabled, apn.networkTypeBitmask, apn.profileId,
263176f28521fd45bb739709d309e7970b1558c9f61Cassie                apn.modemCognitive, apn.maxConns, apn.waitTime, apn.maxConnsTime,
26421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                apn.mtu, apn.mvnoType, apn.mvnoMatchData, apn.apnSetId);
2650e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    }
2660e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Creates an ApnSetting object from a string.
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param data the string to read.
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The string must be in one of two formats (newlines added for clarity,
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * spaces are optional):
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * v1 format:
2763262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
2773262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
2783262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   <type>[| <type>...],
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * v2 format:
2813262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
2823262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
283aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan     *   <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2859d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan     * v3 format:
2863262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   [ApnSettingV3] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
2873262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
288aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan     *   <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
2893262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
2903262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *   <mvnoType>, <mvnoMatchData>
2919d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan     *
292176f28521fd45bb739709d309e7970b1558c9f61Cassie     * v4 format:
293176f28521fd45bb739709d309e7970b1558c9f61Cassie     *   [ApnSettingV4] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
294176f28521fd45bb739709d309e7970b1558c9f61Cassie     *   <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
295176f28521fd45bb739709d309e7970b1558c9f61Cassie     *   <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
296176f28521fd45bb739709d309e7970b1558c9f61Cassie     *   <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
297176f28521fd45bb739709d309e7970b1558c9f61Cassie     *   <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>
298176f28521fd45bb739709d309e7970b1558c9f61Cassie     *
29921f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     * v5 format:
30021f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *   [ApnSettingV5] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
30121f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *   <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
30221f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *   <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
30321f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *   <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
30421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *   <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>
30521f6e74b368a7045981cdb718570bf872471ac0bJordan Liu     *
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Note that the strings generated by toString() do not contain the username
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and password and thus cannot be read by this method.
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static ApnSetting fromString(String data) {
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (data == null) return null;
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int version;
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // matches() operates on the whole string, so append .* to the regex.
31421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        if (data.matches(V5_FORMAT_REGEX + ".*")) {
31521f6e74b368a7045981cdb718570bf872471ac0bJordan Liu            version = 5;
31621f6e74b368a7045981cdb718570bf872471ac0bJordan Liu            data = data.replaceFirst(V5_FORMAT_REGEX, "");
31721f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        } else if (data.matches(V4_FORMAT_REGEX + ".*")) {
318176f28521fd45bb739709d309e7970b1558c9f61Cassie            version = 4;
319176f28521fd45bb739709d309e7970b1558c9f61Cassie            data = data.replaceFirst(V4_FORMAT_REGEX, "");
320176f28521fd45bb739709d309e7970b1558c9f61Cassie        } else if (data.matches(V3_FORMAT_REGEX + ".*")) {
3219d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            version = 3;
3229d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            data = data.replaceFirst(V3_FORMAT_REGEX, "");
3239d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        } else if (data.matches(V2_FORMAT_REGEX + ".*")) {
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            version = 2;
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            data = data.replaceFirst(V2_FORMAT_REGEX, "");
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            version = 1;
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] a = data.split("\\s*,\\s*");
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (a.length < 14) {
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int authType;
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            authType = Integer.parseInt(a[12]);
3383262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        } catch (NumberFormatException e) {
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            authType = 0;
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] typeArray;
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String protocol, roamingProtocol;
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean carrierEnabled;
345aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        int bearerBitmask = 0;
346176f28521fd45bb739709d309e7970b1558c9f61Cassie        int networkTypeBitmask = 0;
3479d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        int profileId = 0;
3489d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        boolean modemCognitive = false;
3499d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        int maxConns = 0;
3509d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        int waitTime = 0;
3519d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        int maxConnsTime = 0;
352e9701717e43cc5aacbcf624f77a53be92350662cw        int mtu = PhoneConstants.UNSET_MTU;
3533262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        String mvnoType = "";
3543262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        String mvnoMatchData = "";
35521f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        int apnSetId = Carriers.NO_SET_SET;
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (version == 1) {
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            typeArray = new String[a.length - 13];
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            System.arraycopy(a, 13, typeArray, 0, a.length - 13);
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            protocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            carrierEnabled = true;
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (a.length < 18) {
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return null;
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            typeArray = a[13].split("\\s*\\|\\s*");
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            protocol = a[14];
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            roamingProtocol = a[15];
3693262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            carrierEnabled = Boolean.parseBoolean(a[16]);
3703262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
371aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan            bearerBitmask = ServiceState.getBitmaskFromString(a[17]);
3723262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
373e9701717e43cc5aacbcf624f77a53be92350662cw            if (a.length > 22) {
3743262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                modemCognitive = Boolean.parseBoolean(a[19]);
3759d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                try {
3769d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                    profileId = Integer.parseInt(a[18]);
3779d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                    maxConns = Integer.parseInt(a[20]);
3789d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                    waitTime = Integer.parseInt(a[21]);
3799d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                    maxConnsTime = Integer.parseInt(a[22]);
3803262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                } catch (NumberFormatException e) {
3819d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan                }
3829d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan            }
383e9701717e43cc5aacbcf624f77a53be92350662cw            if (a.length > 23) {
384e9701717e43cc5aacbcf624f77a53be92350662cw                try {
385e9701717e43cc5aacbcf624f77a53be92350662cw                    mtu = Integer.parseInt(a[23]);
3863262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                } catch (NumberFormatException e) {
387e9701717e43cc5aacbcf624f77a53be92350662cw                }
388e9701717e43cc5aacbcf624f77a53be92350662cw            }
3893262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            if (a.length > 25) {
3903262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                mvnoType = a[24];
3913262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                mvnoMatchData = a[25];
3923262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            }
393176f28521fd45bb739709d309e7970b1558c9f61Cassie            if (a.length > 26) {
394176f28521fd45bb739709d309e7970b1558c9f61Cassie                networkTypeBitmask = ServiceState.getBitmaskFromString(a[26]);
395176f28521fd45bb739709d309e7970b1558c9f61Cassie            }
39621f6e74b368a7045981cdb718570bf872471ac0bJordan Liu            if (a.length > 27) {
39721f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                apnSetId = Integer.parseInt(a[27]);
39821f6e74b368a7045981cdb718570bf872471ac0bJordan Liu            }
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
401176f28521fd45bb739709d309e7970b1558c9f61Cassie        // If both bearerBitmask and networkTypeBitmask were specified, bearerBitmask would be
402176f28521fd45bb739709d309e7970b1558c9f61Cassie        // ignored.
403176f28521fd45bb739709d309e7970b1558c9f61Cassie        if (networkTypeBitmask == 0) {
404176f28521fd45bb739709d309e7970b1558c9f61Cassie            networkTypeBitmask =
405176f28521fd45bb739709d309e7970b1558c9f61Cassie                    ServiceState.convertBearerBitmaskToNetworkTypeBitmask(bearerBitmask);
406176f28521fd45bb739709d309e7970b1558c9f61Cassie        }
407176f28521fd45bb739709d309e7970b1558c9f61Cassie        return new ApnSetting(-1, a[10] + a[11], a[0], a[1], a[2], a[3], a[7], a[8], a[9], a[4],
408176f28521fd45bb739709d309e7970b1558c9f61Cassie                a[5], authType, typeArray, protocol, roamingProtocol, carrierEnabled,
409176f28521fd45bb739709d309e7970b1558c9f61Cassie                networkTypeBitmask, profileId, modemCognitive, maxConns, waitTime, maxConnsTime,
41021f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                mtu, mvnoType, mvnoMatchData, apnSetId);
4113262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    }
4123262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
4133262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    /**
4143262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     * Creates an array of ApnSetting objects from a string.
4153262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *
4163262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     * @param data the string to read.
4173262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     *
4183262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     * Builds on top of the same format used by fromString, but allows for multiple entries
4193262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     * separated by "; ".
4203262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     */
4213262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    public static List<ApnSetting> arrayFromString(String data) {
4223262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        List<ApnSetting> retVal = new ArrayList<ApnSetting>();
4233262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        if (TextUtils.isEmpty(data)) {
4243262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            return retVal;
4253262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        }
4263262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        String[] apnStrings = data.split("\\s*;\\s*");
4273262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        for (String apnString : apnStrings) {
4283262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            ApnSetting apn = fromString(apnString);
4293262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            if (apn != null) {
4303262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal                retVal.add(apn);
4313262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal            }
4323262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        }
4333262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        return retVal;
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
436cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String toString() {
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder sb = new StringBuilder();
43921f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        sb.append("[ApnSettingV5] ")
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(carrier)
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(id)
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(numeric)
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(apn)
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(proxy)
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(mmsc)
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(mmsProxy)
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(mmsPort)
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(port)
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .append(", ").append(authType).append(", ");
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < types.length; i++) {
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sb.append(types[i]);
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (i < types.length - 1) {
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sb.append(" | ");
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append(", ").append(protocol);
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append(", ").append(roamingProtocol);
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append(", ").append(carrierEnabled);
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append(", ").append(bearer);
460aaf0e8d623b1e94004557573aef9235177ca19e3Amit Mahajan        sb.append(", ").append(bearerBitmask);
4619d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        sb.append(", ").append(profileId);
4629d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        sb.append(", ").append(modemCognitive);
4639d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        sb.append(", ").append(maxConns);
4649d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        sb.append(", ").append(waitTime);
4659d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        sb.append(", ").append(maxConnsTime);
466e9701717e43cc5aacbcf624f77a53be92350662cw        sb.append(", ").append(mtu);
4673262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        sb.append(", ").append(mvnoType);
4683262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        sb.append(", ").append(mvnoMatchData);
4690e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        sb.append(", ").append(permanentFailed);
470176f28521fd45bb739709d309e7970b1558c9f61Cassie        sb.append(", ").append(networkTypeBitmask);
47121f6e74b368a7045981cdb718570bf872471ac0bJordan Liu        sb.append(", ").append(apnSetId);
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return sb.toString();
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4753262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    /**
4763262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     * Returns true if there are MVNO params specified.
4773262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal     */
4783262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    public boolean hasMvnoParams() {
4793262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal        return !TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData);
4803262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal    }
4813262c21feb1eede2917450cfdfd3faa86ee70cabShishir Agrawal
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean canHandleType(String type) {
4839d4ec7d45061f1da05f16cd244eb0a798e7f36bbAmit Mahajan        if (!carrierEnabled) return false;
48440b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        boolean wildcardable = true;
48540b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt        if (PhoneConstants.APN_TYPE_IA.equalsIgnoreCase(type)) wildcardable = false;
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (String t : types) {
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // DEFAULT handles all, and HIPRI is handled by DEFAULT
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (t.equalsIgnoreCase(type) ||
48940b0e247a4a79e83f10b6410025ef1d7cc537692Robert Greenwalt                    (wildcardable && t.equalsIgnoreCase(PhoneConstants.APN_TYPE_ALL)) ||
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    (t.equalsIgnoreCase(PhoneConstants.APN_TYPE_DEFAULT) &&
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    type.equalsIgnoreCase(PhoneConstants.APN_TYPE_HIPRI))) {
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4983fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala    private static boolean iccidMatches(String mvnoData, String iccId) {
4993fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala        String[] mvnoIccidList = mvnoData.split(",");
5003fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala        for (String mvnoIccid : mvnoIccidList) {
5013fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala            if (iccId.startsWith(mvnoIccid)) {
5023fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala                Log.d(TAG, "mvno icc id match found");
5033fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala                return true;
5043fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala            }
5053fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala        }
5063fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala        return false;
5073fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala    }
5083fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala
50963913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan    private static boolean imsiMatches(String imsiDB, String imsiSIM) {
51063913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
51163913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        // for MVNO operator. And then digit number is matched at same order and 'x' character
51263913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        // could replace by any digit number.
51363913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
51463913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        //     that means first 6 digits, 8th and 9th digit
51563913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        //     should be set in USIM for GG Operator.
51663913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        int len = imsiDB.length();
51763913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        int idxCompare = 0;
51863913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan
51963913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        if (len <= 0) return false;
52063913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        if (len > imsiSIM.length()) return false;
52163913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan
52263913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        for (int idx=0; idx<len; idx++) {
52363913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            char c = imsiDB.charAt(idx);
52463913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
52563913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                continue;
52663913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            } else {
52763913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                return false;
52863913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            }
52963913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        }
53063913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        return true;
53163913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan    }
53263913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan
53363913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan    public static boolean mvnoMatches(IccRecords r, String mvnoType, String mvnoMatchData) {
53463913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        if (mvnoType.equalsIgnoreCase("spn")) {
53563913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            if ((r.getServiceProviderName() != null) &&
53663913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) {
53763913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                return true;
53863913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            }
53963913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        } else if (mvnoType.equalsIgnoreCase("imsi")) {
54063913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            String imsiSIM = r.getIMSI();
54163913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) {
54263913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                return true;
54363913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            }
54463913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        } else if (mvnoType.equalsIgnoreCase("gid")) {
54563913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            String gid1 = r.getGid1();
54663913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            int mvno_match_data_length = mvnoMatchData.length();
54763913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) &&
54863913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                    gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) {
54963913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan                return true;
55063913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan            }
5513fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala        } else if (mvnoType.equalsIgnoreCase("iccid")) {
5523fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala            String iccId = r.getIccId();
5533fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala            if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) {
5543fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala                return true;
5553fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala            }
55663913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        }
5573fd2f3abe4db925d6f8b2a1db4316c71c30af493Susheel Nyamala
55863913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan        return false;
55963913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan    }
56063913dc903872c45bab7d2483d633d845dd9c5d6Amit Mahajan
56150734be549285702de00295778b8c2a4360215a0Jack Yu    /**
56250734be549285702de00295778b8c2a4360215a0Jack Yu     * Check if this APN type is metered.
56350734be549285702de00295778b8c2a4360215a0Jack Yu     *
56450734be549285702de00295778b8c2a4360215a0Jack Yu     * @param type The APN type
56550734be549285702de00295778b8c2a4360215a0Jack Yu     * @param phone The phone object
56650734be549285702de00295778b8c2a4360215a0Jack Yu     * @return True if the APN type is metered, otherwise false.
56750734be549285702de00295778b8c2a4360215a0Jack Yu     */
56850734be549285702de00295778b8c2a4360215a0Jack Yu    public static boolean isMeteredApnType(String type, Phone phone) {
56950734be549285702de00295778b8c2a4360215a0Jack Yu        if (phone == null) {
57050734be549285702de00295778b8c2a4360215a0Jack Yu            return true;
57150734be549285702de00295778b8c2a4360215a0Jack Yu        }
57250734be549285702de00295778b8c2a4360215a0Jack Yu
57350734be549285702de00295778b8c2a4360215a0Jack Yu        boolean isRoaming = phone.getServiceState().getDataRoaming();
57450734be549285702de00295778b8c2a4360215a0Jack Yu        boolean isIwlan = phone.getServiceState().getRilDataRadioTechnology()
57550734be549285702de00295778b8c2a4360215a0Jack Yu                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
57650734be549285702de00295778b8c2a4360215a0Jack Yu        int subId = phone.getSubId();
57750734be549285702de00295778b8c2a4360215a0Jack Yu
57850734be549285702de00295778b8c2a4360215a0Jack Yu        String carrierConfig;
57950734be549285702de00295778b8c2a4360215a0Jack Yu        // First check if the device is in IWLAN mode. If yes, use the IWLAN metered APN list. Then
58050734be549285702de00295778b8c2a4360215a0Jack Yu        // check if the device is roaming. If yes, use the roaming metered APN list. Otherwise, use
58150734be549285702de00295778b8c2a4360215a0Jack Yu        // the normal metered APN list.
58250734be549285702de00295778b8c2a4360215a0Jack Yu        if (isIwlan) {
58350734be549285702de00295778b8c2a4360215a0Jack Yu            carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_IWLAN_APN_TYPES_STRINGS;
58450734be549285702de00295778b8c2a4360215a0Jack Yu        } else if (isRoaming) {
58550734be549285702de00295778b8c2a4360215a0Jack Yu            carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS;
58650734be549285702de00295778b8c2a4360215a0Jack Yu        } else {
58750734be549285702de00295778b8c2a4360215a0Jack Yu            carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS;
58850734be549285702de00295778b8c2a4360215a0Jack Yu        }
5893d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
59050734be549285702de00295778b8c2a4360215a0Jack Yu        if (DBG) {
59150734be549285702de00295778b8c2a4360215a0Jack Yu            Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming + ", isIwlan=" + isIwlan);
59250734be549285702de00295778b8c2a4360215a0Jack Yu        }
5933d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
5949cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        CarrierConfigManager configManager = (CarrierConfigManager)
59550734be549285702de00295778b8c2a4360215a0Jack Yu                phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
5969cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        if (configManager == null) {
5979cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            Rlog.e(LOG_TAG, "Carrier config service is not available");
5989cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            return true;
5999cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        }
6008b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
6019cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        PersistableBundle b = configManager.getConfigForSubId(subId);
6029cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        if (b == null) {
6039cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId);
6049cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            return true;
6059cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        }
6068b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
6079cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        String[] meteredApnTypes = b.getStringArray(carrierConfig);
6089cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        if (meteredApnTypes == null) {
6099cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            Rlog.e(LOG_TAG, carrierConfig +  " is not available. " + "subId = " + subId);
6109cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            return true;
6119cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        }
6128b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
6139cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes));
6149cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        if (DBG) {
61550734be549285702de00295778b8c2a4360215a0Jack Yu            Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are "
61650734be549285702de00295778b8c2a4360215a0Jack Yu                    + Arrays.toString(meteredApnSet.toArray()));
6179cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        }
6189cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu
6199cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        // If all types of APN are metered, then this APN setting must be metered.
6209cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) {
62150734be549285702de00295778b8c2a4360215a0Jack Yu            if (DBG) Rlog.d(LOG_TAG, "All APN types are metered.");
6229cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            return true;
6239cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        }
6248b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
6259cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        if (meteredApnSet.contains(type)) {
62650734be549285702de00295778b8c2a4360215a0Jack Yu            if (DBG) Rlog.d(LOG_TAG, type + " is metered.");
6279cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            return true;
6289cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu        } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) {
6299cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            // Assuming no configuration error, if at least one APN type is
6309cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            // metered, then this APN setting is metered.
6319cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu            if (meteredApnSet.size() > 0) {
63250734be549285702de00295778b8c2a4360215a0Jack Yu                if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered.");
633783061ca03572618c01ce244d70d82fa4328d45ffionaxu                return true;
6348b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu            }
6358b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu        }
6369cfc7dc5c097a8cba802a7b2256f2e6c27316492Jack Yu
63750734be549285702de00295778b8c2a4360215a0Jack Yu        if (DBG) Rlog.d(LOG_TAG, type + " is not metered.");
638783061ca03572618c01ce244d70d82fa4328d45ffionaxu        return false;
639783061ca03572618c01ce244d70d82fa4328d45ffionaxu    }
6408b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
64150734be549285702de00295778b8c2a4360215a0Jack Yu    /**
64250734be549285702de00295778b8c2a4360215a0Jack Yu     * Check if this APN setting is metered.
64350734be549285702de00295778b8c2a4360215a0Jack Yu     *
64450734be549285702de00295778b8c2a4360215a0Jack Yu     * @param phone The phone object
64550734be549285702de00295778b8c2a4360215a0Jack Yu     * @return True if this APN setting is metered, otherwise false.
64650734be549285702de00295778b8c2a4360215a0Jack Yu     */
64750734be549285702de00295778b8c2a4360215a0Jack Yu    public boolean isMetered(Phone phone) {
64850734be549285702de00295778b8c2a4360215a0Jack Yu        if (phone == null) {
64950734be549285702de00295778b8c2a4360215a0Jack Yu            return true;
65050734be549285702de00295778b8c2a4360215a0Jack Yu        }
65150734be549285702de00295778b8c2a4360215a0Jack Yu
652783061ca03572618c01ce244d70d82fa4328d45ffionaxu        for (String type : types) {
653783061ca03572618c01ce244d70d82fa4328d45ffionaxu            // If one of the APN type is metered, then this APN setting is metered.
65450734be549285702de00295778b8c2a4360215a0Jack Yu            if (isMeteredApnType(type, phone)) {
655783061ca03572618c01ce244d70d82fa4328d45ffionaxu                return true;
656783061ca03572618c01ce244d70d82fa4328d45ffionaxu            }
657783061ca03572618c01ce244d70d82fa4328d45ffionaxu        }
6588b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu        return false;
6598b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu    }
6608b0a1cbd24977a1abbba79736cf9f481ced0703aJack Yu
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // TODO - if we have this function we should also have hashCode.
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Also should handle changes in type order and perhaps case-insensitivity
663cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean equals(Object o) {
6650e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        if (o instanceof ApnSetting == false) {
6660e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu            return false;
6670e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        }
6680e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
6690e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu        ApnSetting other = (ApnSetting) o;
6700e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu
6718e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        return carrier.equals(other.carrier)
6728e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && id == other.id
6738e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && numeric.equals(other.numeric)
6748e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && apn.equals(other.apn)
6758e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && proxy.equals(other.proxy)
6768e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && mmsc.equals(other.mmsc)
6778e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && mmsProxy.equals(other.mmsProxy)
6788e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && TextUtils.equals(mmsPort, other.mmsPort)
6798e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && port.equals(other.port)
6808e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && TextUtils.equals(user, other.user)
6818e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && TextUtils.equals(password, other.password)
6828e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && authType == other.authType
6838e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && Arrays.deepEquals(types, other.types)
6848e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && typesBitmap == other.typesBitmap
6858e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && protocol.equals(other.protocol)
6868e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && roamingProtocol.equals(other.roamingProtocol)
6878e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && carrierEnabled == other.carrierEnabled
6888e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && bearer == other.bearer
6898e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && bearerBitmask == other.bearerBitmask
6908e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && profileId == other.profileId
6918e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && modemCognitive == other.modemCognitive
6928e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && maxConns == other.maxConns
6938e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && waitTime == other.waitTime
6948e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && maxConnsTime == other.maxConnsTime
6958e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && mtu == other.mtu
6968e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu                && mvnoType.equals(other.mvnoType)
697176f28521fd45bb739709d309e7970b1558c9f61Cassie                && mvnoMatchData.equals(other.mvnoMatchData)
69821f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                && networkTypeBitmask == other.networkTypeBitmask
69921f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                && apnSetId == other.apnSetId;
7008e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu    }
7018e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu
7029fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    /**
7039fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * Compare two APN settings
7049fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     *
705176f28521fd45bb739709d309e7970b1558c9f61Cassie     * Note: This method does not compare 'id', 'bearer', 'bearerBitmask', 'networkTypeBitmask'.
706176f28521fd45bb739709d309e7970b1558c9f61Cassie     * We only use this for determining if tearing a data call is needed when conditions change. See
7079fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * cleanUpConnectionsOnUpdatedApns in DcTracker.
7089fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     *
7099fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * @param o the other object to compare
7109fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * @param isDataRoaming True if the device is on data roaming
7119fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * @return True if the two APN settings are same
7129fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     */
7139fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
7149fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    public boolean equals(Object o, boolean isDataRoaming) {
7159fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        if (!(o instanceof ApnSetting)) {
7169fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            return false;
7179fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        }
7189fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
7199fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        ApnSetting other = (ApnSetting) o;
7209fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
7219fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return carrier.equals(other.carrier)
7229fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && numeric.equals(other.numeric)
7239fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && apn.equals(other.apn)
7249fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && proxy.equals(other.proxy)
7259fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && mmsc.equals(other.mmsc)
7269fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && mmsProxy.equals(other.mmsProxy)
7279fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && TextUtils.equals(mmsPort, other.mmsPort)
7289fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && port.equals(other.port)
7299fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && TextUtils.equals(user, other.user)
7309fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && TextUtils.equals(password, other.password)
7319fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && authType == other.authType
7329fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && Arrays.deepEquals(types, other.types)
7339fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && typesBitmap == other.typesBitmap
7349fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && (isDataRoaming || protocol.equals(other.protocol))
7359fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && (!isDataRoaming || roamingProtocol.equals(other.roamingProtocol))
7369fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && carrierEnabled == other.carrierEnabled
7379fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && profileId == other.profileId
7389fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && modemCognitive == other.modemCognitive
7399fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && maxConns == other.maxConns
7409fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && waitTime == other.waitTime
7419fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && maxConnsTime == other.maxConnsTime
7429fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && mtu == other.mtu
7439fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && mvnoType.equals(other.mvnoType)
74421f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                && mvnoMatchData.equals(other.mvnoMatchData)
74521f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                && apnSetId == other.apnSetId;
7469fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
7479fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
7489fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    /**
7499fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * Check if neither mention DUN and are substantially similar
7509fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     *
7519fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * @param other The other APN settings to compare
7529fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     * @return True if two APN settings are similar
7539fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu     */
7549fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    public boolean similar(ApnSetting other) {
7559fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return (!this.canHandleType(PhoneConstants.APN_TYPE_DUN)
7569fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && !other.canHandleType(PhoneConstants.APN_TYPE_DUN)
7579fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && Objects.equals(this.apn, other.apn)
7589fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && !typeSameAny(this, other)
7599fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && xorEquals(this.proxy, other.proxy)
7609fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && xorEquals(this.port, other.port)
7619fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && xorEquals(this.protocol, other.protocol)
7629fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && xorEquals(this.roamingProtocol, other.roamingProtocol)
7639fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && this.carrierEnabled == other.carrierEnabled
7649fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && this.bearerBitmask == other.bearerBitmask
7659fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && this.profileId == other.profileId
7669fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && Objects.equals(this.mvnoType, other.mvnoType)
7679fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && Objects.equals(this.mvnoMatchData, other.mvnoMatchData)
7689fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && xorEquals(this.mmsc, other.mmsc)
7699fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                && xorEquals(this.mmsProxy, other.mmsProxy)
770176f28521fd45bb739709d309e7970b1558c9f61Cassie                && xorEquals(this.mmsPort, other.mmsPort))
77121f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                && this.networkTypeBitmask == other.networkTypeBitmask
77221f6e74b368a7045981cdb718570bf872471ac0bJordan Liu                && this.apnSetId == other.apnSetId;
7739fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
7749fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
7759fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    // check whether the types of two APN same (even only one type of each APN is same)
7769fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    private boolean typeSameAny(ApnSetting first, ApnSetting second) {
7779fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        if (VDBG) {
7789fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
7799fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            for (int index1 = 0; index1 < first.types.length; index1++) {
7809fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                apnType1.append(first.types[index1]);
7819fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                apnType1.append(",");
7829fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            }
7839fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
7849fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
7859fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            for (int index1 = 0; index1 < second.types.length; index1++) {
7869fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                apnType2.append(second.types[index1]);
7879fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                apnType2.append(",");
7889fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            }
7899fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            Rlog.d(LOG_TAG, "APN1: is " + apnType1);
7909fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            Rlog.d(LOG_TAG, "APN2: is " + apnType2);
7919fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        }
7929fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
7939fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        for (int index1 = 0; index1 < first.types.length; index1++) {
7949fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            for (int index2 = 0; index2 < second.types.length; index2++) {
7959fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                if (first.types[index1].equals(PhoneConstants.APN_TYPE_ALL)
7969fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        || second.types[index2].equals(PhoneConstants.APN_TYPE_ALL)
7979fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                        || first.types[index1].equals(second.types[index2])) {
7989fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return true");
7999fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                    return true;
8009fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                }
8019fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu            }
8029fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        }
8039fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
8049fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return false");
8059fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return false;
8069fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
8079fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
8089fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    // equal or one is not specified
8099fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    private boolean xorEquals(String first, String second) {
8109fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu        return (Objects.equals(first, second)
8119fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                || TextUtils.isEmpty(first)
8129fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu                || TextUtils.isEmpty(second));
8139fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu    }
8149fea8a3dfa6ed302ba33d77edf654f51f81ad24aJack Yu
8158e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu    // Helper function to convert APN string into a 32-bit bitmask.
8168e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu    private static int getApnBitmask(String apn) {
8178e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        switch (apn) {
8188e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_DEFAULT: return ApnTypes.DEFAULT;
8198e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_MMS: return ApnTypes.MMS;
8208e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_SUPL: return ApnTypes.SUPL;
8218e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_DUN: return ApnTypes.DUN;
8228e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_HIPRI: return ApnTypes.HIPRI;
8238e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_FOTA: return ApnTypes.FOTA;
8248e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_IMS: return ApnTypes.IMS;
8258e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_CBS: return ApnTypes.CBS;
8268e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_IA: return ApnTypes.IA;
8278e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_EMERGENCY: return ApnTypes.EMERGENCY;
8288e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            case PhoneConstants.APN_TYPE_ALL: return ApnTypes.ALL;
8298e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu            default: return ApnTypes.NONE;
8308e9d1e601dce62cd0328701d7054e03db24727c7Jack Yu        }
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
833