Merge "Don't use APNs xml if CarrierSettings is installed" am: aa63799915
am: 4c33c8cd0b  -s ours

Change-Id: I5bad51458b15cc130395bb8cd4df8364caf886f6
diff --git a/res/values-az-rAZ/config.xml b/res/values-az/config.xml
similarity index 100%
rename from res/values-az-rAZ/config.xml
rename to res/values-az/config.xml
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az/strings.xml
similarity index 100%
rename from res/values-az-rAZ/strings.xml
rename to res/values-az/strings.xml
diff --git a/res/values-az-rAZ/config.xml b/res/values-be/config.xml
similarity index 100%
copy from res/values-az-rAZ/config.xml
copy to res/values-be/config.xml
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
new file mode 100644
index 0000000..3c86bf4
--- /dev/null
+++ b/res/values-be/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Налады мабiльнай сеткi"</string>
+    <string name="app_label" product="default" msgid="8338087656149558019">"Сховішча для тэлефаніі і паведамленняў"</string>
+</resources>
diff --git a/res/values-bn-rBD/config.xml b/res/values-bn/config.xml
similarity index 100%
rename from res/values-bn-rBD/config.xml
rename to res/values-bn/config.xml
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn/strings.xml
similarity index 100%
rename from res/values-bn-rBD/strings.xml
rename to res/values-bn/strings.xml
diff --git a/res/values-az-rAZ/config.xml b/res/values-bs/config.xml
similarity index 100%
copy from res/values-az-rAZ/config.xml
copy to res/values-bs/config.xml
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
new file mode 100644
index 0000000..9d19176
--- /dev/null
+++ b/res/values-bs/strings.xml
@@ -0,0 +1,21 @@
+<?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">"Konfiguracija mobilne mreže"</string>
+    <string name="app_label" product="default" msgid="8338087656149558019">"Pohrana za telefon i poruke"</string>
+</resources>
diff --git a/res/values-et-rEE/config.xml b/res/values-et/config.xml
similarity index 100%
rename from res/values-et-rEE/config.xml
rename to res/values-et/config.xml
diff --git a/res/values-et-rEE/strings.xml b/res/values-et/strings.xml
similarity index 100%
rename from res/values-et-rEE/strings.xml
rename to res/values-et/strings.xml
diff --git a/res/values-eu-rES/config.xml b/res/values-eu/config.xml
similarity index 100%
rename from res/values-eu-rES/config.xml
rename to res/values-eu/config.xml
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu/strings.xml
similarity index 100%
rename from res/values-eu-rES/strings.xml
rename to res/values-eu/strings.xml
diff --git a/res/values-gl-rES/config.xml b/res/values-gl/config.xml
similarity index 100%
rename from res/values-gl-rES/config.xml
rename to res/values-gl/config.xml
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl/strings.xml
similarity index 100%
rename from res/values-gl-rES/strings.xml
rename to res/values-gl/strings.xml
diff --git a/res/values-gu-rIN/config.xml b/res/values-gu/config.xml
similarity index 100%
rename from res/values-gu-rIN/config.xml
rename to res/values-gu/config.xml
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu/strings.xml
similarity index 100%
rename from res/values-gu-rIN/strings.xml
rename to res/values-gu/strings.xml
diff --git a/res/values-hy-rAM/config.xml b/res/values-hy/config.xml
similarity index 100%
rename from res/values-hy-rAM/config.xml
rename to res/values-hy/config.xml
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy/strings.xml
similarity index 100%
rename from res/values-hy-rAM/strings.xml
rename to res/values-hy/strings.xml
diff --git a/res/values-is-rIS/config.xml b/res/values-is/config.xml
similarity index 100%
rename from res/values-is-rIS/config.xml
rename to res/values-is/config.xml
diff --git a/res/values-is-rIS/strings.xml b/res/values-is/strings.xml
similarity index 100%
rename from res/values-is-rIS/strings.xml
rename to res/values-is/strings.xml
diff --git a/res/values-ka-rGE/config.xml b/res/values-ka/config.xml
similarity index 100%
rename from res/values-ka-rGE/config.xml
rename to res/values-ka/config.xml
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka/strings.xml
similarity index 100%
rename from res/values-ka-rGE/strings.xml
rename to res/values-ka/strings.xml
diff --git a/res/values-kk-rKZ/config.xml b/res/values-kk/config.xml
similarity index 100%
rename from res/values-kk-rKZ/config.xml
rename to res/values-kk/config.xml
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk/strings.xml
similarity index 100%
rename from res/values-kk-rKZ/strings.xml
rename to res/values-kk/strings.xml
diff --git a/res/values-km-rKH/config.xml b/res/values-km/config.xml
similarity index 100%
rename from res/values-km-rKH/config.xml
rename to res/values-km/config.xml
diff --git a/res/values-km-rKH/strings.xml b/res/values-km/strings.xml
similarity index 100%
rename from res/values-km-rKH/strings.xml
rename to res/values-km/strings.xml
diff --git a/res/values-kn-rIN/config.xml b/res/values-kn/config.xml
similarity index 100%
rename from res/values-kn-rIN/config.xml
rename to res/values-kn/config.xml
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn/strings.xml
similarity index 100%
rename from res/values-kn-rIN/strings.xml
rename to res/values-kn/strings.xml
diff --git a/res/values-ky-rKG/config.xml b/res/values-ky/config.xml
similarity index 100%
rename from res/values-ky-rKG/config.xml
rename to res/values-ky/config.xml
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky/strings.xml
similarity index 100%
rename from res/values-ky-rKG/strings.xml
rename to res/values-ky/strings.xml
diff --git a/res/values-lo-rLA/config.xml b/res/values-lo/config.xml
similarity index 100%
rename from res/values-lo-rLA/config.xml
rename to res/values-lo/config.xml
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo/strings.xml
similarity index 100%
rename from res/values-lo-rLA/strings.xml
rename to res/values-lo/strings.xml
diff --git a/res/values-mk-rMK/config.xml b/res/values-mk/config.xml
similarity index 100%
rename from res/values-mk-rMK/config.xml
rename to res/values-mk/config.xml
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk/strings.xml
similarity index 100%
rename from res/values-mk-rMK/strings.xml
rename to res/values-mk/strings.xml
diff --git a/res/values-ml-rIN/config.xml b/res/values-ml/config.xml
similarity index 100%
rename from res/values-ml-rIN/config.xml
rename to res/values-ml/config.xml
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml/strings.xml
similarity index 100%
rename from res/values-ml-rIN/strings.xml
rename to res/values-ml/strings.xml
diff --git a/res/values-mn-rMN/config.xml b/res/values-mn/config.xml
similarity index 100%
rename from res/values-mn-rMN/config.xml
rename to res/values-mn/config.xml
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn/strings.xml
similarity index 100%
rename from res/values-mn-rMN/strings.xml
rename to res/values-mn/strings.xml
diff --git a/res/values-mr-rIN/config.xml b/res/values-mr/config.xml
similarity index 100%
rename from res/values-mr-rIN/config.xml
rename to res/values-mr/config.xml
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr/strings.xml
similarity index 100%
rename from res/values-mr-rIN/strings.xml
rename to res/values-mr/strings.xml
diff --git a/res/values-ms-rMY/config.xml b/res/values-ms/config.xml
similarity index 100%
rename from res/values-ms-rMY/config.xml
rename to res/values-ms/config.xml
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms/strings.xml
similarity index 100%
rename from res/values-ms-rMY/strings.xml
rename to res/values-ms/strings.xml
diff --git a/res/values-my-rMM/config.xml b/res/values-my/config.xml
similarity index 100%
rename from res/values-my-rMM/config.xml
rename to res/values-my/config.xml
diff --git a/res/values-my-rMM/strings.xml b/res/values-my/strings.xml
similarity index 100%
rename from res/values-my-rMM/strings.xml
rename to res/values-my/strings.xml
diff --git a/res/values-ne-rNP/config.xml b/res/values-ne/config.xml
similarity index 100%
rename from res/values-ne-rNP/config.xml
rename to res/values-ne/config.xml
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne/strings.xml
similarity index 100%
rename from res/values-ne-rNP/strings.xml
rename to res/values-ne/strings.xml
diff --git a/res/values-pa-rIN/config.xml b/res/values-pa/config.xml
similarity index 100%
rename from res/values-pa-rIN/config.xml
rename to res/values-pa/config.xml
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa/strings.xml
similarity index 100%
rename from res/values-pa-rIN/strings.xml
rename to res/values-pa/strings.xml
diff --git a/res/values-si-rLK/config.xml b/res/values-si/config.xml
similarity index 100%
rename from res/values-si-rLK/config.xml
rename to res/values-si/config.xml
diff --git a/res/values-si-rLK/strings.xml b/res/values-si/strings.xml
similarity index 100%
rename from res/values-si-rLK/strings.xml
rename to res/values-si/strings.xml
diff --git a/res/values-sq-rAL/config.xml b/res/values-sq/config.xml
similarity index 100%
rename from res/values-sq-rAL/config.xml
rename to res/values-sq/config.xml
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq/strings.xml
similarity index 100%
rename from res/values-sq-rAL/strings.xml
rename to res/values-sq/strings.xml
diff --git a/res/values-ta-rIN/config.xml b/res/values-ta/config.xml
similarity index 100%
rename from res/values-ta-rIN/config.xml
rename to res/values-ta/config.xml
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta/strings.xml
similarity index 100%
rename from res/values-ta-rIN/strings.xml
rename to res/values-ta/strings.xml
diff --git a/res/values-te-rIN/config.xml b/res/values-te/config.xml
similarity index 100%
rename from res/values-te-rIN/config.xml
rename to res/values-te/config.xml
diff --git a/res/values-te-rIN/strings.xml b/res/values-te/strings.xml
similarity index 100%
rename from res/values-te-rIN/strings.xml
rename to res/values-te/strings.xml
diff --git a/res/values-ur-rPK/config.xml b/res/values-ur/config.xml
similarity index 100%
rename from res/values-ur-rPK/config.xml
rename to res/values-ur/config.xml
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur/strings.xml
similarity index 100%
rename from res/values-ur-rPK/strings.xml
rename to res/values-ur/strings.xml
diff --git a/res/values-uz-rUZ/config.xml b/res/values-uz/config.xml
similarity index 100%
rename from res/values-uz-rUZ/config.xml
rename to res/values-uz/config.xml
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz/strings.xml
similarity index 100%
rename from res/values-uz-rUZ/strings.xml
rename to res/values-uz/strings.xml
diff --git a/res/values/config.xml b/res/values/config.xml
index 23c08b8..6148e5e 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -7,11 +7,4 @@
         <item>310120</item>
         <item>311480</item>
     </string-array>
