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 cef4fdb..b029f73 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -59,13 +59,10 @@
 import static android.provider.Telephony.Carriers.WAIT_TIME;
 import static android.provider.Telephony.Carriers._ID;
 
-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;
@@ -81,8 +78,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;
@@ -94,9 +89,7 @@
 import android.util.Pair;
 import android.util.Xml;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.IApnSourceService;
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -184,12 +177,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,
@@ -361,13 +348,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);
         }
 
@@ -1662,135 +1643,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 {
-            context.startForegroundService(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");
@@ -2076,19 +1971,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) {
@@ -2588,19 +2472,10 @@
         editorApn.clear();
         editorApn.apply();
 
-        if (apnSourceServiceExists(getContext())) {
-            restoreApnsWithService();
-        } else {
-            initDatabaseWithDatabaseHelper(db);
-        }
+        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;
