DO NOT MERGE - Merge pie-platform-release (PPRL.181205.001, history only) into master
Bug: 120502534
Change-Id: I81e7b906732f23efcb0f9b8ec0035f30e8e807d2
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 31e5364..125a3ae 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -112,6 +112,13 @@
android:singleUser="true"
android:multiprocess="false" />
+ <provider android:name="RcsProvider"
+ android:authorities="rcs"
+ android:multiprocess="false"
+ android:exported="true"
+ android:singleUser="true"
+ android:readPermission="android.permission.READ_SMS" />
+
<service
android:name=".TelephonyBackupAgent$DeferredSmsMmsRestoreService"
android:exported="false" />
diff --git a/OWNERS b/OWNERS
index 0716d33..92458db 100644
--- a/OWNERS
+++ b/OWNERS
@@ -6,4 +6,7 @@
mpq@google.com
jminjie@google.com
shuoq@google.com
-
+hallliu@google.com
+tgunn@google.com
+breadley@google.com
+nazaninb@google.com
diff --git a/assets/carrier_list.pb b/assets/carrier_list.pb
index 856c5bc..f685099 100644
--- a/assets/carrier_list.pb
+++ b/assets/carrier_list.pb
Binary files differ
diff --git a/assets/carrier_list.textpb b/assets/carrier_list.textpb
index 23196a5..776cd91 100644
--- a/assets/carrier_list.textpb
+++ b/assets/carrier_list.textpb
@@ -28,10 +28,12 @@
carrier_name: "EE"
carrier_attribute {
mccmnc_tuple: "23430"
+ mccmnc_tuple: "23433"
imsi_prefix_xpattern: "2343041"
}
carrier_attribute {
mccmnc_tuple: "23430"
+ mccmnc_tuple: "23433"
gid1: "ee"
gid1: "eeff"
}
@@ -185,11 +187,12 @@
mccmnc_tuple: "23201"
mccmnc_tuple: "23211"
mccmnc_tuple: "23212"
+ spn: ""
}
}
carrier_id {
canonical_id: 15
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone - AU"
carrier_attribute {
mccmnc_tuple: "50503"
}
@@ -204,7 +207,7 @@
}
carrier_id {
canonical_id: 18
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone - GR"
carrier_attribute {
mccmnc_tuple: "20205"
spn: "vodafone GR"
@@ -240,14 +243,15 @@
}
carrier_id {
canonical_id: 21
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone - NZ"
carrier_attribute {
mccmnc_tuple: "53001"
+ spn: "vodafone NZ"
}
}
carrier_id {
canonical_id: 22
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone - PT"
carrier_attribute {
mccmnc_tuple: "26801"
spn: ""
@@ -257,7 +261,7 @@
}
carrier_id {
canonical_id: 23
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone - RO"
carrier_attribute {
mccmnc_tuple: "22601"
spn: "Vodafone RO"
@@ -265,7 +269,7 @@
}
carrier_id {
canonical_id: 24
- carrier_name: "Vodacom"
+ carrier_name: "Vodafone - ZA"
carrier_attribute {
mccmnc_tuple: "65501"
}
@@ -347,7 +351,6 @@
carrier_name: "Vodafone"
carrier_attribute {
mccmnc_tuple: "23415"
- mccmnc_tuple: "23491"
spn: ""
spn: "vodafone UK"
}
@@ -639,7 +642,7 @@
}
carrier_id {
canonical_id: 568
- carrier_name: "Velcom"
+ carrier_name: "MDC Velcom"
carrier_attribute {
mccmnc_tuple: "25701"
}
@@ -712,6 +715,10 @@
gid1: "2c"
gid1: "4d"
}
+ carrier_attribute {
+ mccmnc_tuple: "302660"
+ gid1: "MTS"
+ }
}
carrier_id {
canonical_id: 579
@@ -729,6 +736,10 @@
mccmnc_tuple: "302680"
mccmnc_tuple: "302780"
}
+ carrier_attribute {
+ mccmnc_tuple: "20404"
+ gid1: "5a"
+ }
}
carrier_id {
canonical_id: 581
@@ -747,7 +758,7 @@
}
carrier_id {
canonical_id: 625
- carrier_name: "Telefónica Móviles Colombia S.A."
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "732123"
}
@@ -860,9 +871,10 @@
}
carrier_id {
canonical_id: 676
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone Egypt"
carrier_attribute {
mccmnc_tuple: "60202"
+ spn: "vodafone"
}
}
carrier_id {
@@ -870,6 +882,7 @@
carrier_name: "Orange"
carrier_attribute {
mccmnc_tuple: "21403"
+ spn: "Orange"
}
}
carrier_id {
@@ -898,6 +911,7 @@
carrier_name: "Virgin"
carrier_attribute {
mccmnc_tuple: "23430"
+ mccmnc_tuple: "23433"
mccmnc_tuple: "23438"
gid1: "2800000000000000"
}
@@ -911,28 +925,7 @@
carrier_name: "EE"
carrier_attribute {
mccmnc_tuple: "23430"
- imsi_prefix_xpattern: "234300"
- imsi_prefix_xpattern: "234301"
- imsi_prefix_xpattern: "234302"
- imsi_prefix_xpattern: "234303"
- imsi_prefix_xpattern: "2343040"
- imsi_prefix_xpattern: "2343042"
- imsi_prefix_xpattern: "2343043"
- imsi_prefix_xpattern: "2343044"
- imsi_prefix_xpattern: "2343045"
- imsi_prefix_xpattern: "2343046"
- imsi_prefix_xpattern: "2343047"
- imsi_prefix_xpattern: "2343048"
- imsi_prefix_xpattern: "2343049"
- imsi_prefix_xpattern: "234305"
- imsi_prefix_xpattern: "234306"
- imsi_prefix_xpattern: "234307"
- imsi_prefix_xpattern: "234308"
- imsi_prefix_xpattern: "234309"
- }
- carrier_attribute {
mccmnc_tuple: "23433"
- imsi_prefix_xpattern: "x"
}
}
carrier_id {
@@ -1228,6 +1221,7 @@
carrier_name: "Partner Communications Co. Ltd."
carrier_attribute {
mccmnc_tuple: "42501"
+ mccmnc_tuple: "42510"
}
}
carrier_id {
@@ -1271,6 +1265,10 @@
mccmnc_tuple: "405850"
mccmnc_tuple: "405852"
mccmnc_tuple: "405853"
+ mccmnc_tuple: "405908"
+ mccmnc_tuple: "405909"
+ mccmnc_tuple: "405910"
+ mccmnc_tuple: "405911"
}
}
carrier_id {
@@ -1285,6 +1283,7 @@
carrier_name: "NTT DOCOMO"
carrier_attribute {
mccmnc_tuple: "44010"
+ gid1: "00FFFF"
}
}
carrier_id {
@@ -1292,6 +1291,7 @@
carrier_name: "Safaricom"
carrier_attribute {
mccmnc_tuple: "63902"
+ spn: "Safaricom"
}
}
carrier_id {
@@ -1487,7 +1487,7 @@
}
carrier_id {
canonical_id: 959
- carrier_name: "Netcom GSM AS"
+ carrier_name: "Telia"
carrier_attribute {
mccmnc_tuple: "24202"
}
@@ -1580,7 +1580,7 @@
}
carrier_id {
canonical_id: 974
- carrier_name: "movistar (Telefónica Moviles Panama S.A.)"
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "71402"
mccmnc_tuple: "714020"
@@ -2363,7 +2363,7 @@
}
carrier_id {
canonical_id: 1329
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone Albania"
carrier_attribute {
mccmnc_tuple: "27602"
spn: "VODAFONE AL"
@@ -2420,7 +2420,7 @@
}
carrier_id {
canonical_id: 1337
- carrier_name: "Telefonica Comunicaciones Personales S.A."
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "722070"
mccmnc_tuple: "72207"
@@ -2652,7 +2652,7 @@
}
carrier_id {
canonical_id: 1370
- carrier_name: "Mtel"
+ carrier_name: "A1"
carrier_attribute {
mccmnc_tuple: "28401"
}
@@ -2883,6 +2883,7 @@
mccmnc_tuple: "302221"
mccmnc_tuple: "30222"
mccmnc_tuple: "30286"
+ gid1: "5455"
}
}
carrier_id {
@@ -3050,7 +3051,7 @@
}
carrier_id {
canonical_id: 1428
- carrier_name: "Telefónica Móvil"
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "73002"
mccmnc_tuple: "73007"
@@ -3065,9 +3066,10 @@
}
carrier_id {
canonical_id: 1430
- carrier_name: "Centennial Cayman Corp. Chile S.A."
+ carrier_name: "WOM"
carrier_attribute {
mccmnc_tuple: "73004"
+ mccmnc_tuple: "73009"
}
}
carrier_id {
@@ -3105,7 +3107,6 @@
carrier_name: "China Unicom"
carrier_attribute {
mccmnc_tuple: "46001"
- mccmnc_tuple: "46003"
}
}
carrier_id {
@@ -3333,6 +3334,7 @@
carrier_name: "Claro RD"
carrier_attribute {
mccmnc_tuple: "37002"
+ mccmnc_tuple: "370020"
}
}
carrier_id {
@@ -3365,7 +3367,7 @@
}
carrier_id {
canonical_id: 1472
- carrier_name: "Movistar (Otecel S.A.)"
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "74000"
}
@@ -3418,6 +3420,10 @@
carrier_attribute {
mccmnc_tuple: "24421"
}
+ carrier_attribute {
+ mccmnc_tuple: "24405"
+ imsi_prefix_xpattern: "2440541"
+ }
}
carrier_id {
canonical_id: 1480
@@ -3593,6 +3599,7 @@
carrier_name: "Three Mobile"
carrier_attribute {
mccmnc_tuple: "23420"
+ mccmnc_tuple: "23494"
}
}
carrier_id {
@@ -3675,13 +3682,7 @@
carrier_name: "Vodafone"
carrier_attribute {
mccmnc_tuple: "62002"
- }
-}
-carrier_id {
- canonical_id: 1517
- carrier_name: "Mobitel"
- carrier_attribute {
- mccmnc_tuple: "62003"
+ spn: "Vodafone GH"
}
}
carrier_id {
@@ -3714,7 +3715,7 @@
}
carrier_id {
canonical_id: 1522
- carrier_name: "Telefónica Centroamérica Guatemala S.A."
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "70403"
mccmnc_tuple: "704030"
@@ -3774,7 +3775,7 @@
}
carrier_id {
canonical_id: 1530
- carrier_name: "Vip/Tomato"
+ carrier_name: "A1/Tomato"
carrier_attribute {
mccmnc_tuple: "21910"
}
@@ -3815,6 +3816,10 @@
spn: ""
spn: "vodafone HU"
}
+ carrier_attribute {
+ mccmnc_tuple: "21670"
+ imsi_prefix_xpattern: "21670xx2"
+ }
}
carrier_id {
canonical_id: 1536
@@ -3841,6 +3846,27 @@
mccmnc_tuple: "40452"
mccmnc_tuple: "40467"
mccmnc_tuple: "40485"
+ mccmnc_tuple: "40501"
+ mccmnc_tuple: "40503"
+ mccmnc_tuple: "40504"
+ mccmnc_tuple: "40505"
+ mccmnc_tuple: "40506"
+ mccmnc_tuple: "40507"
+ mccmnc_tuple: "40508"
+ mccmnc_tuple: "40509"
+ mccmnc_tuple: "40510"
+ mccmnc_tuple: "40511"
+ mccmnc_tuple: "40512"
+ mccmnc_tuple: "40513"
+ mccmnc_tuple: "40514"
+ mccmnc_tuple: "40515"
+ mccmnc_tuple: "40517"
+ mccmnc_tuple: "40518"
+ mccmnc_tuple: "40519"
+ mccmnc_tuple: "40520"
+ mccmnc_tuple: "40521"
+ mccmnc_tuple: "40522"
+ mccmnc_tuple: "40523"
}
}
carrier_id {
@@ -3900,6 +3926,13 @@
}
}
carrier_id {
+ canonical_id: 1557
+ carrier_name: "Hexicom India"
+ carrier_attribute {
+ mccmnc_tuple: "40470"
+ }
+}
+carrier_id {
canonical_id: 1559
carrier_name: "Reliable Internet Services Ltd."
carrier_attribute {
@@ -4171,6 +4204,7 @@
carrier_name: "Vodacom Lesotho (pty) Ltd."
carrier_attribute {
mccmnc_tuple: "65101"
+ spn: "Vodacom"
}
}
carrier_id {
@@ -4287,9 +4321,10 @@
}
carrier_id {
canonical_id: 1619
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone Malta"
carrier_attribute {
mccmnc_tuple: "27801"
+ spn: "vodafone MT"
}
}
carrier_id {
@@ -4360,6 +4395,8 @@
carrier_name: "Digi"
carrier_attribute {
mccmnc_tuple: "50210"
+ mccmnc_tuple: "502143"
+ mccmnc_tuple: "502146"
mccmnc_tuple: "50216"
}
}
@@ -4397,6 +4434,7 @@
carrier_name: "Vodacom"
carrier_attribute {
mccmnc_tuple: "64304"
+ spn: "Vodacom"
}
}
carrier_id {
@@ -4486,15 +4524,9 @@
}
carrier_id {
canonical_id: 1649
- carrier_name: "Bmobile"
+ carrier_name: "Vodafone"
carrier_attribute {
mccmnc_tuple: "53701"
- }
-}
-carrier_id {
- canonical_id: 1650
- carrier_name: "Greencom"
- carrier_attribute {
mccmnc_tuple: "53702"
}
}
@@ -4530,6 +4562,10 @@
canonical_id: 1655
carrier_name: "Sun"
carrier_attribute {
+ mccmnc_tuple: "51503"
+ imsi_prefix_xpattern: "5150363"
+ }
+ carrier_attribute {
mccmnc_tuple: "51505"
}
}
@@ -4538,6 +4574,7 @@
carrier_name: "Jazz"
carrier_attribute {
mccmnc_tuple: "41001"
+ mccmnc_tuple: "41007"
}
}
carrier_id {
@@ -4619,7 +4656,7 @@
}
carrier_id {
canonical_id: 1668
- carrier_name: "Optimus - Telecomunicações, S.A."
+ carrier_name: "NOS"
carrier_attribute {
mccmnc_tuple: "26803"
}
@@ -4633,7 +4670,7 @@
}
carrier_id {
canonical_id: 1670
- carrier_name: "TMN - Telecomunicações Móveis Nacionais, S.A."
+ carrier_name: "MEO"
carrier_attribute {
mccmnc_tuple: "26806"
}
@@ -4778,6 +4815,10 @@
carrier_attribute {
mccmnc_tuple: "24001"
}
+ carrier_attribute {
+ mccmnc_tuple: "24005"
+ spn: "Telia"
+ }
}
carrier_id {
canonical_id: 1691
@@ -4821,6 +4862,10 @@
carrier_attribute {
mccmnc_tuple: "24007"
}
+ carrier_attribute {
+ mccmnc_tuple: "24024"
+ spn: "Tele2"
+ }
}
carrier_id {
canonical_id: 1697
@@ -5150,6 +5195,7 @@
carrier_name: "Vodacom (T) Ltd."
carrier_attribute {
mccmnc_tuple: "64004"
+ spn: "VodaCom Tanzania"
}
}
carrier_id {
@@ -5336,7 +5382,7 @@
}
carrier_id {
canonical_id: 1771
- carrier_name: "Vodafone"
+ carrier_name: "Vodafone Malta"
carrier_attribute {
mccmnc_tuple: "90119"
}
@@ -5509,7 +5555,6 @@
carrier_name: "New Cell Inc. dba Cellcom"
carrier_attribute {
mccmnc_tuple: "310600"
- mccmnc_tuple: "31060"
}
}
carrier_id {
@@ -5675,7 +5720,7 @@
}
carrier_id {
canonical_id: 1827
- carrier_name: "Taylor Telecommunications Ltd."
+ carrier_name: "Mid-Rivers"
carrier_attribute {
mccmnc_tuple: "310900"
}
@@ -5689,7 +5734,7 @@
}
carrier_id {
canonical_id: 1829
- carrier_name: "Get Mobile"
+ carrier_name: "James Valley"
carrier_attribute {
mccmnc_tuple: "310920"
}
@@ -5731,11 +5776,15 @@
}
carrier_id {
canonical_id: 1836
- carrier_name: "Cellular South Inc."
+ carrier_name: "C Spire"
carrier_attribute {
mccmnc_tuple: "311230"
mccmnc_tuple: "310023"
}
+ carrier_attribute {
+ mccmnc_tuple: "20404"
+ spn: "C Spire"
+ }
}
carrier_id {
canonical_id: 1837
@@ -5760,6 +5809,10 @@
}
carrier_attribute {
mccmnc_tuple: "310004"
+ spn: "Verizon"
+ spn: "Verizon Wireless"
+ }
+ carrier_attribute {
mccmnc_tuple: "310012"
mccmnc_tuple: "311280"
mccmnc_tuple: "311281"
@@ -5834,14 +5887,14 @@
}
carrier_id {
canonical_id: 1847
- carrier_name: "Northwest Missouri Cellular Limited Partnership"
+ carrier_name: "northwestcell"
carrier_attribute {
mccmnc_tuple: "311420"
}
}
carrier_id {
canonical_id: 1848
- carrier_name: "RSA 1 Limited Partnership dba Cellular 29 Plus"
+ carrier_name: "Chat Mobility"
carrier_attribute {
mccmnc_tuple: "311430"
}
@@ -5855,7 +5908,7 @@
}
carrier_id {
canonical_id: 1850
- carrier_name: "Panhandle Telecommunication Systems Inc."
+ carrier_name: "PTCI"
carrier_attribute {
mccmnc_tuple: "311450"
}
@@ -5880,6 +5933,11 @@
carrier_attribute {
mccmnc_tuple: "311490"
}
+ carrier_attribute {
+ mccmnc_tuple: "310120"
+ mccmnc_tuple: "312530"
+ gid1: "000003"
+ }
}
carrier_id {
canonical_id: 1854
@@ -6164,7 +6222,7 @@
}
carrier_id {
canonical_id: 1894
- carrier_name: "SoftBank・Y!mobile"
+ carrier_name: "SoftBank"
carrier_attribute {
mccmnc_tuple: "44020"
}
@@ -6175,6 +6233,11 @@
carrier_attribute {
mccmnc_tuple: "302490"
}
+ carrier_attribute {
+ mccmnc_tuple: "22201"
+ mccmnc_tuple: "22288"
+ gid1: "ffffff00"
+ }
}
carrier_id {
canonical_id: 1896
@@ -6276,6 +6339,10 @@
mccmnc_tuple: "21406"
mccmnc_tuple: "21408"
}
+ carrier_attribute {
+ mccmnc_tuple: "20403"
+ imsi_prefix_xpattern: "2140359"
+ }
}
carrier_id {
canonical_id: 1910
@@ -6299,6 +6366,11 @@
mccmnc_tuple: "334090"
mccmnc_tuple: "33409"
}
+ carrier_attribute {
+ mccmnc_tuple: "22201"
+ spn: "IUSACELL"
+ spn: "UNEFON"
+ }
}
carrier_id {
canonical_id: 1913
@@ -6398,6 +6470,7 @@
carrier_name: "Digicel"
carrier_attribute {
mccmnc_tuple: "71404"
+ mccmnc_tuple: "714040"
}
}
carrier_id {
@@ -6416,7 +6489,7 @@
}
carrier_id {
canonical_id: 1929
- carrier_name: "Telefonica Moviles Peru"
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "71606"
}
@@ -6559,6 +6632,22 @@
carrier_name: "MetroPCS"
carrier_attribute {
mccmnc_tuple: "310260"
+ mccmnc_tuple: "310800"
+ mccmnc_tuple: "310660"
+ mccmnc_tuple: "310640"
+ mccmnc_tuple: "310590"
+ mccmnc_tuple: "310530"
+ mccmnc_tuple: "310490"
+ mccmnc_tuple: "310310"
+ mccmnc_tuple: "310300"
+ mccmnc_tuple: "310270"
+ mccmnc_tuple: "310250"
+ mccmnc_tuple: "310240"
+ mccmnc_tuple: "310230"
+ mccmnc_tuple: "310220"
+ mccmnc_tuple: "310210"
+ mccmnc_tuple: "310200"
+ mccmnc_tuple: "310160"
gid1: "6D38"
}
}
@@ -6575,6 +6664,11 @@
carrier_attribute {
mccmnc_tuple: "311870"
}
+ carrier_attribute {
+ mccmnc_tuple: "310120"
+ mccmnc_tuple: "312530"
+ gid1: "000002"
+ }
}
carrier_id {
canonical_id: 1952
@@ -6583,6 +6677,10 @@
mccmnc_tuple: "311580"
mccmnc_tuple: "311220"
}
+ carrier_attribute {
+ mccmnc_tuple: "20404"
+ spn: "U.S. Cellular"
+ }
}
carrier_id {
canonical_id: 1953
@@ -6648,13 +6746,11 @@
carrier_attribute {
mccmnc_tuple: "40402"
mccmnc_tuple: "40403"
- mccmnc_tuple: "40410"
mccmnc_tuple: "40416"
mccmnc_tuple: "40431"
mccmnc_tuple: "40440"
mccmnc_tuple: "40445"
mccmnc_tuple: "40449"
- mccmnc_tuple: "40470"
mccmnc_tuple: "40490"
mccmnc_tuple: "40492"
mccmnc_tuple: "40493"
@@ -6710,6 +6806,7 @@
mccmnc_tuple: "405754"
mccmnc_tuple: "405755"
mccmnc_tuple: "405756"
+ spn: "Vodafone IN"
}
}
carrier_id {
@@ -6789,6 +6886,12 @@
carrier_attribute {
mccmnc_tuple: "21421"
}
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ mccmnc_tuple: "21407"
+ spn: "JAZZTEL"
+ spn: "Jazztel"
+ }
}
carrier_id {
canonical_id: 1975
@@ -6834,13 +6937,6 @@
}
}
carrier_id {
- canonical_id: 1981
- carrier_name: "WaridTel"
- carrier_attribute {
- mccmnc_tuple: "41007"
- }
-}
-carrier_id {
canonical_id: 1982
carrier_name: "TATA DOCOMO"
carrier_attribute {
@@ -6884,7 +6980,7 @@
}
carrier_id {
canonical_id: 1985
- carrier_name: "Wana"
+ carrier_name: "Inwi"
carrier_attribute {
mccmnc_tuple: "60402"
}
@@ -6927,6 +7023,15 @@
spn: "nova"
}
carrier_attribute {
+ mccmnc_tuple: "310120"
+ gid1: "A00184"
+ gid1: "A00184FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "310120"
+ privilege_access_rule: "4C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EAFE8226079EF6F676FD1859"
+ }
+ carrier_attribute {
mccmnc_tuple: "310260"
imsi_prefix_xpattern: "31026097"
}
@@ -6949,6 +7054,10 @@
mccmnc_tuple: "42507"
mccmnc_tuple: "42577"
}
+ carrier_attribute {
+ mccmnc_tuple: "20404"
+ spn: "HOT mobile"
+ }
}
carrier_id {
canonical_id: 1992
@@ -6997,6 +7106,7 @@
carrier_name: "Vodafone"
carrier_attribute {
mccmnc_tuple: "42702"
+ spn: "Vodafone Qatar"
}
}
carrier_id {
@@ -7029,7 +7139,7 @@
}
carrier_id {
canonical_id: 2003
- carrier_name: "movistar"
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "71204"
}
@@ -7047,6 +7157,11 @@
carrier_attribute {
mccmnc_tuple: "20826"
}
+ carrier_attribute {
+ mccmnc_tuple: "20801"
+ mccmnc_tuple: "20810"
+ gid1: "4E"
+ }
}
carrier_id {
canonical_id: 2006
@@ -7073,7 +7188,7 @@
}
carrier_id {
canonical_id: 2009
- carrier_name: "Movistar (Telefonica Moviles El Salvador)"
+ carrier_name: "Movistar"
carrier_attribute {
mccmnc_tuple: "70604"
mccmnc_tuple: "706040"
@@ -7151,7 +7266,7 @@
mccmnc_tuple: "302221"
mccmnc_tuple: "30222"
mccmnc_tuple: "30286"
- gid1: "4b4f"
+ gid1: "4B4F"
}
}
carrier_id {
@@ -7255,7 +7370,7 @@
}
carrier_id {
canonical_id: 2032
- carrier_name: "XFINITY Mobile"
+ carrier_name: "XFINIY Mobile"
carrier_attribute {
mccmnc_tuple: "311480"
gid1: "BA01450000000000"
@@ -7305,6 +7420,96 @@
}
}
carrier_id {
+ canonical_id: 2039
+ carrier_name: "Fastweb"
+ carrier_attribute {
+ mccmnc_tuple: "22299"
+ spn: "FASTWEB"
+ }
+}
+carrier_id {
+ canonical_id: 2040
+ carrier_name: "Digi.Mobil"
+ carrier_attribute {
+ mccmnc_tuple: "22299"
+ spn: "DIGI.Mobil"
+ }
+}
+carrier_id {
+ canonical_id: 2041
+ carrier_name: "mms mobil"
+ carrier_attribute {
+ mccmnc_tuple: "23210"
+ spn: "MMmobil"
+ }
+}
+carrier_id {
+ canonical_id: 2042
+ carrier_name: "eety"
+ carrier_attribute {
+ mccmnc_tuple: "23210"
+ mccmnc_tuple: "2321283"
+ spn: "eety"
+ }
+}
+carrier_id {
+ canonical_id: 2043
+ carrier_name: "UPC"
+ carrier_attribute {
+ mccmnc_tuple: "23213"
+ gid1: "uat1"
+ }
+}
+carrier_id {
+ canonical_id: 2044
+ carrier_name: "spusu"
+ carrier_attribute {
+ mccmnc_tuple: "23217"
+ spn: "spusu"
+ gid1: "C7FF"
+ }
+}
+carrier_id {
+ canonical_id: 2045
+ carrier_name: "simpli"
+ carrier_attribute {
+ mccmnc_tuple: "23218"
+ spn: "simpli"
+ }
+}
+carrier_id {
+ canonical_id: 2046
+ carrier_name: "HGES"
+ carrier_attribute {
+ mccmnc_tuple: "23420"
+ gid1: "0304"
+ }
+}
+carrier_id {
+ canonical_id: 2047
+ carrier_name: "Kapow"
+ carrier_attribute {
+ mccmnc_tuple: "23420"
+ gid1: "0305"
+ }
+}
+carrier_id {
+ canonical_id: 2049
+ carrier_name: "Generic Wholesale?"
+ carrier_attribute {
+ mccmnc_tuple: "23420"
+ gid1: "0307"
+ }
+}
+carrier_id {
+ canonical_id: 2050
+ carrier_name: "OTONO"
+ carrier_attribute {
+ mccmnc_tuple: "23420"
+ gid1: "0308"
+ }
+}
+carrier_id {
canonical_id: 2052
carrier_name: "Virgin"
carrier_attribute {
@@ -7323,6 +7528,7 @@
}
carrier_attribute {
mccmnc_tuple: "302220"
+ mccmnc_tuple: "302221"
gid1: "5043"
}
}
@@ -7341,9 +7547,16 @@
canonical_id: 2055
carrier_name: "Chatr Mobile"
carrier_attribute {
+ mccmnc_tuple: "302320"
+ }
+ carrier_attribute {
mccmnc_tuple: "302720"
imsi_prefix_xpattern: "302720x94"
- gid1: "ff"
+ imsi_prefix_xpattern: "302720x84"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "302720"
+ gid1: "d2"
}
}
carrier_id {
@@ -7352,7 +7565,10 @@
carrier_attribute {
mccmnc_tuple: "302720"
imsi_prefix_xpattern: "302720x98"
- gid1: "ff"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "302720"
+ gid1: "d4"
}
}
carrier_id {
@@ -7363,6 +7579,10 @@
imsi_prefix_xpattern: "302720x97"
gid1: "cc"
}
+ carrier_attribute {
+ mccmnc_tuple: "302720"
+ spn: "CITYFONE"
+ }
}
carrier_id {
canonical_id: 2060
@@ -7565,7 +7785,8 @@
carrier_name: "Public Mobile"
carrier_attribute {
mccmnc_tuple: "302220"
- gid1: "4d4f"
+ mccmnc_tuple: "302221"
+ gid1: "4D4F"
}
}
carrier_id {
@@ -7700,6 +7921,10 @@
mccmnc_tuple: "44010"
preferred_apn: "iijmio.jp"
}
+ carrier_attribute {
+ mccmnc_tuple: "20601"
+ spn: "IIJ"
+ }
}
carrier_id {
canonical_id: 2107
@@ -7710,8 +7935,9 @@
}
carrier_id {
canonical_id: 2108
- carrier_name: "Airtel"
+ carrier_name: "AirtelTigo"
carrier_attribute {
+ mccmnc_tuple: "62003"
mccmnc_tuple: "62006"
}
}
@@ -7723,11 +7949,16 @@
preferred_apn: "rmobile.co"
preferred_apn: "rmobile.jp"
}
+ carrier_attribute {
+ mccmnc_tuple: "44051"
+ preferred_apn: "a.rmobile.jp"
+ }
}
carrier_id {
canonical_id: 2110
carrier_name: "UQ mobile"
carrier_attribute {
+ mccmnc_tuple: "44050"
mccmnc_tuple: "44051"
preferred_apn: "uqmobile.jp"
}
@@ -7745,12 +7976,25 @@
canonical_id: 2112
carrier_name: "Telecable"
carrier_attribute {
- mccmnc_tuple: "21405"
mccmnc_tuple: "21416"
spn: "telecable"
spn: "Telecable"
spn: "TeleCable"
}
+ carrier_attribute {
+ mccmnc_tuple: "21405"
+ imsi_prefix_xpattern: "214050111"
+ spn: "telecable"
+ spn: "Telecable"
+ spn: "TeleCable"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "21406"
+ imsi_prefix_xpattern: "2140613"
+ spn: "telecable"
+ spn: "Telecable"
+ spn: "TeleCable"
+ }
}
carrier_id {
canonical_id: 2113
@@ -7802,5 +8046,1717 @@
mccmnc_tuple: "23410"
gid1: "508"
}
+ carrier_attribute {
+ mccmnc_tuple: "23410"
+ spn: "giffgaff"
+ }
}
-version: 4
+carrier_id {
+ canonical_id: 2119
+ carrier_name: "FirstNet"
+ carrier_attribute {
+ mccmnc_tuple: "313100"
+ }
+}
+carrier_id {
+ canonical_id: 2120
+ carrier_name: "FirstNet (Lab)"
+ carrier_attribute {
+ mccmnc_tuple: "312670"
+ }
+}
+carrier_id {
+ canonical_id: 2121
+ carrier_name: "mineo"
+ carrier_attribute {
+ mccmnc_tuple: "44010"
+ preferred_apn: "mineo-d.jp"
+ }
+}
+carrier_id {
+ canonical_id: 2122
+ carrier_name: "Lucky Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "30264"
+ mccmnc_tuple: "302610"
+ mccmnc_tuple: "302630"
+ mccmnc_tuple: "302640"
+ gid1: "42"
+ }
+}
+carrier_id {
+ canonical_id: 2123
+ carrier_name: "Vodafone"
+ carrier_attribute {
+ mccmnc_tuple: "54002"
+ }
+}
+carrier_id {
+ canonical_id: 2124
+ carrier_name: "Iliad"
+ carrier_attribute {
+ mccmnc_tuple: "22250"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20815"
+ gid1: "F003"
+ }
+}
+carrier_id {
+ canonical_id: 2125
+ carrier_name: "Simyo"
+ carrier_attribute {
+ mccmnc_tuple: "21419"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ spn: "simyo"
+ }
+}
+carrier_id {
+ canonical_id: 2126
+ carrier_name: "Spectrum Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "311480"
+ gid1: "BA01490000000000"
+ }
+}
+carrier_id {
+ canonical_id: 2127
+ carrier_name: "Free RE"
+ carrier_attribute {
+ mccmnc_tuple: "64703"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20815"
+ gid1: "F2330002"
+ }
+}
+carrier_id {
+ canonical_id: 2128
+ carrier_name: "Sprint Wholesale"
+ carrier_attribute {
+ mccmnc_tuple: "310120"
+ gid1: "A00022FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00305FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00250FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00207FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00105FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00181FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00263FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00271FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00006FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00151FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00058FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00301FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00143FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00247FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00274FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00042FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00092FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00312FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00050FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ gid1: "A00034FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ }
+}
+carrier_id {
+ canonical_id: 2129
+ carrier_name: "ALDI mobile"
+ carrier_attribute {
+ mccmnc_tuple: "50501"
+ spn: "aldimobile"
+ }
+}
+carrier_id {
+ canonical_id: 2130
+ carrier_name: "ALIV BS"
+ carrier_attribute {
+ mccmnc_tuple: "20809"
+ imsi_prefix_xpattern: "208090021"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "36449"
+ }
+}
+carrier_id {
+ canonical_id: 2131
+ carrier_name: "Altecom"
+ carrier_attribute {
+ mccmnc_tuple: "21402"
+ }
+}
+carrier_id {
+ canonical_id: 2132
+ carrier_name: "Bics"
+ carrier_attribute {
+ mccmnc_tuple: "20628"
+ mccmnc_tuple: "90158"
+ }
+}
+carrier_id {
+ canonical_id: 2133
+ carrier_name: "Carrefour"
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ imsi_prefix_xpattern: "2140352"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20801"
+ gid1: "33"
+ }
+}
+carrier_id {
+ canonical_id: 2134
+ carrier_name: "com4"
+ carrier_attribute {
+ mccmnc_tuple: "24209"
+ }
+}
+carrier_id {
+ canonical_id: 2135
+ carrier_name: "Coriolis"
+ carrier_attribute {
+ mccmnc_tuple: "20827"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20810"
+ mccmnc_tuple: "64710"
+ gid1: "12"
+ }
+}
+carrier_id {
+ canonical_id: 2136
+ carrier_name: "Fibracat"
+ carrier_attribute {
+ mccmnc_tuple: "21402"
+ spn: "fibracat"
+ }
+}
+carrier_id {
+ canonical_id: 2137
+ carrier_name: "Gamma"
+ carrier_attribute {
+ mccmnc_tuple: "23439"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "24007"
+ imsi_prefix_xpattern: "24007561"
+ }
+}
+carrier_id {
+ canonical_id: 2138
+ carrier_name: "Jump"
+ carrier_attribute {
+ mccmnc_tuple: "23410"
+ mccmnc_tuple: "23439"
+ mccmnc_tuple: "24007"
+ spn: "jump"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20404"
+ spn: "Jump"
+ }
+}
+carrier_id {
+ canonical_id: 2139
+ carrier_name: "Sky"
+ carrier_attribute {
+ mccmnc_tuple: "23457"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "24007"
+ gid1: "0c"
+ }
+}
+carrier_id {
+ canonical_id: 2140
+ carrier_name: "Smarty"
+ carrier_attribute {
+ mccmnc_tuple: "23420"
+ gid1: "0309"
+ }
+}
+carrier_id {
+ canonical_id: 2141
+ carrier_name: "Superdrug"
+ carrier_attribute {
+ mccmnc_tuple: "23420"
+ gid1: "0310"
+ }
+}
+carrier_id {
+ canonical_id: 2142
+ carrier_name: "Tinkoff"
+ carrier_attribute {
+ mccmnc_tuple: "25062"
+ }
+}
+carrier_id {
+ canonical_id: 2143
+ carrier_name: "Truphone"
+ carrier_attribute {
+ mccmnc_tuple: "20433"
+ mccmnc_tuple: "21427"
+ mccmnc_tuple: "23425"
+ mccmnc_tuple: "26033"
+ mccmnc_tuple: "26242"
+ mccmnc_tuple: "31030"
+ mccmnc_tuple: "50538"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20404"
+ imsi_prefix_xpattern: "204043914"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "23450"
+ imsi_prefix_xpattern: "234500008"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "50502"
+ imsi_prefix_xpattern: "50502100"
+ }
+}
+carrier_id {
+ canonical_id: 2144
+ carrier_name: "Unleashed"
+ carrier_attribute {
+ mccmnc_tuple: "20630"
+ }
+}
+carrier_id {
+ canonical_id: 2145
+ carrier_name: "Virgin"
+ carrier_attribute {
+ mccmnc_tuple: "50502"
+ imsi_prefix_xpattern: "505029"
+ }
+}
+carrier_id {
+ canonical_id: 2146
+ carrier_name: "Visible"
+ carrier_attribute {
+ mccmnc_tuple: "311480"
+ gid1: "bae1000000000000"
+ }
+}
+carrier_id {
+ canonical_id: 2147
+ carrier_name: "Vodafone Lab"
+ carrier_attribute {
+ mccmnc_tuple: "26209"
+ }
+}
+carrier_id {
+ canonical_id: 2148
+ carrier_name: "BIGLOBE"
+ carrier_attribute {
+ mccmnc_tuple: "44010"
+ preferred_apn: "biglobe.jp"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "44051"
+ preferred_apn: "biglobe.jp"
+ }
+}
+carrier_id {
+ canonical_id: 2149
+ carrier_name: "Voiceworks"
+ carrier_attribute {
+ mccmnc_tuple: "20403"
+ }
+}
+carrier_id {
+ canonical_id: 2150
+ carrier_name: "Telenet"
+ carrier_attribute {
+ mccmnc_tuple: "20605"
+ }
+}
+carrier_id {
+ canonical_id: 2151
+ carrier_name: "Legos"
+ carrier_attribute {
+ mccmnc_tuple: "20817"
+ }
+}
+carrier_id {
+ canonical_id: 2152
+ carrier_name: "Lycamobile"
+ carrier_attribute {
+ mccmnc_tuple: "23426"
+ }
+}
+carrier_id {
+ canonical_id: 2153
+ carrier_name: "Unité"
+ carrier_attribute {
+ mccmnc_tuple: "25905"
+ }
+}
+carrier_id {
+ canonical_id: 2154
+ carrier_name: "Tesco"
+ carrier_attribute {
+ mccmnc_tuple: "27211"
+ }
+}
+carrier_id {
+ canonical_id: 2155
+ carrier_name: "Nova"
+ carrier_attribute {
+ mccmnc_tuple: "27411"
+ }
+}
+carrier_id {
+ canonical_id: 2156
+ carrier_name: "PrimeTel"
+ carrier_attribute {
+ mccmnc_tuple: "28020"
+ }
+}
+carrier_id {
+ canonical_id: 2157
+ carrier_name: "IT&E OverSeas"
+ carrier_attribute {
+ mccmnc_tuple: "310032"
+ }
+}
+carrier_id {
+ canonical_id: 2158
+ carrier_name: "North Dakota Network Company"
+ carrier_attribute {
+ mccmnc_tuple: "311610"
+ }
+}
+carrier_id {
+ canonical_id: 2159
+ carrier_name: "United Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "311650"
+ spn: "unitedwireless"
+ }
+}
+carrier_id {
+ canonical_id: 2160
+ carrier_name: "Pine Belt"
+ carrier_attribute {
+ mccmnc_tuple: "311670"
+ spn: "pinebelt"
+ }
+}
+carrier_id {
+ canonical_id: 2161
+ carrier_name: "Missouri RSA No 5 Partnership"
+ carrier_attribute {
+ mccmnc_tuple: "311920"
+ }
+}
+carrier_id {
+ canonical_id: 2162
+ carrier_name: "Custer"
+ carrier_attribute {
+ mccmnc_tuple: "312040"
+ }
+}
+carrier_id {
+ canonical_id: 2163
+ carrier_name: "Digicel"
+ carrier_attribute {
+ mccmnc_tuple: "36302"
+ }
+}
+carrier_id {
+ canonical_id: 2164
+ carrier_name: "ALTEL"
+ carrier_attribute {
+ mccmnc_tuple: "40107"
+ }
+}
+carrier_id {
+ canonical_id: 2165
+ carrier_name: "TashiCell"
+ carrier_attribute {
+ mccmnc_tuple: "40277"
+ }
+}
+carrier_id {
+ canonical_id: 2166
+ carrier_name: "SanaTel"
+ carrier_attribute {
+ mccmnc_tuple: "41808"
+ }
+}
+carrier_id {
+ canonical_id: 2167
+ carrier_name: "Omnnea"
+ carrier_attribute {
+ mccmnc_tuple: "41892"
+ }
+}
+carrier_id {
+ canonical_id: 2168
+ carrier_name: "HiTS-UNITEL"
+ carrier_attribute {
+ mccmnc_tuple: "42104"
+ }
+}
+carrier_id {
+ canonical_id: 2169
+ carrier_name: "Alon Cellular Ltd"
+ carrier_attribute {
+ mccmnc_tuple: "42514"
+ }
+}
+carrier_id {
+ canonical_id: 2170
+ carrier_name: "Home Cellular"
+ carrier_attribute {
+ mccmnc_tuple: "42515"
+ }
+}
+carrier_id {
+ canonical_id: 2171
+ carrier_name: "Rami Levy"
+ carrier_attribute {
+ mccmnc_tuple: "42516"
+ }
+}
+carrier_id {
+ canonical_id: 2172
+ carrier_name: "Skytel"
+ carrier_attribute {
+ mccmnc_tuple: "42891"
+ }
+}
+carrier_id {
+ canonical_id: 2173
+ carrier_name: "G.Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "42898"
+ }
+}
+carrier_id {
+ canonical_id: 2174
+ carrier_name: "Tcell"
+ carrier_attribute {
+ mccmnc_tuple: "43612"
+ }
+}
+carrier_id {
+ canonical_id: 2175
+ carrier_name: "AkTel LLC"
+ carrier_attribute {
+ mccmnc_tuple: "43703"
+ }
+}
+carrier_id {
+ canonical_id: 2176
+ carrier_name: "MegaCom"
+ carrier_attribute {
+ mccmnc_tuple: "43705"
+ }
+}
+carrier_id {
+ canonical_id: 2177
+ carrier_name: "O!"
+ carrier_attribute {
+ mccmnc_tuple: "43709"
+ }
+}
+carrier_id {
+ canonical_id: 2178
+ carrier_name: "Gmobile"
+ carrier_attribute {
+ mccmnc_tuple: "45207"
+ }
+}
+carrier_id {
+ canonical_id: 2179
+ carrier_name: "Viettel Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "45208"
+ }
+}
+carrier_id {
+ canonical_id: 2180
+ carrier_name: "qb"
+ carrier_attribute {
+ mccmnc_tuple: "45604"
+ }
+}
+carrier_id {
+ canonical_id: 2181
+ carrier_name: "Metfone"
+ carrier_attribute {
+ mccmnc_tuple: "45608"
+ }
+}
+carrier_id {
+ canonical_id: 2182
+ carrier_name: "Telkomcel"
+ carrier_attribute {
+ mccmnc_tuple: "51401"
+ }
+}
+carrier_id {
+ canonical_id: 2183
+ carrier_name: "Timor Telecom"
+ carrier_attribute {
+ mccmnc_tuple: "51402"
+ }
+}
+carrier_id {
+ canonical_id: 2184
+ carrier_name: "Redinternet"
+ carrier_attribute {
+ mccmnc_tuple: "51518"
+ }
+}
+carrier_id {
+ canonical_id: 2185
+ carrier_name: "BREEZE"
+ carrier_attribute {
+ mccmnc_tuple: "54001"
+ }
+}
+carrier_id {
+ canonical_id: 2186
+ carrier_name: "Digicel"
+ carrier_attribute {
+ mccmnc_tuple: "54202"
+ }
+}
+carrier_id {
+ canonical_id: 2187
+ carrier_name: "Kiribati Frigate"
+ carrier_attribute {
+ mccmnc_tuple: "54509"
+ }
+}
+carrier_id {
+ canonical_id: 2188
+ carrier_name: "Palau Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "55280"
+ }
+}
+carrier_id {
+ canonical_id: 2189
+ carrier_name: "Al-Jeel"
+ carrier_attribute {
+ mccmnc_tuple: "60602"
+ }
+}
+carrier_id {
+ canonical_id: 2190
+ carrier_name: "Hatef"
+ carrier_attribute {
+ mccmnc_tuple: "60606"
+ }
+}
+carrier_id {
+ canonical_id: 2191
+ carrier_name: "QCell"
+ carrier_attribute {
+ mccmnc_tuple: "60704"
+ }
+}
+carrier_id {
+ canonical_id: 2192
+ carrier_name: "Expresso"
+ carrier_attribute {
+ mccmnc_tuple: "60803"
+ }
+}
+carrier_id {
+ canonical_id: 2193
+ carrier_name: "Intercel"
+ carrier_attribute {
+ mccmnc_tuple: "61103"
+ }
+}
+carrier_id {
+ canonical_id: 2194
+ carrier_name: "Lonestar"
+ carrier_attribute {
+ mccmnc_tuple: "61801"
+ }
+}
+carrier_id {
+ canonical_id: 2195
+ carrier_name: "Libercell"
+ carrier_attribute {
+ mccmnc_tuple: "61802"
+ }
+}
+carrier_id {
+ canonical_id: 2196
+ carrier_name: "LIBTELCO"
+ carrier_attribute {
+ mccmnc_tuple: "61820"
+ }
+}
+carrier_id {
+ canonical_id: 2197
+ carrier_name: "Salam"
+ carrier_attribute {
+ mccmnc_tuple: "62204"
+ }
+}
+carrier_id {
+ canonical_id: 2198
+ carrier_name: "Nationlink"
+ carrier_attribute {
+ mccmnc_tuple: "62304"
+ }
+}
+carrier_id {
+ canonical_id: 2199
+ carrier_name: "Hits-GE"
+ carrier_attribute {
+ mccmnc_tuple: "62703"
+ }
+}
+carrier_id {
+ canonical_id: 2200
+ carrier_name: "Azur"
+ carrier_attribute {
+ mccmnc_tuple: "62804"
+ }
+}
+carrier_id {
+ canonical_id: 2201
+ carrier_name: "MOVICEL"
+ carrier_attribute {
+ mccmnc_tuple: "63104"
+ }
+}
+carrier_id {
+ canonical_id: 2202
+ carrier_name: "Sudani"
+ carrier_attribute {
+ mccmnc_tuple: "63407"
+ }
+}
+carrier_id {
+ canonical_id: 2203
+ carrier_name: "Tigo"
+ carrier_attribute {
+ mccmnc_tuple: "63513"
+ }
+}
+carrier_id {
+ canonical_id: 2204
+ carrier_name: "Airtel"
+ carrier_attribute {
+ mccmnc_tuple: "63514"
+ }
+}
+carrier_id {
+ canonical_id: 2205
+ carrier_name: "Telesom"
+ carrier_attribute {
+ mccmnc_tuple: "63701"
+ }
+}
+carrier_id {
+ canonical_id: 2206
+ carrier_name: "Nationlink"
+ carrier_attribute {
+ mccmnc_tuple: "63710"
+ }
+}
+carrier_id {
+ canonical_id: 2207
+ carrier_name: "Somtel"
+ carrier_attribute {
+ mccmnc_tuple: "63771"
+ }
+}
+carrier_id {
+ canonical_id: 2208
+ carrier_name: "Telcom"
+ carrier_attribute {
+ mccmnc_tuple: "63782"
+ }
+}
+carrier_id {
+ canonical_id: 2209
+ carrier_name: "Yu"
+ carrier_attribute {
+ mccmnc_tuple: "63905"
+ }
+}
+carrier_id {
+ canonical_id: 2210
+ carrier_name: "Telkom"
+ carrier_attribute {
+ mccmnc_tuple: "63907"
+ }
+}
+carrier_id {
+ canonical_id: 2211
+ carrier_name: "Lumitel/Viettel"
+ carrier_attribute {
+ mccmnc_tuple: "64208"
+ }
+}
+carrier_id {
+ canonical_id: 2212
+ carrier_name: "Leo"
+ carrier_attribute {
+ mccmnc_tuple: "64282"
+ }
+}
+carrier_id {
+ canonical_id: 2213
+ carrier_name: "Movitel"
+ carrier_attribute {
+ mccmnc_tuple: "64303"
+ }
+}
+carrier_id {
+ canonical_id: 2214
+ carrier_name: "switch"
+ carrier_attribute {
+ mccmnc_tuple: "64902"
+ }
+}
+carrier_id {
+ canonical_id: 2215
+ carrier_name: "Porto Seguro TeleComumicacoes"
+ carrier_attribute {
+ mccmnc_tuple: "72454"
+ }
+}
+carrier_id {
+ canonical_id: 2216
+ carrier_name: "VTR Banda Ancha SA"
+ carrier_attribute {
+ mccmnc_tuple: "73008"
+ }
+}
+carrier_id {
+ canonical_id: 2217
+ carrier_name: "GT&T Cellink Plus"
+ carrier_attribute {
+ mccmnc_tuple: "73802"
+ mccmnc_tuple: "738002"
+ }
+}
+carrier_id {
+ canonical_id: 2218
+ carrier_name: "ETB 4G"
+ carrier_attribute {
+ mccmnc_tuple: "732187"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "732103"
+ spn: "ETB MOVI"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "732111"
+ spn: "ETB MOVIL"
+ }
+}
+carrier_id {
+ canonical_id: 2219
+ carrier_name: "Digicel"
+ carrier_attribute {
+ mccmnc_tuple: "54105"
+ }
+}
+carrier_id {
+ canonical_id: 2220
+ carrier_name: "Digicel"
+ carrier_attribute {
+ mccmnc_tuple: "53988"
+ }
+}
+carrier_id {
+ canonical_id: 2221
+ carrier_name: "Etisalat"
+ carrier_attribute {
+ mccmnc_tuple: "41250"
+ }
+}
+carrier_id {
+ canonical_id: 2222
+ carrier_name: "Globacom"
+ carrier_attribute {
+ mccmnc_tuple: "62007"
+ }
+}
+carrier_id {
+ canonical_id: 2223
+ carrier_name: "Grenada:Lime"
+ carrier_attribute {
+ mccmnc_tuple: "352110"
+ }
+}
+carrier_id {
+ canonical_id: 2224
+ carrier_name: "Cable & Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "33818"
+ mccmnc_tuple: "338180"
+ }
+}
+carrier_id {
+ canonical_id: 2225
+ carrier_name: "MTN/Areeba"
+ carrier_attribute {
+ mccmnc_tuple: "61104"
+ }
+}
+carrier_id {
+ canonical_id: 2227
+ carrier_name: "Tigo/Milicom/Tchad Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "62203"
+ }
+}
+carrier_id {
+ canonical_id: 2229
+ carrier_name: "Rebtel"
+ carrier_attribute {
+ mccmnc_tuple: "26044"
+ }
+}
+carrier_id {
+ canonical_id: 2230
+ carrier_name: "bulsatcom"
+ carrier_attribute {
+ mccmnc_tuple: "28411"
+ }
+}
+carrier_id {
+ canonical_id: 2231
+ carrier_name: "MAX TELECOM"
+ carrier_attribute {
+ mccmnc_tuple: "28413"
+ }
+}
+carrier_id {
+ canonical_id: 2232
+ carrier_name: "BICS"
+ carrier_attribute {
+ mccmnc_tuple: "29509"
+ spn: "BICS"
+ }
+}
+carrier_id {
+ canonical_id: 2233
+ carrier_name: "EMnify"
+ carrier_attribute {
+ mccmnc_tuple: "29509"
+ }
+}
+carrier_id {
+ canonical_id: 2234
+ carrier_name: "Itisaluna"
+ carrier_attribute {
+ mccmnc_tuple: "41862"
+ }
+}
+carrier_id {
+ canonical_id: 2235
+ carrier_name: "Perfectum Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "43406"
+ }
+}
+carrier_id {
+ canonical_id: 2236
+ carrier_name: "SEATEL"
+ carrier_attribute {
+ mccmnc_tuple: "45611"
+ }
+}
+carrier_id {
+ canonical_id: 2237
+ carrier_name: "China Telecom"
+ carrier_attribute {
+ mccmnc_tuple: "46003"
+ mccmnc_tuple: "46011"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20404"
+ spn: "中国电信"
+ }
+}
+carrier_id {
+ canonical_id: 2238
+ carrier_name: "Sunsurf"
+ carrier_attribute {
+ mccmnc_tuple: "52504"
+ }
+}
+carrier_id {
+ canonical_id: 2239
+ carrier_name: "AIL"
+ carrier_attribute {
+ mccmnc_tuple: "54100"
+ }
+}
+carrier_id {
+ canonical_id: 2240
+ carrier_name: "Kiribati - TSKL"
+ carrier_attribute {
+ mccmnc_tuple: "54501"
+ }
+}
+carrier_id {
+ canonical_id: 2241
+ carrier_name: "Guinetel"
+ carrier_attribute {
+ mccmnc_tuple: "63207"
+ }
+}
+carrier_id {
+ canonical_id: 2242
+ carrier_name: "Privet"
+ carrier_attribute {
+ mccmnc_tuple: "63409"
+ }
+}
+carrier_id {
+ canonical_id: 2243
+ carrier_name: "Rwandatel"
+ carrier_attribute {
+ mccmnc_tuple: "63512"
+ }
+}
+carrier_id {
+ canonical_id: 2244
+ carrier_name: "Somafone"
+ carrier_attribute {
+ mccmnc_tuple: "63704"
+ }
+}
+carrier_id {
+ canonical_id: 2245
+ carrier_name: "Hormuud"
+ carrier_attribute {
+ mccmnc_tuple: "63725"
+ }
+}
+carrier_id {
+ canonical_id: 2246
+ carrier_name: "Unitel"
+ carrier_attribute {
+ mccmnc_tuple: "63757"
+ }
+}
+carrier_id {
+ canonical_id: 2247
+ carrier_name: "Eritel"
+ carrier_attribute {
+ mccmnc_tuple: "65701"
+ }
+}
+carrier_id {
+ canonical_id: 2248
+ carrier_name: "Digicel"
+ carrier_attribute {
+ mccmnc_tuple: "70804"
+ mccmnc_tuple: "708040"
+ }
+}
+carrier_id {
+ canonical_id: 2249
+ carrier_name: "Quam_WEB"
+ carrier_attribute {
+ mccmnc_tuple: "72201"
+ spn: "QUAM"
+ spn: "CELULAR"
+ }
+}
+carrier_id {
+ canonical_id: 2250
+ carrier_name: "Argentina:Nuestro"
+ carrier_attribute {
+ mccmnc_tuple: "72236"
+ }
+}
+carrier_id {
+ canonical_id: 2251
+ carrier_name: "Sberbank-Telecom"
+ carrier_attribute {
+ mccmnc_tuple: "250050"
+ }
+}
+carrier_id {
+ canonical_id: 2252
+ carrier_name: "EastLink"
+ carrier_attribute {
+ mccmnc_tuple: "302270"
+ }
+}
+carrier_id {
+ canonical_id: 2253
+ carrier_name: "ALU Test-SIM"
+ carrier_attribute {
+ mccmnc_tuple: "310028"
+ }
+}
+carrier_id {
+ canonical_id: 2254
+ carrier_name: "etex"
+ carrier_attribute {
+ mccmnc_tuple: "310035"
+ }
+}
+carrier_id {
+ canonical_id: 2255
+ carrier_name: "NexTech Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "311100"
+ }
+}
+carrier_id {
+ canonical_id: 2256
+ carrier_name: "TelAlaska Cellular"
+ carrier_attribute {
+ mccmnc_tuple: "311740"
+ }
+}
+carrier_id {
+ canonical_id: 2257
+ carrier_name: "Cleartalk"
+ carrier_attribute {
+ mccmnc_tuple: "311750"
+ }
+}
+carrier_id {
+ canonical_id: 2258
+ carrier_name: "MobileNation"
+ carrier_attribute {
+ mccmnc_tuple: "311910"
+ }
+}
+carrier_id {
+ canonical_id: 2259
+ carrier_name: "Syringa"
+ carrier_attribute {
+ mccmnc_tuple: "311930"
+ }
+}
+carrier_id {
+ canonical_id: 2260
+ carrier_name: "NexTech Ota"
+ carrier_attribute {
+ mccmnc_tuple: "312420"
+ }
+}
+carrier_id {
+ canonical_id: 2261
+ carrier_name: "Blue Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "312570"
+ }
+}
+carrier_id {
+ canonical_id: 2262
+ carrier_name: "Open Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "330000"
+ }
+}
+carrier_id {
+ canonical_id: 2263
+ carrier_name: "Claro"
+ carrier_attribute {
+ mccmnc_tuple: "338070"
+ }
+}
+carrier_id {
+ canonical_id: 2264
+ carrier_name: "Videocon"
+ carrier_attribute {
+ mccmnc_tuple: "405823"
+ mccmnc_tuple: "405824"
+ mccmnc_tuple: "405825"
+ mccmnc_tuple: "405826"
+ mccmnc_tuple: "405827"
+ mccmnc_tuple: "405828"
+ mccmnc_tuple: "405829"
+ mccmnc_tuple: "405830"
+ mccmnc_tuple: "405832"
+ mccmnc_tuple: "405833"
+ mccmnc_tuple: "405834"
+ mccmnc_tuple: "405835"
+ mccmnc_tuple: "405836"
+ mccmnc_tuple: "405837"
+ mccmnc_tuple: "405838"
+ mccmnc_tuple: "405841"
+ mccmnc_tuple: "405842"
+ mccmnc_tuple: "405843"
+ mccmnc_tuple: "405932"
+ }
+}
+carrier_id {
+ canonical_id: 2265
+ carrier_name: "STEL"
+ carrier_attribute {
+ mccmnc_tuple: "405881"
+ mccmnc_tuple: "405882"
+ mccmnc_tuple: "405883"
+ mccmnc_tuple: "405884"
+ mccmnc_tuple: "405885"
+ mccmnc_tuple: "405886"
+ }
+}
+carrier_id {
+ canonical_id: 2266
+ carrier_name: "Cheers"
+ carrier_attribute {
+ mccmnc_tuple: "405912"
+ mccmnc_tuple: "405913"
+ mccmnc_tuple: "405914"
+ mccmnc_tuple: "405915"
+ mccmnc_tuple: "405916"
+ mccmnc_tuple: "405917"
+ mccmnc_tuple: "405918"
+ mccmnc_tuple: "405919"
+ mccmnc_tuple: "405920"
+ mccmnc_tuple: "405921"
+ mccmnc_tuple: "405922"
+ mccmnc_tuple: "405923"
+ mccmnc_tuple: "405930"
+ }
+}
+carrier_id {
+ canonical_id: 2267
+ carrier_name: "Tuyo"
+ carrier_attribute {
+ mccmnc_tuple: "712019"
+ mccmnc_tuple: "712190"
+ }
+}
+carrier_id {
+ canonical_id: 2268
+ carrier_name: "Viettel"
+ carrier_attribute {
+ mccmnc_tuple: "51403"
+ }
+}
+carrier_id {
+ canonical_id: 2270
+ carrier_name: "Telenet"
+ carrier_attribute {
+ mccmnc_tuple: "20601"
+ imsi_prefix_xpattern: "20601889"
+ }
+}
+carrier_id {
+ canonical_id: 2271
+ carrier_name: "Transatel"
+ carrier_attribute {
+ mccmnc_tuple: "20610"
+ spn: "BE-Transatel"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "20610"
+ gid1: "BB00"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "22803"
+ spn: "CH-Transatel"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "22803"
+ gid1: "BB00"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "27077"
+ gid1: "BB00"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "27077"
+ spn: "LU-Transatel"
+ }
+}
+carrier_id {
+ canonical_id: 2272
+ carrier_name: "Auchan"
+ carrier_attribute {
+ mccmnc_tuple: "20810"
+ spn: "A MOBILE"
+ }
+}
+carrier_id {
+ canonical_id: 2273
+ carrier_name: "Reglo"
+ carrier_attribute {
+ mccmnc_tuple: "20810"
+ spn: "LeclercMobile"
+ spn: "RegloMobile"
+ }
+}
+carrier_id {
+ canonical_id: 2274
+ carrier_name: "La Poste"
+ carrier_attribute {
+ mccmnc_tuple: "20810"
+ gid1: "4C"
+ }
+}
+carrier_id {
+ canonical_id: 2275
+ carrier_name: "Darty"
+ carrier_attribute {
+ mccmnc_tuple: "20810"
+ gid1: "44"
+ }
+}
+carrier_id {
+ canonical_id: 2276
+ carrier_name: "Keyyo"
+ carrier_attribute {
+ mccmnc_tuple: "20810"
+ spn: "Keyyo Mobile"
+ }
+}
+carrier_id {
+ canonical_id: 2277
+ carrier_name: "Zero forfait"
+ carrier_attribute {
+ mccmnc_tuple: "20810"
+ spn: "ZERO FORFAIT"
+ }
+}
+carrier_id {
+ canonical_id: 2278
+ carrier_name: "R"
+ carrier_attribute {
+ mccmnc_tuple: "21406"
+ imsi_prefix_xpattern: "2140612"
+ }
+}
+carrier_id {
+ canonical_id: 2279
+ carrier_name: "eroskimovil"
+ carrier_attribute {
+ mccmnc_tuple: "21406"
+ imsi_prefix_xpattern: "2140606"
+ }
+}
+carrier_id {
+ canonical_id: 2280
+ carrier_name: "pepephone"
+ carrier_attribute {
+ mccmnc_tuple: "21406"
+ spn: "pepephone"
+ }
+}
+carrier_id {
+ canonical_id: 2281
+ carrier_name: "T-2"
+ carrier_attribute {
+ mccmnc_tuple: "21407"
+ imsi_prefix_xpattern: "2140759577"
+ imsi_prefix_xpattern: "2140796692"
+ }
+}
+carrier_id {
+ canonical_id: 2282
+ carrier_name: "Noverca"
+ carrier_attribute {
+ mccmnc_tuple: "22201"
+ spn: "Noverca"
+ }
+}
+carrier_id {
+ canonical_id: 2283
+ carrier_name: "LIFE"
+ carrier_attribute {
+ mccmnc_tuple: "23433"
+ spn: "LIFE"
+ }
+}
+carrier_id {
+ canonical_id: 2284
+ carrier_name: "Telmore"
+ carrier_attribute {
+ mccmnc_tuple: "23801"
+ spn: "TELMORE"
+ }
+}
+carrier_id {
+ canonical_id: 2285
+ carrier_name: "Call Me"
+ carrier_attribute {
+ mccmnc_tuple: "23820"
+ spn: "Call me"
+ }
+}
+carrier_id {
+ canonical_id: 2286
+ carrier_name: "DLG Tele"
+ carrier_attribute {
+ mccmnc_tuple: "23820"
+ spn: "DLG Tele"
+ }
+}
+carrier_id {
+ canonical_id: 2287
+ carrier_name: "Halebop"
+ carrier_attribute {
+ mccmnc_tuple: "24001"
+ imsi_prefix_xpattern: "240017"
+ }
+ carrier_attribute {
+ mccmnc_tuple: "24005"
+ spn: "Halebop"
+ }
+}
+carrier_id {
+ canonical_id: 2288
+ carrier_name: "GSC"
+ carrier_attribute {
+ mccmnc_tuple: "311590"
+ spn: "gsc"
+ }
+}
+carrier_id {
+ canonical_id: 2289
+ carrier_name: "Cable & Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "348170"
+ }
+}
+carrier_id {
+ canonical_id: 2290
+ carrier_name: "Cable & Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "366110"
+ }
+}
+carrier_id {
+ canonical_id: 2291
+ carrier_name: "Cable & Wireless West Indies Ltd (Turks & Caicos)"
+ carrier_attribute {
+ mccmnc_tuple: "376350"
+ }
+}
+carrier_id {
+ canonical_id: 2292
+ carrier_name: "Cable & Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "354860"
+ }
+}
+carrier_id {
+ canonical_id: 2293
+ carrier_name: "Cable & Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "358110"
+ }
+}
+carrier_id {
+ canonical_id: 2294
+ carrier_name: "Cable & Wireless (St. Vincent & the Grenadines) Ltd"
+ carrier_attribute {
+ mccmnc_tuple: "360110"
+ }
+}
+carrier_id {
+ canonical_id: 2295
+ carrier_name: "Cable & Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "365840"
+ }
+}
+carrier_id {
+ canonical_id: 2297
+ carrier_name: "Happy"
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ spn: "Happy"
+ }
+}
+carrier_id {
+ canonical_id: 2298
+ carrier_name: "RACC"
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ spn: "RACC"
+ }
+}
+carrier_id {
+ canonical_id: 2299
+ carrier_name: "CABLE movil"
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ spn: "CABLE movil"
+ }
+}
+carrier_id {
+ canonical_id: 2300
+ carrier_name: "MASMovil"
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ spn: "MASMovil"
+ }
+}
+carrier_id {
+ canonical_id: 2301
+ carrier_name: "Ibercom"
+ carrier_attribute {
+ mccmnc_tuple: "21403"
+ spn: "Ibercom"
+ }
+}
+carrier_id {
+ canonical_id: 2303
+ carrier_name: "PosteMobile"
+ carrier_attribute {
+ mccmnc_tuple: "22210"
+ spn: "PosteMobile"
+ }
+}
+carrier_id {
+ canonical_id: 2304
+ carrier_name: "ERG"
+ carrier_attribute {
+ mccmnc_tuple: "22210"
+ spn: "ERG"
+ }
+}
+carrier_id {
+ canonical_id: 2308
+ carrier_name: "Sainsbury's"
+ carrier_attribute {
+ mccmnc_tuple: "23415"
+ spn: "Sainsbury's"
+ }
+}
+carrier_id {
+ canonical_id: 2309
+ carrier_name: "Lebara"
+ carrier_attribute {
+ mccmnc_tuple: "23415"
+ spn: "Lebara"
+ }
+}
+carrier_id {
+ canonical_id: 2310
+ carrier_name: "Debitel"
+ carrier_attribute {
+ mccmnc_tuple: "26201"
+ spn: "debitel"
+ }
+}
+carrier_id {
+ canonical_id: 2315
+ carrier_name: "Norvado"
+ carrier_attribute {
+ mccmnc_tuple: "311500"
+ spn: "Norvado Wireless"
+ spn: "Norvado Wireless RPA"
+ spn: "Norvado Wireless RPT"
+ spn: "Norvado Wireless RPO"
+ }
+}
+carrier_id {
+ canonical_id: 2316
+ carrier_name: "Mosaic Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "311500"
+ spn: "Mosaic RPA"
+ spn: "Mosaic Mobile"
+ spn: "Mosaic RPT"
+ spn: "Mosaic RPO"
+ }
+}
+carrier_id {
+ canonical_id: 2317
+ carrier_name: "Nemont"
+ carrier_attribute {
+ mccmnc_tuple: "311350"
+ spn: "nemont"
+ }
+}
+carrier_id {
+ canonical_id: 2318
+ carrier_name: "Bravado wireless"
+ carrier_attribute {
+ mccmnc_tuple: "311140"
+ spn: "sprocket"
+ }
+}
+carrier_id {
+ canonical_id: 2319
+ carrier_name: "Element Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "311070"
+ spn: "elementmobile"
+ }
+}
+carrier_id {
+ canonical_id: 2320
+ carrier_name: "strata"
+ carrier_attribute {
+ mccmnc_tuple: "310960"
+ spn: "strata"
+ }
+}
+carrier_id {
+ canonical_id: 2321
+ carrier_name: "southcentral"
+ carrier_attribute {
+ mccmnc_tuple: "310960"
+ spn: "southcentral"
+ }
+}
+carrier_id {
+ canonical_id: 2322
+ carrier_name: "snakeriver"
+ carrier_attribute {
+ mccmnc_tuple: "310960"
+ spn: "snakeriver"
+ }
+}
+carrier_id {
+ canonical_id: 2323
+ carrier_name: "silverstar"
+ carrier_attribute {
+ mccmnc_tuple: "310960"
+ spn: "silverstar"
+ }
+}
+carrier_id {
+ canonical_id: 2324
+ carrier_name: "NNTC Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "310960"
+ spn: "nntcwire"
+ }
+}
+carrier_id {
+ canonical_id: 2325
+ carrier_name: "Clear Sky Wireless"
+ carrier_attribute {
+ mccmnc_tuple: "310820"
+ spn: "nepa"
+ }
+}
+carrier_id {
+ canonical_id: 2326
+ carrier_name: "EMnify"
+ carrier_attribute {
+ mccmnc_tuple: "53703"
+ mccmnc_tuple: "29505"
+ spn: "EMnify"
+ }
+}
+carrier_id {
+ canonical_id: 2327
+ carrier_name: "Telemach"
+ carrier_attribute {
+ mccmnc_tuple: "29370"
+ imsi_prefix_xpattern: "29370029"
+ }
+}
+carrier_id {
+ canonical_id: 2328
+ carrier_name: "Fonic Prepaid"
+ carrier_attribute {
+ mccmnc_tuple: "26207"
+ imsi_prefix_xpattern: "26207515"
+ }
+}
+carrier_id {
+ canonical_id: 2329
+ carrier_name: "Lidl Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "26207"
+ imsi_prefix_xpattern: "26207520"
+ }
+}
+carrier_id {
+ canonical_id: 2330
+ carrier_name: "Tchibo"
+ carrier_attribute {
+ mccmnc_tuple: "26207"
+ imsi_prefix_xpattern: "26207500"
+ }
+}
+carrier_id {
+ canonical_id: 2331
+ carrier_name: "Djuice"
+ carrier_attribute {
+ mccmnc_tuple: "25503"
+ spn: "djuice"
+ }
+}
+carrier_id {
+ canonical_id: 2332
+ carrier_name: "Send"
+ carrier_attribute {
+ mccmnc_tuple: "24801"
+ imsi_prefix_xpattern: "248010x2"
+ imsi_prefix_xpattern: "248010x3"
+ }
+}
+carrier_id {
+ canonical_id: 2333
+ carrier_name: "Ventelo"
+ carrier_attribute {
+ mccmnc_tuple: "24201"
+ imsi_prefix_xpattern: "24201700"
+ }
+}
+carrier_id {
+ canonical_id: 2334
+ carrier_name: "Chess"
+ carrier_attribute {
+ mccmnc_tuple: "24202"
+ imsi_prefix_xpattern: "2420256"
+ }
+}
+carrier_id {
+ canonical_id: 2335
+ carrier_name: "Virgin"
+ carrier_attribute {
+ mccmnc_tuple: "65507"
+ imsi_prefix_xpattern: "6550710"
+ }
+}
+carrier_id {
+ canonical_id: 2336
+ carrier_name: "TrueMove H"
+ carrier_attribute {
+ mccmnc_tuple: "52000"
+ gid1: "01"
+ }
+}
+carrier_id {
+ canonical_id: 2337
+ carrier_name: "Movil exito"
+ carrier_attribute {
+ mccmnc_tuple: "732103"
+ mccmnc_tuple: "732111"
+ spn: "movil exito"
+ }
+}
+carrier_id {
+ canonical_id: 2338
+ carrier_name: "UNE"
+ carrier_attribute {
+ mccmnc_tuple: "732103"
+ mccmnc_tuple: "732111"
+ spn: "UNE"
+ }
+}
+carrier_id {
+ canonical_id: 2339
+ carrier_name: "Virgin Mobile"
+ carrier_attribute {
+ mccmnc_tuple: "732123"
+ spn: "Virgin Mobile"
+ }
+}
+version: 5
diff --git a/res/values-as/config.xml b/res/values-as/config.xml
deleted file mode 100644
index 99877a6..0000000
--- a/res/values-as/config.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="persist_apns_for_plmn">
- <item msgid="6413072509259000954">"20404"</item>
- <item msgid="5639159280778239123">"310004"</item>
- <item msgid="3860605521380788028">"310120"</item>
- <item msgid="537693705785480198">"311480"</item>
- </string-array>
-</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
deleted file mode 100644
index 5a39f18..0000000
--- a/res/values-as/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2008 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" product="tablet" msgid="9194799012395299737">"ম\'বাইল নেটৱৰ্ক কনফিগাৰেশ্বন"</string>
- <string name="app_label" product="default" msgid="8338087656149558019">"ফ\'ন আৰু বাৰ্তাৰ সঞ্চয়াগাৰ"</string>
-</resources>
diff --git a/res/values-or/config.xml b/res/values-or/config.xml
deleted file mode 100644
index 99877a6..0000000
--- a/res/values-or/config.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="persist_apns_for_plmn">
- <item msgid="6413072509259000954">"20404"</item>
- <item msgid="5639159280778239123">"310004"</item>
- <item msgid="3860605521380788028">"310120"</item>
- <item msgid="537693705785480198">"311480"</item>
- </string-array>
-</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
deleted file mode 100644
index b004c4f..0000000
--- a/res/values-or/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2008 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" product="tablet" msgid="9194799012395299737">"ମୋବାଇଲ୍ ନେଟ୍ୱର୍କ କନଫିଗରେଶନ୍"</string>
- <string name="app_label" product="default" msgid="8338087656149558019">"ଫୋନ୍ ଓ ମେସେଜିଙ୍ଗ ଷ୍ଟୋରେଜ୍"</string>
-</resources>
diff --git a/src/com/android/providers/telephony/CarrierIdProvider.java b/src/com/android/providers/telephony/CarrierIdProvider.java
index 1c2e5e5..7f2de12 100644
--- a/src/com/android/providers/telephony/CarrierIdProvider.java
+++ b/src/com/android/providers/telephony/CarrierIdProvider.java
@@ -25,6 +25,7 @@
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.MatrixCursor;
+import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
@@ -74,7 +75,7 @@
private static final String TAG = CarrierIdProvider.class.getSimpleName();
private static final String DATABASE_NAME = "carrierIdentification.db";
- private static final int DATABASE_VERSION = 3;
+ private static final int DATABASE_VERSION = 5;
private static final String ASSETS_PB_FILE = "carrier_list.pb";
private static final String VERSION_KEY = "version";
@@ -119,10 +120,15 @@
* index 7: {@link CarrierId.All#ICCID_PREFIX}
*/
private static final int ICCID_PREFIX_INDEX = 7;
+
+ /**
+ * index 8: {@link CarrierId.All#PRIVILEGE_ACCESS_RULE}
+ */
+ private static final int PRIVILEGE_ACCESS_RULE = 8;
/**
* ending index of carrier attribute list.
*/
- private static final int CARRIER_ATTR_END_IDX = ICCID_PREFIX_INDEX;
+ private static final int CARRIER_ATTR_END_IDX = PRIVILEGE_ACCESS_RULE;
/**
* The authority string for the CarrierIdProvider
*/
@@ -139,15 +145,18 @@
CarrierId.All.IMSI_PREFIX_XPATTERN,
CarrierId.All.SPN,
CarrierId.All.APN,
- CarrierId.All.ICCID_PREFIX));
+ CarrierId.All.ICCID_PREFIX,
+ CarrierId.All.PRIVILEGE_ACCESS_RULE,
+ CarrierId.PARENT_CARRIER_ID));
private CarrierIdDatabaseHelper mDbHelper;
/**
* Stores carrier id information for the current active subscriptions.
- * Key is the active subId and entryValue is a pair of carrier id(int) and Carrier Name(String).
+ * Key is the active subId and entryValue is carrier id(int), mno carrier id (int) and
+ * carrier name(String).
*/
- private final Map<Integer, Pair<Integer, String>> mCurrentSubscriptionMap =
+ private final Map<Integer, ContentValues> mCurrentSubscriptionMap =
new ConcurrentHashMap<>();
@VisibleForTesting
@@ -162,8 +171,10 @@
+ CarrierId.All.SPN + " TEXT,"
+ CarrierId.All.APN + " TEXT,"
+ CarrierId.All.ICCID_PREFIX + " TEXT,"
+ + CarrierId.All.PRIVILEGE_ACCESS_RULE + " TEXT,"
+ CarrierId.CARRIER_NAME + " TEXT,"
+ CarrierId.CARRIER_ID + " INTEGER DEFAULT -1,"
+ + CarrierId.PARENT_CARRIER_ID + " INTEGER DEFAULT -1,"
+ "UNIQUE (" + TextUtils.join(", ", CARRIERS_ID_UNIQUE_FIELDS) + "));";
}
@@ -317,6 +328,7 @@
*/
public CarrierIdDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ setWriteAheadLoggingEnabled(false);
}
@Override
@@ -341,6 +353,9 @@
if (oldVersion < DATABASE_VERSION) {
dropCarrierTable(db);
createCarrierTable(db);
+ // force rewrite carrier id db
+ setAppliedVersion(0);
+ updateDatabaseFromPb(db);
}
}
}
@@ -403,7 +418,9 @@
private void convertCarrierAttrToContentValues(ContentValues cv, List<ContentValues> cvs,
CarrierIdProto.CarrierAttribute attr, int index) {
if (index > CARRIER_ATTR_END_IDX) {
- cvs.add(new ContentValues(cv));
+ ContentValues carrier = new ContentValues(cv);
+ if (!cvs.contains(carrier))
+ cvs.add(carrier);
return;
}
boolean found = false;
@@ -426,7 +443,7 @@
break;
case GID1_INDEX:
for (String str : attr.gid1) {
- cv.put(CarrierId.All.GID1, str);
+ cv.put(CarrierId.All.GID1, str.toLowerCase());
convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
cv.remove(CarrierId.All.GID1);
found = true;
@@ -434,7 +451,7 @@
break;
case GID2_INDEX:
for (String str : attr.gid2) {
- cv.put(CarrierId.All.GID2, str);
+ cv.put(CarrierId.All.GID2, str.toLowerCase());
convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
cv.remove(CarrierId.All.GID2);
found = true;
@@ -450,7 +467,7 @@
break;
case SPN_INDEX:
for (String str : attr.spn) {
- cv.put(CarrierId.All.SPN, str);
+ cv.put(CarrierId.All.SPN, str.toLowerCase());
convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
cv.remove(CarrierId.All.SPN);
found = true;
@@ -472,6 +489,14 @@
found = true;
}
break;
+ case PRIVILEGE_ACCESS_RULE:
+ for (String str : attr.privilegeAccessRule) {
+ cv.put(CarrierId.All.PRIVILEGE_ACCESS_RULE, str);
+ convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
+ cv.remove(CarrierId.All.PRIVILEGE_ACCESS_RULE);
+ found = true;
+ }
+ break;
default:
Log.e(TAG, "unsupported index: " + index);
break;
@@ -584,9 +609,7 @@
}
return count;
} else {
- mCurrentSubscriptionMap.put(subId,
- new Pair(cv.getAsInteger(CarrierId.CARRIER_ID),
- cv.getAsString(CarrierId.CARRIER_NAME)));
+ mCurrentSubscriptionMap.put(subId, new ContentValues(cv));
getContext().getContentResolver().notifyChange(CarrierId.CONTENT_URI, null);
return 1;
}
@@ -618,9 +641,11 @@
for (int i = 0; i < c.getColumnCount(); i++) {
final String columnName = c.getColumnName(i);
if (CarrierId.CARRIER_ID.equals(columnName)) {
- row.add(mCurrentSubscriptionMap.get(subId).first);
+ row.add(mCurrentSubscriptionMap.get(subId).get(CarrierId.CARRIER_ID));
} else if (CarrierId.CARRIER_NAME.equals(columnName)) {
- row.add(mCurrentSubscriptionMap.get(subId).second);
+ row.add(mCurrentSubscriptionMap.get(subId).get(CarrierId.CARRIER_NAME));
+ } else if (CarrierId.MNO_CARRIER_ID.equals(columnName)) {
+ row.add(mCurrentSubscriptionMap.get(subId).get(CarrierId.MNO_CARRIER_ID));
} else {
throw new IllegalArgumentException("Invalid column " + projectionIn[i]);
}
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index f4ae9cc..f7a446b 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -23,6 +23,8 @@
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
+import android.database.DatabaseErrorHandler;
+import android.database.DefaultDatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
@@ -239,6 +241,7 @@
private static MmsSmsDatabaseHelper sDeInstance = null;
private static MmsSmsDatabaseHelper sCeInstance = null;
+ private static MmsSmsDatabaseErrorHandler sDbErrorHandler = null;
private static final String[] BIND_ARGS_NONE = new String[0];
@@ -258,8 +261,36 @@
// cache for INITIAL_CREATE_DONE shared pref so access to it can be avoided when possible
private static AtomicBoolean sInitialCreateDone = new AtomicBoolean(false);
- private MmsSmsDatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ // TODO(sahinc): Turn this to true once the schema finalizes, so that people can update their
+ // messaging databases. NOTE: move the switch/case update to the latest version of the database
+ // before turning this flag to true.
+ private static final boolean IS_RCS_TABLE_SCHEMA_CODE_COMPLETE = false;
+
+ /**
+ * The primary purpose of this DatabaseErrorHandler is to broadcast an intent on corruption and
+ * print a Slog.wtf so database corruption can be caught earlier.
+ */
+ private static class MmsSmsDatabaseErrorHandler implements DatabaseErrorHandler {
+ private DefaultDatabaseErrorHandler mDefaultDatabaseErrorHandler
+ = new DefaultDatabaseErrorHandler();
+ private Context mContext;
+
+ MmsSmsDatabaseErrorHandler(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onCorruption(SQLiteDatabase dbObj) {
+ String logMsg = "Corruption reported by sqlite on database: " + dbObj.getPath();
+ localLogWtf(logMsg);
+ sendDbLostIntent(mContext, true);
+ // Let the default error handler take other actions
+ mDefaultDatabaseErrorHandler.onCorruption(dbObj);
+ }
+ }
+
+ private MmsSmsDatabaseHelper(Context context, MmsSmsDatabaseErrorHandler dbErrorHandler) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION, dbErrorHandler);
mContext = context;
// Memory optimization - close idle connections after 30s of inactivity
setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
@@ -270,12 +301,27 @@
}
}
+ private static synchronized MmsSmsDatabaseErrorHandler getDbErrorHandler(Context context) {
+ if (sDbErrorHandler == null) {
+ sDbErrorHandler = new MmsSmsDatabaseErrorHandler(context);
+ }
+ return sDbErrorHandler;
+ }
+
+ private static void sendDbLostIntent(Context context, boolean isCorrupted) {
+ // Broadcast ACTION_SMS_MMS_DB_LOST
+ Intent intent = new Intent(Sms.Intents.ACTION_SMS_MMS_DB_LOST);
+ intent.putExtra(Sms.Intents.EXTRA_IS_CORRUPTED, isCorrupted);
+ intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ context.sendBroadcast(intent, android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+ }
/**
* Returns a singleton helper for the combined MMS and SMS database in device encrypted storage.
*/
/* package */ static synchronized MmsSmsDatabaseHelper getInstanceForDe(Context context) {
if (sDeInstance == null) {
- sDeInstance = new MmsSmsDatabaseHelper(ProviderUtil.getDeviceEncryptedContext(context));
+ Context deContext = ProviderUtil.getDeviceEncryptedContext(context);
+ sDeInstance = new MmsSmsDatabaseHelper(deContext, getDbErrorHandler(deContext));
}
return sDeInstance;
}
@@ -287,8 +333,8 @@
/* package */ static synchronized MmsSmsDatabaseHelper getInstanceForCe(Context context) {
if (sCeInstance == null) {
if (StorageManager.isFileEncryptedNativeOrEmulated()) {
- sCeInstance = new MmsSmsDatabaseHelper(
- ProviderUtil.getCredentialEncryptedContext(context));
+ Context ceContext = ProviderUtil.getCredentialEncryptedContext(context);
+ sCeInstance = new MmsSmsDatabaseHelper(ceContext, getDbErrorHandler(ceContext));
} else {
sCeInstance = getInstanceForDe(context);
}
@@ -493,6 +539,7 @@
// disappeared mysteriously?
localLogWtf("onCreate: was already called once earlier");
intent.putExtra(Intents.EXTRA_IS_INITIAL_CREATE, false);
+ sendDbLostIntent(mContext, false);
} else {
setInitialCreateDone();
intent.putExtra(Intents.EXTRA_IS_INITIAL_CREATE, true);
@@ -503,18 +550,23 @@
createMmsTables(db);
createSmsTables(db);
createCommonTables(db);
+
+ if (IS_RCS_TABLE_SCHEMA_CODE_COMPLETE) {
+ RcsProviderHelper.createRcsTables(db);
+ }
+
createCommonTriggers(db);
createMmsTriggers(db);
createWordsTables(db);
createIndices(db);
}
- private void localLog(String logMsg) {
+ private static void localLog(String logMsg) {
Log.d(TAG, logMsg);
PhoneFactory.localLog(TAG, logMsg);
}
- private void localLogWtf(String logMsg) {
+ private static void localLogWtf(String logMsg) {
Slog.wtf(TAG, logMsg);
PhoneFactory.localLog(TAG, logMsg);
}
@@ -1583,6 +1635,12 @@
} finally {
db.endTransaction();
}
+ // fall through
+ case 67:
+ if (currentVersion <= 67 || !IS_RCS_TABLE_SCHEMA_CODE_COMPLETE) {
+ return;
+ }
+ RcsProviderHelper.createRcsTables(db);
return;
}
diff --git a/src/com/android/providers/telephony/RcsProvider.java b/src/com/android/providers/telephony/RcsProvider.java
new file mode 100644
index 0000000..83ff130
--- /dev/null
+++ b/src/com/android/providers/telephony/RcsProvider.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2018 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.providers.telephony;
+
+import static com.android.providers.telephony.RcsProviderHelper.ID;
+import static com.android.providers.telephony.RcsProviderHelper.THREAD_TABLE;
+
+import android.app.AppOpsManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.util.Log;
+
+/**
+ * Content provider to handle RCS messages. The functionality here is similar to SmsProvider,
+ * MmsProvider etc. This is not meant to be public.
+ * @hide
+ */
+public class RcsProvider extends ContentProvider {
+ private final static String TAG = "RcsProvider";
+ static final String AUTHORITY = "rcs";
+ private static final UriMatcher URL_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+
+ private static final int THREAD = 1;
+
+ SQLiteOpenHelper mDbOpenHelper;
+
+ static {
+ URL_MATCHER.addURI(AUTHORITY, "thread", THREAD);
+ }
+
+ @Override
+ public boolean onCreate() {
+ setAppOps(AppOpsManager.OP_READ_SMS, AppOpsManager.OP_WRITE_SMS);
+ // Use the credential encrypted mmssms.db for RCS messages.
+ mDbOpenHelper = MmsSmsDatabaseHelper.getInstanceForCe(getContext());
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ int match = URL_MATCHER.match(uri);
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ SQLiteDatabase readableDatabase = mDbOpenHelper.getReadableDatabase();
+
+ switch (match) {
+ case THREAD:
+ RcsProviderHelper.buildThreadQuery(qb);
+ break;
+ default:
+ Log.e(TAG, "Invalid query: " + uri);
+ }
+
+ return qb.query(
+ readableDatabase, projection, selection, selectionArgs, null, null, sortOrder);
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ int match = URL_MATCHER.match(uri);
+ SQLiteDatabase writableDatabase = mDbOpenHelper.getWritableDatabase();
+
+ switch (match) {
+ case THREAD:
+ writableDatabase.insert(THREAD_TABLE, ID, values);
+ break;
+ default:
+ Log.e(TAG, "Invalid insert: " + uri);
+ }
+
+ return null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ int match = URL_MATCHER.match(uri);
+ int deletedCount = 0;
+ SQLiteDatabase writableDatabase = mDbOpenHelper.getWritableDatabase();
+
+ switch (match) {
+ case THREAD:
+ deletedCount = writableDatabase.delete(THREAD_TABLE, selection, selectionArgs);
+ break;
+ default:
+ Log.e(TAG, "Invalid delete: " + uri);
+ }
+
+ return deletedCount;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ int match = URL_MATCHER.match(uri);
+ int updatedCount = 0;
+ SQLiteDatabase writableDatabase = mDbOpenHelper.getWritableDatabase();
+
+ switch (match) {
+ case THREAD:
+ updatedCount = writableDatabase.update(
+ THREAD_TABLE, values, selection, selectionArgs);
+ break;
+ default:
+ Log.e(TAG, "Invalid update: " + uri);
+ }
+
+ return updatedCount;
+ }
+}
diff --git a/src/com/android/providers/telephony/RcsProviderHelper.java b/src/com/android/providers/telephony/RcsProviderHelper.java
new file mode 100644
index 0000000..3966f53
--- /dev/null
+++ b/src/com/android/providers/telephony/RcsProviderHelper.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.providers.telephony;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Constants and helpers for RcsProvider to keep the code clean.
+ * @hide
+ */
+class RcsProviderHelper {
+ static final String ID = "_id";
+ static final String THREAD_TABLE = "rcs_thread";
+ static final String OWNER_PARTICIPANT = "owner_participant";
+
+ @VisibleForTesting
+ public static void createRcsTables(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + THREAD_TABLE + " (" +
+ ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ OWNER_PARTICIPANT + " INTEGER " +
+ ");");
+ }
+
+ static void buildThreadQuery(SQLiteQueryBuilder qb) {
+ qb.setTables(THREAD_TABLE);
+ }
+}
diff --git a/src/com/android/providers/telephony/ServiceStateProvider.java b/src/com/android/providers/telephony/ServiceStateProvider.java
index e589171..7f870b0 100644
--- a/src/com/android/providers/telephony/ServiceStateProvider.java
+++ b/src/com/android/providers/telephony/ServiceStateProvider.java
@@ -61,7 +61,6 @@
import static android.provider.Telephony.ServiceStateTable.CDMA_ERI_ICON_INDEX;
import static android.provider.Telephony.ServiceStateTable.CDMA_ERI_ICON_MODE;
import static android.provider.Telephony.ServiceStateTable.IS_EMERGENCY_ONLY;
-import static android.provider.Telephony.ServiceStateTable.IS_DATA_ROAMING_FROM_REGISTRATION;
import static android.provider.Telephony.ServiceStateTable.IS_USING_CARRIER_AGGREGATION;
@@ -94,7 +93,6 @@
CDMA_ERI_ICON_INDEX,
CDMA_ERI_ICON_MODE,
IS_EMERGENCY_ONLY,
- IS_DATA_ROAMING_FROM_REGISTRATION,
IS_USING_CARRIER_AGGREGATION,
};
@@ -153,8 +151,6 @@
newSS.setCdmaEriIconIndex(values.getAsInteger(CDMA_ERI_ICON_INDEX));
newSS.setCdmaEriIconMode(values.getAsInteger(CDMA_ERI_ICON_MODE));
newSS.setEmergencyOnly(values.getAsBoolean(IS_EMERGENCY_ONLY));
- newSS.setDataRoamingFromRegistration(
- values.getAsBoolean(IS_DATA_ROAMING_FROM_REGISTRATION));
newSS.setIsUsingCarrierAggregation(values.getAsBoolean(IS_USING_CARRIER_AGGREGATION));
// notify listeners
@@ -235,8 +231,6 @@
final int cdma_eri_icon_index = ss.getCdmaEriIconIndex();
final int cdma_eri_icon_mode = ss.getCdmaEriIconMode();
final int is_emergency_only = (ss.isEmergencyOnly()) ? 1 : 0;
- final int is_data_roaming_from_registration =
- (ss.getDataRoamingFromRegistration()) ? 1 : 0;
final int is_using_carrier_aggregation = (ss.isUsingCarrierAggregation()) ? 1 : 0;
return buildSingleRowResult(projection, sColumns, new Object[] {
@@ -261,7 +255,6 @@
cdma_eri_icon_index,
cdma_eri_icon_mode,
is_emergency_only,
- is_data_roaming_from_registration,
is_using_carrier_aggregation,
});
}
diff --git a/src/com/android/providers/telephony/SmsProvider.java b/src/com/android/providers/telephony/SmsProvider.java
index 2b40d7e..95db869 100644
--- a/src/com/android/providers/telephony/SmsProvider.java
+++ b/src/com/android/providers/telephony/SmsProvider.java
@@ -464,7 +464,6 @@
int match = sURLMatcher.match(url);
String table = TABLE_SMS;
- boolean notifyIfNotDefault = true;
switch (match) {
case SMS_ALL:
@@ -503,10 +502,6 @@
case SMS_RAW_MESSAGE:
table = "raw";
- // The raw table is used by the telephony layer for storing an sms before
- // sending out a notification that an sms has arrived. We don't want to notify
- // the default sms app of changes to this table.
- notifyIfNotDefault = false;
break;
case SMS_STATUS_PENDING:
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index df1e58c..b83dc05 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -26,28 +26,29 @@
import static android.provider.Telephony.Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML;
import static android.provider.Telephony.Carriers.CARRIER_EDITED;
import static android.provider.Telephony.Carriers.CARRIER_ENABLED;
+import static android.provider.Telephony.Carriers.CARRIER_ID;
import static android.provider.Telephony.Carriers.CONTENT_URI;
import static android.provider.Telephony.Carriers.CURRENT;
import static android.provider.Telephony.Carriers.DEFAULT_SORT_ORDER;
-import static android.provider.Telephony.Carriers.EDITED;
-import static android.provider.Telephony.Carriers.MAX_CONNS;
-import static android.provider.Telephony.Carriers.MAX_CONNS_TIME;
+import static android.provider.Telephony.Carriers.EDITED_STATUS;
+import static android.provider.Telephony.Carriers.MAX_CONNECTIONS;
+import static android.provider.Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS;
import static android.provider.Telephony.Carriers.MCC;
import static android.provider.Telephony.Carriers.MMSC;
import static android.provider.Telephony.Carriers.MMSPORT;
import static android.provider.Telephony.Carriers.MMSPROXY;
import static android.provider.Telephony.Carriers.MNC;
-import static android.provider.Telephony.Carriers.MODEM_COGNITIVE;
+import static android.provider.Telephony.Carriers.MODEM_PERSIST;
import static android.provider.Telephony.Carriers.MTU;
import static android.provider.Telephony.Carriers.MVNO_MATCH_DATA;
import static android.provider.Telephony.Carriers.MVNO_TYPE;
import static android.provider.Telephony.Carriers.NAME;
import static android.provider.Telephony.Carriers.NETWORK_TYPE_BITMASK;
-import static android.provider.Telephony.Carriers.NO_SET_SET;
+import static android.provider.Telephony.Carriers.NO_APN_SET_ID;
import static android.provider.Telephony.Carriers.NUMERIC;
import static android.provider.Telephony.Carriers.OWNED_BY;
-import static android.provider.Telephony.Carriers.OWNED_BY_OTHERS;
import static android.provider.Telephony.Carriers.OWNED_BY_DPC;
+import static android.provider.Telephony.Carriers.OWNED_BY_OTHERS;
import static android.provider.Telephony.Carriers.PASSWORD;
import static android.provider.Telephony.Carriers.PORT;
import static android.provider.Telephony.Carriers.PROFILE_ID;
@@ -64,11 +65,12 @@
import static android.provider.Telephony.Carriers.USER_EDITABLE;
import static android.provider.Telephony.Carriers.USER_EDITED;
import static android.provider.Telephony.Carriers.USER_VISIBLE;
-import static android.provider.Telephony.Carriers.WAIT_TIME;
+import static android.provider.Telephony.Carriers.WAIT_TIME_RETRY;
import static android.provider.Telephony.Carriers._ID;
import android.content.ComponentName;
import android.content.ContentProvider;
+import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
@@ -95,10 +97,12 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.provider.Telephony;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -108,7 +112,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IApnSourceService;
import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.dataconnection.ApnSetting;
+import com.android.internal.telephony.dataconnection.ApnSettingUtils;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.util.XmlUtils;
@@ -116,15 +120,21 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
+import java.util.Set;
+import java.util.zip.CRC32;
public class TelephonyProvider extends ContentProvider
{
@@ -133,7 +143,7 @@
private static final boolean DBG = true;
private static final boolean VDBG = false; // STOPSHIP if true
- private static final int DATABASE_VERSION = 26 << 16;
+ private static final int DATABASE_VERSION = 32 << 16;
private static final int URL_UNKNOWN = 0;
private static final int URL_TELEPHONY = 1;
private static final int URL_CURRENT = 2;
@@ -157,7 +167,9 @@
private static final int URL_ENFORCE_MANAGED = 20;
private static final int URL_PREFERAPNSET = 21;
private static final int URL_PREFERAPNSET_USING_SUBID = 22;
-
+ private static final int URL_SIM_APN_LIST = 23;
+ private static final int URL_SIM_APN_LIST_ID = 24;
+ private static final int URL_FILTERED_USING_SUBID = 25;
private static final String TAG = "TelephonyProvider";
private static final String CARRIERS_TABLE = "carriers";
@@ -194,24 +206,24 @@
private static final ContentValues s_currentNullMap;
private static final ContentValues s_currentSetMap;
- private static final String IS_UNEDITED = EDITED + "=" + UNEDITED;
- private static final String IS_EDITED = EDITED + "!=" + UNEDITED;
- private static final String IS_USER_EDITED = EDITED + "=" + USER_EDITED;
- private static final String IS_NOT_USER_EDITED = EDITED + "!=" + USER_EDITED;
- private static final String IS_USER_DELETED = EDITED + "=" + USER_DELETED;
- private static final String IS_NOT_USER_DELETED = EDITED + "!=" + USER_DELETED;
+ private static final String IS_UNEDITED = EDITED_STATUS + "=" + UNEDITED;
+ private static final String IS_EDITED = EDITED_STATUS + "!=" + UNEDITED;
+ private static final String IS_USER_EDITED = EDITED_STATUS + "=" + USER_EDITED;
+ private static final String IS_NOT_USER_EDITED = EDITED_STATUS + "!=" + USER_EDITED;
+ private static final String IS_USER_DELETED = EDITED_STATUS + "=" + USER_DELETED;
+ private static final String IS_NOT_USER_DELETED = EDITED_STATUS + "!=" + USER_DELETED;
private static final String IS_USER_DELETED_BUT_PRESENT_IN_XML =
- EDITED + "=" + USER_DELETED_BUT_PRESENT_IN_XML;
+ EDITED_STATUS + "=" + USER_DELETED_BUT_PRESENT_IN_XML;
private static final String IS_NOT_USER_DELETED_BUT_PRESENT_IN_XML =
- EDITED + "!=" + USER_DELETED_BUT_PRESENT_IN_XML;
- private static final String IS_CARRIER_EDITED = EDITED + "=" + CARRIER_EDITED;
- private static final String IS_NOT_CARRIER_EDITED = EDITED + "!=" + CARRIER_EDITED;
- private static final String IS_CARRIER_DELETED = EDITED + "=" + CARRIER_DELETED;
- private static final String IS_NOT_CARRIER_DELETED = EDITED + "!=" + CARRIER_DELETED;
+ EDITED_STATUS + "!=" + USER_DELETED_BUT_PRESENT_IN_XML;
+ private static final String IS_CARRIER_EDITED = EDITED_STATUS + "=" + CARRIER_EDITED;
+ private static final String IS_NOT_CARRIER_EDITED = EDITED_STATUS + "!=" + CARRIER_EDITED;
+ private static final String IS_CARRIER_DELETED = EDITED_STATUS + "=" + CARRIER_DELETED;
+ private static final String IS_NOT_CARRIER_DELETED = EDITED_STATUS + "!=" + CARRIER_DELETED;
private static final String IS_CARRIER_DELETED_BUT_PRESENT_IN_XML =
- EDITED + "=" + CARRIER_DELETED_BUT_PRESENT_IN_XML;
+ EDITED_STATUS + "=" + CARRIER_DELETED_BUT_PRESENT_IN_XML;
private static final String IS_NOT_CARRIER_DELETED_BUT_PRESENT_IN_XML =
- EDITED + "!=" + CARRIER_DELETED_BUT_PRESENT_IN_XML;
+ EDITED_STATUS + "!=" + CARRIER_DELETED_BUT_PRESENT_IN_XML;
private static final String IS_OWNED_BY_DPC = OWNED_BY + "=" + OWNED_BY_DPC;
private static final String IS_NOT_OWNED_BY_DPC = OWNED_BY + "!=" + OWNED_BY_DPC;
@@ -220,6 +232,7 @@
private static final int INVALID_APN_ID = -1;
private static final List<String> CARRIERS_UNIQUE_FIELDS = new ArrayList<String>();
+ private static final Set<String> CARRIERS_BOOLEAN_FIELDS = new HashSet<String>();
private static final Map<String, String> CARRIERS_UNIQUE_FIELDS_DEFAULTS = new HashMap();
@VisibleForTesting
@@ -254,9 +267,19 @@
CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(ROAMING_PROTOCOL, "IP");
CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(USER_EDITABLE, "1");
CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(OWNED_BY, String.valueOf(OWNED_BY_OTHERS));
- CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(APN_SET_ID, String.valueOf(NO_SET_SET));
+ CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(APN_SET_ID, String.valueOf(NO_APN_SET_ID));
+ CARRIERS_UNIQUE_FIELDS_DEFAULTS.put(CARRIER_ID,
+ String.valueOf(TelephonyManager.UNKNOWN_CARRIER_ID));
CARRIERS_UNIQUE_FIELDS.addAll(CARRIERS_UNIQUE_FIELDS_DEFAULTS.keySet());
+
+ // SQLite databases store bools as ints but the ContentValues objects passed in through
+ // queries use bools. As a result there is some special handling of boolean fields within
+ // the TelephonyProvider.
+ CARRIERS_BOOLEAN_FIELDS.add(CARRIER_ENABLED);
+ CARRIERS_BOOLEAN_FIELDS.add(MODEM_PERSIST);
+ CARRIERS_BOOLEAN_FIELDS.add(USER_VISIBLE);
+ CARRIERS_BOOLEAN_FIELDS.add(USER_EDITABLE);
}
@VisibleForTesting
@@ -267,6 +290,7 @@
NUMERIC + " TEXT DEFAULT ''," +
MCC + " TEXT DEFAULT ''," +
MNC + " TEXT DEFAULT ''," +
+ CARRIER_ID + " INTEGER DEFAULT " + TelephonyManager.UNKNOWN_CARRIER_ID + "," +
APN + " TEXT DEFAULT ''," +
USER + " TEXT DEFAULT ''," +
SERVER + " TEXT DEFAULT ''," +
@@ -281,25 +305,25 @@
CURRENT + " INTEGER," +
PROTOCOL + " TEXT DEFAULT " + DEFAULT_PROTOCOL + "," +
ROAMING_PROTOCOL + " TEXT DEFAULT " + DEFAULT_ROAMING_PROTOCOL + "," +
- CARRIER_ENABLED + " BOOLEAN DEFAULT 1," +
+ CARRIER_ENABLED + " BOOLEAN DEFAULT 1," + // SQLite databases store bools as ints
BEARER + " INTEGER DEFAULT 0," +
BEARER_BITMASK + " INTEGER DEFAULT 0," +
NETWORK_TYPE_BITMASK + " INTEGER DEFAULT 0," +
MVNO_TYPE + " TEXT DEFAULT ''," +
MVNO_MATCH_DATA + " TEXT DEFAULT ''," +
- SUBSCRIPTION_ID + " INTEGER DEFAULT "
- + SubscriptionManager.INVALID_SUBSCRIPTION_ID + "," +
+ SUBSCRIPTION_ID + " INTEGER DEFAULT " +
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID + "," +
PROFILE_ID + " INTEGER DEFAULT 0," +
- MODEM_COGNITIVE + " BOOLEAN DEFAULT 0," +
- MAX_CONNS + " INTEGER DEFAULT 0," +
- WAIT_TIME + " INTEGER DEFAULT 0," +
- MAX_CONNS_TIME + " INTEGER DEFAULT 0," +
+ MODEM_PERSIST + " BOOLEAN DEFAULT 0," +
+ MAX_CONNECTIONS + " INTEGER DEFAULT 0," +
+ WAIT_TIME_RETRY + " INTEGER DEFAULT 0," +
+ TIME_LIMIT_FOR_MAX_CONNECTIONS + " INTEGER DEFAULT 0," +
MTU + " INTEGER DEFAULT 0," +
- EDITED + " INTEGER DEFAULT " + UNEDITED + "," +
+ EDITED_STATUS + " INTEGER DEFAULT " + UNEDITED + "," +
USER_VISIBLE + " BOOLEAN DEFAULT 1," +
USER_EDITABLE + " BOOLEAN DEFAULT 1," +
OWNED_BY + " INTEGER DEFAULT " + OWNED_BY_OTHERS + "," +
- APN_SET_ID + " INTEGER DEFAULT " + NO_SET_SET + "," +
+ APN_SET_ID + " INTEGER DEFAULT " + NO_APN_SET_ID + "," +
// Uniqueness collisions are used to trigger merge code so if a field is listed
// here it means we will accept both (user edited + new apn_conf definition)
// Columns not included in UNIQUE constraint: name, current, edited,
@@ -330,6 +354,8 @@
+ " INTEGER DEFAULT " + SubscriptionManager.DATA_ROAMING_DEFAULT + ","
+ SubscriptionManager.MCC + " INTEGER DEFAULT 0,"
+ SubscriptionManager.MNC + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.MCC_STRING + " TEXT,"
+ + SubscriptionManager.MNC_STRING + " TEXT,"
+ SubscriptionManager.SIM_PROVISIONING_STATUS
+ " INTEGER DEFAULT " + SubscriptionManager.SIM_PROVISIONED + ","
+ SubscriptionManager.IS_EMBEDDED + " INTEGER DEFAULT 0,"
@@ -353,7 +379,11 @@
+ SubscriptionManager.WFC_IMS_ENABLED + " INTEGER DEFAULT -1,"
+ SubscriptionManager.WFC_IMS_MODE + " INTEGER DEFAULT -1,"
+ SubscriptionManager.WFC_IMS_ROAMING_MODE + " INTEGER DEFAULT -1,"
- + SubscriptionManager.WFC_IMS_ROAMING_ENABLED + " INTEGER DEFAULT -1"
+ + SubscriptionManager.WFC_IMS_ROAMING_ENABLED + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.IS_OPPORTUNISTIC + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.GROUP_UUID + " TEXT,"
+ + SubscriptionManager.IS_METERED + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.ISO_COUNTRY_CODE + " TEXT"
+ ");";
}
@@ -367,6 +397,7 @@
s_urlMatcher.addURI("telephony", "carriers/preferapnset", URL_PREFERAPNSET);
s_urlMatcher.addURI("telephony", "siminfo", URL_SIMINFO);
+ s_urlMatcher.addURI("telephony", "siminfo/#", URL_SIMINFO_USING_SUBID);
s_urlMatcher.addURI("telephony", "carriers/subId/*", URL_TELEPHONY_USING_SUBID);
s_urlMatcher.addURI("telephony", "carriers/current/subId/*", URL_CURRENT_USING_SUBID);
@@ -390,8 +421,13 @@
// Only called by Settings app, DcTracker and other telephony components to get a
// single APN according to whether DPC records are enforced.
s_urlMatcher.addURI("telephony", "carriers/filtered/#", URL_FILTERED_ID);
+ // Used by DcTracker to pass a subId.
+ s_urlMatcher.addURI("telephony", "carriers/filtered/subId/*", URL_FILTERED_USING_SUBID);
+
// Only Called by DevicePolicyManager to enforce DPC records.
s_urlMatcher.addURI("telephony", "carriers/enforce_managed", URL_ENFORCE_MANAGED);
+ s_urlMatcher.addURI("telephony", "carriers/sim_apn_list", URL_SIM_APN_LIST);
+ s_urlMatcher.addURI("telephony", "carriers/sim_apn_list/#", URL_SIM_APN_LIST_ID);
s_currentNullMap = new ContentValues(1);
s_currentNullMap.put(CURRENT, "0");
@@ -419,7 +455,8 @@
mInjector = injector;
}
- private static class DatabaseHelper extends SQLiteOpenHelper {
+ @VisibleForTesting
+ public static class DatabaseHelper extends SQLiteOpenHelper {
// Context to access resources with
private Context mContext;
@@ -435,10 +472,15 @@
setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
}
- private static int getVersion(Context context) {
+ @VisibleForTesting
+ public static int getVersion(Context context) {
if (VDBG) log("getVersion:+");
// Get the database version, combining a static schema version and the XML version
Resources r = context.getResources();
+ if (r == null) {
+ loge("resources=null, return version=" + Integer.toHexString(DATABASE_VERSION));
+ return DATABASE_VERSION;
+ }
XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
try {
XmlUtils.beginDocument(parser, "apns");
@@ -518,9 +560,32 @@
} catch (IOException e) {
loge("IOException for " + file.getAbsolutePath() + ":" + e);
}
+
+ // The RRO may have been updated in a firmware upgrade. Add checksum for the
+ // resources to the total checksum so that apns in an RRO update is not missed.
+ try (InputStream inputStream = mContext.getResources().
+ openRawResource(com.android.internal.R.xml.apns)) {
+ byte[] array = toByteArray(inputStream);
+ CRC32 c = new CRC32();
+ c.update(array);
+ checksum += c.getValue();
+ if (DBG) log("Checksum after adding resource is " + checksum);
+ } catch (IOException | Resources.NotFoundException e) {
+ loge("Exception when calculating checksum for internal apn resources: " + e);
+ }
return checksum;
}
+ private static byte[] toByteArray(InputStream input) throws IOException {
+ byte[] buffer = new byte[128];
+ int bytesRead;
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ while ((bytesRead = input.read(buffer)) != -1) {
+ output.write(buffer, 0, bytesRead);
+ }
+ return output.toByteArray();
+ }
+
private long getApnConfChecksum() {
SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
return sp.getLong(APN_CONF_CHECKSUM, -1);
@@ -538,8 +603,8 @@
File confFile = new File(Environment.getRootDirectory(), PARTNER_APNS_PATH);
File oemConfFile = new File(Environment.getOemDirectory(), OEM_APNS_PATH);
File updatedConfFile = new File(Environment.getDataDirectory(), OTA_UPDATED_APNS_PATH);
- confFile = getNewerFile(confFile, oemConfFile);
- confFile = getNewerFile(confFile, updatedConfFile);
+ confFile = pickSecondIfExists(confFile, oemConfFile);
+ confFile = pickSecondIfExists(confFile, updatedConfFile);
return confFile;
}
@@ -570,16 +635,20 @@
if (VDBG) log("dbh.initDatabase:+ db=" + db);
// Read internal APNS data
Resources r = mContext.getResources();
- XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
int publicversion = -1;
- try {
- XmlUtils.beginDocument(parser, "apns");
- publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
- loadApns(db, parser);
- } catch (Exception e) {
- loge("Got exception while loading APN database." + e);
- } finally {
- parser.close();
+ if (r != null) {
+ XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
+ try {
+ XmlUtils.beginDocument(parser, "apns");
+ publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
+ loadApns(db, parser);
+ } catch (Exception e) {
+ loge("Got exception while loading APN database." + e);
+ } finally {
+ parser.close();
+ }
+ } else {
+ loge("initDatabase: resources=null");
}
// Read external APNS data (partner-provided)
@@ -622,12 +691,12 @@
// Change USER_DELETED_BUT_PRESENT_IN_XML to USER_DELETED
ContentValues cv = new ContentValues();
- cv.put(EDITED, USER_DELETED);
+ cv.put(EDITED_STATUS, USER_DELETED);
db.update(CARRIERS_TABLE, cv, IS_USER_DELETED_BUT_PRESENT_IN_XML, null);
// Change CARRIER_DELETED_BUT_PRESENT_IN_XML to CARRIER_DELETED
cv = new ContentValues();
- cv.put(EDITED, CARRIER_DELETED);
+ cv.put(EDITED_STATUS, CARRIER_DELETED);
db.update(CARRIERS_TABLE, cv, IS_CARRIER_DELETED_BUT_PRESENT_IN_XML, null);
if (confreader != null) {
@@ -645,26 +714,16 @@
}
- private File getNewerFile(File sysApnFile, File altApnFile) {
+ private File pickSecondIfExists(File sysApnFile, File altApnFile) {
if (altApnFile.exists()) {
- // Alternate file exists. Use the newer one.
- long altFileTime = altApnFile.lastModified();
- long currFileTime = sysApnFile.lastModified();
- if (DBG) log("APNs Timestamp: altFileTime = " + altFileTime + " currFileTime = "
- + currFileTime);
-
- // To get the latest version from OEM or System image
- if (altFileTime > currFileTime) {
- if (DBG) log("APNs Timestamp: Alternate image " + altApnFile.getPath() +
- " is greater than System image");
- return altApnFile;
- }
+ if (DBG) log("Load APNs from " + altApnFile.getPath() +
+ " instead of " + sysApnFile.getPath());
+ return altApnFile;
} else {
- // No Apn in alternate image, so load it from system image.
- if (DBG) log("No APNs in OEM image = " + altApnFile.getPath() +
- " Load APNs from system image");
+ if (DBG) log("Load APNs from " + sysApnFile.getPath() +
+ " instead of " + altApnFile.getPath());
+ return sysApnFile;
}
- return sysApnFile;
}
@Override
@@ -984,7 +1043,7 @@
if (oldVersion < (24 << 16 | 6)) {
Cursor c = null;
String[] proj = {"_id"};
- recreateDB(c, db, proj, /* version */24);
+ recreateDB(db, proj, /* version */24);
if (VDBG) {
c = db.query(CARRIERS_TABLE, proj, null, null, null, null, null);
log("dbh.onUpgrade:- after upgrading total number of rows: " + c.getCount());
@@ -1024,7 +1083,7 @@
// Carriers.NO_SET_SET by default.
try {
db.execSQL("ALTER TABLE " + CARRIERS_TABLE + " ADD COLUMN " +
- APN_SET_ID + " INTEGER DEFAULT " + NO_SET_SET + ";");
+ APN_SET_ID + " INTEGER DEFAULT " + NO_APN_SET_ID + ";");
} catch (SQLiteException e) {
if (DBG) {
log("onUpgrade skipping " + CARRIERS_TABLE + " upgrade. " +
@@ -1033,9 +1092,110 @@
}
oldVersion = 26 << 16 | 6;
}
+
+ if (oldVersion < (27 << 16 | 6)) {
+ // Add the new MCC_STRING and MNC_STRING columns into the subscription table,
+ // and attempt to populate them.
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE +
+ " ADD COLUMN " + SubscriptionManager.MCC_STRING + " TEXT;");
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE +
+ " ADD COLUMN " + SubscriptionManager.MNC_STRING + " TEXT;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ " The table will get created in onOpen.");
+ }
+ }
+ // Migrate the old integer values over to strings
+ String[] proj = {SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID,
+ SubscriptionManager.MCC, SubscriptionManager.MNC};
+ try (Cursor c = db.query(SIMINFO_TABLE, proj, null, null, null, null, null)) {
+ while (c.moveToNext()) {
+ fillInMccMncStringAtCursor(mContext, db, c);
+ }
+ }
+ oldVersion = 27 << 16 | 6;
+ }
+
+ if (oldVersion < (28 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + SubscriptionManager.IS_OPPORTUNISTIC + " INTEGER DEFAULT 0;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 28 << 16 | 6;
+ }
+
+ if (oldVersion < (29 << 16 | 6)) {
+ try {
+ // Add a new column Telephony.CARRIER_ID into the database and add UNIQUE
+ // constraint into table. However, sqlite cannot add constraints to an existing
+ // table, so recreate the table.
+ String[] proj = {"_id"};
+ recreateDB(db, proj, /* version */29);
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + CARRIERS_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 29 << 16 | 6;
+ }
+
+ if (oldVersion < (30 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + SubscriptionManager.GROUP_UUID + " TEXT;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 30 << 16 | 6;
+ }
+
+ if (oldVersion < (31 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + SubscriptionManager.IS_METERED + " INTEGER DEFAULT 1;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 31 << 16 | 6;
+ }
+
+ if (oldVersion < (32 << 16 | 6)) {
+ try {
+ // Try to update the siminfo table. It might not be there.
+ db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+ + SubscriptionManager.ISO_COUNTRY_CODE + " TEXT;");
+ } catch (SQLiteException e) {
+ if (DBG) {
+ log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+ "The table will get created in onOpen.");
+ }
+ }
+ oldVersion = 32 << 16 | 6;
+ }
+
if (DBG) {
log("dbh.onUpgrade:- db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
}
+ // when adding fields to onUpgrade, also add a unit test to TelephonyDatabaseHelperTest
+ // and update the DATABASE_VERSION field and add a column in copyAllApnValues
}
private void recreateSimInfoDB(Cursor c, SQLiteDatabase db, String[] proj) {
@@ -1143,12 +1303,13 @@
}
}
- private void recreateDB(Cursor c, SQLiteDatabase db, String[] proj, int version) {
+ private void recreateDB(SQLiteDatabase db, String[] proj, int version) {
// Upgrade steps are:
// 1. Create a temp table- done in createCarriersTable()
// 2. copy over APNs from old table to new table - done in copyDataToTmpTable()
// 3. Drop the existing table.
// 4. Copy over the tmp table.
+ Cursor c;
if (VDBG) {
c = db.query(CARRIERS_TABLE, proj, null, null, null, null, null);
log("dbh.onUpgrade:- before upgrading total number of rows: " + c.getCount());
@@ -1166,7 +1327,7 @@
createCarriersTable(db, CARRIERS_TABLE_TMP);
- copyDataToTmpTable(db, c);
+ copyDataToTmpTable(db, c, version);
c.close();
db.execSQL("DROP TABLE IF EXISTS " + CARRIERS_TABLE);
@@ -1271,10 +1432,10 @@
queryValOrNull(MVNO_TYPE) +
queryValOrNull(MVNO_MATCH_DATA) +
queryValOrNull(PROFILE_ID) +
- queryVal2OrNull(MODEM_COGNITIVE) +
- queryValOrNull(MAX_CONNS) +
- queryValOrNull(WAIT_TIME) +
- queryValOrNull(MAX_CONNS_TIME) +
+ queryVal2OrNull(MODEM_PERSIST) +
+ queryValOrNull(MAX_CONNECTIONS) +
+ queryValOrNull(WAIT_TIME_RETRY) +
+ queryValOrNull(TIME_LIMIT_FOR_MAX_CONNECTIONS) +
queryValOrNull(MTU);
String[] whereArgs = new String[29];
int i = 0;
@@ -1309,15 +1470,13 @@
whereArgs[i++] = values.containsKey(ROAMING_PROTOCOL) ?
values.getAsString(ROAMING_PROTOCOL) : DEFAULT_ROAMING_PROTOCOL;
- if (values.containsKey(CARRIER_ENABLED) &&
- (values.getAsString(CARRIER_ENABLED).
- equalsIgnoreCase("false") ||
- values.getAsString(CARRIER_ENABLED).equals("0"))) {
- whereArgs[i++] = "false";
- whereArgs[i++] = "0";
+ if (values.containsKey(CARRIER_ENABLED)) {
+ whereArgs[i++] = convertStringToBoolString(values.getAsString(CARRIER_ENABLED));
+ whereArgs[i++] = convertStringToIntString(values.getAsString(CARRIER_ENABLED));
} else {
- whereArgs[i++] = "true";
- whereArgs[i++] = "1";
+ String defaultIntString = CARRIERS_UNIQUE_FIELDS_DEFAULTS.get(CARRIER_ENABLED);
+ whereArgs[i++] = convertStringToBoolString(defaultIntString);
+ whereArgs[i++] = defaultIntString;
}
whereArgs[i++] = values.containsKey(BEARER) ?
@@ -1329,10 +1488,10 @@
whereArgs[i++] = values.containsKey(PROFILE_ID) ?
values.getAsString(PROFILE_ID) : "0";
- if (values.containsKey(MODEM_COGNITIVE) &&
- (values.getAsString(MODEM_COGNITIVE).
+ if (values.containsKey(MODEM_PERSIST) &&
+ (values.getAsString(MODEM_PERSIST).
equalsIgnoreCase("true") ||
- values.getAsString(MODEM_COGNITIVE).equals("1"))) {
+ values.getAsString(MODEM_PERSIST).equals("1"))) {
whereArgs[i++] = "true";
whereArgs[i++] = "1";
} else {
@@ -1340,12 +1499,12 @@
whereArgs[i++] = "0";
}
- whereArgs[i++] = values.containsKey(MAX_CONNS) ?
- values.getAsString(MAX_CONNS) : "0";
- whereArgs[i++] = values.containsKey(WAIT_TIME) ?
- values.getAsString(WAIT_TIME) : "0";
- whereArgs[i++] = values.containsKey(MAX_CONNS_TIME) ?
- values.getAsString(MAX_CONNS_TIME) : "0";
+ whereArgs[i++] = values.containsKey(MAX_CONNECTIONS) ?
+ values.getAsString(MAX_CONNECTIONS) : "0";
+ whereArgs[i++] = values.containsKey(WAIT_TIME_RETRY) ?
+ values.getAsString(WAIT_TIME_RETRY) : "0";
+ whereArgs[i++] = values.containsKey(TIME_LIMIT_FOR_MAX_CONNECTIONS) ?
+ values.getAsString(TIME_LIMIT_FOR_MAX_CONNECTIONS) : "0";
whereArgs[i++] = values.containsKey(MTU) ?
values.getAsString(MTU) : "0";
@@ -1362,14 +1521,16 @@
db.delete(CARRIERS_TABLE, where, whereArgs);
}
- private void copyDataToTmpTable(SQLiteDatabase db, Cursor c) {
+ private void copyDataToTmpTable(SQLiteDatabase db, Cursor c, int version) {
// Move entries from CARRIERS_TABLE to CARRIERS_TABLE_TMP
if (c != null) {
while (c.moveToNext()) {
ContentValues cv = new ContentValues();
- copyApnValuesV17(cv, c);
- // Sync bearer bitmask and network type bitmask
- getNetworkTypeBitmaskFromCursor(cv, c);
+ copyAllApnValues(cv, c);
+ if (version == 24) {
+ // Sync bearer bitmask and network type bitmask
+ getNetworkTypeBitmaskFromCursor(cv, c);
+ }
try {
db.insertWithOnConflict(CARRIERS_TABLE_TMP, null, cv,
SQLiteDatabase.CONFLICT_ABORT);
@@ -1417,95 +1578,141 @@
getIntValueFromCursor(cv, c, BEARER);
getIntValueFromCursor(cv, c, SUBSCRIPTION_ID);
getIntValueFromCursor(cv, c, PROFILE_ID);
- getIntValueFromCursor(cv, c, MODEM_COGNITIVE);
- getIntValueFromCursor(cv, c, MAX_CONNS);
- getIntValueFromCursor(cv, c, WAIT_TIME);
- getIntValueFromCursor(cv, c, MAX_CONNS_TIME);
+ getIntValueFromCursor(cv, c, MODEM_PERSIST);
+ getIntValueFromCursor(cv, c, MAX_CONNECTIONS);
+ getIntValueFromCursor(cv, c, WAIT_TIME_RETRY);
+ getIntValueFromCursor(cv, c, TIME_LIMIT_FOR_MAX_CONNECTIONS);
getIntValueFromCursor(cv, c, MTU);
getIntValueFromCursor(cv, c, BEARER_BITMASK);
- getIntValueFromCursor(cv, c, EDITED);
+ getIntValueFromCursor(cv, c, EDITED_STATUS);
getIntValueFromCursor(cv, c, USER_VISIBLE);
}
+ private void copyAllApnValues(ContentValues cv, Cursor c) {
+ // String vals
+ getStringValueFromCursor(cv, c, NAME);
+ getStringValueFromCursor(cv, c, NUMERIC);
+ getStringValueFromCursor(cv, c, MCC);
+ getStringValueFromCursor(cv, c, MNC);
+ getStringValueFromCursor(cv, c, APN);
+ getStringValueFromCursor(cv, c, USER);
+ getStringValueFromCursor(cv, c, SERVER);
+ getStringValueFromCursor(cv, c, PASSWORD);
+ getStringValueFromCursor(cv, c, PROXY);
+ getStringValueFromCursor(cv, c, PORT);
+ getStringValueFromCursor(cv, c, MMSPROXY);
+ getStringValueFromCursor(cv, c, MMSPORT);
+ getStringValueFromCursor(cv, c, MMSC);
+ getStringValueFromCursor(cv, c, TYPE);
+ getStringValueFromCursor(cv, c, PROTOCOL);
+ getStringValueFromCursor(cv, c, ROAMING_PROTOCOL);
+ getStringValueFromCursor(cv, c, MVNO_TYPE);
+ getStringValueFromCursor(cv, c, MVNO_MATCH_DATA);
+
+ // bool/int vals
+ getIntValueFromCursor(cv, c, AUTH_TYPE);
+ getIntValueFromCursor(cv, c, CURRENT);
+ getIntValueFromCursor(cv, c, CARRIER_ENABLED);
+ getIntValueFromCursor(cv, c, BEARER);
+ getIntValueFromCursor(cv, c, SUBSCRIPTION_ID);
+ getIntValueFromCursor(cv, c, PROFILE_ID);
+ getIntValueFromCursor(cv, c, MODEM_PERSIST);
+ getIntValueFromCursor(cv, c, MAX_CONNECTIONS);
+ getIntValueFromCursor(cv, c, WAIT_TIME_RETRY);
+ getIntValueFromCursor(cv, c, TIME_LIMIT_FOR_MAX_CONNECTIONS);
+ getIntValueFromCursor(cv, c, MTU);
+ getIntValueFromCursor(cv, c, NETWORK_TYPE_BITMASK);
+ getIntValueFromCursor(cv, c, BEARER_BITMASK);
+ getIntValueFromCursor(cv, c, EDITED_STATUS);
+ getIntValueFromCursor(cv, c, USER_VISIBLE);
+ getIntValueFromCursor(cv, c, USER_EDITABLE);
+ getIntValueFromCursor(cv, c, OWNED_BY);
+ getIntValueFromCursor(cv, c, APN_SET_ID);
+ }
private void copyPreservedApnsToNewTable(SQLiteDatabase db, Cursor c) {
// Move entries from CARRIERS_TABLE to CARRIERS_TABLE_TMP
- if (c != null) {
- String[] persistApnsForPlmns = mContext.getResources().getStringArray(
- R.array.persist_apns_for_plmn);
- while (c.moveToNext()) {
- ContentValues cv = new ContentValues();
- String val;
- // Using V17 copy function for V15 upgrade. This should be fine since it handles
- // columns that may not exist properly (getStringValueFromCursor() and
- // getIntValueFromCursor() handle column index -1)
- copyApnValuesV17(cv, c);
- // Change bearer to a bitmask
- String bearerStr = c.getString(c.getColumnIndex(BEARER));
- if (!TextUtils.isEmpty(bearerStr)) {
- int bearer_bitmask = ServiceState.getBitmaskForTech(
- Integer.parseInt(bearerStr));
- cv.put(BEARER_BITMASK, bearer_bitmask);
+ if (c != null && mContext.getResources() != null) {
+ try {
+ String[] persistApnsForPlmns = mContext.getResources().getStringArray(
+ R.array.persist_apns_for_plmn);
+ while (c.moveToNext()) {
+ ContentValues cv = new ContentValues();
+ String val;
+ // Using V17 copy function for V15 upgrade. This should be fine since it handles
+ // columns that may not exist properly (getStringValueFromCursor() and
+ // getIntValueFromCursor() handle column index -1)
+ copyApnValuesV17(cv, c);
+ // Change bearer to a bitmask
+ String bearerStr = c.getString(c.getColumnIndex(BEARER));
+ if (!TextUtils.isEmpty(bearerStr)) {
+ int bearer_bitmask = ServiceState.getBitmaskForTech(
+ Integer.parseInt(bearerStr));
+ cv.put(BEARER_BITMASK, bearer_bitmask);
- int networkTypeBitmask = ServiceState.getBitmaskForTech(
- ServiceState.rilRadioTechnologyToNetworkType(
- Integer.parseInt(bearerStr)));
- cv.put(NETWORK_TYPE_BITMASK, networkTypeBitmask);
- }
-
- int userEditedColumnIdx = c.getColumnIndex("user_edited");
- if (userEditedColumnIdx != -1) {
- String user_edited = c.getString(userEditedColumnIdx);
- if (!TextUtils.isEmpty(user_edited)) {
- cv.put(EDITED, new Integer(user_edited));
+ int networkTypeBitmask = ServiceState.getBitmaskForTech(
+ ServiceState.rilRadioTechnologyToNetworkType(
+ Integer.parseInt(bearerStr)));
+ cv.put(NETWORK_TYPE_BITMASK, networkTypeBitmask);
}
- } else {
- cv.put(EDITED, CARRIER_EDITED);
- }
- // New EDITED column. Default value (UNEDITED) will
- // be used for all rows except for non-mvno entries for plmns indicated
- // by resource: those will be set to CARRIER_EDITED to preserve
- // their current values
- val = c.getString(c.getColumnIndex(NUMERIC));
- for (String s : persistApnsForPlmns) {
- if (!TextUtils.isEmpty(val) && val.equals(s) &&
- (!cv.containsKey(MVNO_TYPE) ||
- TextUtils.isEmpty(cv.getAsString(MVNO_TYPE)))) {
- if (userEditedColumnIdx == -1) {
- cv.put(EDITED, CARRIER_EDITED);
- } else { // if (oldVersion == 14) -- if db had user_edited column
- if (cv.getAsInteger(EDITED) == USER_EDITED) {
- cv.put(EDITED, CARRIER_EDITED);
- }
+ int userEditedColumnIdx = c.getColumnIndex("user_edited");
+ if (userEditedColumnIdx != -1) {
+ String user_edited = c.getString(userEditedColumnIdx);
+ if (!TextUtils.isEmpty(user_edited)) {
+ cv.put(EDITED_STATUS, new Integer(user_edited));
}
+ } else {
+ cv.put(EDITED_STATUS, CARRIER_EDITED);
+ }
- break;
+ // New EDITED column. Default value (UNEDITED) will
+ // be used for all rows except for non-mvno entries for plmns indicated
+ // by resource: those will be set to CARRIER_EDITED to preserve
+ // their current values
+ val = c.getString(c.getColumnIndex(NUMERIC));
+ for (String s : persistApnsForPlmns) {
+ if (!TextUtils.isEmpty(val) && val.equals(s) &&
+ (!cv.containsKey(MVNO_TYPE) ||
+ TextUtils.isEmpty(cv.getAsString(MVNO_TYPE)))) {
+ if (userEditedColumnIdx == -1) {
+ cv.put(EDITED_STATUS, CARRIER_EDITED);
+ } else { // if (oldVersion == 14) -- if db had user_edited column
+ if (cv.getAsInteger(EDITED_STATUS) == USER_EDITED) {
+ cv.put(EDITED_STATUS, CARRIER_EDITED);
+ }
+ }
+
+ break;
+ }
+ }
+
+ try {
+ db.insertWithOnConflict(CARRIERS_TABLE_TMP, null, cv,
+ SQLiteDatabase.CONFLICT_ABORT);
+ if (VDBG) {
+ log("dbh.copyPreservedApnsToNewTable: db.insert returned >= 0; " +
+ "insert successful for cv " + cv);
+ }
+ } catch (SQLException e) {
+ if (VDBG)
+ log("dbh.copyPreservedApnsToNewTable insertWithOnConflict exception " +
+ e + " for cv " + cv);
+ // Insertion failed which could be due to a conflict. Check if that is
+ // the case and merge the entries
+ Cursor oldRow = DatabaseHelper.selectConflictingRow(db,
+ CARRIERS_TABLE_TMP, cv);
+ if (oldRow != null) {
+ ContentValues mergedValues = new ContentValues();
+ mergeFieldsAndUpdateDb(db, CARRIERS_TABLE_TMP, oldRow, cv,
+ mergedValues, true, mContext);
+ oldRow.close();
+ }
}
}
-
- try {
- db.insertWithOnConflict(CARRIERS_TABLE_TMP, null, cv,
- SQLiteDatabase.CONFLICT_ABORT);
- if (VDBG) {
- log("dbh.copyPreservedApnsToNewTable: db.insert returned >= 0; " +
- "insert successful for cv " + cv);
- }
- } catch (SQLException e) {
- if (VDBG)
- log("dbh.copyPreservedApnsToNewTable insertWithOnConflict exception " +
- e + " for cv " + cv);
- // Insertion failed which could be due to a conflict. Check if that is
- // the case and merge the entries
- Cursor oldRow = DatabaseHelper.selectConflictingRow(db,
- CARRIERS_TABLE_TMP, cv);
- if (oldRow != null) {
- ContentValues mergedValues = new ContentValues();
- mergeFieldsAndUpdateDb(db, CARRIERS_TABLE_TMP, oldRow, cv,
- mergedValues, true, mContext);
- oldRow.close();
- }
- }
+ } catch (Resources.NotFoundException e) {
+ loge("array.persist_apns_for_plmn is not found");
+ return;
}
}
}
@@ -1621,15 +1828,15 @@
addIntAttribute(parser, "authtype", map, AUTH_TYPE);
addIntAttribute(parser, "bearer", map, BEARER);
addIntAttribute(parser, "profile_id", map, PROFILE_ID);
- addIntAttribute(parser, "max_conns", map, MAX_CONNS);
- addIntAttribute(parser, "wait_time", map, WAIT_TIME);
- addIntAttribute(parser, "max_conns_time", map, MAX_CONNS_TIME);
+ addIntAttribute(parser, "max_conns", map, MAX_CONNECTIONS);
+ addIntAttribute(parser, "wait_time", map, WAIT_TIME_RETRY);
+ addIntAttribute(parser, "max_conns_time", map, TIME_LIMIT_FOR_MAX_CONNECTIONS);
addIntAttribute(parser, "mtu", map, MTU);
addIntAttribute(parser, "apn_set_id", map, APN_SET_ID);
addBoolAttribute(parser, "carrier_enabled", map, CARRIER_ENABLED);
- addBoolAttribute(parser, "modem_cognitive", map, MODEM_COGNITIVE);
+ addBoolAttribute(parser, "modem_cognitive", map, MODEM_PERSIST);
addBoolAttribute(parser, "user_visible", map, USER_VISIBLE);
addBoolAttribute(parser, "user_editable", map, USER_EDITABLE);
@@ -1751,7 +1958,7 @@
if (oldRow != null) {
// Update the row
ContentValues mergedValues = new ContentValues();
- int edited = oldRow.getInt(oldRow.getColumnIndex(EDITED));
+ int edited = oldRow.getInt(oldRow.getColumnIndex(EDITED_STATUS));
int old_edited = edited;
if (edited != UNEDITED) {
if (edited == USER_DELETED) {
@@ -1763,7 +1970,7 @@
// by user but present in apn xml file.
edited = CARRIER_DELETED_BUT_PRESENT_IN_XML;
}
- mergedValues.put(EDITED, edited);
+ mergedValues.put(EDITED_STATUS, edited);
}
mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, row, mergedValues, false,
@@ -1860,16 +2067,16 @@
if (!onUpgrade) {
// Do not overwrite a carrier or user edit with EDITED=UNEDITED
- if (newRow.containsKey(EDITED)) {
- int oldEdited = oldRow.getInt(oldRow.getColumnIndex(EDITED));
- int newEdited = newRow.getAsInteger(EDITED);
+ if (newRow.containsKey(EDITED_STATUS)) {
+ int oldEdited = oldRow.getInt(oldRow.getColumnIndex(EDITED_STATUS));
+ int newEdited = newRow.getAsInteger(EDITED_STATUS);
if (newEdited == UNEDITED && (oldEdited == CARRIER_EDITED
|| oldEdited == CARRIER_DELETED
|| oldEdited == CARRIER_DELETED_BUT_PRESENT_IN_XML
|| oldEdited == USER_EDITED
|| oldEdited == USER_DELETED
|| oldEdited == USER_DELETED_BUT_PRESENT_IN_XML)) {
- newRow.remove(EDITED);
+ newRow.remove(EDITED_STATUS);
}
}
mergedValues.putAll(newRow);
@@ -1893,13 +2100,17 @@
boolean match = false;
// Check if APN falls under persist_apns_for_plmn
- String[] persistApnsForPlmns = context.getResources().getStringArray(
- R.array.persist_apns_for_plmn);
- for (String s : persistApnsForPlmns) {
- if (s.equalsIgnoreCase(newRow.getAsString(NUMERIC))) {
- match = true;
- break;
+ if (context.getResources() != null) {
+ String[] persistApnsForPlmns = context.getResources().getStringArray(
+ R.array.persist_apns_for_plmn);
+ for (String s : persistApnsForPlmns) {
+ if (s.equalsIgnoreCase(newRow.getAsString(NUMERIC))) {
+ match = true;
+ break;
+ }
}
+ } else {
+ loge("separateRowsNeeded: resources=null");
}
if (!match) return false;
@@ -1986,7 +2197,7 @@
String[] columns = { "_id",
TYPE,
- EDITED,
+ EDITED_STATUS,
BEARER_BITMASK,
NETWORK_TYPE_BITMASK,
PROFILE_ID };
@@ -1994,15 +2205,16 @@
int i = 0;
String[] selectionArgs = new String[CARRIERS_UNIQUE_FIELDS.size()];
for (String field : CARRIERS_UNIQUE_FIELDS) {
- if (CARRIER_ENABLED.equals(field)) {
- // for CARRIER_ENABLED we overwrite the value "false" with "0"
- selectionArgs[i++] = row.containsKey(CARRIER_ENABLED) &&
- (row.getAsString(CARRIER_ENABLED).equals("0") ||
- row.getAsString(CARRIER_ENABLED).equals("false")) ?
- "0" : CARRIERS_UNIQUE_FIELDS_DEFAULTS.get(CARRIER_ENABLED);
+ if (!row.containsKey(field)) {
+ selectionArgs[i++] = CARRIERS_UNIQUE_FIELDS_DEFAULTS.get(field);
} else {
- selectionArgs[i++] = row.containsKey(field) ?
- row.getAsString(field) : CARRIERS_UNIQUE_FIELDS_DEFAULTS.get(field);
+ if (CARRIERS_BOOLEAN_FIELDS.contains(field)) {
+ // for boolean fields we overwrite the strings "true" and "false" with "1"
+ // and "0"
+ selectionArgs[i++] = convertStringToIntString(row.getAsString(field));
+ } else {
+ selectionArgs[i++] = row.getAsString(field);
+ }
}
}
@@ -2032,6 +2244,24 @@
}
/**
+ * Convert "true" and "false" to "1" and "0".
+ * If the passed in string is already "1" or "0" returns the passed in string.
+ */
+ private static String convertStringToIntString(String boolString) {
+ if ("0".equals(boolString) || "false".equalsIgnoreCase(boolString)) return "0";
+ return "1";
+ }
+
+ /**
+ * Convert "1" and "0" to "true" and "false".
+ * If the passed in string is already "true" or "false" returns the passed in string.
+ */
+ private static String convertStringToBoolString(String intString) {
+ if ("0".equals(intString) || "false".equalsIgnoreCase(intString)) return "false";
+ return "true";
+ }
+
+ /**
* These methods can be overridden in a subclass for testing TelephonyProvider using an
* in-memory database.
*/
@@ -2067,7 +2297,7 @@
return s_apnSourceServiceExists;
}
- private void restoreApnsWithService() {
+ private void restoreApnsWithService(int subId) {
Context context = getContext();
Resources r = context.getResources();
ServiceConnection connection = new ServiceConnection() {
@@ -2095,7 +2325,8 @@
r.getString(R.string.apn_source_service)));
log("binding to service to restore apns, intent=" + intent);
try {
- if (context.bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
+ if (context.bindService(intent, connection, Context.BIND_IMPORTANT |
+ Context.BIND_AUTO_CREATE)) {
synchronized (mLock) {
while (mIApnSourceService == null) {
try {
@@ -2105,7 +2336,7 @@
}
}
try {
- ContentValues[] values = mIApnSourceService.getApns();
+ ContentValues[] values = mIApnSourceService.getApns(subId);
if (values != null) {
// we use the unsynchronized insert because this function is called
// within the syncrhonized function delete()
@@ -2241,7 +2472,7 @@
try {
return Integer.parseInt(sp.getString(APN_SET_ID + subId, null));
} catch (NumberFormatException e) {
- return NO_SET_SET;
+ return NO_APN_SET_ID;
}
}
@@ -2304,7 +2535,7 @@
private long getPreferredApnIdFromApn(int subId) {
log("getPreferredApnIdFromApn: for subId " + subId);
- SQLiteDatabase db = getWritableDatabase();
+ SQLiteDatabase db = getReadableDatabase();
String where = TextUtils.join("=? and ", CARRIERS_UNIQUE_FIELDS) + "=?";
String[] whereArgs = new String[CARRIERS_UNIQUE_FIELDS.size()];
SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE_FULL_APN,
@@ -2365,7 +2596,7 @@
public synchronized Cursor query(Uri url, String[] projectionIn, String selection,
String[] selectionArgs, String sort) {
if (VDBG) log("query: url=" + url + ", projectionIn=" + projectionIn + ", selection="
- + selection + "selectionArgs=" + selectionArgs + ", sort=" + sort);
+ + selection + "selectionArgs=" + selectionArgs + ", sort=" + sort);
TelephonyManager mTelephonyManager =
(TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
int subId = SubscriptionManager.getDefaultSubscriptionId();
@@ -2377,6 +2608,7 @@
List<String> constraints = new ArrayList<String>();
int match = s_urlMatcher.match(url);
+ checkQueryPermission(match, projectionIn);
switch (match) {
case URL_TELEPHONY_USING_SUBID: {
subIdString = url.getLastPathSegment();
@@ -2459,7 +2691,7 @@
// intentional fall through from above case
case URL_PREFERAPNSET: {
final int set = getPreferredApnSetId(subId);
- if (set != NO_SET_SET) {
+ if (set != NO_APN_SET_ID) {
constraints.add(APN_SET_ID + "=" + set);
}
break;
@@ -2472,19 +2704,31 @@
break;
}
- case URL_FILTERED_ID: {
- constraints.add("_id = " + url.getLastPathSegment());
+ case URL_FILTERED_ID:
+ case URL_FILTERED_USING_SUBID: {
+ String idString = url.getLastPathSegment();
+ if (match == URL_FILTERED_ID) {
+ qb.appendWhere("_id = " + idString);
+ } else {
+ try {
+ subId = Integer.parseInt(idString);
+ } catch (NumberFormatException e) {
+ loge("NumberFormatException" + e);
+ return null;
+ }
+ }
}
//intentional fall through from above case
case URL_FILTERED: {
- if(isManagedApnEnforced()) {
+ if (isManagedApnEnforced()) {
// If enforced, return DPC records only.
- constraints.add(IS_OWNED_BY_DPC);
+ qb.appendWhereStandalone(IS_OWNED_BY_DPC);
} else {
// Otherwise return non-DPC records only.
- constraints.add(IS_NOT_OWNED_BY_DPC);
+ qb.appendWhereStandalone(IS_NOT_OWNED_BY_DPC);
}
- break;
+ return getSubscriptionMatchingAPNList(qb, projectionIn, selection, selectionArgs,
+ sort, subId);
}
case URL_ENFORCE_MANAGED: {
@@ -2499,6 +2743,21 @@
qb.setTables(SIMINFO_TABLE);
break;
}
+ case URL_SIM_APN_LIST_ID: {
+ subIdString = url.getLastPathSegment();
+ try {
+ subId = Integer.parseInt(subIdString);
+ } catch (NumberFormatException e) {
+ loge("NumberFormatException" + e);
+ return null;
+ }
+ }
+ //intentional fall through from above case
+ case URL_SIM_APN_LIST: {
+ qb.appendWhere(IS_NOT_OWNED_BY_DPC);
+ return getSubscriptionMatchingAPNList(qb, projectionIn, selection, selectionArgs,
+ sort, subId);
+ }
default: {
return null;
@@ -2510,26 +2769,6 @@
qb.appendWhere(TextUtils.join(" AND ", constraints));
}
- if (match != URL_SIMINFO) {
- if (projectionIn != null) {
- for (String column : projectionIn) {
- if (TYPE.equals(column) ||
- MMSC.equals(column) ||
- MMSPROXY.equals(column) ||
- MMSPORT.equals(column) ||
- APN.equals(column)) {
- // noop
- } else {
- checkPermission();
- break;
- }
- }
- } else {
- // null returns all columns, so need permission check
- checkPermission();
- }
- }
-
SQLiteDatabase db = getReadableDatabase();
Cursor ret = null;
try {
@@ -2555,6 +2794,105 @@
return ret;
}
+ private void checkQueryPermission(int match, String[] projectionIn) {
+ if (match != URL_SIMINFO) {
+ if (projectionIn != null) {
+ for (String column : projectionIn) {
+ if (TYPE.equals(column) ||
+ MMSC.equals(column) ||
+ MMSPROXY.equals(column) ||
+ MMSPORT.equals(column) ||
+ MVNO_TYPE.equals(column) ||
+ MVNO_MATCH_DATA.equals(column) ||
+ APN.equals(column)) {
+ // noop
+ } else {
+ checkPermission();
+ break;
+ }
+ }
+ } else {
+ // null returns all columns, so need permission check
+ checkPermission();
+ }
+ }
+ }
+
+ /**
+ * To find the current sim APN. Query APN based on {MCC, MNC, MVNO} to support backward
+ * compatibility but will move to carrier id in the future.
+ *
+ * There has three steps:
+ * 1. Query the APN based on { MCC, MNC, MVNO }.
+ * 2. If can't find the current APN, then query the parent APN. Query based on { MCC, MNC }.
+ * 3. else return empty cursor
+ *
+ */
+ private Cursor getSubscriptionMatchingAPNList(SQLiteQueryBuilder qb, String[] projectionIn,
+ String selection, String[] selectionArgs, String sort, int subId) {
+ Cursor ret;
+ final TelephonyManager tm = ((TelephonyManager)
+ getContext().getSystemService(Context.TELEPHONY_SERVICE))
+ .createForSubscriptionId(subId);
+ SQLiteDatabase db = getReadableDatabase();
+ String mccmnc = tm.getSimOperator();
+
+ // For query db one time, append step 1 and step 2 condition in one selection and
+ // separate results after the query is completed. Because IMSI has special match rule,
+ // so just query the MCC / MNC and filter the MVNO by ourselves
+ qb.appendWhereStandalone(NUMERIC + " = '" + mccmnc + "' ");
+
+ ret = qb.query(db, null, selection, selectionArgs, null, null, sort);
+ if (ret == null) {
+ loge("query current APN but cursor is null.");
+ return null;
+ }
+
+ if (DBG) log("match current APN size: " + ret.getCount());
+
+ String[] coulmnNames = projectionIn != null ? projectionIn : ret.getColumnNames();
+ MatrixCursor currentCursor = new MatrixCursor(coulmnNames);
+ MatrixCursor parentCursor = new MatrixCursor(coulmnNames);
+
+ int numericIndex = ret.getColumnIndex(NUMERIC);
+ int mvnoIndex = ret.getColumnIndex(MVNO_TYPE);
+ int mvnoDataIndex = ret.getColumnIndex(MVNO_MATCH_DATA);
+
+ IccRecords iccRecords = getIccRecords(subId);
+
+ //Separate the result into MatrixCursor
+ while (ret.moveToNext()) {
+ List<String> data = new ArrayList<>();
+ for (String column : coulmnNames) {
+ data.add(ret.getString(ret.getColumnIndex(column)));
+ }
+
+ if (!TextUtils.isEmpty(ret.getString(numericIndex)) &&
+ ApnSettingUtils.mvnoMatches(iccRecords,
+ ApnSetting.getMvnoTypeIntFromString(ret.getString(mvnoIndex)),
+ ret.getString(mvnoDataIndex))) {
+ // 1. APN query result based on legacy SIM MCC/MCC and MVNO
+ currentCursor.addRow(data);
+ } else if (!TextUtils.isEmpty(ret.getString(numericIndex)) &&
+ TextUtils.isEmpty(ret.getString(mvnoIndex))) {
+ // 2. APN query result based on SIM MCC/MNC
+ parentCursor.addRow(data);
+ }
+ }
+ ret.close();
+
+ if (currentCursor.getCount() > 0) {
+ if (DBG) log("match Carrier Id APN: " + currentCursor.getCount());
+ return currentCursor;
+ } else if (parentCursor.getCount() > 0) {
+ if (DBG) log("match MNO Carrier ID APN: " + parentCursor.getCount());
+ return parentCursor;
+ } else {
+ if (DBG) log("APN no match");
+ return new MatrixCursor(coulmnNames);
+ }
+ }
+
@Override
public String getType(Uri url)
{
@@ -2565,6 +2903,7 @@
case URL_ID:
case URL_FILTERED_ID:
+ case URL_FILTERED_USING_SUBID:
return "vnd.android.cursor.item/telephony-carrier";
case URL_PREFERAPN_USING_SUBID:
@@ -2693,8 +3032,8 @@
}
values = DatabaseHelper.setDefaultValue(values);
- if (!values.containsKey(EDITED)) {
- values.put(EDITED, CARRIER_EDITED);
+ if (!values.containsKey(EDITED_STATUS)) {
+ values.put(EDITED_STATUS, CARRIER_EDITED);
}
// Owned_by should be others if inserted via general uri.
values.put(OWNED_BY, OWNED_BY_OTHERS);
@@ -2812,7 +3151,7 @@
IS_NOT_CARRIER_EDITED + ")";
String unedited = ") and " + IS_UNEDITED;
ContentValues cv = new ContentValues();
- cv.put(EDITED, USER_DELETED);
+ cv.put(EDITED_STATUS, USER_DELETED);
checkPermission();
@@ -2999,8 +3338,8 @@
case URL_TELEPHONY:
{
- if (!values.containsKey(EDITED)) {
- values.put(EDITED, CARRIER_EDITED);
+ if (!values.containsKey(EDITED_STATUS)) {
+ values.put(EDITED_STATUS, CARRIER_EDITED);
}
// Replace on conflict so that if same APN is present in db with edited
@@ -3028,8 +3367,8 @@
case URL_CURRENT:
{
- if (!values.containsKey(EDITED)) {
- values.put(EDITED, CARRIER_EDITED);
+ if (!values.containsKey(EDITED_STATUS)) {
+ values.put(EDITED_STATUS, CARRIER_EDITED);
}
// Replace on conflict so that if same APN is present in db with edited
// as UNEDITED or USER/CARRIER_DELETED, it is replaced with
@@ -3047,8 +3386,8 @@
throw new UnsupportedOperationException(
"Cannot update URL " + url + " with a where clause");
}
- if (!values.containsKey(EDITED)) {
- values.put(EDITED, CARRIER_EDITED);
+ if (!values.containsKey(EDITED_STATUS)) {
+ values.put(EDITED_STATUS, CARRIER_EDITED);
}
try {
@@ -3126,6 +3465,24 @@
break;
}
+ case URL_SIMINFO_USING_SUBID:
+ String subIdString = url.getLastPathSegment();
+ try {
+ subId = Integer.parseInt(subIdString);
+ } catch (NumberFormatException e) {
+ loge("NumberFormatException" + e);
+ throw new IllegalArgumentException("Invalid subId " + url);
+ }
+ if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
+ if (where != null || whereArgs != null) {
+ throw new UnsupportedOperationException(
+ "Cannot update URL " + url + " with a where clause");
+ }
+ count = db.update(SIMINFO_TABLE, values, _ID + "=?",
+ new String[] { subIdString});
+ uriType = URL_SIMINFO_USING_SUBID;
+ break;
+
case URL_SIMINFO: {
count = db.update(SIMINFO_TABLE, values, where, whereArgs);
uriType = URL_SIMINFO;
@@ -3138,10 +3495,52 @@
}
if (count > 0) {
+ boolean usingSubId = false;
switch (uriType) {
+ case URL_SIMINFO_USING_SUBID:
+ usingSubId = true;
+ // intentional fall through from above case
case URL_SIMINFO:
+ // skip notifying descendant URLs to avoid unneccessary wake up.
+ // If not set, any change to SIMINFO will notify observers which listens to
+ // specific field of SIMINFO.
getContext().getContentResolver().notifyChange(
- SubscriptionManager.CONTENT_URI, null, true, UserHandle.USER_ALL);
+ SubscriptionManager.CONTENT_URI, null,
+ ContentResolver.NOTIFY_SYNC_TO_NETWORK
+ | ContentResolver.NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS,
+ UserHandle.USER_ALL);
+ // notify observers on specific user settings changes.
+ if (values.containsKey(SubscriptionManager.WFC_IMS_ENABLED)) {
+ getContext().getContentResolver().notifyChange(
+ getNotifyContentUri(SubscriptionManager.WFC_ENABLED_CONTENT_URI,
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
+ if (values.containsKey(SubscriptionManager.ENHANCED_4G_MODE_ENABLED)) {
+ getContext().getContentResolver().notifyChange(
+ getNotifyContentUri(SubscriptionManager
+ .ADVANCED_CALLING_ENABLED_CONTENT_URI,
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
+ if (values.containsKey(SubscriptionManager.VT_IMS_ENABLED)) {
+ getContext().getContentResolver().notifyChange(
+ getNotifyContentUri(SubscriptionManager.VT_ENABLED_CONTENT_URI,
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
+ if (values.containsKey(SubscriptionManager.WFC_IMS_MODE)) {
+ getContext().getContentResolver().notifyChange(
+ getNotifyContentUri(SubscriptionManager.WFC_MODE_CONTENT_URI,
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
+ if (values.containsKey(SubscriptionManager.WFC_IMS_ROAMING_MODE)) {
+ getContext().getContentResolver().notifyChange(getNotifyContentUri(
+ SubscriptionManager.WFC_ROAMING_MODE_CONTENT_URI,
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
+ if (values.containsKey(SubscriptionManager.WFC_IMS_ROAMING_ENABLED)) {
+ getContext().getContentResolver().notifyChange(getNotifyContentUri(
+ SubscriptionManager.WFC_ROAMING_ENABLED_CONTENT_URI,
+ usingSubId, subId), null, true, UserHandle.USER_ALL);
+ }
break;
default:
getContext().getContentResolver().notifyChange(
@@ -3152,6 +3551,10 @@
return count;
}
+ private static Uri getNotifyContentUri(Uri uri, boolean usingSubId, int subId) {
+ return (usingSubId) ? Uri.withAppendedPath(uri, "" + subId) : uri;
+ }
+
private void checkPermission() {
int status = getContext().checkCallingOrSelfPermission(
"android.permission.WRITE_APN_SETTINGS");
@@ -3165,7 +3568,7 @@
TelephonyManager telephonyManager =
(TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
for (String pkg : packages) {
- if (telephonyManager.checkCarrierPrivilegesForPackage(pkg) ==
+ if (telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(pkg) ==
TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
return;
}
@@ -3209,7 +3612,7 @@
editorApn.apply();
if (apnSourceServiceExists(getContext())) {
- restoreApnsWithService();
+ restoreApnsWithService(subId);
} else {
initDatabaseWithDatabaseHelper(db);
}
@@ -3233,7 +3636,8 @@
String mvnoType = cursor.getString(0 /* MVNO_TYPE index */);
String mvnoMatchData = cursor.getString(1 /* MVNO_MATCH_DATA index */);
if (!TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData)
- && ApnSetting.mvnoMatches(iccRecords, mvnoType, mvnoMatchData)) {
+ && ApnSettingUtils.mvnoMatches(iccRecords,
+ ApnSetting.getMvnoTypeIntFromString(mvnoType), mvnoMatchData)) {
where = NUMERIC + "='" + simOperator + "'"
+ " AND " + MVNO_TYPE + "='" + mvnoType + "'"
+ " AND " + MVNO_MATCH_DATA + "='" + mvnoMatchData + "'"
@@ -3289,12 +3693,60 @@
initDatabaseWithDatabaseHelper(db);
- // Notify listereners of DB change since DB has been updated
+ // Notify listeners of DB change since DB has been updated
getContext().getContentResolver().notifyChange(
CONTENT_URI, null, true, UserHandle.USER_ALL);
}
+ public static void fillInMccMncStringAtCursor(Context context, SQLiteDatabase db, Cursor c) {
+ int mcc, mnc;
+ String subId;
+ try {
+ mcc = c.getInt(c.getColumnIndexOrThrow(SubscriptionManager.MCC));
+ mnc = c.getInt(c.getColumnIndexOrThrow(SubscriptionManager.MNC));
+ subId = c.getString(c.getColumnIndexOrThrow(
+ SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Possible database corruption -- some columns not found.");
+ return;
+ }
+
+ String mccString = String.format(Locale.getDefault(), "%03d", mcc);
+ String mncString = getBestStringMnc(context, mccString, mnc);
+ ContentValues cv = new ContentValues(2);
+ cv.put(SubscriptionManager.MCC_STRING, mccString);
+ cv.put(SubscriptionManager.MNC_STRING, mncString);
+ db.update(SIMINFO_TABLE, cv,
+ SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?",
+ new String[]{subId});
+ }
+
+ /*
+ * Find the best string-form mnc by looking up possibilities in the carrier id db.
+ * Default to the three-digit version if neither/both are valid.
+ */
+ private static String getBestStringMnc(Context context, String mcc, int mnc) {
+ if (mnc >= 100 && mnc <= 999) {
+ return String.valueOf(mnc);
+ }
+ String twoDigitMnc = String.format(Locale.getDefault(), "%02d", mnc);
+ String threeDigitMnc = "0" + twoDigitMnc;
+
+ try (
+ Cursor twoDigitMncCursor = context.getContentResolver().query(
+ Telephony.CarrierId.All.CONTENT_URI,
+ /* projection */ null,
+ /* selection */ Telephony.CarrierId.All.MCCMNC + "=?",
+ /* selectionArgs */ new String[]{mcc + twoDigitMnc}, null)
+ ) {
+ if (twoDigitMncCursor.getCount() > 0) {
+ return twoDigitMnc;
+ }
+ return threeDigitMnc;
+ }
+ }
+
/**
* Sync the bearer bitmask and network type bitmask when inserting and updating.
* Since bearerBitmask is deprecating, map the networkTypeBitmask to bearerBitmask if
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index 129f4d9..ad703de 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -22,7 +22,7 @@
<option name="test-tag" value="TelephonyProviderTests" />
<test class="com.android.tradefed.testtype.InstrumentationTest" >
<option name="package" value="com.android.providers.telephony.tests" />
- <option name="runner" value="android.test.InstrumentationTestRunner" />
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>
diff --git a/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java b/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
index 4adcf43..e5dd6e6 100644
--- a/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
+++ b/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
@@ -68,6 +68,8 @@
private static final String dummy_apn = "APN_DUMMY";
private static final String dummy_iccid_prefix = "ICCID_PREFIX_DUMMY";
private static final String dummy_name = "NAME_DUMMY";
+ private static final String dummy_access_rule =
+ "B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51465350";
private static final int dummy_cid = 0;
private MockContextWithProvider mContext;
@@ -104,14 +106,10 @@
private class MockContextWithProvider extends MockContext {
private final MockContentResolver mResolver;
- public MockContextWithProvider(CarrierIdProvider carrierIdProvider) {
+ public MockContextWithProvider(CarrierIdProviderTestable carrierIdProvider) {
mResolver = new FakeContentResolver();
- ProviderInfo providerInfo = new ProviderInfo();
- providerInfo.authority = CarrierIdProvider.AUTHORITY;
-
- // Add context to given carrierIdProvider
- carrierIdProvider.attachInfoForTesting(this, providerInfo);
+ carrierIdProvider.initializeForTesting(this);
Log.d(TAG, "MockContextWithProvider: carrierIdProvider.getContext(): "
+ carrierIdProvider.getContext());
@@ -437,6 +435,7 @@
contentValues.put(CarrierId.All.ICCID_PREFIX, dummy_iccid_prefix);
contentValues.put(CarrierId.CARRIER_NAME, dummy_name);
contentValues.put(CarrierId.CARRIER_ID, dummy_cid);
+ contentValues.put(CarrierId.All.PRIVILEGE_ACCESS_RULE, dummy_access_rule);
return contentValues;
}
}
diff --git a/tests/src/com/android/providers/telephony/CarrierIdProviderTestable.java b/tests/src/com/android/providers/telephony/CarrierIdProviderTestable.java
index 8468801..9ecd93a 100644
--- a/tests/src/com/android/providers/telephony/CarrierIdProviderTestable.java
+++ b/tests/src/com/android/providers/telephony/CarrierIdProviderTestable.java
@@ -15,6 +15,8 @@
*/
package com.android.providers.telephony;
+import android.content.Context;
+import android.content.pm.ProviderInfo;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
@@ -51,6 +53,14 @@
return mDbHelper.getWritableDatabase();
}
+ void initializeForTesting(Context context) {
+ ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.authority = CarrierIdProvider.AUTHORITY;
+
+ // Add context to given carrierIdProvider
+ attachInfoForTesting(context, providerInfo);
+ }
+
/**
* An in memory DB for CarrierIdProviderTestable to use
*/
diff --git a/tests/src/com/android/providers/telephony/RcsProviderTest.java b/tests/src/com/android/providers/telephony/RcsProviderTest.java
new file mode 100644
index 0000000..708078f
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/RcsProviderTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 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.providers.telephony;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.app.AppOpsManager;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.ProviderInfo;
+import android.net.Uri;
+import android.telephony.TelephonyManager;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class RcsProviderTest {
+ private MockContentResolver mContentResolver;
+
+ @Before
+ public void setUp() {
+ RcsProvider rcsProvider = new RcsProviderTestable();
+ MockContextWithProvider context = new MockContextWithProvider(rcsProvider);
+ mContentResolver = context.getContentResolver();
+ }
+
+ // TODO(sahinc): This test isn't that useful for now as it only checks the return value. Revisit
+ // once we have more of the implementation in place.
+ @Test
+ public void testInsertThread() {
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(RcsProviderHelper.OWNER_PARTICIPANT, 5);
+
+ Uri uri = mContentResolver.insert(Uri.parse("content://rcs/thread"), contentValues);
+ assertNull(uri);
+ }
+
+ @Test
+ public void testUpdateThread() {
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(RcsProviderHelper.OWNER_PARTICIPANT, 5);
+ mContentResolver.insert(Uri.parse("content://rcs/thread"), contentValues);
+
+ contentValues.put(RcsProviderHelper.OWNER_PARTICIPANT, 12);
+ int updateCount = mContentResolver.update(Uri.parse("content://rcs/thread"),
+ contentValues, "owner_participant=5", null);
+
+ assertEquals(1, updateCount);
+ }
+
+ class MockContextWithProvider extends MockContext {
+ private final MockContentResolver mResolver;
+
+ MockContextWithProvider(RcsProvider rcsProvider) {
+ mResolver = new MockContentResolver();
+
+ // Add authority="rcs" to given smsProvider
+ ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.authority = RcsProvider.AUTHORITY;
+ rcsProvider.attachInfoForTesting(this, providerInfo);
+ mResolver.addProvider(RcsProvider.AUTHORITY, rcsProvider);
+ }
+
+ @Override
+ public MockContentResolver getContentResolver() {
+ return mResolver;
+ }
+
+ @Override
+ public Object getSystemService(String name) {
+ switch (name) {
+ case Context.APP_OPS_SERVICE:
+ return Mockito.mock(AppOpsManager.class);
+ case Context.TELEPHONY_SERVICE:
+ return Mockito.mock(TelephonyManager.class);
+ default:
+ return null;
+ }
+ }
+ }
+
+}
diff --git a/tests/src/com/android/providers/telephony/RcsProviderTestable.java b/tests/src/com/android/providers/telephony/RcsProviderTestable.java
new file mode 100644
index 0000000..1e4da11
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/RcsProviderTestable.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 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.providers.telephony;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * A subclass of RcsProvider used for testing on an in-memory database
+ */
+public class RcsProviderTestable extends RcsProvider {
+
+ @Override
+ public boolean onCreate() {
+ mDbOpenHelper = new InMemoryRcsDatabase();
+ return true;
+ }
+
+ static class InMemoryRcsDatabase extends SQLiteOpenHelper {
+ InMemoryRcsDatabase() {
+ super(null, // no context is needed for in-memory db
+ null, // db file name is null for in-memory db
+ null, // CursorFactory is null by default
+ 1); // db version is no-op for tests
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ RcsProviderHelper.createRcsTables(db);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // no-op
+ }
+ }
+}
diff --git a/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java b/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
index fd15d01..c5ad5a0 100644
--- a/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
+++ b/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
@@ -87,7 +87,6 @@
ServiceStateTable.CDMA_ERI_ICON_INDEX,
ServiceStateTable.CDMA_ERI_ICON_MODE,
ServiceStateTable.IS_EMERGENCY_ONLY,
- ServiceStateTable.IS_DATA_ROAMING_FROM_REGISTRATION,
ServiceStateTable.IS_USING_CARRIER_AGGREGATION,
};
@@ -188,7 +187,6 @@
final int cdmaEriIconIndex = ss.getCdmaEriIconIndex();
final int cdmaEriIconMode = ss.getCdmaEriIconMode();
final int isEmergencyOnly = (ss.isEmergencyOnly()) ? 1 : 0;
- final int isDataRoamingFromRegistration = (ss.getDataRoamingFromRegistration()) ? 1 : 0;
final int isUsingCarrierAggregation = (ss.isUsingCarrierAggregation()) ? 1 : 0;
assertEquals(voiceRegState, cursor.getInt(0));
@@ -210,8 +208,7 @@
assertEquals(cdmaEriIconIndex, cursor.getInt(16));
assertEquals(cdmaEriIconMode, cursor.getInt(17));
assertEquals(isEmergencyOnly, cursor.getInt(18));
- assertEquals(isDataRoamingFromRegistration, cursor.getInt(19));
- assertEquals(isUsingCarrierAggregation, cursor.getInt(20));
+ assertEquals(isUsingCarrierAggregation, cursor.getInt(19));
}
/**
diff --git a/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
new file mode 100644
index 0000000..6892673
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2018 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.providers.telephony;
+
+import static android.provider.Telephony.Carriers;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.support.test.InstrumentationRegistry;
+import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public final class TelephonyDatabaseHelperTest {
+
+ private final static String TAG = TelephonyDatabaseHelperTest.class.getSimpleName();
+
+ private Context mContext;
+ private TelephonyProvider.DatabaseHelper mHelper; // the actual class being tested
+ private SQLiteOpenHelper mInMemoryDbHelper; // used to give us an in-memory db
+
+ @Before
+ public void setUp() {
+ Log.d(TAG, "setUp() +");
+ mContext = InstrumentationRegistry.getContext();
+ mHelper = new TelephonyProvider.DatabaseHelper(mContext);
+ mInMemoryDbHelper = new InMemoryTelephonyProviderV5DbHelper();
+ Log.d(TAG, "setUp() -");
+ }
+
+ @Test
+ public void databaseHelperOnUpgrade_hasApnSetIdField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasApnSetIdField");
+ // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.DatabaseHelper.getVersion(mContext));
+
+ // the upgraded db must have the APN_SET_ID field
+ Cursor cursor = db.query("carriers", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "carriers columns: " + Arrays.toString(upgradedColumns));
+
+ assertTrue(Arrays.asList(upgradedColumns).contains(Carriers.APN_SET_ID));
+ }
+
+ @Test
+ public void databaseHelperOnUpgrade_hasCarrierIdField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasSubscriptionTypeField");
+ // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.DatabaseHelper.getVersion(mContext));
+
+ // the upgraded db must have the Telephony.Carriers.CARRIER_ID field
+ Cursor cursor = db.query("carriers", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "carriers columns: " + Arrays.toString(upgradedColumns));
+ assertTrue(Arrays.asList(upgradedColumns).contains(Carriers.CARRIER_ID));
+ }
+
+ @Test
+ public void databaseHelperOnUpgrade_hasCountryIsoField() {
+ Log.d(TAG, "databaseHelperOnUpgrade_hasCountryIsoField");
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.DatabaseHelper.getVersion(mContext));
+
+ // the upgraded db must have the Telephony.Carriers.CARRIER_ID field
+ Cursor cursor = db.query("simInfo", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "iso columns: " + Arrays.toString(upgradedColumns));
+ assertTrue(Arrays.asList(upgradedColumns).contains(SubscriptionManager.ISO_COUNTRY_CODE));
+ }
+
+ @Test
+ public void databaseHelperOnUpgrade_columnsMatchNewlyCreatedDb() {
+ Log.d(TAG, "databaseHelperOnUpgrade_columnsMatchNewlyCreatedDb");
+ // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
+ SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
+ mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.DatabaseHelper.getVersion(mContext));
+
+ // compare upgraded carriers table to a carriers table created from scratch
+ db.execSQL(TelephonyProvider.getStringForCarrierTableCreation("carriers_full"));
+
+ Cursor cursor = db.query("carriers", null, null, null, null, null, null);
+ String[] upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "carriers columns: " + Arrays.toString(upgradedColumns));
+
+ cursor = db.query("carriers_full", null, null, null, null, null, null);
+ String[] fullColumns = cursor.getColumnNames();
+ Log.d(TAG, "carriers_full colunmns: " + Arrays.toString(fullColumns));
+
+ assertArrayEquals("Carriers table from onUpgrade doesn't match full table",
+ fullColumns, upgradedColumns);
+
+ // compare upgraded siminfo table to siminfo table created from scratch
+ db.execSQL(TelephonyProvider.getStringForSimInfoTableCreation("siminfo_full"));
+
+ cursor = db.query("siminfo", null, null, null, null, null, null);
+ upgradedColumns = cursor.getColumnNames();
+ Log.d(TAG, "siminfo columns: " + Arrays.toString(upgradedColumns));
+
+ cursor = db.query("siminfo_full", null, null, null, null, null, null);
+ fullColumns = cursor.getColumnNames();
+ Log.d(TAG, "siminfo_full colunmns: " + Arrays.toString(fullColumns));
+
+ assertArrayEquals("Siminfo table from onUpgrade doesn't match full table",
+ fullColumns, upgradedColumns);
+ }
+
+ /**
+ * Helper for an in memory DB used to test the TelephonyProvider#DatabaseHelper.
+ *
+ * We pass this in-memory db to DatabaseHelper#onUpgrade so we can use the actual function
+ * without using the actual telephony db.
+ */
+ private static class InMemoryTelephonyProviderV5DbHelper extends SQLiteOpenHelper {
+
+ public InMemoryTelephonyProviderV5DbHelper() {
+ super(InstrumentationRegistry.getContext(),
+ null, // db file name is null for in-memory db
+ null, // CursorFactory is null by default
+ 1); // in-memory db version doesn't seem to matter
+ Log.d(TAG, "InMemoryTelephonyProviderV5DbHelper creating in-memory database");
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // Set up the carriers table without any fields added in onUpgrade
+ // since these are the initial fields, there is no need to update this test fixture in
+ // the future
+ List<String> originalUniqueFields = new ArrayList<String>();
+ originalUniqueFields.add(Carriers.NUMERIC);
+ originalUniqueFields.add(Carriers.MCC);
+ originalUniqueFields.add(Carriers.MNC);
+ originalUniqueFields.add(Carriers.APN);
+ originalUniqueFields.add(Carriers.PROXY);
+ originalUniqueFields.add(Carriers.PORT);
+ originalUniqueFields.add(Carriers.MMSPROXY);
+ originalUniqueFields.add(Carriers.MMSPORT);
+ originalUniqueFields.add(Carriers.MMSC);
+ Log.d(TAG, "InMemoryTelephonyProviderV5DbHelper onCreate creating the carriers table");
+ db.execSQL(
+ "CREATE TABLE carriers" +
+ "(_id INTEGER PRIMARY KEY," +
+ Carriers.NAME + " TEXT DEFAULT ''," +
+ Carriers.NUMERIC + " TEXT DEFAULT ''," +
+ Carriers.MCC + " TEXT DEFAULT ''," +
+ Carriers.MNC + " TEXT DEFAULT ''," +
+ Carriers.APN + " TEXT DEFAULT ''," +
+ Carriers.USER + " TEXT DEFAULT ''," +
+ Carriers.SERVER + " TEXT DEFAULT ''," +
+ Carriers.PASSWORD + " TEXT DEFAULT ''," +
+ Carriers.PROXY + " TEXT DEFAULT ''," +
+ Carriers.PORT + " TEXT DEFAULT ''," +
+ Carriers.MMSPROXY + " TEXT DEFAULT ''," +
+ Carriers.MMSPORT + " TEXT DEFAULT ''," +
+ Carriers.MMSC + " TEXT DEFAULT ''," +
+ Carriers.TYPE + " TEXT DEFAULT ''," +
+ Carriers.CURRENT + " INTEGER," +
+ "UNIQUE (" + TextUtils.join(", ", originalUniqueFields) + "));");
+
+ // set up the siminfo table without any fields added in onUpgrade
+ // since these are the initial fields, there is no need to update this test fixture in
+ // the future
+ Log.d(TAG, "InMemoryTelephonyProviderV5DbHelper onCreate creating the siminfo table");
+ db.execSQL(
+ "CREATE TABLE siminfo ("
+ + SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + SubscriptionManager.ICC_ID + " TEXT NOT NULL,"
+ + SubscriptionManager.SIM_SLOT_INDEX
+ + " INTEGER DEFAULT " + SubscriptionManager.SIM_NOT_INSERTED + ","
+ + SubscriptionManager.DISPLAY_NAME + " TEXT,"
+ + SubscriptionManager.NAME_SOURCE
+ + " INTEGER DEFAULT " + SubscriptionManager.NAME_SOURCE_DEFAULT_SOURCE + ","
+ + SubscriptionManager.COLOR
+ + " INTEGER DEFAULT " + SubscriptionManager.COLOR_DEFAULT + ","
+ + SubscriptionManager.NUMBER + " TEXT,"
+ + SubscriptionManager.DISPLAY_NUMBER_FORMAT + " INTEGER NOT NULL"
+ + " DEFAULT " + SubscriptionManager.DISPLAY_NUMBER_DEFAULT + ","
+ + SubscriptionManager.DATA_ROAMING
+ + " INTEGER DEFAULT " + SubscriptionManager.DATA_ROAMING_DEFAULT + ","
+ + SubscriptionManager.CARD_ID + " TEXT NOT NULL"
+ + ");");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.d(TAG, "InMemoryTelephonyProviderV5DbHelper onUpgrade doing nothing");
+ return;
+ }
+ }
+}
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index dde9e5c..b77e5cf 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -16,59 +16,39 @@
package com.android.providers.telephony;
-import android.annotation.TargetApi;
-import android.content.ContentProvider;
-import android.content.ContentResolver;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.Manifest;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
-import android.content.SharedPreferences;
-import android.database.Cursor;
import android.database.ContentObserver;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.Cursor;
import android.net.Uri;
-import android.os.Build;
-import android.os.FileUtils;
import android.os.Process;
+import android.provider.Telephony;
import android.provider.Telephony.Carriers;
import android.support.test.InstrumentationRegistry;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
import android.util.Log;
-import com.android.providers.telephony.TelephonyProvider;
-
import junit.framework.TestCase;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Map;
-import java.util.Set;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.IntStream;
/**
@@ -92,11 +72,14 @@
private int notifyChangeCount;
private int notifyChangeRestoreCount;
+ private int notifyWfcCount;
+ private int notifyWfcCountWithTestSubId;
private static final String TEST_SUBID = "1";
private static final String TEST_OPERATOR = "123456";
private static final String TEST_MCC = "123";
private static final String TEST_MNC = "456";
+
// Used to test the path for URL_TELEPHONY_USING_SUBID with subid 1
private static final Uri CONTENT_URI_WITH_SUBID = Uri.parse(
"content://telephony/carriers/subId/" + TEST_SUBID);
@@ -107,6 +90,10 @@
// Used to test the preferred apn
private static final Uri URL_PREFERAPN_USING_SUBID = Uri.parse(
"content://telephony/carriers/preferapn/subId/" + TEST_SUBID);
+ private static final Uri URL_WFC_ENABLED_USING_SUBID = Uri.parse(
+ "content://telephony/siminfo/" + TEST_SUBID);
+ private static final Uri URL_SIM_APN_LIST = Uri.parse(
+ "content://telephony/carriers/sim_apn_list");
private static final String COLUMN_APN_ID = "apn_id";
@@ -126,6 +113,10 @@
private final MockContentResolver mResolver;
private TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
+ private final List<String> GRANTED_PERMISSIONS = Arrays.asList(
+ Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.WRITE_APN_SETTINGS,
+ Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+
public MockContextWithProvider(TelephonyProvider telephonyProvider) {
mResolver = new MockContentResolver() {
@Override
@@ -134,6 +125,10 @@
notifyChangeCount++;
if (URL_RESTOREAPN_USING_SUBID.equals(uri)) {
notifyChangeRestoreCount++;
+ } else if (SubscriptionManager.WFC_ENABLED_CONTENT_URI.equals(uri)) {
+ notifyWfcCount++;
+ } else if (URL_WFC_ENABLED_USING_SUBID.equals(uri)) {
+ notifyWfcCountWithTestSubId++;
}
}
};
@@ -141,6 +136,9 @@
// return test subId 0 for all operators
doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator(anyInt());
+ doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
+ doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator();
+
// Add authority="telephony" to given telephonyProvider
ProviderInfo providerInfo = new ProviderInfo();
providerInfo.authority = "telephony";
@@ -186,7 +184,7 @@
// Gives permission to write to the APN table within the MockContext
@Override
public int checkCallingOrSelfPermission(String permission) {
- if (TextUtils.equals(permission, "android.permission.WRITE_APN_SETTINGS")) {
+ if (GRANTED_PERMISSIONS.contains(permission)) {
Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission
+ ", returning PackageManager.PERMISSION_GRANTED");
return PackageManager.PERMISSION_GRANTED;
@@ -287,6 +285,64 @@
}
/**
+ * Test migrating int-based MCC/MNCs over to Strings in the sim info table
+ */
+ @Test
+ @SmallTest
+ public void testMccMncMigration() {
+ CarrierIdProviderTestable carrierIdProvider = new CarrierIdProviderTestable();
+ carrierIdProvider.initializeForTesting(mContext);
+ mContentResolver.addProvider(Telephony.CarrierId.All.CONTENT_URI.getAuthority(),
+ carrierIdProvider);
+ // Insert a few values into the carrier ID db
+ List<String> mccMncs = Arrays.asList("99910", "999110", "999060", "99905");
+ ContentValues[] carrierIdMccMncs = mccMncs.stream()
+ .map((mccMnc) -> {
+ ContentValues cv = new ContentValues(1);
+ cv.put(Telephony.CarrierId.All.MCCMNC, mccMnc);
+ return cv;
+ }).toArray(ContentValues[]::new);
+ mContentResolver.bulkInsert(Telephony.CarrierId.All.CONTENT_URI, carrierIdMccMncs);
+
+ // Populate the sim info db with int-format entries
+ ContentValues[] existingSimInfoEntries = IntStream.range(0, mccMncs.size())
+ .mapToObj((idx) -> {
+ int mcc = Integer.valueOf(mccMncs.get(idx).substring(0, 3));
+ int mnc = Integer.valueOf(mccMncs.get(idx).substring(3));
+ ContentValues cv = new ContentValues(4);
+ cv.put(SubscriptionManager.MCC, mcc);
+ cv.put(SubscriptionManager.MNC, mnc);
+ cv.put(SubscriptionManager.ICC_ID, String.valueOf(idx));
+ cv.put(SubscriptionManager.CARD_ID, String.valueOf(idx));
+ return cv;
+ }).toArray(ContentValues[]::new);
+
+ mContentResolver.bulkInsert(SubscriptionManager.CONTENT_URI, existingSimInfoEntries);
+
+ // Run the upgrade helper on all the sim info entries.
+ String[] proj = {SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID,
+ SubscriptionManager.MCC, SubscriptionManager.MNC,
+ SubscriptionManager.MCC_STRING, SubscriptionManager.MNC_STRING};
+ try (Cursor c = mContentResolver.query(SubscriptionManager.CONTENT_URI, proj,
+ null, null, null)) {
+ while (c.moveToNext()) {
+ TelephonyProvider.fillInMccMncStringAtCursor(mContext,
+ mTelephonyProviderTestable.getWritableDatabase(), c);
+ }
+ }
+
+ // Loop through and make sure that everything got filled in correctly.
+ try (Cursor c = mContentResolver.query(SubscriptionManager.CONTENT_URI, proj,
+ null, null, null)) {
+ while (c.moveToNext()) {
+ String mcc = c.getString(c.getColumnIndexOrThrow(SubscriptionManager.MCC_STRING));
+ String mnc = c.getString(c.getColumnIndexOrThrow(SubscriptionManager.MNC_STRING));
+ assertTrue(mccMncs.contains(mcc + mnc));
+ }
+ }
+ }
+
+ /**
* Test updating values in carriers table. Verify that when update hits a conflict using URL_ID
* we merge the rows.
*/
@@ -546,7 +602,7 @@
mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID);
final int current = 1;
- final String numeric = "123456789";
+ final String numeric = TEST_OPERATOR;
// Insert DPC record.
final String dpcRecordApn = "exampleApnNameDPC";
@@ -1017,7 +1073,7 @@
editedValue.put(Carriers.NUMERIC, numeric1);
editedValue.put(Carriers.MCC, mcc1);
editedValue.put(Carriers.MNC, mnc1);
- editedValue.put(Carriers.EDITED, value);
+ editedValue.put(Carriers.EDITED_STATUS, value);
assertNotNull(mContentResolver.insert(URI_TELEPHONY, editedValue));
Cursor cur = mContentResolver.query(URI_TELEPHONY, null, null, null, null);
@@ -1030,13 +1086,13 @@
values.put(Carriers.NUMERIC, numeric1);
values.put(Carriers.MCC, mcc1);
values.put(Carriers.MNC, mnc1);
- values.put(Carriers.EDITED, Carriers.UNEDITED);
+ values.put(Carriers.EDITED_STATUS, Carriers.UNEDITED);
mContentResolver.insert(URI_TELEPHONY, values);
String[] testProjection = {
Carriers.NAME,
Carriers.APN,
- Carriers.EDITED,
+ Carriers.EDITED_STATUS,
Carriers.TYPE,
Carriers.PROTOCOL,
Carriers.BEARER_BITMASK,
@@ -1064,7 +1120,7 @@
editedValue.put(Carriers.NUMERIC, numeric1);
editedValue.put(Carriers.MCC, mcc1);
editedValue.put(Carriers.MNC, mnc1);
- editedValue.put(Carriers.EDITED, value);
+ editedValue.put(Carriers.EDITED_STATUS, value);
assertNotNull(mContentResolver.insert(URI_TELEPHONY, editedValue));
// insert APN that conflicts with edited APN
@@ -1074,13 +1130,13 @@
values.put(Carriers.NUMERIC, numeric1);
values.put(Carriers.MCC, mcc1);
values.put(Carriers.MNC, mnc1);
- values.put(Carriers.EDITED, Carriers.UNEDITED);
+ values.put(Carriers.EDITED_STATUS, Carriers.UNEDITED);
mContentResolver.insert(URI_TELEPHONY, values);
String[] testProjection = {
Carriers.NAME,
Carriers.APN,
- Carriers.EDITED,
+ Carriers.EDITED_STATUS,
Carriers.TYPE,
Carriers.PROTOCOL,
Carriers.BEARER_BITMASK,
@@ -1339,4 +1395,140 @@
assertEquals(0, cursor.getCount());
assertEquals(3, notifyChangeRestoreCount);
}
+
+ /**
+ * Test changes to siminfo/WFC_IMS_ENABLED and simInfo/ENHANCED_4G
+ */
+ @Test
+ @SmallTest
+ public void testUpdateWfcEnabled() {
+ // insert test contentValues
+ ContentValues contentValues = new ContentValues();
+ final int insertSubId = 1;
+ final String insertDisplayName = "exampleDisplayName";
+ final String insertCarrierName = "exampleCarrierName";
+ final String insertIccId = "exampleIccId";
+ final String insertCardId = "exampleCardId";
+ contentValues.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, insertSubId);
+ contentValues.put(SubscriptionManager.DISPLAY_NAME, insertDisplayName);
+ contentValues.put(SubscriptionManager.CARRIER_NAME, insertCarrierName);
+ contentValues.put(SubscriptionManager.ICC_ID, insertIccId);
+ contentValues.put(SubscriptionManager.CARD_ID, insertCardId);
+
+ Log.d(TAG, "testSimTable Inserting wfc contentValues: " + contentValues);
+ mContentResolver.insert(SubscriptionManager.CONTENT_URI, contentValues);
+ assertEquals(0, notifyWfcCount);
+
+ // update wfc_enabled
+ ContentValues values = new ContentValues();
+ values.put(SubscriptionManager.WFC_IMS_ENABLED, true);
+ final String selection = SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?";
+ final String[] selectionArgs = { "" + insertSubId };
+ mContentResolver.update(SubscriptionManager.CONTENT_URI, values, selection, selectionArgs);
+ assertEquals(1, notifyWfcCount);
+ assertEquals(0, notifyWfcCountWithTestSubId);
+
+ // update other fields
+ values = new ContentValues();
+ values.put(SubscriptionManager.DISPLAY_NAME, "exampleDisplayNameNew");
+ mContentResolver.update(SubscriptionManager.CONTENT_URI, values, selection, selectionArgs);
+ // expect no change on wfc count
+ assertEquals(1, notifyWfcCount);
+ assertEquals(0, notifyWfcCountWithTestSubId);
+
+ // update WFC using subId
+ values = new ContentValues();
+ values.put(SubscriptionManager.WFC_IMS_ENABLED, false);
+ mContentResolver.update(SubscriptionManager.getUriForSubscriptionId(insertSubId),
+ values, null, null);
+ assertEquals(1, notifyWfcCount);
+ assertEquals(0, notifyWfcCountWithTestSubId);
+ }
+
+ @Test
+ @SmallTest
+ public void testSIMAPNLIST_APNMatchTheMCCMNCAndMVNO() {
+ // Test on getCurrentAPNList() step 1
+ TelephonyManager telephonyManager =
+ ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE));
+ doReturn(telephonyManager).when(telephonyManager).createForSubscriptionId(anyInt());
+
+ final String apnName = "apnName";
+ final String carrierName = "name";
+ final String numeric = TEST_OPERATOR;
+ final String mvnoType = "spn";
+ final String mvnoData = TelephonyProviderTestable.TEST_SPN;
+ final int carrierId = 100;
+ doReturn(carrierId).when(telephonyManager).getSimCarrierId();
+ doReturn(numeric).when(telephonyManager).getSimOperator();
+
+ // Insert the APN and DB only have the MCC/MNC and MVNO APN
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Carriers.APN, apnName);
+ contentValues.put(Carriers.NAME, carrierName);
+ contentValues.put(Carriers.NUMERIC, numeric);
+ contentValues.put(Carriers.MVNO_TYPE, mvnoType);
+ contentValues.put(Carriers.MVNO_MATCH_DATA, mvnoData);
+ mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+ // Query DB
+ final String[] testProjection =
+ {
+ Carriers.APN,
+ Carriers.NAME,
+ Carriers.NUMERIC,
+ Carriers.MVNO_MATCH_DATA
+ };
+ Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
+ testProjection, null, null, null);
+
+ cursor.moveToFirst();
+ assertEquals(apnName, cursor.getString(0));
+ assertEquals(carrierName, cursor.getString(1));
+ assertEquals(numeric, cursor.getString(2));
+ assertEquals(mvnoData, cursor.getString(3));
+ }
+
+ @Test
+ @SmallTest
+ public void testSIMAPNLIST_APNMatchTheParentMCCMNC() {
+ // Test on getCurrentAPNList() step 2
+ TelephonyManager telephonyManager =
+ ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE));
+ doReturn(telephonyManager).when(telephonyManager).createForSubscriptionId(anyInt());
+
+ final String apnName = "apnName";
+ final String carrierName = "name";
+ final String numeric = TEST_OPERATOR;
+ final String mvnoData = TelephonyProviderTestable.TEST_SPN;
+ final int carrierId = 100;
+ final int mnoCarrierId = 101;
+
+ doReturn(carrierId).when(telephonyManager).getSimCarrierId();
+ doReturn(numeric).when(telephonyManager).getSimOperator();
+ doReturn(mvnoData).when(telephonyManager).getSimOperatorName();
+ doReturn(mnoCarrierId).when(telephonyManager).getSimMNOCarrierId();
+
+ // Insert the APN and DB only have the MNO APN
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Carriers.APN, apnName);
+ contentValues.put(Carriers.NAME, carrierName);
+ contentValues.put(Carriers.NUMERIC, numeric);
+ mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+ // Query DB
+ final String[] testProjection =
+ {
+ Carriers.APN,
+ Carriers.NAME,
+ Carriers.NUMERIC,
+ };
+ Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
+ testProjection, null, null, null);
+
+ cursor.moveToFirst();
+ assertEquals(apnName, cursor.getString(0));
+ assertEquals(carrierName, cursor.getString(1));
+ assertEquals(numeric, cursor.getString(2));
+ }
}