-
-    <!-- Specify a service to bind to that returns an implementation of the
-         IApnSourceService interface.
-         (e.g. com.foo/.Bar for the package com.foo and class com.foo.Bar)
-         If this value is empty or unparsable, we will apply APNs from the APN
-         conf xml file.  -->
-    <string name="apn_source_service" translatable="false"></string>
 </resources>
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 597d880..65ec7fd 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -17,13 +17,10 @@
 
 package com.android.providers.telephony;
 
-import android.content.ComponentName;
 import android.content.ContentProvider;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.UriMatcher;
 import android.content.pm.PackageManager;
@@ -39,8 +36,6 @@
 import android.os.Binder;
 import android.os.Environment;
 import android.os.FileUtils;
-import android.os.IBinder;
-import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.telephony.ServiceState;
@@ -53,9 +48,7 @@
 import android.util.Xml;
 
 import com.android.internal.util.XmlUtils;
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.IApnSourceService;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -77,7 +70,7 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false; // STOPSHIP if true
 
-    private static final int DATABASE_VERSION = 18 << 16;
+    private static final int DATABASE_VERSION = 19 << 16;
     private static final int URL_UNKNOWN = 0;
     private static final int URL_TELEPHONY = 1;
     private static final int URL_CURRENT = 2;
@@ -141,12 +134,6 @@
     private static final int INVALID_APN_ID = -1;
     private static final List<String> CARRIERS_UNIQUE_FIELDS = new ArrayList<String>();
 
-    private static Boolean s_apnSourceServiceExists;
-
-    protected final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private IApnSourceService mIApnSourceService;
-
     static {
         // Columns not included in UNIQUE constraint: name, current, edited, user, server, password,
         // authtype, type, protocol, roaming_protocol, sub_id, modem_cognitive, max_conns,
@@ -165,51 +152,54 @@
         CARRIERS_UNIQUE_FIELDS.add(MVNO_TYPE);
         CARRIERS_UNIQUE_FIELDS.add(MVNO_MATCH_DATA);
         CARRIERS_UNIQUE_FIELDS.add(PROFILE_ID);
+        CARRIERS_UNIQUE_FIELDS.add(PROTOCOL);
+        CARRIERS_UNIQUE_FIELDS.add(ROAMING_PROTOCOL);
     }
 
     @VisibleForTesting
-    public static final String CREATE_CARRIERS_TABLE_STRING = "CREATE TABLE " + CARRIERS_TABLE +
-            "(_id INTEGER PRIMARY KEY," +
-            NAME + " TEXT DEFAULT ''," +
-            NUMERIC + " TEXT DEFAULT ''," +
-            MCC + " TEXT DEFAULT ''," +
-            MNC + " TEXT DEFAULT ''," +
-            APN + " TEXT DEFAULT ''," +
-            USER + " TEXT DEFAULT ''," +
-            SERVER + " TEXT DEFAULT ''," +
-            PASSWORD + " TEXT DEFAULT ''," +
-            PROXY + " TEXT DEFAULT ''," +
-            PORT + " TEXT DEFAULT ''," +
-            MMSPROXY + " TEXT DEFAULT ''," +
-            MMSPORT + " TEXT DEFAULT ''," +
-            MMSC + " TEXT DEFAULT ''," +
-            AUTH_TYPE + " INTEGER DEFAULT -1," +
-            TYPE + " TEXT DEFAULT ''," +
-            CURRENT + " INTEGER," +
-            PROTOCOL + " TEXT DEFAULT 'IP'," +
-            ROAMING_PROTOCOL + " TEXT DEFAULT 'IP'," +
-            CARRIER_ENABLED + " BOOLEAN DEFAULT 1," +
-            BEARER + " INTEGER DEFAULT 0," +
-            BEARER_BITMASK + " INTEGER DEFAULT 0," +
-            MVNO_TYPE + " TEXT DEFAULT ''," +
-            MVNO_MATCH_DATA + " TEXT DEFAULT ''," +
-            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," +
-            MTU + " INTEGER DEFAULT 0," +
-            EDITED + " INTEGER DEFAULT " + UNEDITED + "," +
-            USER_VISIBLE + " BOOLEAN DEFAULT 1," +
-            // 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,
-            // user, server, password, authtype, type, protocol, roaming_protocol, sub_id,
-            // modem_cognitive, max_conns, wait_time, max_conns_time, mtu, bearer_bitmask,
-            // user_visible
-            "UNIQUE (" + TextUtils.join(", ", CARRIERS_UNIQUE_FIELDS) + "));";
+    public static String getStringForCarrierTableCreation(String tableName) {
+        return "CREATE TABLE " + tableName +
+                "(_id INTEGER PRIMARY KEY," +
+                NAME + " TEXT DEFAULT ''," +
+                NUMERIC + " TEXT DEFAULT ''," +
+                MCC + " TEXT DEFAULT ''," +
+                MNC + " TEXT DEFAULT ''," +
+                APN + " TEXT DEFAULT ''," +
+                USER + " TEXT DEFAULT ''," +
+                SERVER + " TEXT DEFAULT ''," +
+                PASSWORD + " TEXT DEFAULT ''," +
+                PROXY + " TEXT DEFAULT ''," +
+                PORT + " TEXT DEFAULT ''," +
+                MMSPROXY + " TEXT DEFAULT ''," +
+                MMSPORT + " TEXT DEFAULT ''," +
+                MMSC + " TEXT DEFAULT ''," +
+                AUTH_TYPE + " INTEGER DEFAULT -1," +
+                TYPE + " TEXT DEFAULT ''," +
+                CURRENT + " INTEGER," +
+                PROTOCOL + " TEXT DEFAULT 'IP'," +
+                ROAMING_PROTOCOL + " TEXT DEFAULT 'IP'," +
+                CARRIER_ENABLED + " BOOLEAN DEFAULT 1," +
+                BEARER + " INTEGER DEFAULT 0," +
+                BEARER_BITMASK + " INTEGER DEFAULT 0," +
+                MVNO_TYPE + " TEXT DEFAULT ''," +
+                MVNO_MATCH_DATA + " TEXT DEFAULT ''," +
+                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," +
+                MTU + " INTEGER DEFAULT 0," +
+                EDITED + " INTEGER DEFAULT " + UNEDITED + "," +
+                USER_VISIBLE + " BOOLEAN DEFAULT 1," +
+                // 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,
+                // user, server, password, authtype, type, sub_id, modem_cognitive, max_conns,
+                // wait_time, max_conns_time, mtu, bearer_bitmask, user_visible.
+                "UNIQUE (" + TextUtils.join(", ", CARRIERS_UNIQUE_FIELDS) + "));";
+    }
 
     @VisibleForTesting
     public static final String CREATE_SIMINFO_TABLE_STRING = "CREATE TABLE " + SIMINFO_TABLE + "("
@@ -222,8 +212,7 @@
             + SubscriptionManager.CARRIER_NAME + " TEXT,"
             + SubscriptionManager.NAME_SOURCE
                 + " INTEGER DEFAULT " + SubscriptionManager.NAME_SOURCE_DEFAULT_SOURCE + ","
-            + SubscriptionManager.COLOR
-                + " INTEGER DEFAULT " + SubscriptionManager.COLOR_DEFAULT + ","
+            + SubscriptionManager.COLOR + " INTEGER DEFAULT " + SubscriptionManager.COLOR_DEFAULT + ","
             + SubscriptionManager.NUMBER + " TEXT,"
             + SubscriptionManager.DISPLAY_NUMBER_FORMAT
                 + " INTEGER NOT NULL DEFAULT " + SubscriptionManager.DISPLAY_NUMBER_DEFAULT + ","
@@ -312,13 +301,7 @@
             if (DBG) log("dbh.onCreate:+ db=" + db);
             createSimInfoTable(db);
             createCarriersTable(db, CARRIERS_TABLE);
-            // if CarrierSettings app is installed, we expect it to do the initializiation instead
-            if (apnSourceServiceExists(mContext)) {
-                log("dbh.onCreate: Skipping apply APNs from xml.");
-            } else {
-                log("dbh.onCreate: Apply apns from xml.");
-                initDatabase(db);
-            }
+            initDatabase(db);
             if (DBG) log("dbh.onCreate:- db=" + db);
         }
 
@@ -356,7 +339,7 @@
         private void createCarriersTable(SQLiteDatabase db, String tableName) {
             // Set up the database schema
             if (DBG) log("dbh.createCarriersTable: " + tableName);
-            db.execSQL(CREATE_CARRIERS_TABLE_STRING);
+            db.execSQL(getStringForCarrierTableCreation(tableName));
             if (DBG) log("dbh.createCarriersTable:-");
         }
 
@@ -760,6 +743,54 @@
                 }
                 oldVersion = 18 << 16 | 6;
             }
+            if (oldVersion < (19 << 16 | 6)) {
+                // Upgrade steps from version 18 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;
+                String[] proj = {"_id"};
+                if (VDBG) {
+                    c = db.query(CARRIERS_TABLE, proj, null, null, null, null, null);
+                    log("dbh.onUpgrade:- before upgrading total number of rows: " + c.getCount());
+                    c.close();
+                }
+
+                c = db.query(CARRIERS_TABLE, null, null, null, null, null, null);
+
+                if (VDBG) {
+                    log("dbh.onUpgrade:- starting data copy of existing rows: " +
+                            + ((c == null) ? 0 : c.getCount()));
+                }
+
+                db.execSQL("DROP TABLE IF EXISTS " + CARRIERS_TABLE_TMP);
+
+                createCarriersTable(db, CARRIERS_TABLE_TMP);
+
+                copyDataToTmpTable(db, c);
+                c.close();
+
+                db.execSQL("DROP TABLE IF EXISTS " + CARRIERS_TABLE);
+
+                db.execSQL("ALTER TABLE " + CARRIERS_TABLE_TMP + " rename to " + CARRIERS_TABLE +
+                        ";");
+
+                if (VDBG) {
+                    c = db.query(CARRIERS_TABLE, proj, null, null, null, null, null);
+                    log("dbh.onUpgrade:- after upgrading total number of rows: " + c.getCount());
+                    c.close();
+                    c = db.query(CARRIERS_TABLE, proj, IS_UNEDITED, null, null, null, null);
+                    log("dbh.onUpgrade:- after upgrading total number of rows with " + IS_UNEDITED +
+                            ": " + c.getCount());
+                    c.close();
+                    c = db.query(CARRIERS_TABLE, proj, IS_EDITED, null, null, null, null);
+                    log("dbh.onUpgrade:- after upgrading total number of rows with " + IS_EDITED +
+                            ": " + c.getCount());
+                    c.close();
+                }
+                oldVersion = 19 << 16 | 6;
+            }
             if (DBG) {
                 log("dbh.onUpgrade:- db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
             }
@@ -953,6 +984,70 @@
             db.delete(CARRIERS_TABLE, where, whereArgs);
         }
 
+        private void copyDataToTmpTable(SQLiteDatabase db, Cursor c) {
+            // Move entries from CARRIERS_TABLE to CARRIERS_TABLE_TMP
+            if (c != null) {
+                while (c.moveToNext()) {
+                    ContentValues cv = new ContentValues();
+                    copyApnValuesV17(cv, c);
+                    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);
+                    }
+                }
+            }
+        }
+
+        private void copyApnValuesV17(ContentValues cv, Cursor c) {
+            // Include only non-null values in cv so that null values can be replaced
+            // with default if there's a default value for the field
+
+            // 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_COGNITIVE);
+            getIntValueFromCursor(cv, c, MAX_CONNS);
+            getIntValueFromCursor(cv, c, WAIT_TIME);
+            getIntValueFromCursor(cv, c, MAX_CONNS_TIME);
+            getIntValueFromCursor(cv, c, MTU);
+            getIntValueFromCursor(cv, c, BEARER_BITMASK);
+            getIntValueFromCursor(cv, c, EDITED);
+            getIntValueFromCursor(cv, c, USER_VISIBLE);
+        }
+
+
         private void copyPreservedApnsToNewTable(SQLiteDatabase db, Cursor c) {
             // Move entries from CARRIERS_TABLE to CARRIERS_TABLE_TMP
             if (c != null) {
@@ -961,43 +1056,10 @@
                 while (c.moveToNext()) {
                     ContentValues cv = new ContentValues();
                     String val;
-
-                    // Include only non-null values in cv so that null values can be replaced
-                    // with default if there's a default value for the field
-
-                    // 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_COGNITIVE);
-                    getIntValueFromCursor(cv, c, MAX_CONNS);
-                    getIntValueFromCursor(cv, c, WAIT_TIME);
-                    getIntValueFromCursor(cv, c, MAX_CONNS_TIME);
-                    getIntValueFromCursor(cv, c, MTU);
-
+                    // 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)) {
@@ -1064,19 +1126,25 @@
         }
 
         private void getStringValueFromCursor(ContentValues cv, Cursor c, String key) {
-            String fromCursor = c.getString(c.getColumnIndex(key));
-            if (!TextUtils.isEmpty(fromCursor)) {
-                cv.put(key, fromCursor);
+            int columnIndex = c.getColumnIndex(key);
+            if (columnIndex != -1) {
+                String fromCursor = c.getString(columnIndex);
+                if (!TextUtils.isEmpty(fromCursor)) {
+                    cv.put(key, fromCursor);
+                }
             }
         }
 
         private void getIntValueFromCursor(ContentValues cv, Cursor c, String key) {
-            String fromCursor = c.getString(c.getColumnIndex(key));
-            if (!TextUtils.isEmpty(fromCursor)) {
-                try {
-                    cv.put(key, new Integer(fromCursor));
-                } catch (NumberFormatException nfe) {
-                    // do nothing
+            int columnIndex = c.getColumnIndex(key);
+            if (columnIndex != -1) {
+                String fromCursor = c.getString(columnIndex);
+                if (!TextUtils.isEmpty(fromCursor)) {
+                    try {
+                        cv.put(key, new Integer(fromCursor));
+                    } catch (NumberFormatException nfe) {
+                        // do nothing
+                    }
                 }
             }
         }
@@ -1511,137 +1579,49 @@
         return mOpenHelper.apnDbUpdateNeeded();
     }
 
-    private static boolean apnSourceServiceExists(Context context) {
-        if (s_apnSourceServiceExists != null) {
-            return s_apnSourceServiceExists;
-        }
-        try {
-            String service = context.getResources().getString(R.string.apn_source_service);
-            if (TextUtils.isEmpty(service)) {
-                s_apnSourceServiceExists = false;
-            } else {
-                s_apnSourceServiceExists = context.getPackageManager().getServiceInfo(
-                        ComponentName.unflattenFromString(service), 0)
-                        != null;
-            }
-        } catch (PackageManager.NameNotFoundException e) {
-            s_apnSourceServiceExists = false;
-        }
-        return s_apnSourceServiceExists;
-    }
-
-    private void restoreApnsWithService() {
-        Context context = getContext();
-        Resources r = context.getResources();
-        ServiceConnection connection = new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName className,
-                    IBinder service) {
-                log("restoreApnsWithService: onServiceConnected");
-                synchronized (mLock) {
-                    mIApnSourceService = IApnSourceService.Stub.asInterface(service);
-                    mLock.notifyAll();
-                }
-            }
-
-            @Override
-            public void onServiceDisconnected(ComponentName arg0) {
-                loge("mIApnSourceService has disconnected unexpectedly");
-                synchronized (mLock) {
-                    mIApnSourceService = null;
-                }
-            }
-        };
-
-        Intent intent = new Intent(IApnSourceService.class.getName());
-        intent.setComponent(ComponentName.unflattenFromString(
-                r.getString(R.string.apn_source_service)));
-        log("binding to service to restore apns, intent=" + intent);
-        try {
-            // When the api is available, instead of startService we should use:
-            // context.startForegroundService(intent);
-            context.startService(intent);
-            if (context.bindService(intent, connection, Context.BIND_IMPORTANT)) {
-                synchronized (mLock) {
-                    while (mIApnSourceService == null) {
-                        try {
-                            mLock.wait();
-                        } catch (InterruptedException e) {
-                            loge("Error while waiting for service connection: " + e);
-                        }
-                    }
-                    try {
-                        ContentValues[] values = mIApnSourceService.getApns();
-                        if (values != null) {
-                            // we use the unsynchronized insert because this function is called
-                            // within the syncrhonized function delete()
-                            unsynchronizedBulkInsert(CONTENT_URI, values);
-                            log("restoreApnsWithService: restored");
-                        }
-                    } catch (RemoteException e) {
-                        loge("Error applying apns from service: " + e);
-                    }
-                }
-            } else {
-                loge("unable to bind to service from intent=" + intent);
-            }
-        } catch (SecurityException e) {
-            loge("Error applying apns from service: " + e);
-        } finally {
-            if (connection != null) {
-                context.unbindService(connection);
-            }
-            synchronized (mLock) {
-                mIApnSourceService = null;
-            }
-        }
-    }
-
 
     @Override
     public boolean onCreate() {
         mOpenHelper = new DatabaseHelper(getContext());
 
-        if (!apnSourceServiceExists(getContext())) {
-            // Call getReadableDatabase() to make sure onUpgrade is called
-            if (VDBG) log("onCreate: calling getReadableDatabase to trigger onUpgrade");
-            SQLiteDatabase db = getReadableDatabase();
+        // Call getReadableDatabase() to make sure onUpgrade is called
+        if (VDBG) log("onCreate: calling getReadableDatabase to trigger onUpgrade");
+        SQLiteDatabase db = getReadableDatabase();
 
-            // Update APN db on build update
-            String newBuildId = SystemProperties.get("ro.build.id", null);
-            if (!TextUtils.isEmpty(newBuildId)) {
-                // Check if build id has changed
-                SharedPreferences sp = getContext().getSharedPreferences(BUILD_ID_FILE,
-                        Context.MODE_PRIVATE);
-                String oldBuildId = sp.getString(RO_BUILD_ID, "");
-                if (!newBuildId.equals(oldBuildId)) {
-                    if (DBG) log("onCreate: build id changed from " + oldBuildId + " to " +
-                            newBuildId);
+        // Update APN db on build update
+        String newBuildId = SystemProperties.get("ro.build.id", null);
+        if (!TextUtils.isEmpty(newBuildId)) {
+            // Check if build id has changed
+            SharedPreferences sp = getContext().getSharedPreferences(BUILD_ID_FILE,
+                    Context.MODE_PRIVATE);
+            String oldBuildId = sp.getString(RO_BUILD_ID, "");
+            if (!newBuildId.equals(oldBuildId)) {
+                if (DBG) log("onCreate: build id changed from " + oldBuildId + " to " +
+                        newBuildId);
 
-                    // Get rid of old preferred apn shared preferences
-                    SubscriptionManager sm = SubscriptionManager.from(getContext());
-                    if (sm != null) {
-                        List<SubscriptionInfo> subInfoList = sm.getAllSubscriptionInfoList();
-                        for (SubscriptionInfo subInfo : subInfoList) {
-                            SharedPreferences spPrefFile = getContext().getSharedPreferences(
-                                    PREF_FILE_APN + subInfo.getSubscriptionId(), Context.MODE_PRIVATE);
-                            if (spPrefFile != null) {
-                                SharedPreferences.Editor editor = spPrefFile.edit();
-                                editor.clear();
-                                editor.apply();
-                            }
+                // Get rid of old preferred apn shared preferences
+                SubscriptionManager sm = SubscriptionManager.from(getContext());
+                if (sm != null) {
+                    List<SubscriptionInfo> subInfoList = sm.getAllSubscriptionInfoList();
+                    for (SubscriptionInfo subInfo : subInfoList) {
+                        SharedPreferences spPrefFile = getContext().getSharedPreferences(
+                                PREF_FILE_APN + subInfo.getSubscriptionId(), Context.MODE_PRIVATE);
+                        if (spPrefFile != null) {
+                            SharedPreferences.Editor editor = spPrefFile.edit();
+                            editor.clear();
+                            editor.apply();
                         }
                     }
-
-                    // Update APN DB
-                    updateApnDb();
-                } else {
-                    if (VDBG) log("onCreate: build id did not change: " + oldBuildId);
                 }
-                sp.edit().putString(RO_BUILD_ID, newBuildId).apply();
+
+                // Update APN DB
+                updateApnDb();
             } else {
-                if (VDBG) log("onCreate: newBuildId is empty");
+                if (VDBG) log("onCreate: build id did not change: " + oldBuildId);
             }
+            sp.edit().putString(RO_BUILD_ID, newBuildId).apply();
+        } else {
+            if (VDBG) log("onCreate: newBuildId is empty");
         }
 
         if (VDBG) log("onCreate:- ret true");
@@ -1927,19 +1907,8 @@
         }
     }
 
-    /**
-     * Insert an array of ContentValues and call notifyChange at the end.
-     */
     @Override
     public synchronized int bulkInsert(Uri url, ContentValues[] values) {
-        return unsynchronizedBulkInsert(url, values);
-    }
-
-    /**
-     * Do a bulk insert while inside a synchronized function. This is typically not safe and should
-     * only be done when you are sure there will be no conflict.
-     */
-    private int unsynchronizedBulkInsert(Uri url, ContentValues[] values) {
         int count = 0;
         boolean notify = false;
         for (ContentValues value : values) {
@@ -2416,21 +2385,25 @@
         } catch (SQLException e) {
             loge("got exception when deleting to restore: " + e);
         }
-        setPreferredApnId((long) INVALID_APN_ID, subId);
 
-        if (apnSourceServiceExists(getContext())) {
-            restoreApnsWithService();
-        } else {
-            initDatabaseWithDatabaseHelper(db);
-        }
+        // delete preferred apn ids and preferred apns (both stored in diff SharedPref) for all
+        // subIds
+        SharedPreferences spApnId = getContext().getSharedPreferences(PREF_FILE_APN,
+                Context.MODE_PRIVATE);
+        SharedPreferences.Editor editorApnId = spApnId.edit();
+        editorApnId.clear();
+        editorApnId.apply();
+
+        SharedPreferences spApn = getContext().getSharedPreferences(PREF_FILE_FULL_APN,
+                Context.MODE_PRIVATE);
+        SharedPreferences.Editor editorApn = spApn.edit();
+        editorApn.clear();
+        editorApn.apply();
+
+        initDatabaseWithDatabaseHelper(db);
     }
 
     private synchronized void updateApnDb() {
-        if (apnSourceServiceExists(getContext())) {
-            loge("called updateApnDb when apn source service exists");
-            return;
-        }
-
         if (!needApnDbUpdate()) {
             log("Skipping apn db update since apn-conf has not changed.");
             return;
diff --git a/tests/Android.mk b/tests/Android.mk
index 89136f3..ffd2e39 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -13,6 +13,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 
 LOCAL_PACKAGE_NAME := TelephonyProviderTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
 
 LOCAL_INSTRUMENTATION_FOR := TelephonyProvider
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
new file mode 100644
index 0000000..2a691a7
--- /dev/null
+++ b/tests/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<configuration description="Run Tests for TelephonyProvider.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="TelephonyProviderTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <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" />
+    </test>
+</configuration>
diff --git a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
index 4866dbd..a5dcff7 100644
--- a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
@@ -545,18 +545,18 @@
         mSmsTable.addAll(Arrays.asList(mSmsRows));
         mMmsTable.addAll(Arrays.asList(mMmsRows));
 
-        FullBackupDataOutput fullBackupDataOutput = new FullBackupDataOutput();
+        FullBackupDataOutput fullBackupDataOutput = new FullBackupDataOutput(Long.MAX_VALUE);
         mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
         assertEquals(backupSize, fullBackupDataOutput.getSize());
 
         mTelephonyBackupAgent.onQuotaExceeded(backupSize, backupSize - 100);
-        fullBackupDataOutput = new FullBackupDataOutput();
+        fullBackupDataOutput = new FullBackupDataOutput(Long.MAX_VALUE);
         mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
         assertEquals(backupSizeAfterFirstQuotaHit, fullBackupDataOutput.getSize());
 
         mTelephonyBackupAgent.onQuotaExceeded(backupSizeAfterFirstQuotaHit,
                 backupSizeAfterFirstQuotaHit - 200);
-        fullBackupDataOutput = new FullBackupDataOutput();
+        fullBackupDataOutput = new FullBackupDataOutput(Long.MAX_VALUE);
         mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
         assertEquals(backupSizeAfterSecondQuotaHit, fullBackupDataOutput.getSize());
     }
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java b/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java
index b736545..c3924c3 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTestable.java
@@ -89,7 +89,7 @@
         public void onCreate(SQLiteDatabase db) {
             // Set up the carriers table
             Log.d(TAG, "InMemoryTelephonyProviderDbHelper onCreate creating the carriers table");
-            db.execSQL(CREATE_CARRIERS_TABLE_STRING);
+            db.execSQL(getStringForCarrierTableCreation("carriers"));
 
             // set up the siminfo table
             Log.d(TAG, "InMemoryTelephonyProviderDbHelper onCreate creating the siminfo table");