diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3b95bce..dbd5436 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -107,12 +107,6 @@
                   android:multiprocess="false"
                   android:writePermission="android.permission.MODIFY_PHONE_STATE" />
 
-        <provider android:name="CellBroadcastProvider"
-                  android:authorities="cellbroadcasts_fwk"
-                  android:exported="true"
-                  android:singleUser="true"
-                  android:multiprocess="false" />
-
         <provider android:name="HbpcdLookupProvider"
                   android:authorities="hbpcd_lookup"
                   android:exported="true"
@@ -126,12 +120,6 @@
                   android:singleUser="true"
                   android:multiprocess="false" />
 
-        <provider android:name="RcsProvider"
-                  android:authorities="rcs"
-                  android:multiprocess="false"
-                  android:exported="false"
-                  android:singleUser="true" />
-
         <service
             android:name=".TelephonyBackupAgent$DeferredSmsMmsRestoreService"
             android:exported="false" />
diff --git a/OWNERS b/OWNERS
index 92458db..bce6270 100644
--- a/OWNERS
+++ b/OWNERS
@@ -10,3 +10,4 @@
 tgunn@google.com
 breadley@google.com
 nazaninb@google.com
+sarahchin@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..d287f23
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsTelephonyProviderTestCases"
+    },
+    {
+      "name": "TeleServiceTests",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    }
+  ]
+}
diff --git a/assets/carrier_list.pb b/assets/carrier_list.pb
index 3519d2c..c23d371 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 b1c6825..8439b87 100644
--- a/assets/carrier_list.textpb
+++ b/assets/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk28_carrier_id/carrier_list.pb b/assets/sdk28_carrier_id/carrier_list.pb
index 856c5bc..700eb89 100644
--- a/assets/sdk28_carrier_id/carrier_list.pb
+++ b/assets/sdk28_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk28_carrier_id/carrier_list.textpb b/assets/sdk28_carrier_id/carrier_list.textpb
index 23196a5..619d989 100644
--- a/assets/sdk28_carrier_id/carrier_list.textpb
+++ b/assets/sdk28_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk29_carrier_id/carrier_list.pb b/assets/sdk29_carrier_id/carrier_list.pb
new file mode 100644
index 0000000..3519d2c
--- /dev/null
+++ b/assets/sdk29_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk29_carrier_id/carrier_list.textpb b/assets/sdk29_carrier_id/carrier_list.textpb
new file mode 100644
index 0000000..b1c6825
--- /dev/null
+++ b/assets/sdk29_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f3baf24..6cfcdfb 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -17,5 +17,5 @@
 <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">"Configuration du réseau mobile"</string>
-    <string name="app_label" product="default" msgid="8338087656149558019">"Téléphone et stockage des messages"</string>
+    <string name="app_label" product="default" msgid="8338087656149558019">"Stockage tél. et SMS/MMS"</string>
 </resources>
diff --git a/src/com/android/providers/telephony/CellBroadcastProvider.java b/src/com/android/providers/telephony/CellBroadcastProvider.java
deleted file mode 100644
index 4c8a7e2..0000000
--- a/src/com/android/providers/telephony/CellBroadcastProvider.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2019 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.app.AppOpsManager;
-import android.content.ContentProvider;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.UriMatcher;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Process;
-import android.provider.Telephony.CellBroadcasts;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Arrays;
-
-/**
- * The content provider that provides access of cell broadcast message to application.
- * Permission {@link android.permission.READ_CELL_BROADCASTS} is required for querying the cell
- * broadcast message. Only phone process has the permission to write/update the database via this
- * provider.
- */
-public class CellBroadcastProvider extends ContentProvider {
-    /** Interface for read/write permission check. */
-    public interface PermissionChecker {
-        /** Return {@code True} if the caller has the permission to write/update the database. */
-        boolean hasWritePermission();
-
-        /** Return {@code True} if the caller has the permission to query the database. */
-        boolean hasReadPermission();
-    }
-
-    private static final String TAG = CellBroadcastProvider.class.getSimpleName();
-
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /** Database name. */
-    private static final String DATABASE_NAME = "cellbroadcasts.db";
-
-    /** Database version. */
-    private static final int DATABASE_VERSION = 1;
-
-    /** URI matcher for ContentProvider queries. */
-    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
-    /** URI matcher type to get all cell broadcasts. */
-    private static final int ALL = 0;
-
-    /** MIME type for the list of all cell broadcasts. */
-    private static final String LIST_TYPE = "vnd.android.cursor.dir/cellbroadcast";
-
-    /** Table name of cell broadcast message. */
-    @VisibleForTesting
-    public static final String CELL_BROADCASTS_TABLE_NAME = "cell_broadcasts";
-
-    /** Authority string for content URIs. */
-    @VisibleForTesting
-    public static final String AUTHORITY = "cellbroadcasts_fwk";
-
-    /** Content uri of this provider. */
-    public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts_fwk");
-
-    @VisibleForTesting
-    public PermissionChecker mPermissionChecker;
-
-    /** The database helper for this content provider. */
-    @VisibleForTesting
-    public SQLiteOpenHelper mDbHelper;
-
-    static {
-        sUriMatcher.addURI(AUTHORITY, null, ALL);
-    }
-
-    public CellBroadcastProvider() {}
-
-    @VisibleForTesting
-    public CellBroadcastProvider(PermissionChecker permissionChecker) {
-        mPermissionChecker = permissionChecker;
-    }
-
-    @Override
-    public boolean onCreate() {
-        mDbHelper = new CellBroadcastDatabaseHelper(getContext());
-        mPermissionChecker = new CellBroadcastPermissionChecker();
-        setAppOps(AppOpsManager.OP_READ_CELL_BROADCASTS, AppOpsManager.OP_NONE);
-        return true;
-    }
-
-    /**
-     * Return the MIME type of the data at the specified URI.
-     *
-     * @param uri the URI to query.
-     * @return a MIME type string, or null if there is no type.
-     */
-    @Override
-    public String getType(Uri uri) {
-        int match = sUriMatcher.match(uri);
-        switch (match) {
-            case ALL:
-                return LIST_TYPE;
-            default:
-                return null;
-        }
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        checkReadPermission();
-
-        if (DBG) {
-            Log.d(TAG, "query:"
-                    + " uri = " + uri
-                    + " projection = " + Arrays.toString(projection)
-                    + " selection = " + selection
-                    + " selectionArgs = " + Arrays.toString(selectionArgs)
-                    + " sortOrder = " + sortOrder);
-        }
-
-        String orderBy;
-        if (!TextUtils.isEmpty(sortOrder)) {
-            orderBy = sortOrder;
-        } else {
-            orderBy = CellBroadcasts.RECEIVED_TIME + " DESC";
-        }
-
-        int match = sUriMatcher.match(uri);
-        switch (match) {
-            case ALL:
-                return getReadableDatabase().query(
-                        CELL_BROADCASTS_TABLE_NAME, projection, selection, selectionArgs,
-                        null /* groupBy */, null /* having */, orderBy);
-            default:
-                throw new IllegalArgumentException(
-                        "Query method doesn't support this uri = " + uri);
-        }
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        checkWritePermission();
-
-        if (DBG) {
-            Log.d(TAG, "insert:"
-                    + " uri = " + uri
-                    + " contentValue = " + values);
-        }
-
-        switch (sUriMatcher.match(uri)) {
-            case ALL:
-                long row = getWritableDatabase().insertOrThrow(CELL_BROADCASTS_TABLE_NAME, null,
-                        values);
-                if (row > 0) {
-                    Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row);
-                    getContext().getContentResolver()
-                            .notifyChange(CONTENT_URI, null /* observer */);
-                    return newUri;
-                } else {
-                    Log.e(TAG, "Insert record failed because of unknown reason, uri = " + uri);
-                    return null;
-                }
-            default:
-                throw new IllegalArgumentException(
-                        "Insert method doesn't support this uri = " + uri);
-        }
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        checkWritePermission();
-
-        if (DBG) {
-            Log.d(TAG, "delete:"
-                    + " uri = " + uri
-                    + " selection = " + selection
-                    + " selectionArgs = " + Arrays.toString(selectionArgs));
-        }
-
-        switch (sUriMatcher.match(uri)) {
-            case ALL:
-                return getWritableDatabase().delete(CELL_BROADCASTS_TABLE_NAME,
-                        selection, selectionArgs);
-            default:
-                throw new IllegalArgumentException(
-                        "Delete method doesn't support this uri = " + uri);
-        }
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        checkWritePermission();
-
-        if (DBG) {
-            Log.d(TAG, "update:"
-                    + " uri = " + uri
-                    + " values = {" + values + "}"
-                    + " selection = " + selection
-                    + " selectionArgs = " + Arrays.toString(selectionArgs));
-        }
-
-        switch (sUriMatcher.match(uri)) {
-            case ALL:
-                int rowCount = getWritableDatabase().update(
-                        CELL_BROADCASTS_TABLE_NAME,
-                        values,
-                        selection,
-                        selectionArgs);
-                if (rowCount > 0) {
-                    getContext().getContentResolver().notifyChange(uri, null /* observer */);
-                }
-                return rowCount;
-            default:
-                throw new IllegalArgumentException(
-                        "Update method doesn't support this uri = " + uri);
-        }
-    }
-
-    @VisibleForTesting
-    public static String getStringForCellBroadcastTableCreation(String tableName) {
-        return "CREATE TABLE " + tableName + " ("
-                + CellBroadcasts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
-                + CellBroadcasts.SUB_ID + " INTEGER,"
-                + CellBroadcasts.GEOGRAPHICAL_SCOPE + " INTEGER,"
-                + CellBroadcasts.PLMN + " TEXT,"
-                + CellBroadcasts.LAC + " INTEGER,"
-                + CellBroadcasts.CID + " INTEGER,"
-                + CellBroadcasts.SERIAL_NUMBER + " INTEGER,"
-                + CellBroadcasts.SERVICE_CATEGORY + " INTEGER,"
-                + CellBroadcasts.LANGUAGE_CODE + " TEXT,"
-                + CellBroadcasts.MESSAGE_BODY + " TEXT,"
-                + CellBroadcasts.MESSAGE_FORMAT + " INTEGER,"
-                + CellBroadcasts.MESSAGE_PRIORITY + " INTEGER,"
-                + CellBroadcasts.ETWS_WARNING_TYPE + " INTEGER,"
-                + CellBroadcasts.CMAS_MESSAGE_CLASS + " INTEGER,"
-                + CellBroadcasts.CMAS_CATEGORY + " INTEGER,"
-                + CellBroadcasts.CMAS_RESPONSE_TYPE + " INTEGER,"
-                + CellBroadcasts.CMAS_SEVERITY + " INTEGER,"
-                + CellBroadcasts.CMAS_URGENCY + " INTEGER,"
-                + CellBroadcasts.CMAS_CERTAINTY + " INTEGER,"
-                + CellBroadcasts.RECEIVED_TIME + " BIGINT,"
-                + CellBroadcasts.MESSAGE_BROADCASTED + " BOOLEAN DEFAULT 0,"
-                + CellBroadcasts.GEOMETRIES + " TEXT,"
-                + CellBroadcasts.MAXIMUM_WAIT_TIME + " INTEGER);";
-    }
-
-    private SQLiteDatabase getWritableDatabase() {
-        return mDbHelper.getWritableDatabase();
-    }
-
-    private SQLiteDatabase getReadableDatabase() {
-        return mDbHelper.getReadableDatabase();
-    }
-
-    private void checkWritePermission() {
-        if (!mPermissionChecker.hasWritePermission()) {
-            throw new SecurityException(
-                    "No permission to write CellBroadcast provider");
-        }
-    }
-
-    private void checkReadPermission() {
-        if (!mPermissionChecker.hasReadPermission()) {
-            throw new SecurityException(
-                    "No permission to read CellBroadcast provider");
-        }
-    }
-
-    private class CellBroadcastDatabaseHelper extends SQLiteOpenHelper {
-        CellBroadcastDatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null /* factory */, DATABASE_VERSION);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL(getStringForCellBroadcastTableCreation(CELL_BROADCASTS_TABLE_NAME));
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
-    }
-
-    private class CellBroadcastPermissionChecker implements PermissionChecker {
-        @Override
-        public boolean hasWritePermission() {
-            // Only the phone process has the write permission to modify this provider. 
-            return Binder.getCallingUid() == Process.PHONE_UID;
-        }
-
-        @Override
-        public boolean hasReadPermission() {
-            // Only the phone process has the read permission to query data from this provider. 
-            return Binder.getCallingUid() == Process.PHONE_UID;
-        }
-    }
-}
diff --git a/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java b/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
index 0149687..056738f 100644
--- a/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
+++ b/src/com/android/providers/telephony/HbpcdLookupDatabaseHelper.java
@@ -65,7 +65,6 @@
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.util.Log;
 import android.util.Xml;
-import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -79,6 +78,7 @@
 import com.android.internal.telephony.HbpcdLookup.MccSidRange;
 import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch;
 import com.android.internal.telephony.HbpcdLookup.NanpAreaCode;
+import com.android.internal.util.XmlUtils;
 
 public class HbpcdLookupDatabaseHelper extends SQLiteOpenHelper {
     private static final String TAG = "HbpcdLockupDatabaseHelper";
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
index 7ecfc46..d5aa308 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -17,6 +17,7 @@
 package com.android.providers.telephony;
 
 import static android.provider.Telephony.RcsColumns.IS_RCS_TABLE_SCHEMA_CODE_COMPLETE;
+import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
 
 import android.content.BroadcastReceiver;
 import android.content.ContentValues;
@@ -49,7 +50,6 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.PhoneFactory;
 import com.google.android.mms.pdu.EncodedStringValue;
 import com.google.android.mms.pdu.PduHeaders;
 
@@ -294,11 +294,6 @@
         // Memory optimization - close idle connections after 30s of inactivity
         setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
         setWriteAheadLoggingEnabled(false);
-        try {
-            PhoneFactory.addLocalLog(TAG, 100);
-        } catch (IllegalArgumentException e) {
-            // ignore
-        }
     }
 
     private static synchronized MmsSmsDatabaseErrorHandler getDbErrorHandler(Context context) {
@@ -550,14 +545,6 @@
         createMmsTables(db);
         createSmsTables(db);
         createCommonTables(db);
-
-        if (IS_RCS_TABLE_SCHEMA_CODE_COMPLETE) {
-            RcsProviderThreadHelper.createThreadTables(db);
-            RcsProviderParticipantHelper.createParticipantTables(db);
-            RcsProviderMessageHelper.createRcsMessageTables(db);
-            RcsProviderEventHelper.createRcsEventTables(db);
-        }
-
         createCommonTriggers(db);
         createMmsTriggers(db);
         createWordsTables(db);
@@ -566,12 +553,10 @@
 
     private static void localLog(String logMsg) {
         Log.d(TAG, logMsg);
-        PhoneFactory.localLog(TAG, logMsg);
     }
 
     private static void localLogWtf(String logMsg) {
         Slog.wtf(TAG, logMsg);
-        PhoneFactory.localLog(TAG, logMsg);
     }
 
     private boolean isInitialCreateDone() {
@@ -1012,7 +997,7 @@
             "service_center TEXT," +
             "locked INTEGER DEFAULT 0," +
             "sub_id INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " +
-            "error_code INTEGER DEFAULT 0," +
+            "error_code INTEGER DEFAULT " + NO_ERROR_CODE + ", " +
             "creator TEXT," +
             "seen INTEGER DEFAULT 0" +
             ");";
@@ -1665,15 +1650,6 @@
                 db.endTransaction();
             }
             // fall through
-        case 67:
-            if (currentVersion <= 67 || !IS_RCS_TABLE_SCHEMA_CODE_COMPLETE) {
-                return;
-            }
-            RcsProviderThreadHelper.createThreadTables(db);
-            RcsProviderParticipantHelper.createParticipantTables(db);
-            RcsProviderMessageHelper.createRcsMessageTables(db);
-            RcsProviderEventHelper.createRcsEventTables(db);
-            return;
         }
 
         Log.e(TAG, "Destroying all old data.");
@@ -1816,7 +1792,7 @@
 
     private void upgradeDatabaseToVersion48(SQLiteDatabase db) {
         // Add 'error_code' column to sms table.
-        db.execSQL("ALTER TABLE sms ADD COLUMN error_code INTEGER DEFAULT 0");
+        db.execSQL("ALTER TABLE sms ADD COLUMN error_code INTEGER DEFAULT " + NO_ERROR_CODE);
     }
 
     private void upgradeDatabaseToVersion51(SQLiteDatabase db) {
diff --git a/src/com/android/providers/telephony/MmsSmsProvider.java b/src/com/android/providers/telephony/MmsSmsProvider.java
index 8c3555c..1170aad 100644
--- a/src/com/android/providers/telephony/MmsSmsProvider.java
+++ b/src/com/android/providers/telephony/MmsSmsProvider.java
@@ -305,6 +305,7 @@
     private SQLiteOpenHelper mOpenHelper;
 
     private boolean mUseStrictPhoneNumberComparation;
+    private int mMinMatch;
 
     private static final String METHOD_IS_RESTORING = "is_restoring";
     private static final String IS_RESTORING_KEY = "restoring";
@@ -316,6 +317,9 @@
         mUseStrictPhoneNumberComparation =
             getContext().getResources().getBoolean(
                     com.android.internal.R.bool.config_use_strict_phone_number_comparation);
+        mMinMatch =
+            getContext().getResources().getInteger(
+                    com.android.internal.R.integer.config_phonenumber_compare_min_match);
         TelephonyBackupAgent.DeferredSmsMmsRestoreService.startIfFilesExist(getContext());
         return true;
     }
@@ -542,7 +546,7 @@
             selectionArgs = new String[] { refinedAddress };
         } else {
             selection += " OR PHONE_NUMBERS_EQUAL(address, ?, " +
-                        (mUseStrictPhoneNumberComparation ? 1 : 0) + ")";
+                        (mUseStrictPhoneNumberComparation ? "1)" : "0, " + mMinMatch + ")");
             selectionArgs = new String[] { refinedAddress, refinedAddress };
         }
 
@@ -997,13 +1001,14 @@
      *   FROM pdu, (SELECT msg_id AS address_msg_id
      *              FROM addr
      *              WHERE (address='<phoneNumber>' OR
-     *              PHONE_NUMBERS_EQUAL(addr.address, '<phoneNumber>', 1/0)))
+     *              PHONE_NUMBERS_EQUAL(addr.address, '<phoneNumber>', 1/0, none/mMinMatch)))
      *             AS matching_addresses
      *   WHERE pdu._id = matching_addresses.address_msg_id
      * UNION
      * SELECT ...
      *   FROM sms
-     *   WHERE (address='<phoneNumber>' OR PHONE_NUMBERS_EQUAL(sms.address, '<phoneNumber>', 1/0));
+     *   WHERE (address='<phoneNumber>' OR
+     *          PHONE_NUMBERS_EQUAL(sms.address, '<phoneNumber>', 1/0, none/mMinMatch));
      */
     private Cursor getMessagesByPhoneNumber(
             String phoneNumber, String[] projection, String selection,
@@ -1018,7 +1023,7 @@
                         selection,
                         "(address=" + escapedPhoneNumber + " OR PHONE_NUMBERS_EQUAL(address, " +
                         escapedPhoneNumber +
-                        (mUseStrictPhoneNumberComparation ? ", 1))" : ", 0))"));
+                        (mUseStrictPhoneNumberComparation ? ", 1))" : ", 0, " + mMinMatch + "))"));
         SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
         SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
 
@@ -1030,7 +1035,7 @@
                 "FROM addr WHERE (address=" + escapedPhoneNumber +
                 " OR PHONE_NUMBERS_EQUAL(addr.address, " +
                 escapedPhoneNumber +
-                (mUseStrictPhoneNumberComparation ? ", 1))) " : ", 0))) ") +
+                (mUseStrictPhoneNumberComparation ? ", 1))) " : ", 0, " + mMinMatch + "))) ") +
                 "AS matching_addresses");
         smsQueryBuilder.setTables(smsTable);
 
diff --git a/src/com/android/providers/telephony/RcsProvider.java b/src/com/android/providers/telephony/RcsProvider.java
deleted file mode 100644
index 3235b27..0000000
--- a/src/com/android/providers/telephony/RcsProvider.java
+++ /dev/null
@@ -1,804 +0,0 @@
-/*
- * 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.RcsColumns.RcsThreadColumns.RCS_THREAD_URI_PART;
-import static android.provider.Telephony.RcsColumns.TRANSACTION_FAILED;
-
-import static com.android.providers.telephony.RcsProviderUtil.buildUriWithRowIdAppended;
-import static com.android.providers.telephony.RcsProviderUtil.returnUriAsIsIfSuccessful;
-
-import android.app.AppOpsManager;
-import android.content.ContentProvider;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Content provider to handle RCS messages. The functionality here is similar to SmsProvider,
- * MmsProvider etc.
- *
- * The provider has constraints around inserting, updating and deleting - the user needs to know
- * whether they are inserting a message that is incoming/outgoing, or the thread they are inserting
- * is a group or p2p etc. This is in order to keep the implementation simple and avoid complex
- * queries.
- *
- * @hide
- */
-public class RcsProvider extends ContentProvider {
-    static final String TAG = "RcsProvider";
-    static final String AUTHORITY = "rcs";
-    private static final String CONTENT_AUTHORITY = "content://" + AUTHORITY;
-
-    private static final Uri PARTICIPANT_URI_PREFIX =
-            Uri.parse(CONTENT_AUTHORITY + "/participant/");
-    private static final Uri P2P_THREAD_URI_PREFIX = Uri.parse(CONTENT_AUTHORITY + "/p2p_thread/");
-    private static final Uri FILE_TRANSFER_PREFIX = Uri.parse(
-            CONTENT_AUTHORITY + "/file_transfer/");
-    static final Uri GROUP_THREAD_URI_PREFIX = Uri.parse(CONTENT_AUTHORITY + "/group_thread/");
-
-    // Rcs table names
-    static final String RCS_THREAD_TABLE = "rcs_thread";
-    static final String RCS_1_TO_1_THREAD_TABLE = "rcs_1_to_1_thread";
-    static final String RCS_GROUP_THREAD_TABLE = "rcs_group_thread";
-    static final String UNIFIED_RCS_THREAD_VIEW = "rcs_unified_rcs_thread_view";
-    static final String RCS_PARTICIPANT_TABLE = "rcs_participant";
-    static final String RCS_PARTICIPANT_THREAD_JUNCTION_TABLE = "rcs_thread_participant";
-    static final String RCS_MESSAGE_TABLE = "rcs_message";
-    static final String RCS_INCOMING_MESSAGE_TABLE = "rcs_incoming_message";
-    static final String RCS_OUTGOING_MESSAGE_TABLE = "rcs_outgoing_message";
-    static final String RCS_MESSAGE_DELIVERY_TABLE = "rcs_message_delivery";
-    static final String UNIFIED_MESSAGE_VIEW = "rcs_unified_message_view";
-    static final String RCS_FILE_TRANSFER_TABLE = "rcs_file_transfer";
-    static final String RCS_THREAD_EVENT_TABLE = "rcs_thread_event";
-    static final String RCS_PARTICIPANT_EVENT_TABLE = "rcs_participant_event";
-    static final String RCS_UNIFIED_EVENT_VIEW = "rcs_unified_event_view";
-
-    private static final UriMatcher URL_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
-
-    private static final int UNIFIED_RCS_THREAD = 1;
-    private static final int UNIFIED_RCS_THREAD_WITH_ID = 2;
-    private static final int PARTICIPANT = 3;
-    private static final int PARTICIPANT_WITH_ID = 4;
-    private static final int PARTICIPANT_ALIAS_CHANGE_EVENT = 5;
-    private static final int PARTICIPANT_ALIAS_CHANGE_EVENT_WITH_ID = 6;
-    private static final int P2P_THREAD = 7;
-    private static final int P2P_THREAD_WITH_ID = 8;
-    private static final int P2P_THREAD_PARTICIPANT = 9;
-    private static final int P2P_THREAD_PARTICIPANT_WITH_ID = 10;
-    private static final int GROUP_THREAD = 11;
-    private static final int GROUP_THREAD_WITH_ID = 12;
-    private static final int GROUP_THREAD_PARTICIPANT = 13;
-    private static final int GROUP_THREAD_PARTICIPANT_WITH_ID = 14;
-    private static final int GROUP_THREAD_PARTICIPANT_JOINED_EVENT = 15;
-    private static final int GROUP_THREAD_PARTICIPANT_JOINED_EVENT_WITH_ID = 16;
-    private static final int GROUP_THREAD_PARTICIPANT_LEFT_EVENT = 17;
-    private static final int GROUP_THREAD_PARTICIPANT_LEFT_EVENT_WITH_ID = 18;
-    private static final int GROUP_THREAD_NAME_CHANGE_EVENT = 19;
-    private static final int GROUP_THREAD_NAME_CHANGE_EVENT_WITH_ID = 20;
-    private static final int GROUP_THREAD_ICON_CHANGE_EVENT = 21;
-    private static final int GROUP_THREAD_ICON_CHANGE_EVENT_WITH_ID = 22;
-    private static final int UNIFIED_MESSAGE = 23;
-    private static final int UNIFIED_MESSAGE_WITH_ID = 24;
-    private static final int UNIFIED_MESSAGE_WITH_FILE_TRANSFER = 25;
-    private static final int INCOMING_MESSAGE = 26;
-    private static final int INCOMING_MESSAGE_WITH_ID = 27;
-    private static final int OUTGOING_MESSAGE = 28;
-    private static final int OUTGOING_MESSAGE_WITH_ID = 29;
-    private static final int OUTGOING_MESSAGE_DELIVERY = 30;
-    private static final int OUTGOING_MESSAGE_DELIVERY_WITH_ID = 31;
-    private static final int UNIFIED_MESSAGE_ON_THREAD = 32;
-    private static final int UNIFIED_MESSAGE_ON_THREAD_WITH_ID = 33;
-    private static final int INCOMING_MESSAGE_ON_P2P_THREAD = 34;
-    private static final int INCOMING_MESSAGE_ON_P2P_THREAD_WITH_ID = 35;
-    private static final int OUTGOING_MESSAGE_ON_P2P_THREAD = 36;
-    private static final int OUTGOING_MESSAGE_ON_P2P_THREAD_WITH_ID = 37;
-    private static final int INCOMING_MESSAGE_ON_GROUP_THREAD = 38;
-    private static final int INCOMING_MESSAGE_ON_GROUP_THREAD_WITH_ID = 39;
-    private static final int OUTGOING_MESSAGE_ON_GROUP_THREAD = 40;
-    private static final int OUTGOING_MESSAGE_ON_GROUP_THREAD_WITH_ID = 41;
-    private static final int FILE_TRANSFER_WITH_ID = 42;
-    private static final int EVENT = 43;
-    private static final int CANONICAL_ADDRESS = 44;
-
-    SQLiteOpenHelper mDbOpenHelper;
-
-    @VisibleForTesting
-    RcsProviderThreadHelper mThreadHelper;
-    @VisibleForTesting
-    RcsProviderParticipantHelper mParticipantHelper;
-    @VisibleForTesting
-    RcsProviderMessageHelper mMessageHelper;
-    @VisibleForTesting
-    RcsProviderEventHelper mEventHelper;
-    @VisibleForTesting
-    RcsProviderCanonicalAddressHelper mCanonicalAddressHelper;
-
-    static {
-        // example URI: content://rcs/thread
-        URL_MATCHER.addURI(AUTHORITY, RCS_THREAD_URI_PART, UNIFIED_RCS_THREAD);
-
-        // example URI: content://rcs/thread/4, where 4 is the thread id.
-        URL_MATCHER.addURI(AUTHORITY, "thread/#", UNIFIED_RCS_THREAD_WITH_ID);
-
-        // example URI: content://rcs/participant
-        URL_MATCHER.addURI(AUTHORITY, "participant", PARTICIPANT);
-
-        // example URI: content://rcs/participant/12, where 12 is the participant id
-        URL_MATCHER.addURI(AUTHORITY, "participant/#", PARTICIPANT_WITH_ID);
-
-        // example URI: content://rcs/participant/12/alias_change_event, where 12 is the participant
-        // id.
-        URL_MATCHER.addURI(AUTHORITY, "participant/#/alias_change_event",
-                PARTICIPANT_ALIAS_CHANGE_EVENT);
-
-        // example URI: content://rcs/participant/12/alias_change_event/4, where 12 is the
-        // participant id, and 4 is the event id
-        URL_MATCHER.addURI(AUTHORITY, "participant/#/alias_change_event/#",
-                PARTICIPANT_ALIAS_CHANGE_EVENT_WITH_ID);
-
-        // example URI: content://rcs/p2p_thread
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread", P2P_THREAD);
-
-        // example URI: content://rcs/p2p_thread/4, where 4 is the thread id
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread/#", P2P_THREAD_WITH_ID);
-
-        // example URI: content://rcs/p2p_thread/4/participant, where 4 is the thread id
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread/#/participant", P2P_THREAD_PARTICIPANT);
-
-        // example URI: content://rcs/p2p_thread/9/participant/3", only supports a 1 time insert.
-        // 9 is the thread ID, 3 is the participant ID.
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread/#/participant/#", P2P_THREAD_PARTICIPANT_WITH_ID);
-
-        // example URI: content://rcs/group_thread
-        URL_MATCHER.addURI(AUTHORITY, "group_thread", GROUP_THREAD);
-
-        // example URI: content://rcs/group_thread/13, where 13 is the _id in rcs_threads table.
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#", GROUP_THREAD_WITH_ID);
-
-        // example URI: content://rcs/group_thread/13/participant_joined_event. Supports
-        // queries and inserts
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/participant_joined_event",
-                GROUP_THREAD_PARTICIPANT_JOINED_EVENT);
-
-        // example URI: content://rcs/group_thread/13/participant_joined_event/3. Supports deletes.
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/participant_joined_event/#",
-                GROUP_THREAD_PARTICIPANT_JOINED_EVENT_WITH_ID);
-
-        // example URI: content://rcs/group_thread/13/participant_left_event. Supports queries
-        // and inserts
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/participant_left_event",
-                GROUP_THREAD_PARTICIPANT_LEFT_EVENT);
-
-        // example URI: content://rcs/group_thread/13/participant_left_event/5. Supports deletes
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/participant_left_event/#",
-                GROUP_THREAD_PARTICIPANT_LEFT_EVENT_WITH_ID);
-
-        // example URI: content://rcs/group_thread/13/name_changed_event. Supports queries and
-        // inserts
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/name_changed_event",
-                GROUP_THREAD_NAME_CHANGE_EVENT);
-
-        // example URI: content://rcs/group_thread/13/name_changed_event/7. Supports deletes
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/name_changed_event/#",
-                GROUP_THREAD_NAME_CHANGE_EVENT_WITH_ID);
-
-        // example URI: content://rcs/group_thread/13/icon_changed_event. Supports queries and
-        // inserts
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/icon_changed_event",
-                GROUP_THREAD_ICON_CHANGE_EVENT);
-
-        // example URI: content://rcs/group_thread/13/icon_changed_event/9. Supports deletes
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/icon_changed_event/#",
-                GROUP_THREAD_ICON_CHANGE_EVENT_WITH_ID);
-
-        // example URI: content://rcs/group_thread/18/participant
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/participant",
-                GROUP_THREAD_PARTICIPANT);
-
-        // example URI: content://rcs/group_thread/21/participant/4, only supports inserts and
-        // deletes
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/participant/#",
-                GROUP_THREAD_PARTICIPANT_WITH_ID);
-
-        // example URI: content://rcs/message
-        URL_MATCHER.addURI(AUTHORITY, "message", UNIFIED_MESSAGE);
-
-        // example URI: content://rcs/message/4, where 4 is the message id.
-        URL_MATCHER.addURI(AUTHORITY, "message/#", UNIFIED_MESSAGE_WITH_ID);
-
-        // example URI: content://rcs/message/4/file_transfer, only supports inserts
-        URL_MATCHER.addURI(AUTHORITY, "message/#/file_transfer",
-                UNIFIED_MESSAGE_WITH_FILE_TRANSFER);
-
-        // example URI: content://rcs/incoming_message
-        URL_MATCHER.addURI(AUTHORITY, "incoming_message", INCOMING_MESSAGE);
-
-        // example URI: content://rcs/incoming_message/45
-        URL_MATCHER.addURI(AUTHORITY, "incoming_message/#", INCOMING_MESSAGE_WITH_ID);
-
-        // example URI: content://rcs/outgoing_message
-        URL_MATCHER.addURI(AUTHORITY, "outgoing_message", OUTGOING_MESSAGE);
-
-        // example URI: content://rcs/outgoing_message/54
-        URL_MATCHER.addURI(AUTHORITY, "outgoing_message/#", OUTGOING_MESSAGE_WITH_ID);
-
-        // example URI: content://rcs/outgoing_message/54/delivery. Only supports queries
-        URL_MATCHER.addURI(AUTHORITY, "outgoing_message/#/delivery", OUTGOING_MESSAGE_DELIVERY);
-
-        // example URI: content://rcs/outgoing_message/9/delivery/4. Does not support queries
-        URL_MATCHER.addURI(AUTHORITY, "outgoing_message/#/delivery/#",
-                OUTGOING_MESSAGE_DELIVERY_WITH_ID);
-
-        // example URI: content://rcs/thread/5/message, only supports querying.
-        URL_MATCHER.addURI(AUTHORITY, "thread/#/message", UNIFIED_MESSAGE_ON_THREAD);
-
-        // example URI: content://rcs/thread/5/message/40, only supports querying.
-        URL_MATCHER.addURI(AUTHORITY, "thread/#/message/#", UNIFIED_MESSAGE_ON_THREAD_WITH_ID);
-
-        // example URI: content://rcs/p2p_thread/3/incoming_message. Only available for inserting
-        // incoming messages onto a 1 to 1 thread.
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread/#/incoming_message",
-                INCOMING_MESSAGE_ON_P2P_THREAD);
-
-        // example URI: content://rcs/p2p_thread/11/incoming_message/45. Only supports querying
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread/#/incoming_message/#",
-                INCOMING_MESSAGE_ON_P2P_THREAD_WITH_ID);
-
-        // example URI: content://rcs/p2p_thread/3/outgoing_message. Only available for inserting
-        // outgoing messages onto a 1 to 1 thread.
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread/#/outgoing_message",
-                OUTGOING_MESSAGE_ON_P2P_THREAD);
-
-        // example URI: content://rcs/p2p_thread/11/outgoing_message/46. Only supports querying
-        URL_MATCHER.addURI(AUTHORITY, "p2p_thread/#/outgoing_message/#",
-                OUTGOING_MESSAGE_ON_P2P_THREAD_WITH_ID);
-
-        // example URI: content://rcs/group_thread/3/incoming_message. Only available for inserting
-        // incoming messages onto a group thread.
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/incoming_message",
-                INCOMING_MESSAGE_ON_GROUP_THREAD);
-
-        // example URI: content://rcs/group_thread/3/incoming_message/71. Only supports querying
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/incoming_message/#",
-                INCOMING_MESSAGE_ON_GROUP_THREAD_WITH_ID);
-
-        // example URI: content://rcs/group_thread/3/outgoing_message. Only available for inserting
-        // outgoing messages onto a group thread.
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/outgoing_message",
-                OUTGOING_MESSAGE_ON_GROUP_THREAD);
-
-        // example URI: content://rcs/group_thread/13/outgoing_message/72. Only supports querying
-        URL_MATCHER.addURI(AUTHORITY, "group_thread/#/outgoing_message/#",
-                OUTGOING_MESSAGE_ON_GROUP_THREAD_WITH_ID);
-
-        // example URI: content://rcs/file_transfer/1. Does not support insertion
-        URL_MATCHER.addURI(AUTHORITY, "file_transfer/#", FILE_TRANSFER_WITH_ID);
-
-        // example URI: content://rcs/event
-        URL_MATCHER.addURI(AUTHORITY, "event", EVENT);
-
-        URL_MATCHER.addURI(AUTHORITY, "canonical-address", CANONICAL_ADDRESS);
-    }
-
-    @Override
-    public boolean onCreate() {
-        // Use the credential encrypted mmssms.db for RCS messages.
-        mDbOpenHelper = MmsSmsDatabaseHelper.getInstanceForCe(getContext());
-        mParticipantHelper = new RcsProviderParticipantHelper(mDbOpenHelper);
-        mThreadHelper = new RcsProviderThreadHelper(mDbOpenHelper);
-        mMessageHelper = new RcsProviderMessageHelper(mDbOpenHelper);
-        mEventHelper = new RcsProviderEventHelper(mDbOpenHelper);
-        mCanonicalAddressHelper = new RcsProviderCanonicalAddressHelper(mDbOpenHelper);
-        return true;
-    }
-
-    /**
-     * ContentResolver has a weird bug that if both query methods are overridden, it will always
-     * pick the bundle one to call, but will still require us to override this one as it is
-     * abstract. Work around by putting parameters in a bundle.
-     */
-    @Override
-    public synchronized Cursor query(Uri uri, String[] projection, String selection,
-            String[] selectionArgs, String sortOrder) {
-        Bundle bundle = new Bundle();
-        bundle.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection);
-        bundle.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs);
-        bundle.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, sortOrder);
-        return query(uri, projection, bundle, null);
-    }
-
-    @Override
-    public synchronized Cursor query(Uri uri, String[] projection, Bundle queryArgs,
-            CancellationSignal unused) {
-        int match = URL_MATCHER.match(uri);
-
-        String selection = null;
-        String[] selectionArgs = null;
-        String sortOrder = null;
-
-        if (queryArgs != null) {
-            selection = queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SELECTION);
-            selectionArgs = queryArgs.getStringArray(
-                    ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS);
-            sortOrder = queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER);
-        }
-
-        switch (match) {
-            case UNIFIED_RCS_THREAD:
-                return mThreadHelper.queryUnifiedThread(queryArgs);
-            case UNIFIED_RCS_THREAD_WITH_ID:
-                return mThreadHelper.queryUnifiedThreadUsingId(uri, projection);
-            case PARTICIPANT:
-                return mParticipantHelper.queryParticipant(queryArgs);
-            case PARTICIPANT_WITH_ID:
-                return mParticipantHelper.queryParticipantWithId(uri, projection);
-            case PARTICIPANT_ALIAS_CHANGE_EVENT:
-                Log.e(TAG, "Querying individual event types is not supported, uri: " + uri);
-                break;
-            case PARTICIPANT_ALIAS_CHANGE_EVENT_WITH_ID:
-                Log.e(TAG, "Querying participant events with id's is not supported, uri: " + uri);
-                break;
-            case P2P_THREAD:
-                return mThreadHelper.query1to1Thread(projection, selection,
-                        selectionArgs, sortOrder);
-            case P2P_THREAD_WITH_ID:
-                return mThreadHelper.query1To1ThreadUsingId(uri, projection);
-            case P2P_THREAD_PARTICIPANT:
-                return mParticipantHelper.queryParticipantIn1To1Thread(uri);
-            case P2P_THREAD_PARTICIPANT_WITH_ID:
-                Log.e(TAG,
-                        "Querying participants in 1 to 1 threads via id's is not supported, uri: "
-                                + uri);
-                break;
-            case GROUP_THREAD:
-                return mThreadHelper.queryGroupThread(projection, selection,
-                        selectionArgs, sortOrder);
-            case GROUP_THREAD_WITH_ID:
-                return mThreadHelper.queryGroupThreadUsingId(uri, projection);
-            case GROUP_THREAD_PARTICIPANT:
-                return mParticipantHelper.queryParticipantsInGroupThread(uri);
-            case GROUP_THREAD_PARTICIPANT_WITH_ID:
-                return mParticipantHelper.queryParticipantInGroupThreadWithId(uri);
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT:
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT_WITH_ID:
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT:
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT_WITH_ID:
-            case GROUP_THREAD_NAME_CHANGE_EVENT:
-            case GROUP_THREAD_NAME_CHANGE_EVENT_WITH_ID:
-            case GROUP_THREAD_ICON_CHANGE_EVENT:
-            case GROUP_THREAD_ICON_CHANGE_EVENT_WITH_ID:
-                Log.e(TAG, "Querying individual event types is not supported, uri: " + uri);
-                break;
-            case UNIFIED_MESSAGE:
-                return mMessageHelper.queryMessages(queryArgs);
-            case UNIFIED_MESSAGE_WITH_ID:
-                return mMessageHelper.queryUnifiedMessageWithId(uri);
-            case UNIFIED_MESSAGE_WITH_FILE_TRANSFER:
-                Log.e(TAG,
-                        "Querying file transfers through messages is not supported, uri: " + uri);
-            case INCOMING_MESSAGE:
-                return mMessageHelper.queryIncomingMessageWithSelection(selection, selectionArgs);
-            case INCOMING_MESSAGE_WITH_ID:
-                return mMessageHelper.queryIncomingMessageWithId(uri);
-            case OUTGOING_MESSAGE:
-                return mMessageHelper.queryOutgoingMessageWithSelection(selection, selectionArgs);
-            case OUTGOING_MESSAGE_WITH_ID:
-                return mMessageHelper.queryOutgoingMessageWithId(uri);
-            case OUTGOING_MESSAGE_DELIVERY:
-                return mMessageHelper.queryOutgoingMessageDeliveries(uri);
-            case OUTGOING_MESSAGE_DELIVERY_WITH_ID:
-                Log.e(TAG,
-                        "Querying deliveries with message and participant ids is not supported, "
-                                + "uri: "
-                                + uri);
-            case UNIFIED_MESSAGE_ON_THREAD:
-                return mMessageHelper.queryAllMessagesOnThread(uri, selection, selectionArgs);
-            case UNIFIED_MESSAGE_ON_THREAD_WITH_ID:
-                return mMessageHelper.queryUnifiedMessageWithIdInThread(uri);
-            case INCOMING_MESSAGE_ON_P2P_THREAD:
-                Log.e(TAG,
-                        "Querying incoming messages on P2P thread with selection is not "
-                                + "supported, uri: "
-                                + uri);
-                break;
-            case INCOMING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-                return mMessageHelper.queryUnifiedMessageWithIdInThread(uri);
-            case OUTGOING_MESSAGE_ON_P2P_THREAD:
-                Log.e(TAG,
-                        "Querying outgoing messages on P2P thread with selection is not "
-                                + "supported, uri: "
-                                + uri);
-                break;
-            case OUTGOING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-                return mMessageHelper.queryUnifiedMessageWithIdInThread(uri);
-            case INCOMING_MESSAGE_ON_GROUP_THREAD:
-                Log.e(TAG,
-                        "Querying incoming messages on group thread with selection is not "
-                                + "supported, uri: "
-                                + uri);
-                break;
-            case INCOMING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-                return mMessageHelper.queryUnifiedMessageWithIdInThread(uri);
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD:
-                Log.e(TAG,
-                        "Querying outgoing messages on group thread with selection is not "
-                                + "supported, uri: "
-                                + uri);
-                break;
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-                return mMessageHelper.queryUnifiedMessageWithIdInThread(uri);
-            case FILE_TRANSFER_WITH_ID:
-                return mMessageHelper.queryFileTransfer(uri);
-            case EVENT:
-                return mEventHelper.queryEvents(queryArgs);
-            case CANONICAL_ADDRESS:
-                String canonicalAddress = uri.getQueryParameter("address");
-                return mCanonicalAddressHelper.getOrCreateCanonicalAddress(canonicalAddress);
-            default:
-                Log.e(TAG, "Invalid query: " + uri);
-        }
-
-        return null;
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        return null;
-    }
-
-    @Override
-    public synchronized Uri insert(Uri uri, ContentValues values) {
-        int match = URL_MATCHER.match(uri);
-        long rowId;
-
-        switch (match) {
-            case UNIFIED_RCS_THREAD:
-            case UNIFIED_RCS_THREAD_WITH_ID:
-                Log.e(TAG, "Inserting into unified thread view is not supported, uri: " + uri);
-                break;
-            case PARTICIPANT:
-                return buildUriWithRowIdAppended(PARTICIPANT_URI_PREFIX,
-                        mParticipantHelper.insertParticipant(values));
-            case PARTICIPANT_WITH_ID:
-                Log.e(TAG, "Inserting participant with a specified ID is not supported, uri: "
-                        + uri);
-                break;
-            case PARTICIPANT_ALIAS_CHANGE_EVENT:
-                return buildUriWithRowIdAppended(uri,
-                        mEventHelper.insertParticipantEvent(uri, values));
-            case PARTICIPANT_ALIAS_CHANGE_EVENT_WITH_ID:
-                Log.e(TAG, "Inserting participant events with id's is not supported, uri: " + uri);
-                break;
-            case P2P_THREAD:
-                return buildUriWithRowIdAppended(P2P_THREAD_URI_PREFIX,
-                        mThreadHelper.insert1To1Thread(values));
-            case P2P_THREAD_WITH_ID:
-                Log.e(TAG, "Inserting a thread with a specified ID is not supported, uri: " + uri);
-                break;
-            case P2P_THREAD_PARTICIPANT:
-                Log.e(TAG,
-                        "Inserting a participant into a thread via content values is not "
-                                + "supported, uri: "
-                                + uri);
-                break;
-            case P2P_THREAD_PARTICIPANT_WITH_ID:
-                Log.e(TAG,
-                        "Inserting participant into a thread via URI is not supported, uri: "
-                                + uri);
-                break;
-            case GROUP_THREAD:
-                return buildUriWithRowIdAppended(GROUP_THREAD_URI_PREFIX,
-                        mThreadHelper.insertGroupThread(values));
-            case GROUP_THREAD_WITH_ID:
-                Log.e(TAG, "Inserting a thread with a specified ID is not supported, uri: " + uri);
-                break;
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT:
-                return buildUriWithRowIdAppended(uri,
-                        mEventHelper.insertParticipantJoinedEvent(uri, values));
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT_WITH_ID:
-                Log.e(TAG, "Inserting thread events with id's is not supported, uri: " + uri);
-                break;
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT:
-                return buildUriWithRowIdAppended(uri,
-                        mEventHelper.insertParticipantLeftEvent(uri, values));
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT_WITH_ID:
-                Log.e(TAG, "Inserting thread events with id's is not supported, uri: " + uri);
-                break;
-            case GROUP_THREAD_NAME_CHANGE_EVENT:
-                return buildUriWithRowIdAppended(uri,
-                        mEventHelper.insertThreadNameChangeEvent(uri, values));
-            case GROUP_THREAD_NAME_CHANGE_EVENT_WITH_ID:
-                Log.e(TAG, "Inserting thread events with id's is not supported, uri: " + uri);
-                break;
-            case GROUP_THREAD_ICON_CHANGE_EVENT:
-                return buildUriWithRowIdAppended(uri,
-                        mEventHelper.insertThreadIconChangeEvent(uri, values));
-            case GROUP_THREAD_ICON_CHANGE_EVENT_WITH_ID:
-                Log.e(TAG, "Inserting thread events with id's is not supported, uri: " + uri);
-                break;
-            case GROUP_THREAD_PARTICIPANT:
-                rowId = mParticipantHelper.insertParticipantIntoGroupThread(values);
-                if (rowId == TRANSACTION_FAILED) {
-                    return null;
-                }
-                return mParticipantHelper.getParticipantInThreadUri(values, rowId);
-            case GROUP_THREAD_PARTICIPANT_WITH_ID:
-                return returnUriAsIsIfSuccessful(uri,
-                        mParticipantHelper.insertParticipantIntoGroupThreadWithId(uri));
-            case UNIFIED_MESSAGE:
-            case UNIFIED_MESSAGE_WITH_ID:
-                Log.e(TAG, "Inserting into unified message view is not supported, uri: " + uri);
-                break;
-            case UNIFIED_MESSAGE_WITH_FILE_TRANSFER:
-                return buildUriWithRowIdAppended(FILE_TRANSFER_PREFIX,
-                        mMessageHelper.insertFileTransferToMessage(uri, values));
-            case INCOMING_MESSAGE:
-            case INCOMING_MESSAGE_WITH_ID:
-            case OUTGOING_MESSAGE:
-            case OUTGOING_MESSAGE_WITH_ID:
-                Log.e(TAG, "Inserting a message without a thread is not supported, uri: "
-                        + uri);
-                break;
-            case OUTGOING_MESSAGE_DELIVERY:
-                Log.e(TAG,
-                        "Inserting an outgoing message delivery without a participant is not "
-                                + "supported, uri: "
-                                + uri);
-                break;
-            case OUTGOING_MESSAGE_DELIVERY_WITH_ID:
-                return returnUriAsIsIfSuccessful(uri,
-                        mMessageHelper.insertMessageDelivery(uri, values));
-            case UNIFIED_MESSAGE_ON_THREAD:
-            case UNIFIED_MESSAGE_ON_THREAD_WITH_ID:
-                Log.e(TAG,
-                        "Inserting a message on unified thread view is not supported, uri: " + uri);
-                break;
-            case INCOMING_MESSAGE_ON_P2P_THREAD:
-                return mMessageHelper.insertMessageOnThread(uri, values, /* isIncoming= */
-                        true, /* is1To1 */ true);
-            case OUTGOING_MESSAGE_ON_P2P_THREAD:
-                return mMessageHelper.insertMessageOnThread(uri, values, /* isIncoming= */
-                        false, /* is1To1 */ true);
-            case INCOMING_MESSAGE_ON_GROUP_THREAD:
-                return mMessageHelper.insertMessageOnThread(uri, values, /* isIncoming= */
-                        true, /* is1To1 */ false);
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD:
-                return mMessageHelper.insertMessageOnThread(uri, values, /* isIncoming= */
-                        false, /* is1To1 */ false);
-            case INCOMING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-            case OUTGOING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-            case INCOMING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-                Log.e(TAG, "Inserting a message with a specific id is not supported, uri: " + uri);
-                break;
-            case FILE_TRANSFER_WITH_ID:
-                Log.e(TAG, "Inserting a file transfer without a message is not supported, uri: "
-                        + uri);
-                break;
-            case EVENT:
-                Log.e(TAG,
-                        "Inserting event using unified event query is not supported, uri: " + uri);
-                break;
-            default:
-                Log.e(TAG, "Invalid insert: " + uri);
-        }
-
-        return null;
-    }
-
-    @Override
-    public synchronized int delete(Uri uri, String selection, String[] selectionArgs) {
-        int match = URL_MATCHER.match(uri);
-        int deletedCount = 0;
-
-        switch (match) {
-            case UNIFIED_RCS_THREAD:
-            case UNIFIED_RCS_THREAD_WITH_ID:
-                Log.e(TAG, "Deleting entries from unified view is not allowed: " + uri);
-                break;
-            case PARTICIPANT:
-                Log.e(TAG, "Deleting participant with selection is not allowed: " + uri);
-                break;
-            case PARTICIPANT_WITH_ID:
-                return mParticipantHelper.deleteParticipantWithId(uri);
-            case PARTICIPANT_ALIAS_CHANGE_EVENT:
-                Log.e(TAG, "Deleting participant events without id is not allowed: " + uri);
-                break;
-            case PARTICIPANT_ALIAS_CHANGE_EVENT_WITH_ID:
-                return mEventHelper.deleteParticipantEvent(uri);
-            case P2P_THREAD:
-                return mThreadHelper.delete1To1Thread(selection, selectionArgs);
-            case P2P_THREAD_WITH_ID:
-                return mThreadHelper.delete1To1ThreadWithId(uri);
-            case P2P_THREAD_PARTICIPANT:
-                Log.e(TAG, "Removing participant from 1 to 1 thread is not allowed, uri: " + uri);
-                break;
-            case GROUP_THREAD:
-                return mThreadHelper.deleteGroupThread(selection, selectionArgs);
-            case GROUP_THREAD_WITH_ID:
-                return mThreadHelper.deleteGroupThreadWithId(uri);
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT_WITH_ID:
-                return mEventHelper.deleteGroupThreadEvent(uri);
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT_WITH_ID:
-                return mEventHelper.deleteGroupThreadEvent(uri);
-            case GROUP_THREAD_NAME_CHANGE_EVENT_WITH_ID:
-                return mEventHelper.deleteGroupThreadEvent(uri);
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT:
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT:
-            case GROUP_THREAD_NAME_CHANGE_EVENT:
-            case GROUP_THREAD_ICON_CHANGE_EVENT:
-                Log.e(TAG, "Deleting thread events via selection is not allowed, uri: " + uri);
-                break;
-            case GROUP_THREAD_ICON_CHANGE_EVENT_WITH_ID:
-                return mEventHelper.deleteGroupThreadEvent(uri);
-            case GROUP_THREAD_PARTICIPANT:
-                Log.e(TAG,
-                        "Deleting a participant from group thread via selection is not allowed, "
-                                + "uri: "
-                                + uri);
-                break;
-            case GROUP_THREAD_PARTICIPANT_WITH_ID:
-                return mParticipantHelper.deleteParticipantFromGroupThread(uri);
-            case UNIFIED_MESSAGE:
-                Log.e(TAG,
-                        "Deleting message from unified view with selection is not allowed: " + uri);
-                break;
-            case UNIFIED_MESSAGE_WITH_ID:
-                Log.e(TAG, "Deleting message from unified view with id is not allowed: " + uri);
-                break;
-            case UNIFIED_MESSAGE_WITH_FILE_TRANSFER:
-                Log.e(TAG, "Deleting file transfer using message uri is not allowed, uri: " + uri);
-                break;
-            case INCOMING_MESSAGE:
-                return mMessageHelper.deleteIncomingMessageWithSelection(selection, selectionArgs);
-            case INCOMING_MESSAGE_WITH_ID:
-                return mMessageHelper.deleteIncomingMessageWithId(uri);
-            case OUTGOING_MESSAGE:
-                return mMessageHelper.deleteOutgoingMessageWithSelection(selection, selectionArgs);
-            case OUTGOING_MESSAGE_WITH_ID:
-                return mMessageHelper.deleteOutgoingMessageWithId(uri);
-            case OUTGOING_MESSAGE_DELIVERY:
-            case OUTGOING_MESSAGE_DELIVERY_WITH_ID:
-                Log.e(TAG, "Deleting message deliveries is not supported, uri: " + uri);
-                break;
-            case UNIFIED_MESSAGE_ON_THREAD:
-            case UNIFIED_MESSAGE_ON_THREAD_WITH_ID:
-            case INCOMING_MESSAGE_ON_P2P_THREAD:
-            case INCOMING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-            case OUTGOING_MESSAGE_ON_P2P_THREAD:
-            case OUTGOING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-            case INCOMING_MESSAGE_ON_GROUP_THREAD:
-            case INCOMING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD:
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-                Log.e(TAG, "Deleting messages using thread uris is not supported, uri: " + uri);
-                break;
-            case FILE_TRANSFER_WITH_ID:
-                return mMessageHelper.deleteFileTransfer(uri);
-            case EVENT:
-                Log.e(TAG, "Deleting events using unified event uri is not supported, uri: " + uri);
-                break;
-            default:
-                Log.e(TAG, "Invalid delete: " + uri);
-        }
-
-        return deletedCount;
-    }
-
-    @Override
-    public synchronized int update(Uri uri, ContentValues values, String selection,
-            String[] selectionArgs) {
-        int match = URL_MATCHER.match(uri);
-        int updatedCount = 0;
-
-        switch (match) {
-            case UNIFIED_RCS_THREAD:
-            case UNIFIED_RCS_THREAD_WITH_ID:
-                Log.e(TAG, "Updating unified thread view is not supported, uri: " + uri);
-                break;
-            case PARTICIPANT:
-                Log.e(TAG, "Updating participants with selection is not supported, uri: " + uri);
-                break;
-            case PARTICIPANT_WITH_ID:
-                return mParticipantHelper.updateParticipantWithId(values, uri);
-            case PARTICIPANT_ALIAS_CHANGE_EVENT:
-            case PARTICIPANT_ALIAS_CHANGE_EVENT_WITH_ID:
-                Log.e(TAG, "Updating events is not supported, uri: " + uri);
-                break;
-            case P2P_THREAD:
-                return mThreadHelper.update1To1Thread(values, selection, selectionArgs);
-            case P2P_THREAD_WITH_ID:
-                return mThreadHelper.update1To1ThreadWithId(values, uri);
-            case P2P_THREAD_PARTICIPANT:
-                Log.e(TAG, "Updating junction table entries is not supported, uri: " + uri);
-                break;
-            case GROUP_THREAD:
-                return mThreadHelper.updateGroupThread(values, selection, selectionArgs);
-            case GROUP_THREAD_WITH_ID:
-                return mThreadHelper.updateGroupThreadWithId(values, uri);
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT:
-            case GROUP_THREAD_PARTICIPANT_JOINED_EVENT_WITH_ID:
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT:
-            case GROUP_THREAD_PARTICIPANT_LEFT_EVENT_WITH_ID:
-            case GROUP_THREAD_NAME_CHANGE_EVENT:
-            case GROUP_THREAD_NAME_CHANGE_EVENT_WITH_ID:
-            case GROUP_THREAD_ICON_CHANGE_EVENT:
-            case GROUP_THREAD_ICON_CHANGE_EVENT_WITH_ID:
-                Log.e(TAG, "Updating thread events is not supported, uri: " + uri);
-                break;
-            case GROUP_THREAD_PARTICIPANT:
-            case GROUP_THREAD_PARTICIPANT_WITH_ID:
-                Log.e(TAG, "Updating junction table entries is not supported, uri: " + uri);
-                break;
-            case UNIFIED_MESSAGE:
-            case UNIFIED_MESSAGE_WITH_ID:
-                Log.e(TAG, "Updating unified message view is not supported, uri: " + uri);
-                break;
-            case UNIFIED_MESSAGE_WITH_FILE_TRANSFER:
-                Log.e(TAG,
-                        "Updating file transfer using unified message uri is not supported, uri: "
-                                + uri);
-            case INCOMING_MESSAGE:
-                Log.e(TAG,
-                        "Updating an incoming message via selection is not supported, uri: " + uri);
-                break;
-            case INCOMING_MESSAGE_WITH_ID:
-                return mMessageHelper.updateIncomingMessage(uri, values);
-            case OUTGOING_MESSAGE:
-                Log.e(TAG,
-                        "Updating an outgoing message via selection is not supported, uri: " + uri);
-                break;
-            case OUTGOING_MESSAGE_WITH_ID:
-                return mMessageHelper.updateOutgoingMessage(uri, values);
-            case OUTGOING_MESSAGE_DELIVERY:
-                Log.e(TAG, "Updating message deliveries using message uris is not supported, uri: "
-                        + uri);
-                break;
-            case OUTGOING_MESSAGE_DELIVERY_WITH_ID:
-                return mMessageHelper.updateDelivery(uri, values);
-            case UNIFIED_MESSAGE_ON_THREAD:
-            case UNIFIED_MESSAGE_ON_THREAD_WITH_ID:
-            case INCOMING_MESSAGE_ON_P2P_THREAD:
-            case INCOMING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-            case OUTGOING_MESSAGE_ON_P2P_THREAD:
-            case OUTGOING_MESSAGE_ON_P2P_THREAD_WITH_ID:
-            case INCOMING_MESSAGE_ON_GROUP_THREAD:
-            case INCOMING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD:
-            case OUTGOING_MESSAGE_ON_GROUP_THREAD_WITH_ID:
-                Log.e(TAG, "Updating messages using threads uris is not supported, uri: " + uri);
-                break;
-            case FILE_TRANSFER_WITH_ID:
-                return mMessageHelper.updateFileTransfer(uri, values);
-            case EVENT:
-                Log.e(TAG, "Updating events is not supported, uri: " + uri);
-                break;
-            default:
-                Log.e(TAG, "Invalid update: " + uri);
-        }
-
-        return updatedCount;
-    }
-}
diff --git a/src/com/android/providers/telephony/RcsProviderCanonicalAddressHelper.java b/src/com/android/providers/telephony/RcsProviderCanonicalAddressHelper.java
deleted file mode 100644
index 496b512..0000000
--- a/src/com/android/providers/telephony/RcsProviderCanonicalAddressHelper.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.android.providers.telephony;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.provider.BaseColumns;
-import android.provider.Telephony;
-
-public class RcsProviderCanonicalAddressHelper {
-    SQLiteOpenHelper mSQLiteOpenHelper;
-
-    RcsProviderCanonicalAddressHelper(SQLiteOpenHelper sqLiteOpenHelper) {
-        mSQLiteOpenHelper = sqLiteOpenHelper;
-    }
-
-    Cursor getOrCreateCanonicalAddress(String canonicalAddress) {
-        SQLiteDatabase db = mSQLiteOpenHelper.getReadableDatabase();
-
-        Cursor cursor = db.query(
-                MmsSmsProvider.TABLE_CANONICAL_ADDRESSES,
-                new String[]{BaseColumns._ID}, Telephony.CanonicalAddressesColumns.ADDRESS + "=?",
-                new String[]{canonicalAddress}, null, null, null);
-
-        if (cursor != null && cursor.getCount() > 0) {
-            return cursor;
-        }
-
-        if (cursor != null) {
-            cursor.close();
-        }
-
-        return insertCanonicalAddress(canonicalAddress);
-    }
-
-    private Cursor insertCanonicalAddress(String canonicalAddress) {
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(Telephony.CanonicalAddressesColumns.ADDRESS, canonicalAddress);
-
-        SQLiteDatabase db = mSQLiteOpenHelper.getWritableDatabase();
-
-        long id = db.insert(MmsSmsProvider.TABLE_CANONICAL_ADDRESSES, null, contentValues);
-
-        if (id == -1) {
-            return null;
-        }
-
-        MatrixCursor matrixCursor = new MatrixCursor(new String[]{BaseColumns._ID}, 1);
-        matrixCursor.addRow(new Object[]{id});
-
-        return matrixCursor;
-    }
-}
diff --git a/src/com/android/providers/telephony/RcsProviderEventHelper.java b/src/com/android/providers/telephony/RcsProviderEventHelper.java
deleted file mode 100644
index c6a6fc6..0000000
--- a/src/com/android/providers/telephony/RcsProviderEventHelper.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2019 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.RcsColumns.RcsEventTypes.PARTICIPANT_ALIAS_CHANGED_EVENT_TYPE;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantEventColumns.NEW_ALIAS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsEventTypes.ICON_CHANGED_EVENT_TYPE;
-import static android.provider.Telephony.RcsColumns.RcsEventTypes.NAME_CHANGED_EVENT_TYPE;
-import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_JOINED_EVENT_TYPE;
-import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_LEFT_EVENT_TYPE;
-import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.DESTINATION_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.EVENT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.EVENT_TYPE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_ICON_URI_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_NAME_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.SOURCE_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.TRANSACTION_FAILED;
-import static android.telephony.ims.RcsEventQueryParams.ALL_EVENTS;
-import static android.telephony.ims.RcsEventQueryParams.ALL_GROUP_THREAD_EVENTS;
-import static android.telephony.ims.RcsEventQueryParams.EVENT_QUERY_PARAMETERS_KEY;
-
-import static android.telephony.ims.RcsQueryContinuationToken.EVENT_QUERY_CONTINUATION_TOKEN_TYPE;
-import static android.telephony.ims.RcsQueryContinuationToken.QUERY_CONTINUATION_TOKEN;
-import static com.android.providers.telephony.RcsProvider.RCS_PARTICIPANT_EVENT_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_PARTICIPANT_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_THREAD_EVENT_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_THREAD_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_UNIFIED_EVENT_VIEW;
-import static com.android.providers.telephony.RcsProvider.TAG;
-import static com.android.providers.telephony.RcsProviderThreadHelper.getThreadIdFromUri;
-import static com.android.providers.telephony.RcsProviderUtil.INSERTION_FAILED;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.os.Bundle;
-import android.telephony.ims.RcsEventQueryParams;
-import android.telephony.ims.RcsQueryContinuationToken;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Constants and helpers related to events for {@link RcsProvider} to keep the code clean.
- *
- * @hide
- */
-class RcsProviderEventHelper {
-    private static final int PARTICIPANT_INDEX_IN_EVENT_URI = 1;
-    private static final int EVENT_INDEX_IN_EVENT_URI = 3;
-
-    @VisibleForTesting
-    public static void createRcsEventTables(SQLiteDatabase db) {
-        Log.d(TAG, "Creating event tables");
-
-        // Add the event tables
-        db.execSQL("CREATE TABLE " + RCS_THREAD_EVENT_TABLE + "(" + EVENT_ID_COLUMN
-                + " INTEGER PRIMARY KEY AUTOINCREMENT, " + RCS_THREAD_ID_COLUMN + " INTEGER, "
-                + SOURCE_PARTICIPANT_ID_COLUMN + " INTEGER, " + EVENT_TYPE_COLUMN + " INTEGER, "
-                + TIMESTAMP_COLUMN + " INTEGER, " + DESTINATION_PARTICIPANT_ID_COLUMN + " INTEGER, "
-                + NEW_ICON_URI_COLUMN + " TEXT, " + NEW_NAME_COLUMN + " TEXT, " + " FOREIGN KEY ("
-                + RCS_THREAD_ID_COLUMN + ") REFERENCES " + RCS_THREAD_TABLE + " ("
-                + RCS_THREAD_ID_COLUMN + "), FOREIGN KEY (" + SOURCE_PARTICIPANT_ID_COLUMN
-                + ") REFERENCES " + RCS_PARTICIPANT_TABLE + " (" + RCS_PARTICIPANT_ID_COLUMN
-                + "))");
-
-        db.execSQL("CREATE TABLE " + RCS_PARTICIPANT_EVENT_TABLE + "(" + EVENT_ID_COLUMN
-                + " INTEGER PRIMARY KEY AUTOINCREMENT, " + SOURCE_PARTICIPANT_ID_COLUMN +
-                " INTEGER, " + TIMESTAMP_COLUMN + " INTEGER, "
-                + NEW_ALIAS_COLUMN + " TEXT," + " FOREIGN KEY (" + SOURCE_PARTICIPANT_ID_COLUMN
-                + ") REFERENCES " + RCS_PARTICIPANT_TABLE + " (" + RCS_PARTICIPANT_ID_COLUMN
-                + "))");
-
-        // Add the views
-
-        // The following is a unified event view that puts every entry in both tables into one query
-        db.execSQL("CREATE VIEW " + RCS_UNIFIED_EVENT_VIEW + " AS "
-                + "SELECT " + PARTICIPANT_ALIAS_CHANGED_EVENT_TYPE + " AS " + EVENT_TYPE_COLUMN
-                + ", " + EVENT_ID_COLUMN + ", " + SOURCE_PARTICIPANT_ID_COLUMN + ", "
-                + TIMESTAMP_COLUMN + ", " + NEW_ALIAS_COLUMN + ", NULL as " + RCS_THREAD_ID_COLUMN
-                + ", NULL as " + DESTINATION_PARTICIPANT_ID_COLUMN + ", NULL as "
-                + NEW_ICON_URI_COLUMN + ", NULL as " + NEW_NAME_COLUMN + " "
-                + "FROM " + RCS_PARTICIPANT_EVENT_TABLE + " "
-                + "UNION "
-                + "SELECT " + EVENT_TYPE_COLUMN + ", " + EVENT_ID_COLUMN + ", "
-                + SOURCE_PARTICIPANT_ID_COLUMN + ", " + TIMESTAMP_COLUMN + ", "
-                + "NULL as " + NEW_ALIAS_COLUMN + ", " + RCS_THREAD_ID_COLUMN + ", "
-                + DESTINATION_PARTICIPANT_ID_COLUMN + ", " + NEW_ICON_URI_COLUMN + ", "
-                + NEW_NAME_COLUMN + " "
-                + "FROM " + RCS_THREAD_EVENT_TABLE);
-    }
-
-    private final SQLiteOpenHelper mSqLiteOpenHelper;
-
-    Cursor queryEvents(Bundle bundle) {
-        RcsEventQueryParams queryParameters = null;
-        RcsQueryContinuationToken continuationToken = null;
-
-        if (bundle != null) {
-            queryParameters = bundle.getParcelable(EVENT_QUERY_PARAMETERS_KEY);
-            continuationToken = bundle.getParcelable(QUERY_CONTINUATION_TOKEN);
-        }
-
-        if (continuationToken != null) {
-            return RcsProviderUtil.performContinuationQuery(mSqLiteOpenHelper.getReadableDatabase(),
-                    continuationToken);
-        }
-
-        // if no query parameters were entered, build an empty query parameters object
-        if (queryParameters == null) {
-            queryParameters = new RcsEventQueryParams.Builder().build();
-        }
-
-        return performInitialQuery(queryParameters);
-    }
-
-    private Cursor performInitialQuery(RcsEventQueryParams queryParameters) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        StringBuilder rawQuery = new StringBuilder("SELECT * FROM ").append(RCS_UNIFIED_EVENT_VIEW);
-
-        int eventType = queryParameters.getEventType();
-        if (eventType != ALL_EVENTS) {
-            rawQuery.append(" WHERE ").append(EVENT_TYPE_COLUMN);
-            if (eventType == ALL_GROUP_THREAD_EVENTS) {
-                rawQuery.append(" IN (").append(
-                        PARTICIPANT_JOINED_EVENT_TYPE).append(", ").append(
-                        PARTICIPANT_LEFT_EVENT_TYPE).append(", ").append(
-                        ICON_CHANGED_EVENT_TYPE).append(", ").append(
-                        NAME_CHANGED_EVENT_TYPE).append(
-                        ")");
-            } else {
-                rawQuery.append("=").append(eventType);
-            }
-        }
-
-        rawQuery.append(" ORDER BY ");
-
-        int sortingProperty = queryParameters.getSortingProperty();
-        if (sortingProperty == RcsEventQueryParams.SORT_BY_TIMESTAMP) {
-            rawQuery.append(TIMESTAMP_COLUMN);
-        } else {
-            rawQuery.append(EVENT_ID_COLUMN);
-        }
-
-        rawQuery.append(queryParameters.getSortDirection() ? " ASC " : " DESC ");
-
-        RcsProviderUtil.appendLimit(rawQuery, queryParameters.getLimit());
-        String rawQueryAsString = rawQuery.toString();
-        Cursor cursor = db.rawQuery(rawQueryAsString, null);
-
-        // if the query was paginated, build the next query
-        int limit = queryParameters.getLimit();
-        if (limit > 0) {
-            RcsProviderUtil.createContinuationTokenBundle(cursor,
-                    new RcsQueryContinuationToken(EVENT_QUERY_CONTINUATION_TOKEN_TYPE,
-                        rawQueryAsString, limit, limit), QUERY_CONTINUATION_TOKEN);
-        }
-
-        return cursor;
-    }
-
-    RcsProviderEventHelper(SQLiteOpenHelper sqLiteOpenHelper) {
-        mSqLiteOpenHelper = sqLiteOpenHelper;
-    }
-
-    long insertParticipantEvent(Uri uri, ContentValues values) {
-        String participantId = getParticipantIdFromUri(uri);
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        values.put(SOURCE_PARTICIPANT_ID_COLUMN, participantId);
-        long rowId = db.insert(RCS_PARTICIPANT_EVENT_TABLE, SOURCE_PARTICIPANT_ID_COLUMN, values);
-        values.remove(SOURCE_PARTICIPANT_ID_COLUMN);
-
-        if (rowId == INSERTION_FAILED) {
-            return TRANSACTION_FAILED;
-        }
-
-        return rowId;
-    }
-
-    long insertParticipantJoinedEvent(Uri uri, ContentValues values) {
-        return insertGroupThreadEvent(uri, values, PARTICIPANT_JOINED_EVENT_TYPE);
-    }
-
-    long insertParticipantLeftEvent(Uri uri, ContentValues values) {
-        return insertGroupThreadEvent(uri, values, PARTICIPANT_LEFT_EVENT_TYPE);
-    }
-
-    long insertThreadNameChangeEvent(Uri uri, ContentValues values) {
-        return insertGroupThreadEvent(uri, values, NAME_CHANGED_EVENT_TYPE);
-    }
-
-    long insertThreadIconChangeEvent(Uri uri, ContentValues values) {
-        return insertGroupThreadEvent(uri, values, ICON_CHANGED_EVENT_TYPE);
-    }
-
-    private long insertGroupThreadEvent(Uri uri, ContentValues valuesParameter,
-            int eventType) {
-        String threadId = getThreadIdFromUri(uri);
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        ContentValues values = new ContentValues(valuesParameter);
-        values.put(EVENT_TYPE_COLUMN, eventType);
-        values.put(RCS_THREAD_ID_COLUMN, threadId);
-        long rowId = db.insert(RCS_THREAD_EVENT_TABLE, EVENT_ID_COLUMN, values);
-
-        if (rowId == INSERTION_FAILED) {
-            return TRANSACTION_FAILED;
-        }
-
-        return rowId;
-    }
-
-    int deleteParticipantEvent(Uri uri) {
-        String eventId = getEventIdFromEventUri(uri);
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-
-        return db.delete(RCS_PARTICIPANT_EVENT_TABLE, EVENT_ID_COLUMN + "=?",
-                new String[]{eventId});
-    }
-
-    int deleteGroupThreadEvent(Uri uri) {
-        String eventId = getEventIdFromEventUri(uri);
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-
-        return db.delete(RCS_THREAD_EVENT_TABLE, EVENT_ID_COLUMN + "=?", new String[]{eventId});
-    }
-
-    private String getEventIdFromEventUri(Uri uri) {
-        return uri.getPathSegments().get(EVENT_INDEX_IN_EVENT_URI);
-    }
-
-    private String getParticipantIdFromUri(Uri uri) {
-        return uri.getPathSegments().get(PARTICIPANT_INDEX_IN_EVENT_URI);
-    }
-}
diff --git a/src/com/android/providers/telephony/RcsProviderMessageHelper.java b/src/com/android/providers/telephony/RcsProviderMessageHelper.java
deleted file mode 100644
index 670c641..0000000
--- a/src/com/android/providers/telephony/RcsProviderMessageHelper.java
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * 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.RcsColumns.CONTENT_AND_AUTHORITY;
-import static android.provider.Telephony.RcsColumns.Rcs1To1ThreadColumns.RCS_1_TO_1_THREAD_URI_PART;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.CONTENT_TYPE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.CONTENT_URI_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.FILE_SIZE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.FILE_TRANSFER_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.HEIGHT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.DURATION_MILLIS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.PREVIEW_TYPE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.PREVIEW_URI_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.SESSION_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.SUCCESSFULLY_TRANSFERRED_BYTES;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.TRANSFER_STATUS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.WIDTH_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.RCS_GROUP_THREAD_URI_PART;
-import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.ARRIVAL_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.INCOMING_MESSAGE_URI_PART;
-import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.SENDER_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.GLOBAL_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.LATITUDE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.LONGITUDE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_TEXT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.ORIGINATION_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.STATUS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.SUB_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageDeliveryColumns.DELIVERED_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsOutgoingMessageColumns.OUTGOING_MESSAGE_URI_PART;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsUnifiedMessageColumns.MESSAGE_TYPE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsUnifiedMessageColumns.MESSAGE_TYPE_INCOMING;
-import static android.provider.Telephony.RcsColumns.RcsUnifiedMessageColumns.MESSAGE_TYPE_OUTGOING;
-import static android.provider.Telephony.RcsColumns.RcsUnifiedMessageColumns.UNIFIED_INCOMING_MESSAGE_VIEW;
-import static android.provider.Telephony.RcsColumns.RcsUnifiedMessageColumns.UNIFIED_OUTGOING_MESSAGE_VIEW;
-import static android.provider.Telephony.RcsColumns.TRANSACTION_FAILED;
-import static android.telephony.ims.RcsMessageQueryParams.MESSAGE_QUERY_PARAMETERS_KEY;
-import static android.telephony.ims.RcsMessageQueryParams.THREAD_ID_NOT_SET;
-
-import static android.telephony.ims.RcsQueryContinuationToken.MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE;
-import static android.telephony.ims.RcsQueryContinuationToken.QUERY_CONTINUATION_TOKEN;
-import static com.android.providers.telephony.RcsProvider.RCS_FILE_TRANSFER_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_INCOMING_MESSAGE_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_MESSAGE_DELIVERY_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_MESSAGE_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_OUTGOING_MESSAGE_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_PARTICIPANT_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_PARTICIPANT_THREAD_JUNCTION_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_THREAD_TABLE;
-import static com.android.providers.telephony.RcsProvider.TAG;
-import static com.android.providers.telephony.RcsProvider.UNIFIED_MESSAGE_VIEW;
-import static com.android.providers.telephony.RcsProviderThreadHelper.getThreadIdFromUri;
-import static com.android.providers.telephony.RcsProviderUtil.INSERTION_FAILED;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns;
-import android.provider.Telephony.RcsColumns.RcsMessageDeliveryColumns;
-import android.telephony.ims.RcsMessageQueryParams;
-import android.telephony.ims.RcsQueryContinuationToken;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Constants and helpers related to messages for {@link RcsProvider} to keep the code clean.
- *
- * @hide
- */
-public class RcsProviderMessageHelper {
-    private static final int MESSAGE_ID_INDEX_IN_URI = 1;
-    private static final int MESSAGE_ID_INDEX_IN_THREAD_URI = 3;
-
-    private final SQLiteOpenHelper mSqLiteOpenHelper;
-
-    @VisibleForTesting
-    public static void createRcsMessageTables(SQLiteDatabase db) {
-        Log.d(TAG, "Creating message tables");
-
-        // Add the message tables
-        db.execSQL("CREATE TABLE " + RCS_MESSAGE_TABLE + "(" + MESSAGE_ID_COLUMN
-                + " INTEGER PRIMARY KEY AUTOINCREMENT, " + RCS_THREAD_ID_COLUMN + " INTEGER, "
-                + GLOBAL_ID_COLUMN + " TEXT, " + SUB_ID_COLUMN + " INTEGER, " + MESSAGE_TEXT_COLUMN
-                + " TEXT," + LATITUDE_COLUMN + " REAL, " + LONGITUDE_COLUMN + " REAL, "
-                + STATUS_COLUMN + " INTEGER, " + ORIGINATION_TIMESTAMP_COLUMN
-                + " INTEGER, FOREIGN KEY(" + RCS_THREAD_ID_COLUMN + ") REFERENCES "
-                + RCS_THREAD_TABLE + "(" + RCS_THREAD_ID_COLUMN + "))");
-
-        db.execSQL("CREATE TABLE " + RCS_INCOMING_MESSAGE_TABLE + "(" + MESSAGE_ID_COLUMN
-                + " INTEGER PRIMARY KEY, " + SENDER_PARTICIPANT_ID_COLUMN + " INTEGER, "
-                + ARRIVAL_TIMESTAMP_COLUMN + " INTEGER, "
-                + RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN + " INTEGER, FOREIGN KEY ("
-                + MESSAGE_ID_COLUMN + ") REFERENCES " + RCS_MESSAGE_TABLE + "(" + MESSAGE_ID_COLUMN
-                + "))");
-
-        db.execSQL("CREATE TABLE " + RCS_OUTGOING_MESSAGE_TABLE + "(" + MESSAGE_ID_COLUMN
-                + " INTEGER PRIMARY KEY, FOREIGN KEY (" + MESSAGE_ID_COLUMN + ") REFERENCES "
-                + RCS_MESSAGE_TABLE + "(" + MESSAGE_ID_COLUMN + "))");
-
-        db.execSQL("CREATE TABLE " + RCS_MESSAGE_DELIVERY_TABLE + "(" + MESSAGE_ID_COLUMN
-                + " INTEGER, " + RCS_PARTICIPANT_ID_COLUMN + " INTEGER, "
-                + DELIVERED_TIMESTAMP_COLUMN + " INTEGER, "
-                + RcsMessageDeliveryColumns.SEEN_TIMESTAMP_COLUMN + " INTEGER, "
-                + "CONSTRAINT message_delivery PRIMARY KEY (" + MESSAGE_ID_COLUMN + ", "
-                + RCS_PARTICIPANT_ID_COLUMN + "), FOREIGN KEY (" + MESSAGE_ID_COLUMN
-                + ") REFERENCES " + RCS_MESSAGE_TABLE + "(" + MESSAGE_ID_COLUMN + "), FOREIGN KEY ("
-                + RCS_PARTICIPANT_ID_COLUMN + ") REFERENCES " + RCS_PARTICIPANT_TABLE + "("
-                + RCS_PARTICIPANT_ID_COLUMN + "))");
-
-        db.execSQL("CREATE TABLE " + RCS_FILE_TRANSFER_TABLE + " (" + FILE_TRANSFER_ID_COLUMN
-                + " INTEGER PRIMARY KEY AUTOINCREMENT, " + MESSAGE_ID_COLUMN + " INTEGER, "
-                + SESSION_ID_COLUMN + " TEXT, " + CONTENT_URI_COLUMN + " TEXT, "
-                + CONTENT_TYPE_COLUMN + " TEXT, " + FILE_SIZE_COLUMN + " INTEGER, "
-                + SUCCESSFULLY_TRANSFERRED_BYTES + " INTEGER, " + TRANSFER_STATUS_COLUMN +
-                " INTEGER, " + WIDTH_COLUMN + " INTEGER, " + HEIGHT_COLUMN + " INTEGER, "
-                + DURATION_MILLIS_COLUMN + " INTEGER, " + PREVIEW_URI_COLUMN + " TEXT, "
-                + PREVIEW_TYPE_COLUMN + " TEXT, FOREIGN KEY (" + MESSAGE_ID_COLUMN + ") REFERENCES "
-                + RCS_MESSAGE_TABLE + "(" + MESSAGE_ID_COLUMN + "))");
-
-        // Add the views
-        //
-        // The following view inner joins incoming messages with all messages, inner joins outgoing
-        // messages with all messages, and unions them together, while also adding an is_incoming
-        // column for easily telling where the record came from. This may have been achieved with
-        // an outer join but SQLite doesn't support them.
-        //
-        // CREATE VIEW unified_message_view AS
-        //
-        // SELECT rcs_message.rcs_message_row_id,
-        //        rcs_message.rcs_thread_id,
-        //        rcs_message.rcs_message_global_id,
-        //        rcs_message.sub_id,
-        //        rcs_message.status,
-        //        rcs_message.origination_timestamp,
-        //        rcs_message.rcs_text,
-        //        rcs_message.latitude,
-        //        rcs_message.longitude,
-        //        0 AS sender_participant,
-        //        0 AS arrival_timestamp,
-        //        0 AS seen_timestamp,
-        //        outgoing AS message_type
-        //
-        // FROM rcs_message INNER JOIN rcs_outgoing_message
-        //          ON rcs_message.rcs_message_row_id=rcs_outgoing_message.rcs_message_row_id
-        //
-        // UNION
-        //
-        // SELECT rcs_message.rcs_message_row_id,
-        //        rcs_message.rcs_thread_id,
-        //        rcs_message.rcs_message_global_id,
-        //        rcs_message.sub_id,
-        //        rcs_message.status,
-        //        rcs_message.origination_timestamp,
-        //        rcs_message.rcs_text,
-        //        rcs_message.latitude,
-        //        rcs_message.longitude,
-        //        rcs_incoming_message.sender_participant,
-        //        rcs_incoming_message.arrival_timestamp,
-        //        rcs_incoming_message.seen_timestamp,
-        //        incoming AS message_type
-        //
-        // FROM rcs_message INNER JOIN rcs_incoming_message
-        //          ON rcs_message.rcs_message_row_id=rcs_incoming_message.rcs_message_row_id
-        //
-        db.execSQL("CREATE VIEW " + UNIFIED_MESSAGE_VIEW + " AS SELECT "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + RCS_THREAD_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + GLOBAL_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + SUB_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + STATUS_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + ORIGINATION_TIMESTAMP_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_TEXT_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LATITUDE_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LONGITUDE_COLUMN + ", "
-                + "0 AS " + SENDER_PARTICIPANT_ID_COLUMN + ", "
-                + "0 AS " + ARRIVAL_TIMESTAMP_COLUMN + ", "
-                + "0 AS " + RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN + ", "
-                + MESSAGE_TYPE_OUTGOING + " AS " + MESSAGE_TYPE_COLUMN
-                + " FROM " + RCS_MESSAGE_TABLE + " INNER JOIN " + RCS_OUTGOING_MESSAGE_TABLE
-                + " ON " + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + "="
-                + RCS_OUTGOING_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN
-                + " UNION SELECT "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + RCS_THREAD_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + GLOBAL_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + SUB_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + STATUS_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + ORIGINATION_TIMESTAMP_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_TEXT_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LATITUDE_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LONGITUDE_COLUMN + ", "
-                + RCS_INCOMING_MESSAGE_TABLE + "." + SENDER_PARTICIPANT_ID_COLUMN + ", "
-                + RCS_INCOMING_MESSAGE_TABLE + "." + ARRIVAL_TIMESTAMP_COLUMN + ", "
-                + RCS_INCOMING_MESSAGE_TABLE + "." + RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN
-                + ", "
-                + MESSAGE_TYPE_INCOMING + " AS " + MESSAGE_TYPE_COLUMN
-                + " FROM " + RCS_MESSAGE_TABLE + " INNER JOIN " + RCS_INCOMING_MESSAGE_TABLE
-                + " ON " + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + "="
-                + RCS_INCOMING_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN);
-
-        // The following view inner joins incoming messages with all messages
-        //
-        // CREATE VIEW unified_incoming_message_view AS
-        //
-        // SELECT rcs_message.rcs_message_row_id,
-        //        rcs_message.rcs_thread_id,
-        //        rcs_message.rcs_message_global_id,
-        //        rcs_message.sub_id,
-        //        rcs_message.status,
-        //        rcs_message.origination_timestamp,
-        //        rcs_message.rcs_text,
-        //        rcs_message.latitude,
-        //        rcs_message.longitude,
-        //        rcs_incoming_message.sender_participant,
-        //        rcs_incoming_message.arrival_timestamp,
-        //        rcs_incoming_message.seen_timestamp,
-        //
-        // FROM rcs_message INNER JOIN rcs_incoming_message
-        //          ON rcs_message.rcs_message_row_id=rcs_incoming_message.rcs_message_row_id
-
-        db.execSQL("CREATE VIEW " + UNIFIED_INCOMING_MESSAGE_VIEW + " AS SELECT "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + RCS_THREAD_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + GLOBAL_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + SUB_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + STATUS_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + ORIGINATION_TIMESTAMP_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_TEXT_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LATITUDE_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LONGITUDE_COLUMN + ", "
-                + RCS_INCOMING_MESSAGE_TABLE + "." + SENDER_PARTICIPANT_ID_COLUMN + ", "
-                + RCS_INCOMING_MESSAGE_TABLE + "." + ARRIVAL_TIMESTAMP_COLUMN + ", "
-                + RCS_INCOMING_MESSAGE_TABLE + "." + RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN
-                + " FROM " + RCS_MESSAGE_TABLE + " INNER JOIN " + RCS_INCOMING_MESSAGE_TABLE
-                + " ON " + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + "="
-                + RCS_INCOMING_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN);
-
-        // The following view inner joins outgoing messages with all messages.
-        //
-        // CREATE VIEW unified_outgoing_message AS
-        //
-        // SELECT rcs_message.rcs_message_row_id,
-        //        rcs_message.rcs_thread_id,
-        //        rcs_message.rcs_message_global_id,
-        //        rcs_message.sub_id,
-        //        rcs_message.status,
-        //        rcs_message.origination_timestamp
-        //        rcs_message.rcs_text,
-        //        rcs_message.latitude,
-        //        rcs_message.longitude,
-        //
-        // FROM rcs_message INNER JOIN rcs_outgoing_message
-        //          ON rcs_message.rcs_message_row_id=rcs_outgoing_message.rcs_message_row_id
-
-        db.execSQL("CREATE VIEW " + UNIFIED_OUTGOING_MESSAGE_VIEW + " AS SELECT "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + RCS_THREAD_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + GLOBAL_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + SUB_ID_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + STATUS_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + ORIGINATION_TIMESTAMP_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + MESSAGE_TEXT_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LATITUDE_COLUMN + ", "
-                + RCS_MESSAGE_TABLE + "." + LONGITUDE_COLUMN
-                + " FROM " + RCS_MESSAGE_TABLE + " INNER JOIN " + RCS_OUTGOING_MESSAGE_TABLE
-                + " ON " + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + "="
-                + RCS_OUTGOING_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN);
-
-        // Add triggers
-
-        // Delete the corresponding rcs_message row upon deleting a row in rcs_incoming_message
-        //
-        // CREATE TRIGGER delete_common_message_after_incoming
-        //  AFTER DELETE ON rcs_incoming_message
-        // BEGIN
-        //  DELETE FROM rcs_message WHERE rcs_message.rcs_message_row_id=OLD.rcs_message_row_id;
-        // END
-        db.execSQL("CREATE TRIGGER deleteCommonMessageAfterIncoming AFTER DELETE ON "
-                + RCS_INCOMING_MESSAGE_TABLE + " BEGIN DELETE FROM " + RCS_MESSAGE_TABLE
-                + " WHERE " + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + "=OLD."
-                + MESSAGE_ID_COLUMN + "; END");
-
-        // Delete the corresponding rcs_message row upon deleting a row in rcs_outgoing_message
-        //
-        // CREATE TRIGGER delete_common_message_after_outgoing
-        //  AFTER DELETE ON rcs_outgoing_message
-        // BEGIN
-        //  DELETE FROM rcs_message WHERE rcs_message.rcs_message_row_id=OLD.rcs_message_row_id;
-        // END
-        db.execSQL("CREATE TRIGGER deleteCommonMessageAfterOutgoing AFTER DELETE ON "
-                + RCS_OUTGOING_MESSAGE_TABLE + " BEGIN DELETE FROM " + RCS_MESSAGE_TABLE
-                + " WHERE " + RCS_MESSAGE_TABLE + "." + MESSAGE_ID_COLUMN + "=OLD."
-                + MESSAGE_ID_COLUMN + "; END");
-    }
-
-    RcsProviderMessageHelper(SQLiteOpenHelper sqLiteOpenHelper) {
-        mSqLiteOpenHelper = sqLiteOpenHelper;
-    }
-
-    Cursor queryMessages(Bundle bundle) {
-        RcsMessageQueryParams queryParameters = null;
-        RcsQueryContinuationToken continuationToken = null;
-
-        if (bundle != null) {
-            queryParameters = bundle.getParcelable(MESSAGE_QUERY_PARAMETERS_KEY);
-            continuationToken = bundle.getParcelable(QUERY_CONTINUATION_TOKEN);
-        }
-
-        if (continuationToken != null) {
-            return RcsProviderUtil.performContinuationQuery(mSqLiteOpenHelper.getReadableDatabase(),
-                    continuationToken);
-        }
-
-        // if no parameters were entered, build an empty query parameters object
-        if (queryParameters == null) {
-            queryParameters = new RcsMessageQueryParams.Builder().build();
-        }
-
-        return performInitialQuery(queryParameters);
-    }
-
-    private Cursor performInitialQuery(RcsMessageQueryParams queryParameters) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-
-        StringBuilder rawQuery = new StringBuilder("SELECT * FROM ").append(UNIFIED_MESSAGE_VIEW);
-
-        int messageType = queryParameters.getMessageType();
-        String messageLike = queryParameters.getMessageLike();
-        int threadId = queryParameters.getThreadId();
-
-        boolean isMessageLikePresent = !TextUtils.isEmpty(messageLike);
-        boolean isMessageTypeFiltered = (messageType == MESSAGE_TYPE_INCOMING)
-                || (messageType == MESSAGE_TYPE_OUTGOING);
-        boolean isThreadFiltered = threadId != THREAD_ID_NOT_SET;
-
-        if (isMessageLikePresent || isMessageTypeFiltered || isThreadFiltered) {
-            rawQuery.append(" WHERE ");
-        }
-
-        if (messageType == MESSAGE_TYPE_INCOMING) {
-            rawQuery.append(MESSAGE_TYPE_COLUMN).append("=").append(MESSAGE_TYPE_INCOMING);
-        } else if (messageType == MESSAGE_TYPE_OUTGOING) {
-            rawQuery.append(MESSAGE_TYPE_COLUMN).append("=").append(MESSAGE_TYPE_OUTGOING);
-        }
-
-        if (isMessageLikePresent) {
-            if (isMessageTypeFiltered) {
-                rawQuery.append(" AND ");
-            }
-            rawQuery.append(MESSAGE_TEXT_COLUMN).append(" LIKE \"").append(messageLike)
-                    .append("\"");
-        }
-
-        if (isThreadFiltered) {
-            if (isMessageLikePresent || isMessageTypeFiltered) {
-                rawQuery.append(" AND ");
-            }
-            rawQuery.append(RCS_THREAD_ID_COLUMN).append("=").append(threadId);
-        }
-
-        // TODO - figure out a way to see if this message has file transfer or not. Ideally we
-        // should join the unified table with file transfer table, but using a trigger to change a
-        // flag on rcs_message would also work
-
-        rawQuery.append(" ORDER BY ");
-
-        int sortingProperty = queryParameters.getSortingProperty();
-        if (sortingProperty == RcsMessageQueryParams.SORT_BY_TIMESTAMP) {
-            rawQuery.append(ORIGINATION_TIMESTAMP_COLUMN);
-        } else {
-            rawQuery.append(MESSAGE_ID_COLUMN);
-        }
-
-        rawQuery.append(queryParameters.getSortDirection() ? " ASC " : " DESC ");
-
-        RcsProviderUtil.appendLimit(rawQuery, queryParameters.getLimit());
-        String rawQueryAsString = rawQuery.toString();
-        Cursor cursor = db.rawQuery(rawQueryAsString, null);
-
-        // If the query was paginated, build the next query
-        int limit = queryParameters.getLimit();
-        if (limit > 0) {
-            RcsProviderUtil.createContinuationTokenBundle(cursor,
-                    new RcsQueryContinuationToken(MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE,
-                            rawQueryAsString, limit, limit), QUERY_CONTINUATION_TOKEN);
-        }
-
-        return cursor;
-    }
-
-    Cursor queryUnifiedMessageWithId(Uri uri) {
-        return queryUnifiedMessageWithSelection(getMessageIdSelection(uri), null);
-    }
-
-    Cursor queryUnifiedMessageWithIdInThread(Uri uri) {
-        return queryUnifiedMessageWithSelection(getMessageIdSelectionInThreadUri(uri), null);
-    }
-
-    Cursor queryUnifiedMessageWithSelection(String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(UNIFIED_MESSAGE_VIEW, null, selection, selectionArgs, null, null, null,
-                null);
-    }
-
-    Cursor queryIncomingMessageWithId(Uri uri) {
-        return queryIncomingMessageWithSelection(getMessageIdSelection(uri), null);
-    }
-
-    Cursor queryIncomingMessageWithSelection(String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(UNIFIED_INCOMING_MESSAGE_VIEW, null, selection, selectionArgs, null, null,
-                null, null);
-    }
-
-    Cursor queryOutgoingMessageWithId(Uri uri) {
-        return queryOutgoingMessageWithSelection(getMessageIdSelection(uri), null);
-    }
-
-    Cursor queryOutgoingMessageWithSelection(String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(UNIFIED_OUTGOING_MESSAGE_VIEW, null, selection, selectionArgs, null, null,
-                null, null);
-    }
-
-    Cursor queryAllMessagesOnThread(Uri uri, String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-
-        String appendedSelection = appendThreadIdToSelection(uri, selection);
-        return db.query(UNIFIED_MESSAGE_VIEW, null, appendedSelection, null, null, null, null);
-    }
-
-    Uri insertMessageOnThread(Uri uri, ContentValues valuesParameter, boolean isIncoming,
-            boolean is1To1) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-
-        String threadId = RcsProviderThreadHelper.getThreadIdFromUri(uri);
-        ContentValues values = new ContentValues(valuesParameter);
-        values.put(RCS_THREAD_ID_COLUMN, Integer.parseInt(threadId));
-
-        db.beginTransaction();
-
-        ContentValues subMessageTableValues = new ContentValues();
-        if (isIncoming) {
-            subMessageTableValues = getIncomingMessageValues(values);
-        }
-
-        long rowId;
-        try {
-            rowId = db.insert(RCS_MESSAGE_TABLE, MESSAGE_ID_COLUMN, values);
-            if (rowId == INSERTION_FAILED) {
-                return null;
-            }
-
-            subMessageTableValues.put(MESSAGE_ID_COLUMN, rowId);
-            long tempId = db.insert(
-                    isIncoming ? RCS_INCOMING_MESSAGE_TABLE : RCS_OUTGOING_MESSAGE_TABLE,
-                    MESSAGE_ID_COLUMN, subMessageTableValues);
-            if (tempId == INSERTION_FAILED) {
-                return null;
-            }
-
-            // if the thread is outgoing, insert message deliveries
-            if (!isIncoming && !insertMessageDeliveriesForOutgoingMessageCreation(db, tempId,
-                    threadId)) {
-                return null;
-            }
-
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
-        }
-
-        values.remove(RCS_THREAD_ID_COLUMN);
-
-        String threadPart =  is1To1 ? RCS_1_TO_1_THREAD_URI_PART : RCS_GROUP_THREAD_URI_PART;
-        String messagePart = isIncoming ? INCOMING_MESSAGE_URI_PART : OUTGOING_MESSAGE_URI_PART;
-
-        return CONTENT_AND_AUTHORITY.buildUpon().appendPath(threadPart).appendPath(threadId).
-                appendPath(messagePart).appendPath(Long.toString(rowId)).build();
-    }
-
-    // Tries to insert deliveries for outgoing message, returns false if it fails.
-    private boolean insertMessageDeliveriesForOutgoingMessageCreation(
-            SQLiteDatabase dbInTransaction, long messageId, String threadId) {
-        try (Cursor participantsInThreadCursor = dbInTransaction.query(
-                RCS_PARTICIPANT_THREAD_JUNCTION_TABLE, null, RCS_THREAD_ID_COLUMN + "=?",
-                new String[]{threadId}, null, null, null)) {
-            if (participantsInThreadCursor == null) {
-                return false;
-            }
-
-            while (participantsInThreadCursor.moveToNext()) {
-                String participantId = participantsInThreadCursor.getString(
-                        participantsInThreadCursor.getColumnIndex(
-                                RCS_PARTICIPANT_ID_COLUMN));
-
-                long insertionRow = insertMessageDelivery(Long.toString(messageId), participantId,
-                        new ContentValues());
-
-                if (insertionRow == INSERTION_FAILED) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    long insertMessageDelivery(Uri uri, ContentValues values) {
-        String messageId = getMessageIdFromUri(uri);
-        String participantId = getParticipantIdFromDeliveryUri(uri);
-        return insertMessageDelivery(messageId, participantId, values);
-    }
-
-    private long insertMessageDelivery(String messageId, String participantId,
-            ContentValues valuesParameter) {
-        ContentValues values = new ContentValues(valuesParameter);
-        values.put(MESSAGE_ID_COLUMN, messageId);
-        values.put(RCS_PARTICIPANT_ID_COLUMN, participantId);
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.insert(RCS_MESSAGE_DELIVERY_TABLE, MESSAGE_ID_COLUMN, values);
-    }
-
-    int updateDelivery(Uri uri, ContentValues contentValues) {
-        String messageId = getMessageIdFromUri(uri);
-        String participantId = getParticipantIdFromDeliveryUri(uri);
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.update(RCS_MESSAGE_DELIVERY_TABLE, contentValues,
-                MESSAGE_ID_COLUMN + "=? AND " + RCS_PARTICIPANT_ID_COLUMN + "=?",
-                new String[]{messageId, participantId});
-    }
-
-    int deleteIncomingMessageWithId(Uri uri) {
-        return deleteIncomingMessageWithSelection(getMessageIdSelection(uri), null);
-    }
-
-    int deleteIncomingMessageWithSelection(String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.delete(RCS_INCOMING_MESSAGE_TABLE, selection, selectionArgs);
-    }
-
-    int deleteOutgoingMessageWithId(Uri uri) {
-        return deleteOutgoingMessageWithSelection(getMessageIdSelection(uri), null);
-    }
-
-    int deleteOutgoingMessageWithSelection(String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.delete(RCS_OUTGOING_MESSAGE_TABLE, selection, selectionArgs);
-    }
-
-    int updateIncomingMessage(Uri uri, ContentValues values) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-
-        ContentValues incomingMessageValues = getIncomingMessageValues(values);
-
-        int updateCountInIncoming = 0;
-        int updateCountInCommon = 0;
-        db.beginTransaction();
-        if (!incomingMessageValues.isEmpty()) {
-            updateCountInIncoming = db.update(RCS_INCOMING_MESSAGE_TABLE, incomingMessageValues,
-                    getMessageIdSelection(uri), null);
-        }
-        if (!values.isEmpty()) {
-            updateCountInCommon = db.update(RCS_MESSAGE_TABLE, values, getMessageIdSelection(uri),
-                    null);
-        }
-        db.setTransactionSuccessful();
-        db.endTransaction();
-
-        return Math.max(updateCountInIncoming, updateCountInCommon);
-    }
-
-    int updateOutgoingMessage(Uri uri, ContentValues values) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.update(RCS_MESSAGE_TABLE, values, getMessageIdSelection(uri), null);
-    }
-
-    Cursor queryOutgoingMessageDeliveries(Uri uri) {
-        String messageId = getMessageIdFromUri(uri);
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(RCS_MESSAGE_DELIVERY_TABLE, null, MESSAGE_ID_COLUMN + "=?",
-                new String[]{messageId}, null, null, null);
-    }
-
-    Cursor queryFileTransfer(Uri uri) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(RCS_FILE_TRANSFER_TABLE, null, FILE_TRANSFER_ID_COLUMN + "=?",
-                new String[]{getFileTransferIdFromUri(uri)}, null, null, null, null);
-    }
-
-    long insertFileTransferToMessage(Uri uri, ContentValues values) {
-        String messageId = getMessageIdFromUri(uri);
-        values.put(MESSAGE_ID_COLUMN, messageId);
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        long rowId = db.insert(RCS_FILE_TRANSFER_TABLE, MESSAGE_ID_COLUMN, values);
-        values.remove(MESSAGE_ID_COLUMN);
-
-        if (rowId == INSERTION_FAILED) {
-            rowId = TRANSACTION_FAILED;
-        }
-
-        return rowId;
-    }
-
-    int deleteFileTransfer(Uri uri) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.delete(RCS_FILE_TRANSFER_TABLE, FILE_TRANSFER_ID_COLUMN + "=?",
-                new String[]{getFileTransferIdFromUri(uri)});
-    }
-
-    int updateFileTransfer(Uri uri, ContentValues values) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.update(RCS_FILE_TRANSFER_TABLE, values,
-                FILE_TRANSFER_ID_COLUMN + "=?", new String[]{getFileTransferIdFromUri(uri)});
-    }
-
-    /**
-     * Removes the incoming message values out of all values and returns as a separate content
-     * values object.
-     */
-    private ContentValues getIncomingMessageValues(ContentValues allValues) {
-        ContentValues incomingMessageValues = new ContentValues();
-
-        if (allValues.containsKey(SENDER_PARTICIPANT_ID_COLUMN)) {
-            incomingMessageValues.put(SENDER_PARTICIPANT_ID_COLUMN,
-                    allValues.getAsInteger(SENDER_PARTICIPANT_ID_COLUMN));
-            allValues.remove(SENDER_PARTICIPANT_ID_COLUMN);
-        }
-
-        if (allValues.containsKey(ARRIVAL_TIMESTAMP_COLUMN)) {
-            incomingMessageValues.put(
-                    ARRIVAL_TIMESTAMP_COLUMN, allValues.getAsLong(ARRIVAL_TIMESTAMP_COLUMN));
-            allValues.remove(ARRIVAL_TIMESTAMP_COLUMN);
-        }
-
-        if (allValues.containsKey(RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN)) {
-            incomingMessageValues.put(
-                    RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN,
-                    allValues.getAsLong(RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN));
-            allValues.remove(RcsIncomingMessageColumns.SEEN_TIMESTAMP_COLUMN);
-        }
-
-        return incomingMessageValues;
-    }
-
-    private String appendThreadIdToSelection(Uri uri, String selection) {
-        String threadIdSelection = RCS_THREAD_ID_COLUMN + "=" + getThreadIdFromUri(uri);
-
-        if (TextUtils.isEmpty(selection)) {
-            return threadIdSelection;
-        }
-
-        return "(" + selection + ") AND " + threadIdSelection;
-    }
-
-    private String getMessageIdSelection(Uri uri) {
-        return MESSAGE_ID_COLUMN + "=" + getMessageIdFromUri(uri);
-    }
-
-    private String getMessageIdSelectionInThreadUri(Uri uri) {
-        return MESSAGE_ID_COLUMN + "=" + getMessageIdFromThreadUri(uri);
-    }
-
-    private String getMessageIdFromUri(Uri uri) {
-        return uri.getPathSegments().get(MESSAGE_ID_INDEX_IN_URI);
-    }
-
-    private String getFileTransferIdFromUri(Uri uri) {
-        // this works because messages and file transfer uri's have the same indices.
-        return getMessageIdFromUri(uri);
-    }
-
-    private String getParticipantIdFromDeliveryUri(Uri uri) {
-        // this works because messages in threads and participants in deliveries have the same
-        // indices.
-        return getMessageIdFromThreadUri(uri);
-    }
-
-    private String getMessageIdFromThreadUri(Uri uri) {
-        return uri.getPathSegments().get(MESSAGE_ID_INDEX_IN_THREAD_URI);
-    }
-}
diff --git a/src/com/android/providers/telephony/RcsProviderParticipantHelper.java b/src/com/android/providers/telephony/RcsProviderParticipantHelper.java
deleted file mode 100644
index ab23d6d..0000000
--- a/src/com/android/providers/telephony/RcsProviderParticipantHelper.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * 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.CanonicalAddressesColumns.ADDRESS;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.CANONICAL_ADDRESS_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_ALIAS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_URI_PART;
-import static android.provider.Telephony.RcsColumns.RcsParticipantHelpers.RCS_PARTICIPANT_WITH_ADDRESS_VIEW;
-import static android.provider.Telephony.RcsColumns.RcsParticipantHelpers.RCS_PARTICIPANT_WITH_THREAD_VIEW;
-import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.TRANSACTION_FAILED;
-import static android.telephony.ims.RcsParticipantQueryParams.PARTICIPANT_QUERY_PARAMETERS_KEY;
-
-import static android.telephony.ims.RcsQueryContinuationToken.PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE;
-import static android.telephony.ims.RcsQueryContinuationToken.QUERY_CONTINUATION_TOKEN;
-import static com.android.providers.telephony.RcsProvider.GROUP_THREAD_URI_PREFIX;
-import static com.android.providers.telephony.RcsProvider.RCS_PARTICIPANT_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_PARTICIPANT_THREAD_JUNCTION_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_THREAD_TABLE;
-import static com.android.providers.telephony.RcsProvider.TAG;
-import static com.android.providers.telephony.RcsProviderThreadHelper.getThreadIdFromUri;
-import static com.android.providers.telephony.RcsProviderUtil.INSERTION_FAILED;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.os.Bundle;
-import android.telephony.ims.RcsParticipantQueryParams;
-import android.telephony.ims.RcsQueryContinuationToken;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Constants and helpers related to participants for {@link RcsProvider} to keep the code clean.
- *
- * @hide
- */
-class RcsProviderParticipantHelper {
-    private static final int PARTICIPANT_ID_INDEX_IN_URI = 1;
-    private static final int PARTICIPANT_ID_INDEX_IN_THREAD_URI = 3;
-
-    @VisibleForTesting
-    public static void createParticipantTables(SQLiteDatabase db) {
-        Log.d(TAG, "Creating participant tables");
-
-        // create participant tables
-        db.execSQL("CREATE TABLE " + RCS_PARTICIPANT_TABLE + " (" +
-                RCS_PARTICIPANT_ID_COLUMN + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
-                CANONICAL_ADDRESS_ID_COLUMN + " INTEGER ," +
-                RCS_ALIAS_COLUMN + " TEXT, " +
-                "FOREIGN KEY(" + CANONICAL_ADDRESS_ID_COLUMN + ") "
-                + "REFERENCES canonical_addresses(_id)" +
-                ");");
-
-        db.execSQL("CREATE TABLE " + RCS_PARTICIPANT_THREAD_JUNCTION_TABLE + " (" +
-                RCS_THREAD_ID_COLUMN + " INTEGER, " +
-                RCS_PARTICIPANT_ID_COLUMN + " INTEGER, " +
-                "CONSTRAINT thread_participant PRIMARY KEY("
-                + RCS_THREAD_ID_COLUMN + ", " + RCS_PARTICIPANT_ID_COLUMN + "), " +
-                "FOREIGN KEY(" + RCS_THREAD_ID_COLUMN
-                + ") REFERENCES " + RCS_THREAD_TABLE + "(" + RCS_THREAD_ID_COLUMN + "), " +
-                "FOREIGN KEY(" + RCS_PARTICIPANT_ID_COLUMN
-                + ") REFERENCES " + RCS_PARTICIPANT_TABLE + "(" + RCS_PARTICIPANT_ID_COLUMN + "))");
-
-        // create views
-
-        // The following view joins rcs_participant table with canonical_addresses table to add the
-        // actual address of a participant in the result.
-        db.execSQL("CREATE VIEW " + RCS_PARTICIPANT_WITH_ADDRESS_VIEW + " AS SELECT "
-                + "rcs_participant.rcs_participant_id, rcs_participant.canonical_address_id, "
-                + "rcs_participant.rcs_alias, canonical_addresses.address FROM rcs_participant "
-                + "LEFT JOIN canonical_addresses ON "
-                + "rcs_participant.canonical_address_id=canonical_addresses._id");
-
-        // The following view is the rcs_participant_with_address_view above, plus the information
-        // on which threads this participant contributes to, to enable getting participants of a
-        // thread
-        db.execSQL("CREATE VIEW " + RCS_PARTICIPANT_WITH_THREAD_VIEW + " AS SELECT "
-                + "rcs_participant.rcs_participant_id, rcs_participant.canonical_address_id, "
-                + "rcs_participant.rcs_alias, canonical_addresses.address, rcs_thread_participant"
-                + ".rcs_thread_id FROM rcs_participant LEFT JOIN canonical_addresses ON "
-                + "rcs_participant.canonical_address_id=canonical_addresses._id LEFT JOIN "
-                + "rcs_thread_participant ON rcs_participant.rcs_participant_id="
-                + "rcs_thread_participant.rcs_participant_id");
-
-        // TODO - create indexes for faster querying
-    }
-
-    private final SQLiteOpenHelper mSqLiteOpenHelper;
-
-    RcsProviderParticipantHelper(SQLiteOpenHelper sqLiteOpenHelper) {
-        mSqLiteOpenHelper = sqLiteOpenHelper;
-    }
-
-    Cursor queryParticipant(Bundle bundle) {
-        RcsParticipantQueryParams queryParameters = null;
-        RcsQueryContinuationToken continuationToken = null;
-
-        if (bundle != null) {
-            queryParameters = bundle.getParcelable(PARTICIPANT_QUERY_PARAMETERS_KEY);
-            continuationToken = bundle.getParcelable(QUERY_CONTINUATION_TOKEN);
-        }
-
-        if (continuationToken != null) {
-            return RcsProviderUtil.performContinuationQuery(mSqLiteOpenHelper.getReadableDatabase(),
-                    continuationToken);
-        }
-
-        if (queryParameters == null) {
-            queryParameters = new RcsParticipantQueryParams.Builder().build();
-        }
-
-        return performInitialQuery(queryParameters);
-    }
-
-    private Cursor performInitialQuery(RcsParticipantQueryParams queryParameters) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-
-        StringBuilder rawQuery = buildInitialRawQuery(queryParameters);
-        RcsProviderUtil.appendLimit(rawQuery, queryParameters.getLimit());
-        String rawQueryAsString = rawQuery.toString();
-        Cursor cursor = db.rawQuery(rawQueryAsString, null);
-
-        // If the query was paginated, build the next query
-        int limit = queryParameters.getLimit();
-        if (limit > 0) {
-            RcsProviderUtil.createContinuationTokenBundle(cursor,
-                    new RcsQueryContinuationToken(PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE,
-                            rawQueryAsString, limit, limit), QUERY_CONTINUATION_TOKEN);
-        }
-
-        return cursor;
-    }
-
-    private StringBuilder buildInitialRawQuery(RcsParticipantQueryParams queryParameters) {
-        StringBuilder rawQuery = new StringBuilder("SELECT * FROM ");
-
-        boolean isThreadFiltered = queryParameters.getThreadId() > 0;
-
-        if (isThreadFiltered) {
-            rawQuery.append(RCS_PARTICIPANT_WITH_THREAD_VIEW);
-        } else {
-            rawQuery.append(RCS_PARTICIPANT_WITH_ADDRESS_VIEW);
-        }
-
-        boolean isAliasFiltered = !TextUtils.isEmpty(queryParameters.getAliasLike());
-        boolean isCanonicalAddressFiltered = !TextUtils.isEmpty(
-                queryParameters.getCanonicalAddressLike());
-
-        if (isAliasFiltered || isCanonicalAddressFiltered || isThreadFiltered) {
-            rawQuery.append(" WHERE ");
-        }
-
-        if (isAliasFiltered) {
-            rawQuery.append(RCS_ALIAS_COLUMN).append(" LIKE \"").append(
-                    queryParameters.getAliasLike()).append("\"");
-        }
-
-        if (isCanonicalAddressFiltered) {
-            if (isAliasFiltered) {
-                rawQuery.append(" AND ");
-            }
-            rawQuery.append(ADDRESS).append(" LIKE \"").append(
-                    queryParameters.getCanonicalAddressLike()).append("\"");
-        }
-
-        if (isThreadFiltered) {
-            if (isAliasFiltered || isCanonicalAddressFiltered) {
-                rawQuery.append(" AND ");
-            }
-            rawQuery.append(RCS_THREAD_ID_COLUMN).append("=").append(queryParameters.getThreadId());
-        }
-
-        rawQuery.append(" ORDER BY ");
-
-        int sortingProperty = queryParameters.getSortingProperty();
-        if (sortingProperty == RcsParticipantQueryParams.SORT_BY_ALIAS) {
-            rawQuery.append(RCS_ALIAS_COLUMN);
-        } else if (sortingProperty == RcsParticipantQueryParams.SORT_BY_CANONICAL_ADDRESS) {
-            rawQuery.append(ADDRESS);
-        } else {
-            rawQuery.append(RCS_PARTICIPANT_ID_COLUMN);
-        }
-        rawQuery.append(queryParameters.getSortDirection() ? " ASC " : " DESC ");
-
-        return rawQuery;
-    }
-
-    Cursor queryParticipantWithId(Uri uri, String[] projection) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(RCS_PARTICIPANT_WITH_ADDRESS_VIEW, projection,
-                getParticipantIdSelection(uri), null, null, null, null);
-    }
-
-    Cursor queryParticipantIn1To1Thread(Uri uri) {
-        String threadId = getThreadIdFromUri(uri);
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-
-        return db.rawQuery(
-                "  SELECT * "
-                        + "FROM rcs_participant "
-                        + "WHERE rcs_participant.rcs_participant_id = ("
-                        + "  SELECT rcs_thread_participant.rcs_participant_id "
-                        + "  FROM rcs_thread_participant "
-                        + "  WHERE rcs_thread_participant.rcs_thread_id=" + threadId + ")", null);
-    }
-
-    Cursor queryParticipantsInGroupThread(Uri uri) {
-        String threadId = getThreadIdFromUri(uri);
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-
-        return db.rawQuery("  SELECT * "
-                + "FROM rcs_participant "
-                + "WHERE rcs_participant.rcs_participant_id = ("
-                + "  SELECT rcs_participant_id "
-                + "  FROM rcs_thread_participant "
-                + "  WHERE rcs_thread_id= " + threadId + ")", null);
-    }
-
-    Cursor queryParticipantInGroupThreadWithId(Uri uri) {
-        String threadId = getThreadIdFromUri(uri);
-        String participantId = getParticipantIdFromUri(uri);
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-
-        return db.rawQuery("  SELECT * "
-                        + "FROM rcs_participant "
-                        + "WHERE rcs_participant.rcs_participant_id = ("
-                        + "  SELECT rcs_participant_id "
-                        + "  FROM rcs_thread_participant "
-                        + "  WHERE rcs_thread_id=? AND rcs_participant_id=?)",
-                new String[]{threadId, participantId});
-    }
-
-    long insertParticipant(ContentValues contentValues) {
-        if (!contentValues.containsKey(CANONICAL_ADDRESS_ID_COLUMN) || TextUtils.isEmpty(
-                contentValues.getAsString(CANONICAL_ADDRESS_ID_COLUMN))) {
-            Log.e(TAG,
-                    "RcsProviderParticipantHelper: Inserting participants without canonical "
-                            + "address is not supported");
-            return TRANSACTION_FAILED;
-        }
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        long rowId = db.insert(RCS_PARTICIPANT_TABLE, RCS_PARTICIPANT_ID_COLUMN, contentValues);
-        Log.e(TAG, "Inserted participant with rowId=" + rowId);
-        if (rowId < 0) {
-            return TRANSACTION_FAILED;
-        }
-        return rowId;
-    }
-
-    /**
-     * Inserts a participant into group thread. This function returns the participant ID instead of
-     * the row id in the junction table
-     */
-    long insertParticipantIntoGroupThread(ContentValues values) {
-        if (!values.containsKey(RCS_THREAD_ID_COLUMN) || !values.containsKey(
-                RCS_PARTICIPANT_ID_COLUMN)) {
-            Log.e(TAG, "RcsProviderParticipantHelper: Cannot insert participant into group.");
-            return TRANSACTION_FAILED;
-        }
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        long insertedRowId = db.insert(RCS_PARTICIPANT_THREAD_JUNCTION_TABLE,
-                RCS_PARTICIPANT_ID_COLUMN,
-                values);
-
-        if (insertedRowId == INSERTION_FAILED) {
-            return TRANSACTION_FAILED;
-        }
-
-        return values.getAsLong(RCS_PARTICIPANT_ID_COLUMN);
-    }
-
-    /**
-     * Inserts a participant into group thread. This function returns the participant ID instead of
-     * the row id in the junction table
-     */
-    long insertParticipantIntoGroupThreadWithId(Uri uri) {
-        String threadId = getThreadIdFromUri(uri);
-        String participantId = getParticipantIdFromUri(uri);
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-
-        ContentValues contentValues = new ContentValues(2);
-        contentValues.put(RCS_THREAD_ID_COLUMN, threadId);
-        contentValues.put(RCS_PARTICIPANT_ID_COLUMN, participantId);
-
-        long insertedRowId = db.insert(
-                RCS_PARTICIPANT_THREAD_JUNCTION_TABLE, RCS_PARTICIPANT_ID_COLUMN, contentValues);
-
-        if (insertedRowId == INSERTION_FAILED) {
-            return TRANSACTION_FAILED;
-        }
-
-        return Long.parseLong(participantId);
-    }
-
-    int deleteParticipantWithId(Uri uri) {
-        String participantId = uri.getPathSegments().get(PARTICIPANT_ID_INDEX_IN_URI);
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-
-        // See if this participant is involved in any threads
-        Cursor cursor = db.query(RCS_PARTICIPANT_THREAD_JUNCTION_TABLE, null,
-                RCS_PARTICIPANT_ID_COLUMN + "=?", new String[]{participantId}, null, null, null);
-
-        int participatingThreadCount = 0;
-        if (cursor != null) {
-            participatingThreadCount = cursor.getCount();
-            cursor.close();
-        }
-
-        if (participatingThreadCount > 0) {
-            Log.e(TAG,
-                    "RcsProviderParticipantHelper: Can't delete participant while it is still in "
-                            + "RCS threads, uri:"
-                            + uri);
-            return 0;
-        }
-
-        return db.delete(RCS_PARTICIPANT_TABLE, RCS_PARTICIPANT_ID_COLUMN + "=?",
-                new String[]{participantId});
-    }
-
-    int deleteParticipantFromGroupThread(Uri uri) {
-        String threadId = getThreadIdFromUri(uri);
-        String participantId = getParticipantIdFromUri(uri);
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        // TODO check to remove owner
-        return db.delete(RCS_PARTICIPANT_THREAD_JUNCTION_TABLE,
-                RCS_THREAD_ID_COLUMN + "=? AND " + RCS_PARTICIPANT_ID_COLUMN + "=?",
-                new String[]{threadId, participantId});
-    }
-
-    int updateParticipant(ContentValues contentValues, String selection, String[] selectionArgs) {
-        if (contentValues.containsKey(RCS_PARTICIPANT_ID_COLUMN)) {
-            Log.e(TAG, "RcsProviderParticipantHelper: Updating participant id is not supported");
-            return 0;
-        }
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.update(RCS_PARTICIPANT_TABLE, contentValues, selection, selectionArgs);
-    }
-
-    int updateParticipantWithId(ContentValues contentValues, Uri uri) {
-        return updateParticipant(contentValues, getParticipantIdSelection(uri), null);
-    }
-
-    private String getParticipantIdSelection(Uri uri) {
-        return RCS_PARTICIPANT_ID_COLUMN + "=" + uri.getPathSegments().get(
-                PARTICIPANT_ID_INDEX_IN_URI);
-    }
-
-    Uri getParticipantInThreadUri(ContentValues values, long rowId) {
-        if (values == null) {
-            return null;
-        }
-        Integer threadId = values.getAsInteger(RCS_THREAD_ID_COLUMN);
-        if (threadId == null) {
-            return null;
-        }
-
-        return GROUP_THREAD_URI_PREFIX.buildUpon().appendPath(
-                Integer.toString(threadId)).appendPath(RCS_PARTICIPANT_URI_PART).appendPath(
-                Long.toString(rowId)).build();
-    }
-
-    private String getParticipantIdFromUri(Uri uri) {
-        return uri.getPathSegments().get(PARTICIPANT_ID_INDEX_IN_THREAD_URI);
-    }
-}
diff --git a/src/com/android/providers/telephony/RcsProviderThreadHelper.java b/src/com/android/providers/telephony/RcsProviderThreadHelper.java
deleted file mode 100644
index c1a35ef..0000000
--- a/src/com/android/providers/telephony/RcsProviderThreadHelper.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * 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.RcsColumns.Rcs1To1ThreadColumns.FALLBACK_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.CONFERENCE_URI_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_ICON_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_NAME_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.OWNER_PARTICIPANT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_TEXT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.ORIGINATION_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.STATUS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsUnifiedThreadColumns.THREAD_TYPE_COLUMN;
-import static android.provider.Telephony.RcsColumns.TRANSACTION_FAILED;
-import static android.telephony.ims.RcsQueryContinuationToken.QUERY_CONTINUATION_TOKEN;
-import static android.telephony.ims.RcsQueryContinuationToken.THREAD_QUERY_CONTINUATION_TOKEN_TYPE;
-import static android.telephony.ims.RcsThreadQueryParams.THREAD_QUERY_PARAMETERS_KEY;
-
-import static com.android.providers.telephony.RcsProvider.RCS_1_TO_1_THREAD_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_GROUP_THREAD_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_MESSAGE_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_PARTICIPANT_THREAD_JUNCTION_TABLE;
-import static com.android.providers.telephony.RcsProvider.RCS_THREAD_TABLE;
-import static com.android.providers.telephony.RcsProvider.TAG;
-import static com.android.providers.telephony.RcsProvider.UNIFIED_RCS_THREAD_VIEW;
-import static com.android.providers.telephony.RcsProviderUtil.INSERTION_FAILED;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.BaseColumns;
-import android.telephony.ims.RcsQueryContinuationToken;
-import android.telephony.ims.RcsThreadQueryParams;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Constants and helpers related to threads for {@link RcsProvider} to keep the code clean.
- *
- * @hide
- */
-class RcsProviderThreadHelper {
-    private static final int THREAD_ID_INDEX_IN_URI = 1;
-
-    @VisibleForTesting
-    public static void createThreadTables(SQLiteDatabase db) {
-        Log.d(TAG, "Creating thread tables");
-
-        // Add the thread tables
-        db.execSQL("CREATE TABLE " + RCS_THREAD_TABLE + " (" +
-                RCS_THREAD_ID_COLUMN + " INTEGER PRIMARY KEY AUTOINCREMENT);");
-
-        db.execSQL("CREATE TABLE " + RCS_1_TO_1_THREAD_TABLE + " (" +
-                RCS_THREAD_ID_COLUMN + " INTEGER PRIMARY KEY, " +
-                FALLBACK_THREAD_ID_COLUMN + " INTEGER, " +
-                "FOREIGN KEY(" + RCS_THREAD_ID_COLUMN
-                + ") REFERENCES " + RCS_THREAD_TABLE + "(" + RCS_THREAD_ID_COLUMN + ")," +
-                "FOREIGN KEY(" + FALLBACK_THREAD_ID_COLUMN
-                + ") REFERENCES threads( " + BaseColumns._ID + "))");
-
-        db.execSQL("CREATE TABLE " + RCS_GROUP_THREAD_TABLE + " (" +
-                RCS_THREAD_ID_COLUMN + " INTEGER PRIMARY KEY, " +
-                OWNER_PARTICIPANT_COLUMN + " INTEGER, " +
-                GROUP_NAME_COLUMN + " TEXT, " +
-                GROUP_ICON_COLUMN + " TEXT, " +
-                CONFERENCE_URI_COLUMN + " TEXT, " +
-                "FOREIGN KEY(" + RCS_THREAD_ID_COLUMN
-                + ") REFERENCES " + RCS_THREAD_TABLE + "(" + RCS_THREAD_ID_COLUMN + "))");
-
-        // Add the views
-
-        // The following is a unified thread view. Since SQLite does not support right or full
-        // joins, we are using a union with null values for unused variables for each thread type.
-        // The thread_type column is an easy way to figure out whether the entry came from a 1 to 1
-        // thread or a group thread. The last message in each thread is appended to the table
-        // entries to figure out the latest threads and snippet text. We use COALESCE so that MAX()
-        // can take null values into account in order to have threads with no messages still
-        // represented here
-        //
-        // SELECT <1 to 1 thread and first message>
-        // FROM (
-        //     SELECT *
-        //     FROM rcs_1_to_1_thread LEFT JOIN rcs_message
-        //         ON rcs_1_to_1_thread.rcs_thread_id=rcs_message.rcs_thread_id)
-        // GROUP BY rcs_thread_id
-        // HAVING MAX(COALESCE(origination_timestamp,1))
-        //
-        // UNION
-        // SELECT <group thread and first message>
-        // FROM (
-        //     SELECT *
-        //     FROM rcs_group_thread LEFT JOIN rcs_message
-        //         ON rcs_group_thread.rcs_thread_id=rcs_message.rcs_thread_id)
-        // GROUP BY rcs_thread_id
-        // HAVING MAX(COALESCE(origination_timestamp,1))
-
-        db.execSQL("CREATE VIEW " + UNIFIED_RCS_THREAD_VIEW + " AS "
-                + "SELECT "
-                + RCS_THREAD_ID_COLUMN + ", "
-                + FALLBACK_THREAD_ID_COLUMN + ", "
-                + "null AS " + OWNER_PARTICIPANT_COLUMN + ", "
-                + "null AS " + GROUP_NAME_COLUMN + ", "
-                + "null AS " + GROUP_ICON_COLUMN + ", "
-                + "null AS " + CONFERENCE_URI_COLUMN + ", "
-                + "0 AS " + THREAD_TYPE_COLUMN + ", "
-                + ORIGINATION_TIMESTAMP_COLUMN + ", "
-                + MESSAGE_TEXT_COLUMN + ", "
-                + STATUS_COLUMN
-                + " FROM (SELECT * FROM "
-                + RCS_1_TO_1_THREAD_TABLE + " LEFT JOIN " + RCS_MESSAGE_TABLE
-                + " ON "
-                + RCS_1_TO_1_THREAD_TABLE + "." + RCS_THREAD_ID_COLUMN + "="
-                + RCS_MESSAGE_TABLE + "." + RCS_THREAD_ID_COLUMN + ")"
-                + " GROUP BY " + RCS_THREAD_ID_COLUMN
-                + " HAVING MAX(COALESCE("
-                + ORIGINATION_TIMESTAMP_COLUMN + ", 1))"
-                + " UNION SELECT "
-                + RCS_THREAD_ID_COLUMN + ", "
-                + "null AS " + FALLBACK_THREAD_ID_COLUMN + ", "
-                + OWNER_PARTICIPANT_COLUMN + ", "
-                + GROUP_NAME_COLUMN + ", "
-                + GROUP_ICON_COLUMN + ", "
-                + CONFERENCE_URI_COLUMN + ", "
-                + "1 AS " + THREAD_TYPE_COLUMN + ", "
-                + ORIGINATION_TIMESTAMP_COLUMN + ", "
-                + MESSAGE_TEXT_COLUMN + ", "
-                + STATUS_COLUMN
-                + " FROM (SELECT * FROM "
-                + RCS_GROUP_THREAD_TABLE + " LEFT JOIN " + RCS_MESSAGE_TABLE
-                + " ON "
-                + RCS_GROUP_THREAD_TABLE + "." + RCS_THREAD_ID_COLUMN + "="
-                + RCS_MESSAGE_TABLE + "." + RCS_THREAD_ID_COLUMN + ")"
-                + " GROUP BY " + RCS_THREAD_ID_COLUMN
-                + " HAVING MAX(COALESCE("
-                + ORIGINATION_TIMESTAMP_COLUMN + ", 1))");
-
-        // Add the triggers
-
-        // Delete the corresponding rcs_thread row upon deleting a row in rcs_1_to_1_thread
-        //
-        // CREATE TRIGGER deleteRcsThreadAfter1to1
-        //  AFTER DELETE ON rcs_1_to_1_thread
-        // BEGIN
-        //	DELETE FROM rcs_thread WHERE rcs_thread._id=OLD.rcs_thread_id;
-        // END
-        db.execSQL("CREATE TRIGGER deleteRcsThreadAfter1to1 AFTER DELETE ON "
-                + RCS_1_TO_1_THREAD_TABLE + " BEGIN DELETE FROM " + RCS_THREAD_TABLE + " WHERE "
-                + RCS_THREAD_TABLE + "." + RCS_THREAD_ID_COLUMN + "=OLD." + RCS_THREAD_ID_COLUMN
-                + "; END");
-
-        // Delete the corresponding rcs_thread row upon deleting a row in rcs_group_thread
-        //
-        // CREATE TRIGGER deleteRcsThreadAfter1to1
-        //  AFTER DELETE ON rcs_1_to_1_thread
-        // BEGIN
-        //	DELETE FROM rcs_thread WHERE rcs_thread._id=OLD.rcs_thread_id;
-        // END
-        db.execSQL("CREATE TRIGGER deleteRcsThreadAfterGroup AFTER DELETE ON "
-                + RCS_GROUP_THREAD_TABLE + " BEGIN DELETE FROM " + RCS_THREAD_TABLE + " WHERE "
-                + RCS_THREAD_TABLE + "." + RCS_THREAD_ID_COLUMN + "=OLD." + RCS_THREAD_ID_COLUMN
-                + "; END");
-
-        // Delete the junction table entries upon deleting a 1 to 1 thread
-        //
-        // CREATE TRIGGER delete1To1JunctionEntries
-        // AFTER
-        //  DELETE ON rcs_1_to_1_thread
-        // BEGIN
-        //  DELETE FROM
-        //   rcs_thread_participant
-        //  WHERE
-        //   rcs_thread_participant.rcs_thread_id = OLD.rcs_thread_id;
-        // END
-        db.execSQL("CREATE TRIGGER delete1To1JunctionEntries AFTER DELETE ON "
-                + RCS_1_TO_1_THREAD_TABLE + " BEGIN DELETE FROM "
-                + RCS_PARTICIPANT_THREAD_JUNCTION_TABLE + " WHERE "
-                + RCS_PARTICIPANT_THREAD_JUNCTION_TABLE + "." + RCS_THREAD_ID_COLUMN + "=OLD."
-                + RCS_THREAD_ID_COLUMN + "; END");
-
-        // Delete the junction table entries upon deleting a group thread
-        //
-        // CREATE TRIGGER delete1To1JunctionEntries
-        // AFTER
-        //  DELETE ON rcs_1_to_1_thread
-        // BEGIN
-        //  DELETE FROM
-        //   rcs_thread_participant
-        //  WHERE
-        //   rcs_thread_participant.rcs_thread_id = OLD.rcs_thread_id;
-        // END
-        db.execSQL("CREATE TRIGGER deleteGroupJunctionEntries AFTER DELETE ON "
-                + RCS_GROUP_THREAD_TABLE + " BEGIN DELETE FROM "
-                + RCS_PARTICIPANT_THREAD_JUNCTION_TABLE + " WHERE "
-                + RCS_PARTICIPANT_THREAD_JUNCTION_TABLE + "." + RCS_THREAD_ID_COLUMN + "=OLD."
-                +RCS_THREAD_ID_COLUMN + "; END");
-
-        // TODO - delete all messages in a thread after deleting a thread
-
-        // TODO - create indexes for faster querying
-    }
-
-    private final SQLiteOpenHelper mSqLiteOpenHelper;
-
-    RcsProviderThreadHelper(SQLiteOpenHelper sqLiteOpenHelper) {
-        mSqLiteOpenHelper = sqLiteOpenHelper;
-    }
-
-    Cursor queryUnifiedThread(Bundle bundle) {
-        RcsThreadQueryParams queryParameters = null;
-        RcsQueryContinuationToken continuationToken = null;
-        if (bundle != null) {
-            queryParameters = bundle.getParcelable(
-                    THREAD_QUERY_PARAMETERS_KEY);
-            continuationToken = bundle.getParcelable(QUERY_CONTINUATION_TOKEN);
-        }
-
-        if (continuationToken != null) {
-            return RcsProviderUtil.performContinuationQuery(mSqLiteOpenHelper.getReadableDatabase(),
-                    continuationToken);
-        }
-
-        if (queryParameters == null) {
-            queryParameters = new RcsThreadQueryParams.Builder().build();
-        }
-
-        return performInitialQuery(queryParameters);
-    }
-
-    private Cursor performInitialQuery(RcsThreadQueryParams queryParameters) {
-        if (queryParameters == null) {
-            // return everything for test purposes
-            queryParameters = new RcsThreadQueryParams.Builder().build();
-        }
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        StringBuilder rawQuery = new StringBuilder("SELECT * FROM ").append(
-                UNIFIED_RCS_THREAD_VIEW);
-
-        if (queryParameters.getThreadType() == RcsThreadQueryParams.THREAD_TYPE_1_TO_1) {
-            rawQuery.append(" WHERE ").append(THREAD_TYPE_COLUMN).append("=0");
-        } else if (queryParameters.getThreadType() == RcsThreadQueryParams.THREAD_TYPE_GROUP) {
-            rawQuery.append(" WHERE ").append(THREAD_TYPE_COLUMN).append("=1");
-        }
-
-        rawQuery.append(" ORDER BY ");
-
-        if (queryParameters.getSortingProperty() == RcsThreadQueryParams.SORT_BY_TIMESTAMP) {
-            rawQuery.append(ORIGINATION_TIMESTAMP_COLUMN);
-        } else {
-            rawQuery.append(RCS_THREAD_ID_COLUMN);
-        }
-
-        rawQuery.append(queryParameters.getSortDirection() ? " ASC " : " DESC ");
-        RcsProviderUtil.appendLimit(rawQuery, queryParameters.getLimit());
-
-        String rawQueryAsString = rawQuery.toString();
-        Cursor cursor = db.rawQuery(rawQueryAsString, null);
-
-        // If this is a paginated query, build the next query and return as a Cursor extra. Only do
-        // this if the current query returned a result.
-        int limit = queryParameters.getLimit();
-        if (limit > 0) {
-            RcsProviderUtil.createContinuationTokenBundle(cursor,
-                    new RcsQueryContinuationToken(THREAD_QUERY_CONTINUATION_TOKEN_TYPE,
-                            rawQueryAsString, limit, limit), QUERY_CONTINUATION_TOKEN);
-        }
-
-        return cursor;
-    }
-
-    Cursor queryUnifiedThreadUsingId(Uri uri, String[] projection) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        String threadId = getThreadIdFromUri(uri);
-
-        return db.query(UNIFIED_RCS_THREAD_VIEW, projection, RCS_THREAD_ID_COLUMN + "=?",
-                new String[]{threadId},
-                null, null, null);
-    }
-
-    Cursor query1to1Thread(String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(RCS_1_TO_1_THREAD_TABLE, projection, selection, selectionArgs, null,
-                null, sortOrder);
-    }
-
-    Cursor query1To1ThreadUsingId(Uri uri, String[] projection) {
-        return query1to1Thread(projection, getThreadIdSelection(uri), null, null);
-    }
-
-    Cursor queryGroupThread(String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getReadableDatabase();
-        return db.query(RCS_GROUP_THREAD_TABLE, projection, selection, selectionArgs, null,
-                null, sortOrder);
-    }
-
-    Cursor queryGroupThreadUsingId(Uri uri, String[] projection) {
-        return queryGroupThread(projection, getThreadIdSelection(uri), null, null);
-    }
-
-    /**
-     * @param contentValues should contain the participant ID of the other participant under key
-     *                      {@link RCS_PARTICIPANT_ID_COLUMN}
-     */
-    long insert1To1Thread(ContentValues contentValues) {
-        if (contentValues.containsKey(RCS_THREAD_ID_COLUMN)) {
-            Log.e(RcsProvider.TAG,
-                    "RcsProviderThreadHelper: inserting threads with IDs is not supported");
-            return TRANSACTION_FAILED;
-        }
-
-        Long participantId = contentValues.getAsLong(RCS_PARTICIPANT_ID_COLUMN);
-        if (participantId == null) {
-            Log.e(RcsProvider.TAG,
-                    "inserting threads without participant IDs is not supported");
-            return TRANSACTION_FAILED;
-        }
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        try {
-            db.beginTransaction();
-
-            if (hasExisting1To1ThreadForParticipant(db, participantId)) {
-                return TRANSACTION_FAILED;
-            }
-
-            long threadId = insertIntoCommonRcsThreads(db);
-            if (threadId == -1) {
-                return TRANSACTION_FAILED;
-            }
-
-            if (insertP2pThread(db, threadId) == -1) {
-                return TRANSACTION_FAILED;
-            }
-
-            if (insertParticipantIntoP2pThread(db, threadId, participantId) == -1) {
-                return TRANSACTION_FAILED;
-            }
-
-            db.setTransactionSuccessful();
-
-            return threadId;
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    private long insertP2pThread(SQLiteDatabase db, long threadId) {
-        ContentValues contentValues = new ContentValues(1);
-        contentValues.put(RCS_THREAD_ID_COLUMN, threadId);
-
-        return db.insert(RCS_1_TO_1_THREAD_TABLE, RCS_THREAD_ID_COLUMN, contentValues);
-    }
-
-    private long insertParticipantIntoP2pThread(
-            SQLiteDatabase db, long threadId, long participantId) {
-        ContentValues contentValues = new ContentValues(2);
-        contentValues.put(RCS_THREAD_ID_COLUMN, threadId);
-        contentValues.put(RCS_PARTICIPANT_ID_COLUMN, participantId);
-
-        return db.insert(
-                RCS_PARTICIPANT_THREAD_JUNCTION_TABLE, RCS_PARTICIPANT_ID_COLUMN, contentValues);
-    }
-
-    private boolean hasExisting1To1ThreadForParticipant(SQLiteDatabase db, long participantId) {
-        String table = joinOnColumn(
-                RCS_PARTICIPANT_THREAD_JUNCTION_TABLE,
-                RCS_1_TO_1_THREAD_TABLE,
-                RCS_THREAD_ID_COLUMN);
-
-        try (Cursor cursor = db.query(
-                table,
-                null,
-                RCS_PARTICIPANT_ID_COLUMN + "=?",
-                new String[]{Long.toString(participantId)},
-                null,
-                null,
-                null)) {
-            if (cursor == null || cursor.getCount() == 0) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private String joinOnColumn(String t1, String t2, String col) {
-        return t1 + " JOIN " + t2 + " ON (" + t1 + "." + col + "=" + t2 + "." + col + ")";
-    }
-
-    long insertGroupThread(ContentValues contentValues) {
-        long returnValue = TRANSACTION_FAILED;
-        if (contentValues.containsKey(RCS_THREAD_ID_COLUMN)) {
-            Log.e(RcsProvider.TAG,
-                    "RcsProviderThreadHelper: inserting threads with IDs is not supported");
-            return returnValue;
-        }
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        try {
-            db.beginTransaction();
-
-            // Insert into the common rcs_threads table
-            long rowId = insertIntoCommonRcsThreads(db);
-            if (rowId == INSERTION_FAILED) {
-                return returnValue;
-            }
-
-            // Add the rowId in rcs_threads table as a foreign key in rcs_group_table
-            contentValues.put(RCS_THREAD_ID_COLUMN, rowId);
-            db.insert(RCS_GROUP_THREAD_TABLE, RCS_THREAD_ID_COLUMN, contentValues);
-            contentValues.remove(RCS_THREAD_ID_COLUMN);
-
-            db.setTransactionSuccessful();
-            returnValue = rowId;
-        } finally {
-            db.endTransaction();
-        }
-        return returnValue;
-    }
-
-    private long insertIntoCommonRcsThreads(SQLiteDatabase db) {
-        return db.insert(RCS_THREAD_TABLE, RCS_THREAD_ID_COLUMN, new ContentValues());
-    }
-
-    int delete1To1Thread(String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.delete(RCS_1_TO_1_THREAD_TABLE, selection, selectionArgs);
-    }
-
-    int delete1To1ThreadWithId(Uri uri) {
-        return delete1To1Thread(getThreadIdSelection(uri), null);
-    }
-
-    int deleteGroupThread(String selection, String[] selectionArgs) {
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.delete(RCS_GROUP_THREAD_TABLE, selection, selectionArgs);
-    }
-
-    int deleteGroupThreadWithId(Uri uri) {
-        return deleteGroupThread(getThreadIdSelection(uri), null);
-    }
-
-    int update1To1Thread(ContentValues values, String selection, String[] selectionArgs) {
-        if (values.containsKey(RCS_THREAD_ID_COLUMN)) {
-            Log.e(TAG,
-                    "RcsProviderThreadHelper: updating thread id for 1 to 1 threads is not "
-                            + "allowed");
-            return 0;
-        }
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.update(RCS_1_TO_1_THREAD_TABLE, values, selection, selectionArgs);
-    }
-
-    int update1To1ThreadWithId(ContentValues values, Uri uri) {
-        return update1To1Thread(values, getThreadIdSelection(uri), null);
-    }
-
-    int updateGroupThread(ContentValues values, String selection, String[] selectionArgs) {
-        if (values.containsKey(RCS_THREAD_ID_COLUMN)) {
-            Log.e(TAG,
-                    "RcsProviderThreadHelper: updating thread id for group threads is not "
-                            + "allowed");
-            return 0;
-        }
-
-        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
-        return db.update(RCS_GROUP_THREAD_TABLE, values, selection, selectionArgs);
-    }
-
-    int updateGroupThreadWithId(ContentValues values, Uri uri) {
-        return updateGroupThread(values, getThreadIdSelection(uri), null);
-    }
-
-    private String getThreadIdSelection(Uri uri) {
-        return RCS_THREAD_ID_COLUMN + "=" + getThreadIdFromUri(uri);
-    }
-
-    static String getThreadIdFromUri(Uri uri) {
-        return uri.getPathSegments().get(THREAD_ID_INDEX_IN_URI);
-    }
-}
diff --git a/src/com/android/providers/telephony/RcsProviderUtil.java b/src/com/android/providers/telephony/RcsProviderUtil.java
deleted file mode 100644
index 38f7be1..0000000
--- a/src/com/android/providers/telephony/RcsProviderUtil.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2019 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.RcsColumns.TRANSACTION_FAILED;
-
-import static android.telephony.ims.RcsQueryContinuationToken.QUERY_CONTINUATION_TOKEN;
-import static com.android.providers.telephony.RcsProvider.TAG;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.telephony.ims.RcsQueryContinuationToken;
-import android.text.TextUtils;
-import android.util.Log;
-
-class RcsProviderUtil {
-    /**
-     * The value returned when database insertion fails,
-     * @see SQLiteDatabase#insert(String, String, ContentValues)
-     */
-    static final int INSERTION_FAILED = -1;
-
-    static void appendLimit(StringBuilder stringBuilder, int limit) {
-        if (limit > 0) {
-            stringBuilder.append(" LIMIT ").append(limit);
-        }
-    }
-
-    static void createContinuationTokenBundle(Cursor cursor, Parcelable continuationToken,
-            String tokenKey) {
-        if (cursor.getCount() > 0) {
-            Bundle bundle = new Bundle();
-            bundle.putParcelable(tokenKey, continuationToken);
-            cursor.setExtras(bundle);
-        }
-    }
-
-    /**
-     * This method gets a token with raw query, performs the query, increments the token's offset
-     * and returns it as a cursor extra
-     */
-    static Cursor performContinuationQuery(SQLiteDatabase db,
-            RcsQueryContinuationToken continuationToken) {
-        String rawQuery = continuationToken.getRawQuery();
-        int offset = continuationToken.getOffset();
-
-        if (offset <= 0 || TextUtils.isEmpty(rawQuery)) {
-            Log.e(TAG, "RcsProviderUtil: Invalid continuation token");
-            return null;
-        }
-
-        String continuationQuery = rawQuery + " OFFSET " + offset;
-
-        Cursor cursor = db.rawQuery(continuationQuery, null);
-        if (cursor.getCount() > 0) {
-            continuationToken.incrementOffset();
-            Bundle bundle = new Bundle();
-            bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken);
-            cursor.setExtras(bundle);
-        }
-
-        return cursor;
-    }
-
-    static Uri buildUriWithRowIdAppended(Uri prefix, long rowId) {
-        if (rowId == TRANSACTION_FAILED) {
-            return null;
-        }
-        return Uri.withAppendedPath(prefix, Long.toString(rowId));
-    }
-
-    static Uri returnUriAsIsIfSuccessful(Uri uri, long rowId) {
-        if (rowId == TRANSACTION_FAILED) {
-            return null;
-        }
-        return uri;
-    }
-}
diff --git a/src/com/android/providers/telephony/ServiceStateProvider.java b/src/com/android/providers/telephony/ServiceStateProvider.java
index afd8fa1..f707200 100644
--- a/src/com/android/providers/telephony/ServiceStateProvider.java
+++ b/src/com/android/providers/telephony/ServiceStateProvider.java
@@ -201,12 +201,12 @@
             final int data_reg_state = ss.getDataRegState();
             final int voice_roaming_type = ss.getVoiceRoamingType();
             final int data_roaming_type = ss.getDataRoamingType();
-            final String voice_operator_alpha_long = ss.getVoiceOperatorAlphaLong();
-            final String voice_operator_alpha_short = ss.getVoiceOperatorAlphaShort();
-            final String voice_operator_numeric = ss.getVoiceOperatorNumeric();
-            final String data_operator_alpha_long = ss.getDataOperatorAlphaLong();
-            final String data_operator_alpha_short = ss.getDataOperatorAlphaShort();
-            final String data_operator_numeric = ss.getDataOperatorNumeric();
+            final String voice_operator_alpha_long = ss.getOperatorAlphaLong();
+            final String voice_operator_alpha_short = ss.getOperatorAlphaShort();
+            final String voice_operator_numeric = ss.getOperatorNumeric();
+            final String data_operator_alpha_long = ss.getOperatorAlphaLong();
+            final String data_operator_alpha_short = ss.getOperatorAlphaShort();
+            final String data_operator_numeric = ss.getOperatorNumeric();
             final int is_manual_network_selection = (ss.getIsManualSelection()) ? 1 : 0;
             final int ril_voice_radio_technology = ss.getRilVoiceRadioTechnology();
             final int ril_data_radio_technology = ss.getRilDataRadioTechnology();
diff --git a/src/com/android/providers/telephony/SmsProvider.java b/src/com/android/providers/telephony/SmsProvider.java
index e2e6d10..ddfa14c 100644
--- a/src/com/android/providers/telephony/SmsProvider.java
+++ b/src/com/android/providers/telephony/SmsProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.providers.telephony;
 
+import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
+
 import android.annotation.NonNull;
 import android.app.AppOpsManager;
 import android.content.ContentProvider;
@@ -75,7 +77,7 @@
         // N.B.: These columns must appear in the same order as the
         // calls to add appear in convertIccToSms.
         "service_center_address",       // getServiceCenterAddress
-        "address",                      // getDisplayOriginatingAddress
+        "address",                      // getDisplayOriginatingAddress or getRecipientAddress
         "message_class",                // getMessageClass
         "body",                         // getDisplayMessageBody
         "date",                         // getTimestampMillis
@@ -83,9 +85,9 @@
         "index_on_icc",                 // getIndexOnIcc
         "is_status_report",             // isStatusReportMessage
         "transport_type",               // Always "sms".
-        "type",                         // Always MESSAGE_TYPE_ALL.
+        "type",                         // depend on getStatusOnIcc
         "locked",                       // Always 0 (false).
-        "error_code",                   // Always 0
+        "error_code",                   // Always -1 (NO_ERROR_CODE), previously it was 0 always.
         "_id"
     };
 
@@ -292,21 +294,39 @@
     }
 
     private Object[] convertIccToSms(SmsMessage message, int id) {
+        int statusOnIcc = message.getStatusOnIcc();
+        int type = Sms.MESSAGE_TYPE_ALL;
+        switch (statusOnIcc) {
+            case SmsManager.STATUS_ON_ICC_READ:
+            case SmsManager.STATUS_ON_ICC_UNREAD:
+                type = Sms.MESSAGE_TYPE_INBOX;
+                break;
+            case SmsManager.STATUS_ON_ICC_SENT:
+                type = Sms.MESSAGE_TYPE_SENT;
+                break;
+            case SmsManager.STATUS_ON_ICC_UNSENT:
+                type = Sms.MESSAGE_TYPE_OUTBOX;
+                break;
+        }
         // N.B.: These calls must appear in the same order as the
         // columns appear in ICC_COLUMNS.
         Object[] row = new Object[13];
         row[0] = message.getServiceCenterAddress();
-        row[1] = message.getDisplayOriginatingAddress();
+        row[1] =
+                (type == Sms.MESSAGE_TYPE_INBOX)
+                        ? message.getDisplayOriginatingAddress()
+                        : message.getRecipientAddress();
+
         row[2] = String.valueOf(message.getMessageClass());
         row[3] = message.getDisplayMessageBody();
         row[4] = message.getTimestampMillis();
-        row[5] = Sms.STATUS_NONE;
+        row[5] = statusOnIcc;
         row[6] = message.getIndexOnIcc();
         row[7] = message.isStatusReportMessage();
         row[8] = "sms";
-        row[9] = TextBasedSmsColumns.MESSAGE_TYPE_ALL;
+        row[9] = type;
         row[10] = 0;      // locked
-        row[11] = 0;      // error_code
+        row[11] = NO_ERROR_CODE;
         row[12] = id;
         return row;
     }
@@ -632,7 +652,12 @@
             db.insert(TABLE_WORDS, Telephony.MmsSms.WordsTable.INDEXED_TEXT, cv);
         }
         if (rowID > 0) {
-            Uri uri = Uri.withAppendedPath(url, String.valueOf(rowID));
+            Uri uri = null;
+            if (table == TABLE_SMS) {
+                uri = Uri.withAppendedPath(Sms.CONTENT_URI, String.valueOf(rowID));
+            } else {
+                uri = Uri.withAppendedPath(url, String.valueOf(rowID));
+            }
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.d(TAG, "insert " + uri + " succeeded");
             }
diff --git a/src/com/android/providers/telephony/SqlTokenFinder.java b/src/com/android/providers/telephony/SqlTokenFinder.java
deleted file mode 100644
index 9be49fe..0000000
--- a/src/com/android/providers/telephony/SqlTokenFinder.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2019 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.annotation.Nullable;
-
-import java.util.function.Consumer;
-
-/**
- * Simple SQL parser to check statements for usage of prohibited/sensitive fields. Mostly copied
- * from
- * packages/providers/ContactsProvider/src/com/android/providers/contacts/sqlite/SqlChecker.java
- */
-public class SqlTokenFinder{
-    private static boolean isAlpha(char ch) {
-        return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_');
-    }
-
-    private static boolean isNum(char ch) {
-        return ('0' <= ch && ch <= '9');
-    }
-
-    private static boolean isAlNum(char ch) {
-        return isAlpha(ch) || isNum(ch);
-    }
-
-    private static boolean isAnyOf(char ch, String set) {
-        return set.indexOf(ch) >= 0;
-    }
-
-    private static char peek(String s, int index) {
-        return index < s.length() ? s.charAt(index) : '\0';
-    }
-
-    /**
-     * SQL Tokenizer specialized to extract tokens from SQL (snippets).
-     *
-     * Based on sqlite3GetToken() in tokenzie.c in SQLite.
-     *
-     * Source for v3.8.6 (which android uses): http://www.sqlite.org/src/artifact/ae45399d6252b4d7
-     * (Latest source as of now: http://www.sqlite.org/src/artifact/78c8085bc7af1922)
-     *
-     * Also draft spec: http://www.sqlite.org/draft/tokenreq.html
-     */
-    public static void findTokens(@Nullable String sql, Consumer<String> checker) {
-        if (sql == null) {
-            return;
-        }
-        int pos = 0;
-        final int len = sql.length();
-        while (pos < len) {
-            final char ch = peek(sql, pos);
-
-            // Regular token.
-            if (isAlpha(ch)) {
-                final int start = pos;
-                pos++;
-                while (isAlNum(peek(sql, pos))) {
-                    pos++;
-                }
-                final int end = pos;
-
-                final String token = sql.substring(start, end);
-                checker.accept(token);
-
-                continue;
-            }
-
-            // Handle quoted tokens
-            if (isAnyOf(ch, "'\"`")) {
-                final int quoteStart = pos;
-                pos++;
-
-                for (;;) {
-                    pos = sql.indexOf(ch, pos);
-                    if (pos < 0) {
-                        throw new IllegalArgumentException("Unterminated quote in" + sql);
-                    }
-                    if (peek(sql, pos + 1) != ch) {
-                        break;
-                    }
-                    // Quoted quote char -- e.g. "abc""def" is a single string.
-                    pos += 2;
-                }
-                final int quoteEnd = pos;
-                pos++;
-
-                if (ch != '\'') {
-                    // Extract the token
-                    final String tokenUnquoted = sql.substring(quoteStart + 1, quoteEnd);
-
-                    final String token;
-
-                    // Unquote if needed. i.e. "aa""bb" -> aa"bb
-                    if (tokenUnquoted.indexOf(ch) >= 0) {
-                        token = tokenUnquoted.replaceAll(
-                                String.valueOf(ch) + ch, String.valueOf(ch));
-                    } else {
-                        token = tokenUnquoted;
-                    }
-                    checker.accept(token);
-                }
-                continue;
-            }
-            // Handle tokens enclosed in [...]
-            if (ch == '[') {
-                final int quoteStart = pos;
-                pos++;
-
-                pos = sql.indexOf(']', pos);
-                if (pos < 0) {
-                    throw new IllegalArgumentException("Unterminated quote in" + sql);
-                }
-                final int quoteEnd = pos;
-                pos++;
-
-                final String token = sql.substring(quoteStart + 1, quoteEnd);
-
-                checker.accept(token);
-                continue;
-            }
-
-            // Detect comments.
-            if (ch == '-' && peek(sql, pos + 1) == '-') {
-                pos += 2;
-                pos = sql.indexOf('\n', pos);
-                if (pos < 0) {
-                    // We disallow strings ending in an inline comment.
-                    throw new IllegalArgumentException("Unterminated comment in" + sql);
-                }
-                pos++;
-
-                continue;
-            }
-            if (ch == '/' && peek(sql, pos + 1) == '*') {
-                pos += 2;
-                pos = sql.indexOf("*/", pos);
-                if (pos < 0) {
-                    throw new IllegalArgumentException("Unterminated comment in" + sql);
-                }
-                pos += 2;
-
-                continue;
-            }
-
-            // Semicolon is never allowed.
-            if (ch == ';') {
-                throw new IllegalArgumentException("Semicolon is not allowed in " + sql);
-            }
-
-            // For this purpose, we can simply ignore other characters.
-            // (Note it doesn't handle the X'' literal properly and reports this X as a token,
-            // but that should be fine...)
-            pos++;
-        }
-    }
-}
diff --git a/src/com/android/providers/telephony/TelephonyBackupAgent.java b/src/com/android/providers/telephony/TelephonyBackupAgent.java
index 437b5a2..b3c0d99 100644
--- a/src/com/android/providers/telephony/TelephonyBackupAgent.java
+++ b/src/com/android/providers/telephony/TelephonyBackupAgent.java
@@ -319,7 +319,7 @@
         final SubscriptionManager subscriptionManager = SubscriptionManager.from(this);
         if (subscriptionManager != null) {
             final List<SubscriptionInfo> subInfo =
-                    subscriptionManager.getActiveSubscriptionInfoList(/* userVisibleonly */false);
+                    subscriptionManager.getActiveAndHiddenSubscriptionInfoList();
             if (subInfo != null) {
                 for (SubscriptionInfo sub : subInfo) {
                     final String phoneNumber = getNormalizedNumber(sub);
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index c564a07..b5cd6e9 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -70,6 +70,7 @@
 import static android.provider.Telephony.Carriers.WAIT_TIME_RETRY;
 import static android.provider.Telephony.Carriers._ID;
 
+import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
@@ -106,20 +107,19 @@
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
 import android.text.TextUtils;
-import android.util.EventLog;
+import android.util.ArrayMap;
 import android.util.Log;
 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.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
 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;
+import android.service.carrier.IApnSourceService;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -177,6 +177,11 @@
     private static final int URL_SIM_APN_LIST_FILTERED = 26;
     private static final int URL_SIM_APN_LIST_FILTERED_ID = 27;
 
+    /**
+     * Default value for mtu if it's not set. Moved from PhoneConstants.
+     */
+    private static final int UNSPECIFIED_INT = -1;
+
     private static final String TAG = "TelephonyProvider";
     private static final String CARRIERS_TABLE = "carriers";
     private static final String CARRIERS_TABLE_TMP = "carriers_tmp";
@@ -207,10 +212,6 @@
     private static final String DEFAULT_PROTOCOL = "IP";
     private static final String DEFAULT_ROAMING_PROTOCOL = "IP";
 
-    // Used to check if certain queries contain subqueries that may attempt to access sensitive
-    // fields in the carriers db.
-    private static final String SQL_SELECT_TOKEN = "select";
-
     private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 
     private static final ContentValues s_currentNullMap;
@@ -255,6 +256,8 @@
 
     private boolean mManagedApnEnforced;
 
+    private static final Map<String, Integer> MVNO_TYPE_STRING_MAP;
+
     static {
         // Columns not included in UNIQUE constraint: name, current, edited, user, server, password,
         // authtype, type, protocol, roaming_protocol, sub_id, modem_cognitive, max_conns,
@@ -291,6 +294,12 @@
         CARRIERS_BOOLEAN_FIELDS.add(MODEM_PERSIST);
         CARRIERS_BOOLEAN_FIELDS.add(USER_VISIBLE);
         CARRIERS_BOOLEAN_FIELDS.add(USER_EDITABLE);
+
+        MVNO_TYPE_STRING_MAP = new ArrayMap<String, Integer>();
+        MVNO_TYPE_STRING_MAP.put("spn", ApnSetting.MVNO_TYPE_SPN);
+        MVNO_TYPE_STRING_MAP.put("imsi", ApnSetting.MVNO_TYPE_IMSI);
+        MVNO_TYPE_STRING_MAP.put("gid", ApnSetting.MVNO_TYPE_GID);
+        MVNO_TYPE_STRING_MAP.put("iccid", ApnSetting.MVNO_TYPE_ICCID);
     }
 
     @VisibleForTesting
@@ -484,7 +493,41 @@
     }
 
     @VisibleForTesting
-    public static class DatabaseHelper extends SQLiteOpenHelper {
+    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");
+            int publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
+            int version = DATABASE_VERSION | publicversion;
+            if (VDBG) log("getVersion:- version=0x" + Integer.toHexString(version));
+            return version;
+        } catch (Exception e) {
+            loge("Can't get version of APN database" + e + " return version=" +
+                    Integer.toHexString(DATABASE_VERSION));
+            return DATABASE_VERSION;
+        } finally {
+            parser.close();
+        }
+    }
+
+    static public ContentValues setDefaultValue(ContentValues values) {
+        if (!values.containsKey(SUBSCRIPTION_ID)) {
+            int subId = SubscriptionManager.getDefaultSubscriptionId();
+            values.put(SUBSCRIPTION_ID, subId);
+        }
+
+        return values;
+    }
+
+    @VisibleForTesting
+    public class DatabaseHelper extends SQLiteOpenHelper {
         // Context to access resources with
         private Context mContext;
 
@@ -501,31 +544,6 @@
             setWriteAheadLoggingEnabled(false);
         }
 
-        @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");
-                int publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
-                int version = DATABASE_VERSION | publicversion;
-                if (VDBG) log("getVersion:- version=0x" + Integer.toHexString(version));
-                return version;
-            } catch (Exception e) {
-                loge("Can't get version of APN database" + e + " return version=" +
-                        Integer.toHexString(DATABASE_VERSION));
-                return DATABASE_VERSION;
-            } finally {
-                parser.close();
-            }
-        }
-
         @Override
         public void onCreate(SQLiteDatabase db) {
             if (DBG) log("dbh.onCreate:+ db=" + db);
@@ -605,7 +623,7 @@
             return checksum;
         }
 
-        private static byte[] toByteArray(InputStream input) throws IOException {
+        private byte[] toByteArray(InputStream input) throws IOException {
             byte[] buffer = new byte[128];
             int bytesRead;
             ByteArrayOutputStream output = new ByteArrayOutputStream();
@@ -763,6 +781,8 @@
                 log("dbh.onUpgrade:+ db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
             }
 
+            deletePreferredApnId(mContext);
+
             if (oldVersion < (5 << 16 | 6)) {
                 // 5 << 16 is the Database version and 6 in the xml version.
 
@@ -1878,7 +1898,7 @@
                                         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,
+                            Cursor oldRow = selectConflictingRow(db,
                                     CARRIERS_TABLE_TMP, cv);
                             if (oldRow != null) {
                                 ContentValues mergedValues = new ContentValues();
@@ -2111,15 +2131,6 @@
             }
         }
 
-        static public ContentValues setDefaultValue(ContentValues values) {
-            if (!values.containsKey(SUBSCRIPTION_ID)) {
-                int subId = SubscriptionManager.getDefaultSubscriptionId();
-                values.put(SUBSCRIPTION_ID, subId);
-            }
-
-            return values;
-        }
-
         private void insertAddingDefaults(SQLiteDatabase db, ContentValues row) {
             row = setDefaultValue(row);
             try {
@@ -2162,264 +2173,264 @@
                 }
             }
         }
+    }
 
-        public static void mergeFieldsAndUpdateDb(SQLiteDatabase db, String table, Cursor oldRow,
-                                                  ContentValues newRow, ContentValues mergedValues,
-                                                  boolean onUpgrade, Context context) {
-            if (newRow.containsKey(TYPE)) {
-                // Merge the types
-                String oldType = oldRow.getString(oldRow.getColumnIndex(TYPE));
-                String newType = newRow.getAsString(TYPE);
+    public static void mergeFieldsAndUpdateDb(SQLiteDatabase db, String table, Cursor oldRow,
+            ContentValues newRow, ContentValues mergedValues,
+            boolean onUpgrade, Context context) {
+        if (newRow.containsKey(TYPE)) {
+            // Merge the types
+            String oldType = oldRow.getString(oldRow.getColumnIndex(TYPE));
+            String newType = newRow.getAsString(TYPE);
 
-                if (!oldType.equalsIgnoreCase(newType)) {
-                    if (oldType.equals("") || newType.equals("")) {
-                        newRow.put(TYPE, "");
-                    } else {
-                        String[] oldTypes = oldType.toLowerCase().split(",");
-                        String[] newTypes = newType.toLowerCase().split(",");
+            if (!oldType.equalsIgnoreCase(newType)) {
+                if (oldType.equals("") || newType.equals("")) {
+                    newRow.put(TYPE, "");
+                } else {
+                    String[] oldTypes = oldType.toLowerCase().split(",");
+                    String[] newTypes = newType.toLowerCase().split(",");
 
-                        if (VDBG) {
-                            log("mergeFieldsAndUpdateDb: Calling separateRowsNeeded() oldType=" +
-                                    oldType + " old bearer=" + oldRow.getInt(oldRow.getColumnIndex(
-                                    BEARER_BITMASK)) +  " old networkType=" +
-                                    oldRow.getInt(oldRow.getColumnIndex(NETWORK_TYPE_BITMASK)) +
-                                    " old profile_id=" + oldRow.getInt(oldRow.getColumnIndex(
-                                    PROFILE_ID)) + " newRow " + newRow);
-                        }
-
-                        // If separate rows are needed, do not need to merge any further
-                        if (separateRowsNeeded(db, table, oldRow, newRow, context, oldTypes,
-                                newTypes)) {
-                            if (VDBG) log("mergeFieldsAndUpdateDb: separateRowsNeeded() returned " +
-                                    "true");
-                            return;
-                        }
-
-                        // Merge the 2 types
-                        ArrayList<String> mergedTypes = new ArrayList<String>();
-                        mergedTypes.addAll(Arrays.asList(oldTypes));
-                        for (String s : newTypes) {
-                            if (!mergedTypes.contains(s.trim())) {
-                                mergedTypes.add(s);
-                            }
-                        }
-                        StringBuilder mergedType = new StringBuilder();
-                        for (int i = 0; i < mergedTypes.size(); i++) {
-                            mergedType.append((i == 0 ? "" : ",") + mergedTypes.get(i));
-                        }
-                        newRow.put(TYPE, mergedType.toString());
+                    if (VDBG) {
+                        log("mergeFieldsAndUpdateDb: Calling separateRowsNeeded() oldType=" +
+                                oldType + " old bearer=" + oldRow.getInt(oldRow.getColumnIndex(
+                                BEARER_BITMASK)) +  " old networkType=" +
+                                oldRow.getInt(oldRow.getColumnIndex(NETWORK_TYPE_BITMASK)) +
+                                " old profile_id=" + oldRow.getInt(oldRow.getColumnIndex(
+                                PROFILE_ID)) + " newRow " + newRow);
                     }
-                }
-                mergedValues.put(TYPE, newRow.getAsString(TYPE));
-            }
 
-            if (newRow.containsKey(BEARER_BITMASK)) {
-                int oldBearer = oldRow.getInt(oldRow.getColumnIndex(BEARER_BITMASK));
-                int newBearer = newRow.getAsInteger(BEARER_BITMASK);
-                if (oldBearer != newBearer) {
-                    if (oldBearer == 0 || newBearer == 0) {
-                        newRow.put(BEARER_BITMASK, 0);
-                    } else {
-                        newRow.put(BEARER_BITMASK, (oldBearer | newBearer));
+                    // If separate rows are needed, do not need to merge any further
+                    if (separateRowsNeeded(db, table, oldRow, newRow, context, oldTypes,
+                            newTypes)) {
+                        if (VDBG) log("mergeFieldsAndUpdateDb: separateRowsNeeded() returned " +
+                                "true");
+                        return;
                     }
-                }
-                mergedValues.put(BEARER_BITMASK, newRow.getAsInteger(BEARER_BITMASK));
-            }
 
-            if (newRow.containsKey(NETWORK_TYPE_BITMASK)) {
-                int oldBitmask = oldRow.getInt(oldRow.getColumnIndex(NETWORK_TYPE_BITMASK));
-                int newBitmask = newRow.getAsInteger(NETWORK_TYPE_BITMASK);
-                if (oldBitmask != newBitmask) {
-                    if (oldBitmask == 0 || newBitmask == 0) {
-                        newRow.put(NETWORK_TYPE_BITMASK, 0);
-                    } else {
-                        newRow.put(NETWORK_TYPE_BITMASK, (oldBitmask | newBitmask));
+                    // Merge the 2 types
+                    ArrayList<String> mergedTypes = new ArrayList<String>();
+                    mergedTypes.addAll(Arrays.asList(oldTypes));
+                    for (String s : newTypes) {
+                        if (!mergedTypes.contains(s.trim())) {
+                            mergedTypes.add(s);
+                        }
                     }
-                }
-                mergedValues.put(NETWORK_TYPE_BITMASK, newRow.getAsInteger(NETWORK_TYPE_BITMASK));
-            }
-
-            if (newRow.containsKey(BEARER_BITMASK)
-                    && newRow.containsKey(NETWORK_TYPE_BITMASK)) {
-                syncBearerBitmaskAndNetworkTypeBitmask(mergedValues);
-            }
-
-            if (!onUpgrade) {
-                // Do not overwrite a carrier or user edit with EDITED=UNEDITED
-                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_STATUS);
+                    StringBuilder mergedType = new StringBuilder();
+                    for (int i = 0; i < mergedTypes.size(); i++) {
+                        mergedType.append((i == 0 ? "" : ",") + mergedTypes.get(i));
                     }
+                    newRow.put(TYPE, mergedType.toString());
                 }
-                mergedValues.putAll(newRow);
             }
-
-            if (mergedValues.size() > 0) {
-                db.update(table, mergedValues, "_id=" + oldRow.getInt(oldRow.getColumnIndex("_id")),
-                        null);
-            }
+            mergedValues.put(TYPE, newRow.getAsString(TYPE));
         }
 
-        private static boolean separateRowsNeeded(SQLiteDatabase db, String table, Cursor oldRow,
-                                                  ContentValues newRow, Context context,
-                                                  String[] oldTypes, String[] newTypes) {
-            // If this APN falls under persist_apns_for_plmn, and the
-            // only difference between old type and new type is that one has dun, and
-            // the APNs have profile_id 0 or not set, then set the profile_id to 1 for
-            // the dun APN/remove dun from type. This will ensure both oldRow and newRow exist
-            // separately in db.
-
-            boolean match = false;
-
-            // Check if APN falls under persist_apns_for_plmn
-            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;
-                    }
+        if (newRow.containsKey(BEARER_BITMASK)) {
+            int oldBearer = oldRow.getInt(oldRow.getColumnIndex(BEARER_BITMASK));
+            int newBearer = newRow.getAsInteger(BEARER_BITMASK);
+            if (oldBearer != newBearer) {
+                if (oldBearer == 0 || newBearer == 0) {
+                    newRow.put(BEARER_BITMASK, 0);
+                } else {
+                    newRow.put(BEARER_BITMASK, (oldBearer | newBearer));
                 }
-            } else {
-                loge("separateRowsNeeded: resources=null");
+            }
+            mergedValues.put(BEARER_BITMASK, newRow.getAsInteger(BEARER_BITMASK));
+        }
+
+        if (newRow.containsKey(NETWORK_TYPE_BITMASK)) {
+            int oldBitmask = oldRow.getInt(oldRow.getColumnIndex(NETWORK_TYPE_BITMASK));
+            int newBitmask = newRow.getAsInteger(NETWORK_TYPE_BITMASK);
+            if (oldBitmask != newBitmask) {
+                if (oldBitmask == 0 || newBitmask == 0) {
+                    newRow.put(NETWORK_TYPE_BITMASK, 0);
+                } else {
+                    newRow.put(NETWORK_TYPE_BITMASK, (oldBitmask | newBitmask));
+                }
+            }
+            mergedValues.put(NETWORK_TYPE_BITMASK, newRow.getAsInteger(NETWORK_TYPE_BITMASK));
+        }
+
+        if (newRow.containsKey(BEARER_BITMASK)
+                && newRow.containsKey(NETWORK_TYPE_BITMASK)) {
+            syncBearerBitmaskAndNetworkTypeBitmask(mergedValues);
+        }
+
+        if (!onUpgrade) {
+            // Do not overwrite a carrier or user edit with EDITED=UNEDITED
+            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_STATUS);
+                }
+            }
+            mergedValues.putAll(newRow);
+        }
+
+        if (mergedValues.size() > 0) {
+            db.update(table, mergedValues, "_id=" + oldRow.getInt(oldRow.getColumnIndex("_id")),
+                    null);
+        }
+    }
+
+    private static boolean separateRowsNeeded(SQLiteDatabase db, String table, Cursor oldRow,
+            ContentValues newRow, Context context,
+            String[] oldTypes, String[] newTypes) {
+        // If this APN falls under persist_apns_for_plmn, and the
+        // only difference between old type and new type is that one has dun, and
+        // the APNs have profile_id 0 or not set, then set the profile_id to 1 for
+        // the dun APN/remove dun from type. This will ensure both oldRow and newRow exist
+        // separately in db.
+
+        boolean match = false;
+
+        // Check if APN falls under persist_apns_for_plmn
+        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;
+
+        // APN falls under persist_apns_for_plmn
+        // Check if only difference between old type and new type is that
+        // one has dun
+        ArrayList<String> oldTypesAl = new ArrayList<String>(Arrays.asList(oldTypes));
+        ArrayList<String> newTypesAl = new ArrayList<String>(Arrays.asList(newTypes));
+        ArrayList<String> listWithDun = null;
+        ArrayList<String> listWithoutDun = null;
+        boolean dunInOld = false;
+        if (oldTypesAl.size() == newTypesAl.size() + 1) {
+            listWithDun = oldTypesAl;
+            listWithoutDun = newTypesAl;
+            dunInOld = true;
+        } else if (oldTypesAl.size() + 1 == newTypesAl.size()) {
+            listWithDun = newTypesAl;
+            listWithoutDun = oldTypesAl;
+        } else {
+            return false;
+        }
+
+        if (listWithDun.contains("dun") && !listWithoutDun.contains("dun")) {
+            listWithoutDun.add("dun");
+            if (!listWithDun.containsAll(listWithoutDun)) {
+                return false;
             }
 
-            if (!match) return false;
-
-            // APN falls under persist_apns_for_plmn
-            // Check if only difference between old type and new type is that
+            // Only difference between old type and new type is that
             // one has dun
-            ArrayList<String> oldTypesAl = new ArrayList<String>(Arrays.asList(oldTypes));
-            ArrayList<String> newTypesAl = new ArrayList<String>(Arrays.asList(newTypes));
-            ArrayList<String> listWithDun = null;
-            ArrayList<String> listWithoutDun = null;
-            boolean dunInOld = false;
-            if (oldTypesAl.size() == newTypesAl.size() + 1) {
-                listWithDun = oldTypesAl;
-                listWithoutDun = newTypesAl;
-                dunInOld = true;
-            } else if (oldTypesAl.size() + 1 == newTypesAl.size()) {
-                listWithDun = newTypesAl;
-                listWithoutDun = oldTypesAl;
+            // Check if profile_id is 0/not set
+            if (oldRow.getInt(oldRow.getColumnIndex(PROFILE_ID)) == 0) {
+                if (dunInOld) {
+                    // Update oldRow to remove dun from its type field
+                    ContentValues updateOldRow = new ContentValues();
+                    StringBuilder sb = new StringBuilder();
+                    boolean first = true;
+                    for (String s : listWithDun) {
+                        if (!s.equalsIgnoreCase("dun")) {
+                            sb.append(first ? s : "," + s);
+                            first = false;
+                        }
+                    }
+                    String updatedType = sb.toString();
+                    if (VDBG) {
+                        log("separateRowsNeeded: updating type in oldRow to " + updatedType);
+                    }
+                    updateOldRow.put(TYPE, updatedType);
+                    db.update(table, updateOldRow,
+                            "_id=" + oldRow.getInt(oldRow.getColumnIndex("_id")), null);
+                    return true;
+                } else {
+                    if (VDBG) log("separateRowsNeeded: adding profile id 1 to newRow");
+                    // Update newRow to set profile_id to 1
+                    newRow.put(PROFILE_ID, new Integer(1));
+                }
             } else {
                 return false;
             }
 
-            if (listWithDun.contains("dun") && !listWithoutDun.contains("dun")) {
-                listWithoutDun.add("dun");
-                if (!listWithDun.containsAll(listWithoutDun)) {
-                    return false;
-                }
-
-                // Only difference between old type and new type is that
-                // one has dun
-                // Check if profile_id is 0/not set
-                if (oldRow.getInt(oldRow.getColumnIndex(PROFILE_ID)) == 0) {
-                    if (dunInOld) {
-                        // Update oldRow to remove dun from its type field
-                        ContentValues updateOldRow = new ContentValues();
-                        StringBuilder sb = new StringBuilder();
-                        boolean first = true;
-                        for (String s : listWithDun) {
-                            if (!s.equalsIgnoreCase("dun")) {
-                                sb.append(first ? s : "," + s);
-                                first = false;
-                            }
-                        }
-                        String updatedType = sb.toString();
-                        if (VDBG) {
-                            log("separateRowsNeeded: updating type in oldRow to " + updatedType);
-                        }
-                        updateOldRow.put(TYPE, updatedType);
-                        db.update(table, updateOldRow,
-                                "_id=" + oldRow.getInt(oldRow.getColumnIndex("_id")), null);
-                        return true;
-                    } else {
-                        if (VDBG) log("separateRowsNeeded: adding profile id 1 to newRow");
-                        // Update newRow to set profile_id to 1
-                        newRow.put(PROFILE_ID, new Integer(1));
-                    }
-                } else {
-                    return false;
-                }
-
-                // If match was found, both oldRow and newRow need to exist
-                // separately in db. Add newRow to db.
-                try {
-                    db.insertWithOnConflict(table, null, newRow, SQLiteDatabase.CONFLICT_REPLACE);
-                    if (VDBG) log("separateRowsNeeded: added newRow with profile id 1 to db");
-                    return true;
-                } catch (SQLException e) {
-                    loge("Exception on trying to add new row after updating profile_id");
-                }
+            // If match was found, both oldRow and newRow need to exist
+            // separately in db. Add newRow to db.
+            try {
+                db.insertWithOnConflict(table, null, newRow, SQLiteDatabase.CONFLICT_REPLACE);
+                if (VDBG) log("separateRowsNeeded: added newRow with profile id 1 to db");
+                return true;
+            } catch (SQLException e) {
+                loge("Exception on trying to add new row after updating profile_id");
             }
-
-            return false;
         }
 
-        public static Cursor selectConflictingRow(SQLiteDatabase db, String table,
-                                                  ContentValues row) {
-            // Conflict is possible only when numeric, mcc, mnc (fields without any default value)
-            // are set in the new row
-            if (!row.containsKey(NUMERIC) || !row.containsKey(MCC) || !row.containsKey(MNC)) {
-                loge("dbh.selectConflictingRow: called for non-conflicting row: " + row);
-                return null;
-            }
+        return false;
+    }
 
-            String[] columns = { "_id",
-                    TYPE,
-                    EDITED_STATUS,
-                    BEARER_BITMASK,
-                    NETWORK_TYPE_BITMASK,
-                    PROFILE_ID };
-            String selection = TextUtils.join("=? AND ", CARRIERS_UNIQUE_FIELDS) + "=?";
-            int i = 0;
-            String[] selectionArgs = new String[CARRIERS_UNIQUE_FIELDS.size()];
-            for (String field : CARRIERS_UNIQUE_FIELDS) {
-                if (!row.containsKey(field)) {
-                    selectionArgs[i++] = CARRIERS_UNIQUE_FIELDS_DEFAULTS.get(field);
-                } else {
-                    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);
-                    }
-                }
-            }
-
-            Cursor c = db.query(table, columns, selection, selectionArgs, null, null, null);
-
-            if (c != null) {
-                if (c.getCount() == 1) {
-                    if (VDBG) log("dbh.selectConflictingRow: " + c.getCount() + " conflicting " +
-                            "row found");
-                    if (c.moveToFirst()) {
-                        return c;
-                    } else {
-                        loge("dbh.selectConflictingRow: moveToFirst() failed");
-                    }
-                } else {
-                    loge("dbh.selectConflictingRow: Expected 1 but found " + c.getCount() +
-                            " matching rows found for cv " + row);
-                }
-                c.close();
-            } else {
-                loge("dbh.selectConflictingRow: Error - c is null; no matching row found for " +
-                        "cv " + row);
-            }
-
+    public static Cursor selectConflictingRow(SQLiteDatabase db, String table,
+            ContentValues row) {
+        // Conflict is possible only when numeric, mcc, mnc (fields without any default value)
+        // are set in the new row
+        if (!row.containsKey(NUMERIC) || !row.containsKey(MCC) || !row.containsKey(MNC)) {
+            loge("dbh.selectConflictingRow: called for non-conflicting row: " + row);
             return null;
         }
+
+        String[] columns = { "_id",
+                TYPE,
+                EDITED_STATUS,
+                BEARER_BITMASK,
+                NETWORK_TYPE_BITMASK,
+                PROFILE_ID };
+        String selection = TextUtils.join("=? AND ", CARRIERS_UNIQUE_FIELDS) + "=?";
+        int i = 0;
+        String[] selectionArgs = new String[CARRIERS_UNIQUE_FIELDS.size()];
+        for (String field : CARRIERS_UNIQUE_FIELDS) {
+            if (!row.containsKey(field)) {
+                selectionArgs[i++] = CARRIERS_UNIQUE_FIELDS_DEFAULTS.get(field);
+            } else {
+                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);
+                }
+            }
+        }
+
+        Cursor c = db.query(table, columns, selection, selectionArgs, null, null, null);
+
+        if (c != null) {
+            if (c.getCount() == 1) {
+                if (VDBG) log("dbh.selectConflictingRow: " + c.getCount() + " conflicting " +
+                        "row found");
+                if (c.moveToFirst()) {
+                    return c;
+                } else {
+                    loge("dbh.selectConflictingRow: moveToFirst() failed");
+                }
+            } else {
+                loge("dbh.selectConflictingRow: Expected 1 but found " + c.getCount() +
+                        " matching rows found for cv " + row);
+            }
+            c.close();
+        } else {
+            loge("dbh.selectConflictingRow: Error - c is null; no matching row found for " +
+                    "cv " + row);
+        }
+
+        return null;
     }
 
     /**
@@ -2546,12 +2557,6 @@
     public boolean onCreate() {
         mOpenHelper = new DatabaseHelper(getContext());
 
-        try {
-            PhoneFactory.addLocalLog(TAG, 100);
-        } catch (IllegalArgumentException e) {
-            // ignore
-        }
-
         boolean isNewBuild = false;
         String newBuildId = SystemProperties.get("ro.build.id", null);
         if (!TextUtils.isEmpty(newBuildId)) {
@@ -2572,25 +2577,6 @@
 
         if (isNewBuild) {
             if (!apnSourceServiceExists(getContext())) {
-                // Call getReadableDatabase() to make sure onUpgrade is called
-                if (VDBG) log("onCreate: calling getReadableDatabase to trigger onUpgrade");
-                SQLiteDatabase db = getReadableDatabase();
-
-                // 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();
             }
@@ -2637,7 +2623,6 @@
 
     private static void localLog(String logMsg) {
         Log.d(TAG, logMsg);
-        PhoneFactory.localLog(TAG, logMsg);
     }
 
     private synchronized boolean isManagedApnEnforced() {
@@ -2701,29 +2686,9 @@
         }
     }
 
-    private void deletePreferredApnId() {
-        SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE_APN,
+    private void deletePreferredApnId(Context context) {
+        SharedPreferences sp = context.getSharedPreferences(PREF_FILE_APN,
                 Context.MODE_PRIVATE);
-
-        // Before deleting, save actual preferred apns (not the ids) in a separate SP.
-        // NOTE: This code to call setPreferredApn() can be removed since the function is now called
-        // from setPreferredApnId(). However older builds (pre oc-mr1) do not have that change, so
-        // when devices upgrade from those builds and this function is called, this code is needed
-        // otherwise the preferred APN will be lost.
-        Map<String, ?> allPrefApnId = sp.getAll();
-        for (String key : allPrefApnId.keySet()) {
-            // extract subId from key by removing COLUMN_APN_ID
-            try {
-                int subId = Integer.parseInt(key.replace(COLUMN_APN_ID, ""));
-                long apnId = getPreferredApnId(subId, false);
-                if (apnId != INVALID_APN_ID) {
-                    setPreferredApn(apnId, subId);
-                }
-            } catch (Exception e) {
-                loge("Skipping over key " + key + " due to exception " + e);
-            }
-        }
-
         SharedPreferences.Editor editor = sp.edit();
         editor.clear();
         editor.apply();
@@ -2764,19 +2729,27 @@
     private long getPreferredApnIdFromApn(int subId) {
         log("getPreferredApnIdFromApn: for subId " + subId);
         SQLiteDatabase db = getReadableDatabase();
-        String where = TextUtils.join("=? and ", CARRIERS_UNIQUE_FIELDS) + "=?";
-        String[] whereArgs = new String[CARRIERS_UNIQUE_FIELDS.size()];
+
+        List<String> whereList = new ArrayList<>();
+        List<String> whereArgsList = new ArrayList<>();
         SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE_FULL_APN,
                 Context.MODE_PRIVATE);
-        long apnId = INVALID_APN_ID;
-        int i = 0;
         for (String key : CARRIERS_UNIQUE_FIELDS) {
-            whereArgs[i] = sp.getString(key + subId, null);
-            if (whereArgs[i] == null) {
-                return INVALID_APN_ID;
+            String value = sp.getString(key + subId, null);
+            if (value == null) {
+                continue;
+            } else {
+                whereList.add(key);
+                whereArgsList.add(value);
             }
-            i++;
         }
+        if (whereList.size() == 0) return INVALID_APN_ID;
+
+        String where = TextUtils.join("=? and ", whereList) + "=?";
+        String[] whereArgs = new String[whereArgsList.size()];
+        whereArgs = whereArgsList.toArray(whereArgs);
+
+        long apnId = INVALID_APN_ID;
         Cursor c = db.query(CARRIERS_TABLE, new String[]{"_id"}, where, whereArgs, null, null,
                 null);
         if (c != null) {
@@ -2825,8 +2798,6 @@
             String[] selectionArgs, String sort) {
         if (VDBG) log("query: url=" + url + ", projectionIn=" + projectionIn + ", selection="
                 + selection + "selectionArgs=" + selectionArgs + ", sort=" + sort);
-        TelephonyManager mTelephonyManager =
-                (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
         int subId = SubscriptionManager.getDefaultSubscriptionId();
         String subIdString;
         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
@@ -2836,7 +2807,7 @@
         List<String> constraints = new ArrayList<String>();
 
         int match = s_urlMatcher.match(url);
-        checkQueryPermission(match, projectionIn, selection, sort);
+        checkPermission();
         switch (match) {
             case URL_TELEPHONY_USING_SUBID: {
                 subIdString = url.getLastPathSegment();
@@ -2847,7 +2818,9 @@
                     return null;
                 }
                 if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
-                constraints.add(NUMERIC + " = '" + mTelephonyManager.getSimOperator(subId) + "'");
+                TelephonyManager telephonyManager = getContext()
+                    .getSystemService(TelephonyManager.class).createForSubscriptionId(subId);
+                constraints.add(NUMERIC + " = '" + telephonyManager.getSimOperator() + "'");
                 // TODO b/74213956 turn this back on once insertion includes correct sub id
                 // constraints.add(SUBSCRIPTION_ID + "=" + subIdString);
             }
@@ -3045,97 +3018,35 @@
         return ret;
     }
 
-    private void checkQueryPermission(int match, String[] projectionIn, String selection,
-            String sort) {
-        // Determine if we need to do a check for fields in the selection
-        boolean selectionOrSortContainsSensitiveFields;
-        try {
-            selectionOrSortContainsSensitiveFields = containsSensitiveFields(selection);
-            selectionOrSortContainsSensitiveFields |= containsSensitiveFields(sort);
-        } catch (IllegalArgumentException e) {
-            // Malformed sql, check permission anyway and return.
-            checkPermission();
-            return;
-        }
-
-        if (selectionOrSortContainsSensitiveFields) {
-            try {
-                checkPermission();
-            } catch (SecurityException e) {
-                EventLog.writeEvent(0x534e4554, "124107808", Binder.getCallingUid());
-                throw e;
-            }
-        }
-
-        if (match != URL_SIMINFO && match != URL_SIMINFO_USING_SUBID) {
-            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)) {
-                    } else {
-                        checkPermission();
-                        break;
-                    }
-                }
-            } else {
-                // null returns all columns, so need permission check
-                checkPermission();
-            }
-        } else {
-            // if querying siminfo, caller should have read privilege permissions
-            checkPhonePrivilegePermission();
-        }
-    }
-
-    private boolean containsSensitiveFields(String sqlStatement) {
-        try {
-            SqlTokenFinder.findTokens(sqlStatement, s -> {
-                switch (s.toLowerCase()) {
-                    case USER:
-                    case PASSWORD:
-                    case SQL_SELECT_TOKEN:
-                        throw new SecurityException();
-                }
-            });
-        } catch (SecurityException e) {
-            return true;
-        }
-        return false;
-    }
-
     /**
-     * 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.
+     * To find the current sim APN. Query APN based on {MCC, MNC, MVNO} and {Carrier_ID}.
      *
      * 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
-     *
+     * 1. Query the APN based on { MCC, MNC, MVNO } and if has results jump to step 3, else jump to
+     *    step 2.
+     * 2. Fallback to query the parent APN that query based on { MCC, MNC }.
+     * 3. Append the result with the APN that query based on { Carrier_ID }
      */
     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))
+        final TelephonyManager tm = ((TelephonyManager) getContext()
+                .getSystemService(Context.TELEPHONY_SERVICE))
                 .createForSubscriptionId(subId);
         SQLiteDatabase db = getReadableDatabase();
         String mccmnc = tm.getSimOperator();
+        int carrierId = tm.getSimCarrierId();
 
         qb.appendWhereStandalone(IS_NOT_USER_DELETED + " and " +
                 IS_NOT_USER_DELETED_BUT_PRESENT_IN_XML + " and " +
                 IS_NOT_CARRIER_DELETED + " and " +
                 IS_NOT_CARRIER_DELETED_BUT_PRESENT_IN_XML);
 
-        // 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 + "' ");
+        // For query db one time, append all conditions in one selection and separate results after
+        // the query is completed. IMSI has special match rule, so just query the MCC / MNC and
+        // filter the MVNO by ourselves
+        qb.appendWhereStandalone(NUMERIC + " = '" + mccmnc + "' OR " +
+                CARRIER_ID + " = '" + carrierId + "'");
 
         ret = qb.query(db, null, selection, selectionArgs, null, null, sort);
         if (ret == null) {
@@ -3145,13 +3056,15 @@
 
         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);
+        String[] columnNames = projectionIn != null ? projectionIn : ret.getColumnNames();
+        MatrixCursor currentCursor = new MatrixCursor(columnNames);
+        MatrixCursor parentCursor = new MatrixCursor(columnNames);
+        MatrixCursor carrierIdCursor = new MatrixCursor(columnNames);
 
         int numericIndex = ret.getColumnIndex(NUMERIC);
         int mvnoIndex = ret.getColumnIndex(MVNO_TYPE);
         int mvnoDataIndex = ret.getColumnIndex(MVNO_MATCH_DATA);
+        int carrierIdIndex = ret.getColumnIndex(CARRIER_ID);
 
         IccRecords iccRecords = UiccController.getInstance().getIccRecords(
                 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
@@ -3163,33 +3076,68 @@
         //Separate the result into MatrixCursor
         while (ret.moveToNext()) {
             List<String> data = new ArrayList<>();
-            for (String column : coulmnNames) {
+            for (String column : columnNames) {
                 data.add(ret.getString(ret.getColumnIndex(column)));
             }
 
             if (!TextUtils.isEmpty(ret.getString(numericIndex)) &&
                     ApnSettingUtils.mvnoMatches(iccRecords,
-                            ApnSetting.getMvnoTypeIntFromString(ret.getString(mvnoIndex)),
+                            getMvnoTypeIntFromString(ret.getString(mvnoIndex)),
                             ret.getString(mvnoDataIndex))) {
-                // 1. APN query result based on legacy SIM MCC/MCC and MVNO
+                // 1. The APN that query 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
+            } else if (!TextUtils.isEmpty(ret.getString(numericIndex))
+                    && TextUtils.isEmpty(ret.getString(mvnoIndex))) {
+                // 2. The APN that query based on SIM MCC/MNC
                 parentCursor.addRow(data);
+            } else if (!TextUtils.isEmpty(ret.getString(carrierIdIndex))
+                    && ret.getString(carrierIdIndex).equals(String.valueOf(carrierId))) {
+                // The APN that query based on carrier Id (not include the MVNO or MNO APN)
+                carrierIdCursor.addRow(data);
             }
         }
         ret.close();
 
+        MatrixCursor result;
         if (currentCursor.getCount() > 0) {
             if (DBG) log("match MVNO APN: " + currentCursor.getCount());
-            return currentCursor;
+            result = currentCursor;
         } else if (parentCursor.getCount() > 0) {
             if (DBG) log("match MNO APN: " + parentCursor.getCount());
-            return parentCursor;
+            result = parentCursor;
         } else {
-            if (DBG) log("APN no match");
-            return new MatrixCursor(coulmnNames);
+            if (DBG) log("can't find the MVNO and MNO APN");
+            result = new MatrixCursor(columnNames);
+        }
+
+        if (DBG) log("match carrier id APN: " + carrierIdCursor.getCount());
+        appendCursorData(result, carrierIdCursor);
+        return result;
+    }
+
+    private static void appendCursorData(@NonNull MatrixCursor from, @NonNull MatrixCursor to) {
+        while (to.moveToNext()) {
+            List<Object> data = new ArrayList<>();
+            for (String column : to.getColumnNames()) {
+                int index = to.getColumnIndex(column);
+                switch (to.getType(index)) {
+                    case Cursor.FIELD_TYPE_NULL:
+                        break;
+                    case Cursor.FIELD_TYPE_INTEGER:
+                        data.add(to.getInt(index));
+                        break;
+                    case Cursor.FIELD_TYPE_FLOAT:
+                        data.add(to.getFloat(index));
+                        break;
+                    case Cursor.FIELD_TYPE_BLOB:
+                        data.add(to.getBlob(index));
+                        break;
+                    case Cursor.FIELD_TYPE_STRING:
+                        data.add(to.getString(index));
+                        break;
+                }
+            }
+            from.addRow(data);
         }
     }
 
@@ -3285,10 +3233,10 @@
             log("insert: exception " + e);
             // 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, values);
+            Cursor oldRow = selectConflictingRow(db, CARRIERS_TABLE, values);
             if (oldRow != null) {
                 ContentValues mergedValues = new ContentValues();
-                DatabaseHelper.mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, values,
+                mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, values,
                         mergedValues, false, getContext());
                 oldRow.close();
                 notify = true;
@@ -3331,7 +3279,7 @@
                     values = new ContentValues();
                 }
 
-                values = DatabaseHelper.setDefaultValue(values);
+                values = setDefaultValue(values);
                 if (!values.containsKey(EDITED_STATUS)) {
                     values.put(EDITED_STATUS, CARRIER_EDITED);
                 }
@@ -3462,7 +3410,7 @@
             case URL_DELETE:
             {
                 // Delete preferred APN for all subIds
-                deletePreferredApnId();
+                deletePreferredApnId(getContext());
                 // Delete unedited entries
                 count = db.delete(CARRIERS_TABLE, "(" + where + unedited + " and " +
                         IS_NOT_OWNED_BY_DPC, whereArgs);
@@ -3698,10 +3646,10 @@
                     // Update failed which could be due to a conflict. Check if that is
                     // the case and merge the entries
                     log("update: exception " + e);
-                    Cursor oldRow = DatabaseHelper.selectConflictingRow(db, CARRIERS_TABLE, values);
+                    Cursor oldRow = selectConflictingRow(db, CARRIERS_TABLE, values);
                     if (oldRow != null) {
                         ContentValues mergedValues = new ContentValues();
-                        DatabaseHelper.mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, values,
+                        mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, values,
                                 mergedValues, false, getContext());
                         oldRow.close();
                         db.delete(CARRIERS_TABLE, _ID + "=?" + " and " + IS_NOT_OWNED_BY_DPC,
@@ -3933,8 +3881,8 @@
             return null;
         }
         TelephonyManager telephonyManager =
-                (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
-        String simOperator = telephonyManager.getSimOperator(subId);
+            getContext().getSystemService(TelephonyManager.class).createForSubscriptionId(subId);
+        String simOperator = telephonyManager.getSimOperator();
         Cursor cursor = db.query(CARRIERS_TABLE, new String[] {MVNO_TYPE, MVNO_MATCH_DATA},
                 NUMERIC + "='" + simOperator + "'", null, null, null, DEFAULT_SORT_ORDER);
         String where = null;
@@ -3946,7 +3894,7 @@
                 String mvnoMatchData = cursor.getString(1 /* MVNO_MATCH_DATA index */);
                 if (!TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData)
                         && ApnSettingUtils.mvnoMatches(iccRecords,
-                        ApnSetting.getMvnoTypeIntFromString(mvnoType), mvnoMatchData)) {
+                        getMvnoTypeIntFromString(mvnoType), mvnoMatchData)) {
                     where = NUMERIC + "='" + simOperator + "'"
                             + " AND " + MVNO_TYPE + "='" + mvnoType + "'"
                             + " AND " + MVNO_MATCH_DATA + "='" + mvnoMatchData + "'"
@@ -3969,7 +3917,7 @@
     @VisibleForTesting
     IccRecords getIccRecords(int subId) {
         TelephonyManager telephonyManager =
-                TelephonyManager.from(getContext()).createForSubscriptionId(subId);
+            getContext().getSystemService(TelephonyManager.class).createForSubscriptionId(subId);
         int family = telephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM ?
                 UiccController.APP_FAM_3GPP : UiccController.APP_FAM_3GPP2;
         return UiccController.getInstance().getIccRecords(
@@ -3990,7 +3938,7 @@
         SQLiteDatabase db = getWritableDatabase();
 
         // Delete preferred APN for all subIds
-        deletePreferredApnId();
+        deletePreferredApnId(getContext());
 
         // Delete entries in db
         try {
@@ -4093,4 +4041,10 @@
     private static void loge(String s) {
         Log.e(TAG, s);
     }
+
+    private static int getMvnoTypeIntFromString(String mvnoType) {
+        String mvnoTypeString = TextUtils.isEmpty(mvnoType) ? mvnoType : mvnoType.toLowerCase();
+        Integer mvnoTypeInt = MVNO_TYPE_STRING_MAP.get(mvnoTypeString);
+        return  mvnoTypeInt == null ? UNSPECIFIED_INT : mvnoTypeInt;
+    }
 }
diff --git a/tests/src/com/android/providers/telephony/CellBroadcastProviderTest.java b/tests/src/com/android/providers/telephony/CellBroadcastProviderTest.java
deleted file mode 100644
index b5ff07b..0000000
--- a/tests/src/com/android/providers/telephony/CellBroadcastProviderTest.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2019 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.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-
-import junit.framework.TestCase;
-
-import android.content.ContentValues;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.Telephony.CellBroadcasts;
-import android.test.mock.MockContentResolver;
-import android.test.mock.MockContext;
-import android.util.Log;
-
-import com.android.providers.telephony.CellBroadcastProvider.PermissionChecker;
-
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class CellBroadcastProviderTest extends TestCase {
-    private static final String TAG = CellBroadcastProviderTest.class.getSimpleName();
-
-    public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts_fwk");
-
-    private static final int GEO_SCOPE = 1;
-    private static final String PLMN = "123456";
-    private static final int LAC = 13;
-    private static final int CID = 123;
-    private static final int SERIAL_NUMBER = 17984;
-    private static final int SERVICE_CATEGORY = 4379;
-    private static final String LANGUAGE_CODE = "en";
-    private static final String MESSAGE_BODY = "AMBER Alert: xxxx";
-    private static final int MESSAGE_FORMAT = 1;
-    private static final int MESSAGE_PRIORITY = 3;
-    private static final int ETWS_WARNING_TYPE = 1;
-    private static final int CMAS_MESSAGE_CLASS = 1;
-    private static final int CMAS_CATEGORY = 6;
-    private static final int CMAS_RESPONSE_TYPE = 1;
-    private static final int CMAS_SEVERITY = 2;
-    private static final int CMAS_URGENCY = 3;
-    private static final int CMAS_CERTAINTY = 4;
-    private static final int RECEIVED_TIME = 1562792637;
-    private static final int MESSAGE_BROADCASTED = 1;
-    private static final String GEOMETRIES_COORDINATES
-            = "polygon|0,0|0,1|1,1|1,0;circle|0,0|100";
-
-    private static final String SELECT_BY_ID = CellBroadcasts._ID + "=?";
-
-    private static final String[] QUERY_COLUMNS = {
-            CellBroadcasts._ID,
-            CellBroadcasts.GEOGRAPHICAL_SCOPE,
-            CellBroadcasts.PLMN,
-            CellBroadcasts.LAC,
-            CellBroadcasts.CID,
-            CellBroadcasts.SERIAL_NUMBER,
-            CellBroadcasts.SERVICE_CATEGORY,
-            CellBroadcasts.LANGUAGE_CODE,
-            CellBroadcasts.MESSAGE_BODY,
-            CellBroadcasts.MESSAGE_FORMAT,
-            CellBroadcasts.MESSAGE_PRIORITY,
-            CellBroadcasts.ETWS_WARNING_TYPE,
-            CellBroadcasts.CMAS_MESSAGE_CLASS,
-            CellBroadcasts.CMAS_CATEGORY,
-            CellBroadcasts.CMAS_RESPONSE_TYPE,
-            CellBroadcasts.CMAS_SEVERITY,
-            CellBroadcasts.CMAS_URGENCY,
-            CellBroadcasts.CMAS_CERTAINTY,
-            CellBroadcasts.RECEIVED_TIME,
-            CellBroadcasts.MESSAGE_BROADCASTED,
-            CellBroadcasts.GEOMETRIES
-    };
-
-    private CellBroadcastProviderTestable mCellBroadcastProviderTestable;
-    private MockContextWithProvider mContext;
-    private MockContentResolver mContentResolver;
-
-    @Mock
-    private PermissionChecker mMockPermissionChecker;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        doReturn(true).when(mMockPermissionChecker).hasReadPermission();
-        doReturn(true).when(mMockPermissionChecker).hasWritePermission();
-
-        mCellBroadcastProviderTestable = new CellBroadcastProviderTestable(mMockPermissionChecker);
-        mContext = new MockContextWithProvider(mCellBroadcastProviderTestable);
-        mContentResolver = mContext.getContentResolver();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mCellBroadcastProviderTestable.closeDatabase();
-        super.tearDown();
-    }
-
-    @Test
-    public void testUpdate() {
-        // Insert a cellbroadcast to the database.
-        ContentValues cv = fakeCellBroadcast();
-        Uri uri = mContentResolver.insert(CONTENT_URI, cv);
-        assertThat(uri).isNotNull();
-
-        // Change some fields of this cell broadcast.
-        int messageBroadcasted = 1 - cv.getAsInteger(CellBroadcasts.MESSAGE_BROADCASTED);
-        int receivedTime = 1234555555;
-        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, messageBroadcasted);
-        cv.put(CellBroadcasts.RECEIVED_TIME, receivedTime);
-        mContentResolver.update(CONTENT_URI, cv, SELECT_BY_ID,
-                new String[] { uri.getLastPathSegment() });
-
-        // Query and check if the update is successed.
-        Cursor cursor = mContentResolver.query(CONTENT_URI, QUERY_COLUMNS,
-                SELECT_BY_ID, new String[] { uri.getLastPathSegment() }, null /* orderBy */);
-        cursor.moveToNext();
-
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME)))
-                .isEqualTo(receivedTime);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BROADCASTED)))
-                .isEqualTo(messageBroadcasted);
-        cursor.close();
-    }
-
-    @Test
-    public void testUpdate_WithoutWritePermission_fail() {
-        ContentValues cv = fakeCellBroadcast();
-        Uri uri = mContentResolver.insert(CONTENT_URI, cv);
-        assertThat(uri).isNotNull();
-
-        // Revoke the write permission
-        doReturn(false).when(mMockPermissionChecker).hasWritePermission();
-
-        try {
-            mContentResolver.update(CONTENT_URI, cv, SELECT_BY_ID,
-                    new String[] { uri.getLastPathSegment() });
-            fail();
-        } catch (SecurityException ex) {
-            // pass the test
-        }
-    }
-
-    @Test
-    public void testGetAllCellBroadcast() {
-        // Insert some cell broadcasts which message_broadcasted is false
-        int messageNotBroadcastedCount = 5;
-        ContentValues cv = fakeCellBroadcast();
-        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, 0);
-        for (int i = 0; i < messageNotBroadcastedCount; i++) {
-            mContentResolver.insert(CONTENT_URI, cv);
-        }
-
-        // Insert some cell broadcasts which message_broadcasted is true
-        int messageBroadcastedCount = 6;
-        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, 1);
-        for (int i = 0; i < messageBroadcastedCount; i++) {
-            mContentResolver.insert(CONTENT_URI, cv);
-        }
-
-        // Query the broadcast with message_broadcasted is false
-        Cursor cursor = mContentResolver.query(
-                CONTENT_URI,
-                QUERY_COLUMNS,
-                String.format("%s=?", CellBroadcasts.MESSAGE_BROADCASTED), /* selection */
-                new String[] {"0"}, /* selectionArgs */
-                null /* sortOrder */);
-        assertThat(cursor.getCount()).isEqualTo(messageNotBroadcastedCount);
-    }
-
-    @Test
-    public void testDelete_withoutWritePermission_throwSecurityException() {
-        Uri uri = mContentResolver.insert(CONTENT_URI, fakeCellBroadcast());
-        assertThat(uri).isNotNull();
-
-        // Revoke the write permission
-        doReturn(false).when(mMockPermissionChecker).hasWritePermission();
-
-        try {
-            mContentResolver.delete(CONTENT_URI, SELECT_BY_ID,
-                    new String[] { uri.getLastPathSegment() });
-            fail();
-        } catch (SecurityException ex) {
-            // pass the test
-        }
-    }
-
-
-    @Test
-    public void testDelete_oneRecord_success() {
-        // Insert a cellbroadcast to the database.
-        ContentValues cv = fakeCellBroadcast();
-        Uri uri = mContentResolver.insert(CONTENT_URI, cv);
-        assertThat(uri).isNotNull();
-
-        String[] selectionArgs = new String[] { uri.getLastPathSegment() };
-
-        // Ensure the cell broadcast is inserted.
-        Cursor cursor = mContentResolver.query(CONTENT_URI, QUERY_COLUMNS,
-                SELECT_BY_ID, selectionArgs, null /* orderBy */);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.close();
-
-        // Delete the cell broadcast
-        int rowCount = mContentResolver.delete(CONTENT_URI, SELECT_BY_ID,
-                selectionArgs);
-        assertThat(rowCount).isEqualTo(1);
-
-        // Ensure the cell broadcast is deleted.
-        cursor = mContentResolver.query(CONTENT_URI, QUERY_COLUMNS, SELECT_BY_ID,
-                selectionArgs, null /* orderBy */);
-        assertThat(cursor.getCount()).isEqualTo(0);
-        cursor.close();
-    }
-
-    @Test
-    public void testDelete_all_success() {
-        // Insert a cellbroadcast to the database.
-        mContentResolver.insert(CONTENT_URI, fakeCellBroadcast());
-        mContentResolver.insert(CONTENT_URI, fakeCellBroadcast());
-
-        // Ensure the cell broadcast are inserted.
-        Cursor cursor = mContentResolver.query(CONTENT_URI, QUERY_COLUMNS,
-                null /* selection */, null /* selectionArgs */, null /* orderBy */);
-        assertThat(cursor.getCount()).isEqualTo(2);
-        cursor.close();
-
-        // Delete all cell broadcasts.
-        int rowCount = mContentResolver.delete(
-                CONTENT_URI, null /* selection */, null /* selectionArgs */);
-        assertThat(rowCount).isEqualTo(2);
-        cursor.close();
-
-        // Ensure all cell broadcasts are deleted.
-        cursor = mContentResolver.query(CONTENT_URI, QUERY_COLUMNS,
-                null /* selection */, null /* selectionArgs */, null /* orderBy */);
-        assertThat(cursor.getCount()).isEqualTo(0);
-        cursor.close();
-    }
-
-    @Test
-    public void testInsert_withoutWritePermission_fail() {
-        doReturn(false).when(mMockPermissionChecker).hasWritePermission();
-
-        try {
-            mContentResolver.insert(CONTENT_URI, fakeCellBroadcast());
-            fail();
-        } catch (SecurityException ex) {
-            // pass the test
-        }
-    }
-
-    @Test
-    public void testInsertAndQuery() {
-        // Insert a cell broadcast message
-        Uri uri = mContentResolver.insert(CONTENT_URI, fakeCellBroadcast());
-
-        // Verify that the return uri is not null and the record is inserted into the database
-        // correctly.
-        assertThat(uri).isNotNull();
-        Cursor cursor = mContentResolver.query(
-                CONTENT_URI, QUERY_COLUMNS, SELECT_BY_ID,
-                new String[] { uri.getLastPathSegment() }, null /* orderBy */);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.GEOGRAPHICAL_SCOPE)))
-                .isEqualTo(GEO_SCOPE);
-        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.PLMN)))
-                .isEqualTo(PLMN);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.LAC))).isEqualTo(LAC);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CID))).isEqualTo(CID);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERIAL_NUMBER)))
-                .isEqualTo(SERIAL_NUMBER);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERVICE_CATEGORY)))
-                .isEqualTo(SERVICE_CATEGORY);
-        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.LANGUAGE_CODE)))
-                .isEqualTo(LANGUAGE_CODE);
-        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY)))
-                .isEqualTo(MESSAGE_BODY);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT)))
-                .isEqualTo(MESSAGE_FORMAT);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY)))
-                .isEqualTo(MESSAGE_PRIORITY);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.ETWS_WARNING_TYPE)))
-                .isEqualTo(ETWS_WARNING_TYPE);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_MESSAGE_CLASS)))
-                .isEqualTo(CMAS_MESSAGE_CLASS);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_CATEGORY)))
-                .isEqualTo(CMAS_CATEGORY);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_RESPONSE_TYPE)))
-                .isEqualTo(CMAS_RESPONSE_TYPE);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_SEVERITY)))
-                .isEqualTo(CMAS_SEVERITY);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_URGENCY)))
-                .isEqualTo(CMAS_URGENCY);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_CERTAINTY)))
-                .isEqualTo(CMAS_CERTAINTY);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME)))
-                .isEqualTo(RECEIVED_TIME);
-        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BROADCASTED)))
-                .isEqualTo(MESSAGE_BROADCASTED);
-        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(
-                CellBroadcasts.GEOMETRIES))).isEqualTo(GEOMETRIES_COORDINATES);
-    }
-
-    /**
-     * This is used to give the CellBroadcastProviderTest a mocked context which takes a
-     * CellBroadcastProvider and attaches it to the ContentResolver.
-     */
-    private class MockContextWithProvider extends MockContext {
-        private final MockContentResolver mResolver;
-
-        public MockContextWithProvider(CellBroadcastProviderTestable cellBroadcastProvider) {
-            mResolver = new MockContentResolver();
-            cellBroadcastProvider.initializeForTesting(this);
-
-            // Add given cellBroadcastProvider to mResolver, so that mResolver can send queries
-            // to the provider.
-            mResolver.addProvider(CellBroadcastProvider.AUTHORITY, cellBroadcastProvider);
-        }
-
-        @Override
-        public MockContentResolver getContentResolver() {
-            return mResolver;
-        }
-
-
-        @Override
-        public Object getSystemService(String name) {
-            Log.d(TAG, "getSystemService: returning null");
-            return null;
-        }
-
-        @Override
-        public int checkCallingOrSelfPermission(String permission) {
-            return PackageManager.PERMISSION_GRANTED;
-        }
-    }
-
-    private static ContentValues fakeCellBroadcast() {
-        ContentValues cv = new ContentValues();
-        cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, GEO_SCOPE);
-        cv.put(CellBroadcasts.PLMN, PLMN);
-        cv.put(CellBroadcasts.LAC, LAC);
-        cv.put(CellBroadcasts.CID, CID);
-        cv.put(CellBroadcasts.SERIAL_NUMBER, SERIAL_NUMBER);
-        cv.put(CellBroadcasts.SERVICE_CATEGORY, SERVICE_CATEGORY);
-        cv.put(CellBroadcasts.LANGUAGE_CODE, LANGUAGE_CODE);
-        cv.put(CellBroadcasts.MESSAGE_BODY, MESSAGE_BODY);
-        cv.put(CellBroadcasts.MESSAGE_FORMAT, MESSAGE_FORMAT);
-        cv.put(CellBroadcasts.MESSAGE_PRIORITY, MESSAGE_PRIORITY);
-        cv.put(CellBroadcasts.ETWS_WARNING_TYPE, ETWS_WARNING_TYPE);
-        cv.put(CellBroadcasts.CMAS_MESSAGE_CLASS, CMAS_MESSAGE_CLASS);
-        cv.put(CellBroadcasts.CMAS_CATEGORY, CMAS_CATEGORY);
-        cv.put(CellBroadcasts.CMAS_RESPONSE_TYPE, CMAS_RESPONSE_TYPE);
-        cv.put(CellBroadcasts.CMAS_SEVERITY, CMAS_SEVERITY);
-        cv.put(CellBroadcasts.CMAS_URGENCY, CMAS_URGENCY);
-        cv.put(CellBroadcasts.CMAS_CERTAINTY, CMAS_CERTAINTY);
-        cv.put(CellBroadcasts.RECEIVED_TIME, RECEIVED_TIME);
-        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, MESSAGE_BROADCASTED);
-        cv.put(CellBroadcasts.GEOMETRIES, GEOMETRIES_COORDINATES);
-        return cv;
-    }
-}
diff --git a/tests/src/com/android/providers/telephony/CellBroadcastProviderTestable.java b/tests/src/com/android/providers/telephony/CellBroadcastProviderTestable.java
deleted file mode 100644
index 8334312..0000000
--- a/tests/src/com/android/providers/telephony/CellBroadcastProviderTestable.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2019 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.content.Context;
-import android.content.pm.ProviderInfo;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-
-public class CellBroadcastProviderTestable extends CellBroadcastProvider {
-    private static final String TAG = CellBroadcastProviderTestable.class.getSimpleName();
-
-    public CellBroadcastProviderTestable(PermissionChecker permissionChecker) {
-        super(permissionChecker);
-    }
-
-    @Override
-    public boolean onCreate() {
-        // DO NOT call super.onCreate(), otherwise the permission checker will be override.
-        Log.d(TAG, "CellBroadcastProviderTestable onCreate");
-        mDbHelper = new InMemoryCellBroadcastProviderDbHelper();
-        return true;
-    }
-
-    public void closeDatabase() {
-        mDbHelper.close();
-    }
-
-    public static class InMemoryCellBroadcastProviderDbHelper extends SQLiteOpenHelper {
-        public InMemoryCellBroadcastProviderDbHelper() {
-            super(InstrumentationRegistry.getTargetContext(),
-                    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) {
-            Log.d(TAG, "IN MEMORY DB CREATED");
-            db.execSQL(getStringForCellBroadcastTableCreation(CELL_BROADCASTS_TABLE_NAME));
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
-    }
-
-    public void initializeForTesting(Context context) {
-        ProviderInfo providerInfo = new ProviderInfo();
-        providerInfo.authority = CellBroadcastProvider.AUTHORITY;
-
-        // Add context to given carrierIdProvider
-        attachInfoForTesting(context, providerInfo);
-    }
-}
diff --git a/tests/src/com/android/providers/telephony/RcsProviderDeleteTest.java b/tests/src/com/android/providers/telephony/RcsProviderDeleteTest.java
deleted file mode 100644
index c0cef0a..0000000
--- a/tests/src/com/android/providers/telephony/RcsProviderDeleteTest.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * 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.RcsColumns.RcsGroupThreadColumns.GROUP_NAME_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.OWNER_PARTICIPANT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.CANONICAL_ADDRESS_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_ALIAS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantEventColumns.NEW_ALIAS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_NAME_COLUMN;
-
-import static com.android.providers.telephony.RcsProvider.RCS_MESSAGE_TABLE;
-import static com.android.providers.telephony.RcsProviderHelper.setup1To1Thread;
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.test.mock.MockContentResolver;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class RcsProviderDeleteTest {
-    private MockContentResolver mContentResolver;
-    private RcsProviderTestable mRcsProvider;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mRcsProvider = new RcsProviderTestable();
-        RcsProviderTestable.MockContextWithProvider
-                context = new RcsProviderTestable.MockContextWithProvider(mRcsProvider);
-        mContentResolver = context.getContentResolver();
-
-        // insert a participant
-        //  first into the MmsSmsProvider
-        mRcsProvider.getWritableDatabase().execSQL(
-                "INSERT INTO canonical_addresses VALUES (1, \"+15551234567\")");
-
-        //  then into the RcsProvider
-        ContentValues participantValues = new ContentValues();
-        participantValues.put(RCS_ALIAS_COLUMN, "Bob");
-        participantValues.put(CANONICAL_ADDRESS_ID_COLUMN, 1);
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/participant"),
-                participantValues)).isEqualTo(Uri.parse("content://rcs/participant/1"));
-
-        setup1To1Thread(mContentResolver);
-
-        // insert one group thread
-        ContentValues groupContentValues = new ContentValues();
-        groupContentValues.put(OWNER_PARTICIPANT_COLUMN, 1);
-        groupContentValues.put(GROUP_NAME_COLUMN, "name");
-        Uri groupThreadUri = Uri.parse("content://rcs/group_thread");
-        assertThat(mContentResolver.insert(groupThreadUri, groupContentValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2"));
-
-        Uri addParticipantToGroupThread = Uri.parse("content://rcs/group_thread/2/participant/1");
-        assertThat(mContentResolver.insert(addParticipantToGroupThread, null)).isEqualTo(
-                addParticipantToGroupThread);
-
-        // add incoming and outgoing messages to both threads
-        ContentValues messageValues = new ContentValues();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/incoming_message"),
-                messageValues)).isEqualTo(
-                Uri.parse("content://rcs/p2p_thread/1/incoming_message/1"));
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/outgoing_message"),
-                messageValues)).isEqualTo(
-                Uri.parse("content://rcs/p2p_thread/1/outgoing_message/2"));
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/group_thread/2/incoming_message"),
-                        messageValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2/incoming_message/3"));
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/group_thread/2/outgoing_message"),
-                        messageValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2/outgoing_message/4"));
-
-        // add a file transfer to a message
-        ContentValues fileTransferValues = new ContentValues();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/message/3/file_transfer"),
-                fileTransferValues)).isEqualTo(Uri.parse("content://rcs/file_transfer/1"));
-
-        // insert an alias change event
-        ContentValues eventValues = new ContentValues();
-        eventValues.put(NEW_ALIAS_COLUMN, "new alias");
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/participant/1/alias_change_event"),
-                        eventValues)).isEqualTo(Uri.parse(
-                "content://rcs/participant/1/alias_change_event/1"));
-
-        // create a group name change event
-        eventValues.clear();
-        eventValues.put(NEW_NAME_COLUMN, "new name");
-        assertThat(mContentResolver.insert(
-                Uri.parse("content://rcs/group_thread/2/name_changed_event"),
-                eventValues)).isEqualTo(Uri.parse(
-                "content://rcs/group_thread/2/name_changed_event/1"));
-    }
-
-    @After
-    public void tearDown() {
-        mRcsProvider.tearDown();
-    }
-
-    @Test
-    public void testDelete1To1ThreadWithId() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/p2p_thread/1"), null,
-                null)).isEqualTo(1);
-        assertDeletionViaQuery("content://rcs/p2p_thread/1");
-    }
-
-    @Test
-    public void testDelete1To1ThreadWithSelection() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/p2p_thread"),
-                "rcs_fallback_thread_id=1", null)).isEqualTo(1);
-        assertDeletionViaQuery("content://rcs/p2p_thread/1");
-    }
-
-    @Test
-    public void testDeleteGroupThreadWithId() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/group_thread/2"), null,
-                null)).isEqualTo(1);
-        assertDeletionViaQuery("content://rcs/group_thread/2");
-    }
-
-    @Test
-    public void testDeleteGroupThreadWithSelection() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/group_thread"),
-                "group_name=\"name\"", null)).isEqualTo(1);
-        assertDeletionViaQuery("content://rcs/group_thread/1");
-    }
-
-    @Test
-    public void testDeleteParticipantWithIdWhileParticipatingInAThread() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/participant/1"), null,
-                null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testDeleteParticipantAfterLeavingThreads() {
-        // leave the first thread
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/group_thread/2/participant/1"),
-                null, null)).isEqualTo(1);
-
-        // try deleting the participant. It should fail
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/participant/1"), null,
-                null)).isEqualTo(0);
-
-        // delete the p2p thread
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/p2p_thread/1"), null,
-                null)).isEqualTo(1);
-
-        // try deleting the participant. It should succeed
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/participant/1"), null,
-                null)).isEqualTo(1);
-        assertDeletionViaQuery("content://rcs/participant/1");
-    }
-
-    @Test
-    public void testDeleteParticipantWithSelectionFails() {
-        assertThat(
-                mContentResolver.delete(Uri.parse("content://rcs/participant"), "rcs_alias=\"Bob\"",
-                        null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testDeleteParticipantFrom1To1ThreadFails() {
-        assertThat(
-                mContentResolver.delete(Uri.parse("content://rcs/p2p_thread/1/participant/1"), null,
-                        null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testDeleteParticipantFromGroupThread() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/group_thread/2/participant/1"),
-                null, null)).isEqualTo(1);
-        assertDeletionViaQuery("content://rcs/group_thread/2/participant");
-    }
-
-    @Test
-    public void testDeleteParticipantFromGroupThreadWithSelectionFails() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/group_thread/2/participant"),
-                "rcs_alias=?", new String[]{"Bob"})).isEqualTo(0);
-    }
-
-    @Test
-    public void testDeleteMessagesUsingUnifiedMessageViewFails() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/message/1"), null,
-                null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testDeleteMessagesUsingThreadUrisFails() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/p2p_thread/1/message/1"), null,
-                null)).isEqualTo(0);
-        assertThat(
-                mContentResolver.delete(Uri.parse("content://rcs/p2p_thread/1/incoming_message/1"),
-                        null, null)).isEqualTo(0);
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testDeleteMessage() {
-        // verify there exists 4 messages
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/message"), null, null,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(4);
-        cursor.close();
-
-        // delete 2 of them
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/incoming_message/1"), null,
-                null)).isEqualTo(1);
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/outgoing_message/4"), null,
-                null)).isEqualTo(1);
-
-        // verify that only 2 messages are left
-        cursor = mContentResolver.query(Uri.parse("content://rcs/message"), null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(2);
-        cursor.close();
-
-        // verify that entries in common table is deleted and only messages with id's 2 and 3 remain
-        SQLiteDatabase db = mRcsProvider.getWritableDatabase();
-        cursor = db.query(RCS_MESSAGE_TABLE, null, null, null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(2);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(2);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(3);
-        cursor.close();
-    }
-
-    @Test
-    public void testDeleteFileTransfer() {
-        assertThat(mContentResolver.delete(Uri.parse("content://rcs/file_transfer/1"), null,
-                null)).isEqualTo(1);
-        assertDeletionViaQuery("content://rcs/file_transfer/1");
-    }
-
-    @Test
-    public void testDeleteParticipantEvent() {
-        assertThat(mContentResolver.delete(Uri.parse(
-                "content://rcs/participant/1/alias_change_event/1"), null, null)).isEqualTo(1);
-
-        // try deleting again and verify nothing is deleted
-        // TODO - convert to query once querying is in place
-        assertThat(mContentResolver.delete(Uri.parse(
-                "content://rcs/participant/1/alias_change_event/1"), null, null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testDeleteGroupThreadEvent() {
-        assertThat(mContentResolver.delete(Uri.parse(
-                "content://rcs/group_thread/2/name_changed_event/1"), null, null)).isEqualTo(1);
-
-        // try deleting again and verify nothing is deleted
-        // TODO - convert to query once querying is in place
-        assertThat(mContentResolver.delete(Uri.parse(
-                "content://rcs/group_thread/2/name_changed_event/1"), null, null)).isEqualTo(0);
-    }
-
-    private void assertDeletionViaQuery(String queryUri) {
-        Cursor cursor = mContentResolver.query(Uri.parse(queryUri), null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(0);
-        cursor.close();
-    }
-}
diff --git a/tests/src/com/android/providers/telephony/RcsProviderHelper.java b/tests/src/com/android/providers/telephony/RcsProviderHelper.java
deleted file mode 100644
index 5a7f9a0..0000000
--- a/tests/src/com/android/providers/telephony/RcsProviderHelper.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2019 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.RcsColumns.Rcs1To1ThreadColumns.FALLBACK_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.net.Uri;
-
-class RcsProviderHelper {
-    /**
-     * Sets up a 1-to-1 thread with a participant ID of 1 and a fallback thread ID of 1.
-     *
-     * @return the {@link Uri} of the newly inserted row
-     */
-    static Uri setup1To1Thread(ContentResolver contentResolver) {
-        return setup1To1Thread(contentResolver, 1, 1);
-    }
-
-    static Uri setup1To1Thread(
-            ContentResolver contentResolver, int participantId, int fallbackThreadId) {
-        ContentValues insertValues = new ContentValues();
-        Uri insertionUri = Uri.parse("content://rcs/p2p_thread");
-        insertValues.put(RCS_PARTICIPANT_ID_COLUMN, participantId);
-
-        Uri rowUri = contentResolver.insert(insertionUri, insertValues);
-        assertThat(rowUri).isNotNull();
-
-        ContentValues updateValues = new ContentValues();
-        updateValues.put(FALLBACK_THREAD_ID_COLUMN, fallbackThreadId);
-        assertThat(contentResolver.update(rowUri, updateValues, null, null))
-                .isEqualTo(1);
-
-        return rowUri;
-    }
-
-}
diff --git a/tests/src/com/android/providers/telephony/RcsProviderInsertTest.java b/tests/src/com/android/providers/telephony/RcsProviderInsertTest.java
deleted file mode 100644
index 1a48a49..0000000
--- a/tests/src/com/android/providers/telephony/RcsProviderInsertTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * 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.RcsColumns.RcsGroupThreadColumns.CONFERENCE_URI_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_ICON_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_NAME_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.GLOBAL_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.CANONICAL_ADDRESS_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_ALIAS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantEventColumns.NEW_ALIAS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_NAME_COLUMN;
-
-import static com.android.providers.telephony.RcsProviderHelper.setup1To1Thread;
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.test.mock.MockContentResolver;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class RcsProviderInsertTest {
-    private MockContentResolver mContentResolver;
-    private RcsProviderTestable mRcsProvider;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mRcsProvider = new RcsProviderTestable();
-        RcsProviderTestable.MockContextWithProvider
-                context = new RcsProviderTestable.MockContextWithProvider(mRcsProvider);
-        mContentResolver = context.getContentResolver();
-    }
-
-    @After
-    public void tearDown() {
-        mRcsProvider.tearDown();
-    }
-
-    @Test
-    public void testInsertUnifiedThreadFails() {
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/thread"), null)).isNull();
-    }
-
-    @Test
-    public void testDuplicate1To1ThreadInsertion() {
-        Uri uri = setup1To1Thread(mContentResolver);
-
-        assertThat(mContentResolver.insert(uri, null)).isNull();
-    }
-
-    @Test
-    public void testInsertGroupThread() {
-        ContentValues contentValues = new ContentValues(3);
-        contentValues.put(CONFERENCE_URI_COLUMN, "conference uri");
-        contentValues.put(GROUP_NAME_COLUMN, "group name");
-        contentValues.put(GROUP_ICON_COLUMN, "groupIcon");
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/group_thread"),
-                contentValues)).isEqualTo(Uri.parse("content://rcs/group_thread/1"));
-    }
-
-    @Test
-    public void testInsertParticipant() {
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(CANONICAL_ADDRESS_ID_COLUMN, 6);
-        contentValues.put(RCS_ALIAS_COLUMN, "Alias");
-
-        Uri uri = mContentResolver.insert(Uri.parse("content://rcs/participant"), contentValues);
-        assertThat(uri).isEqualTo(Uri.parse("content://rcs/participant/1"));
-    }
-
-    @Test
-    public void testInsertParticipantIntoGroupThread() {
-        // create a participant
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(CANONICAL_ADDRESS_ID_COLUMN, 23);
-        mContentResolver.insert(Uri.parse("content://rcs/participant"), contentValues);
-
-        // create a thread
-        ContentValues values = new ContentValues(1);
-        values.put(GROUP_NAME_COLUMN, "Group");
-        mContentResolver.insert(Uri.parse("content://rcs/group_thread"), values);
-
-        // add participant to the thread
-        Uri uri = Uri.parse("content://rcs/group_thread/1/participant/1");
-        assertThat(mContentResolver.insert(uri, null)).isEqualTo(uri);
-
-        // assert that adding again fails
-        assertThat(mContentResolver.insert(uri, null)).isNull();
-    }
-
-    @Test
-    public void testInsertMessageFails() {
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(GLOBAL_ID_COLUMN, "global RCS id");
-
-        // try inserting messages without threads
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/message"),
-                contentValues)).isNull();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/message/6"),
-                contentValues)).isNull();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/incoming_message"),
-                contentValues)).isNull();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/incoming_message/12"),
-                contentValues)).isNull();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/outgoing_message"),
-                contentValues)).isNull();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/outgoing_message/18"),
-                contentValues)).isNull();
-
-        // try inserting into unified thread view
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/thread/5/incoming_message"),
-                contentValues)).isNull();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/thread/5/outgoing_message"),
-                contentValues)).isNull();
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testInsertMessageIntoThread() {
-        // create two threads
-        setup1To1Thread(mContentResolver);
-        ContentValues values = new ContentValues();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/group_thread"),
-                values)).isNotNull();
-
-        // add messages to threads
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/incoming_message"),
-                values)).isEqualTo(Uri.parse("content://rcs/p2p_thread/1/incoming_message/1"));
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/outgoing_message"),
-                values)).isEqualTo(Uri.parse("content://rcs/p2p_thread/1/outgoing_message/2"));
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/group_thread/2/incoming_message"),
-                        values)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2/incoming_message/3"));
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/group_thread/2/outgoing_message"),
-                        values)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2/outgoing_message/4"));
-
-        // assert that they are accessible in messages table
-        Cursor messageCursor = mContentResolver.query(Uri.parse("content://rcs/message"), null,
-                null, null, null);
-        assertThat(messageCursor.getCount()).isEqualTo(4);
-    }
-
-    @Test
-    public void testInsertMessageDelivery() {
-        setup1To1Thread(mContentResolver);
-
-        ContentValues values = new ContentValues();
-
-        // add an outgoing message to the thread
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/outgoing_message"),
-                values)).isEqualTo(Uri.parse("content://rcs/p2p_thread/1/outgoing_message/1"));
-
-        // add a delivery to the outgoing message
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/outgoing_message/1/delivery/1"),
-                values)).isEqualTo(Uri.parse("content://rcs/outgoing_message/1/delivery/1"));
-    }
-
-    @Test
-    public void testInsertFileTransfer() {
-        setup1To1Thread(mContentResolver);
-
-        ContentValues values = new ContentValues();
-
-        // add an outgoing message to the thread
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/outgoing_message"),
-                values)).isEqualTo(Uri.parse("content://rcs/p2p_thread/1/outgoing_message/1"));
-
-        // add a file transfer to the message
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/message/1/file_transfer"),
-                values)).isEqualTo(Uri.parse("content://rcs/file_transfer/1"));
-    }
-
-    @Test
-    public void testInsertParticipantEvent() {
-        // create a participant
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(CANONICAL_ADDRESS_ID_COLUMN, 23);
-        mContentResolver.insert(Uri.parse("content://rcs/participant"), contentValues);
-
-        // insert an alias change event
-        ContentValues eventValues = new ContentValues();
-        eventValues.put(NEW_ALIAS_COLUMN, "new alias");
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/participant/1/alias_change_event"),
-                        eventValues)).isEqualTo(Uri.parse(
-                "content://rcs/participant/1/alias_change_event/1"));
-    }
-
-    @Test
-    public void testInsertGroupThreadEvent() {
-        // create a group thread
-        ContentValues contentValues = new ContentValues();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/group_thread"),
-                contentValues)).isEqualTo(Uri.parse("content://rcs/group_thread/1"));
-
-        // create a group name change event
-        ContentValues eventValues = new ContentValues();
-        eventValues.put(NEW_NAME_COLUMN, "new name");
-        assertThat(mContentResolver.insert(
-                Uri.parse("content://rcs/group_thread/1/name_changed_event"),
-                eventValues)).isEqualTo(Uri.parse(
-                "content://rcs/group_thread/1/name_changed_event/1"));
-    }
-}
diff --git a/tests/src/com/android/providers/telephony/RcsProviderQueryTest.java b/tests/src/com/android/providers/telephony/RcsProviderQueryTest.java
deleted file mode 100644
index f0579ea..0000000
--- a/tests/src/com/android/providers/telephony/RcsProviderQueryTest.java
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * 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.RcsColumns.RcsEventTypes.PARTICIPANT_JOINED_EVENT_TYPE;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.FILE_SIZE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.SESSION_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_NAME_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_TEXT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.MESSAGE_TYPE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.ORIGINATION_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.CANONICAL_ADDRESS_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_ALIAS_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.DESTINATION_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.EVENT_TYPE_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_NAME_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.SOURCE_PARTICIPANT_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsUnifiedThreadColumns.THREAD_TYPE_COLUMN;
-import static android.telephony.ims.RcsEventQueryParams.EVENT_QUERY_PARAMETERS_KEY;
-import static android.telephony.ims.RcsEventQueryParams.GROUP_THREAD_NAME_CHANGED_EVENT;
-import static android.telephony.ims.RcsMessageQueryParams.MESSAGE_QUERY_PARAMETERS_KEY;
-import static android.telephony.ims.RcsParticipantQueryParams.PARTICIPANT_QUERY_PARAMETERS_KEY;
-import static android.telephony.ims.RcsQueryContinuationToken.QUERY_CONTINUATION_TOKEN;
-import static android.telephony.ims.RcsThreadQueryParams.THREAD_QUERY_PARAMETERS_KEY;
-
-import static com.android.providers.telephony.RcsProviderHelper.setup1To1Thread;
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.telephony.ims.RcsEventQueryParams;
-import android.telephony.ims.RcsGroupThread;
-import android.telephony.ims.RcsMessageQueryParams;
-import android.telephony.ims.RcsParticipantQueryParams;
-import android.telephony.ims.RcsQueryContinuationToken;
-import android.telephony.ims.RcsThreadQueryParams;
-import android.test.mock.MockContentResolver;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.providers.telephony.RcsProviderTestable.MockContextWithProvider;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class RcsProviderQueryTest {
-    private MockContentResolver mContentResolver;
-    private RcsProviderTestable mRcsProvider;
-
-    private static final String GROUP_NAME = "group name";
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mRcsProvider = new RcsProviderTestable();
-        MockContextWithProvider context = new MockContextWithProvider(mRcsProvider);
-        mContentResolver = context.getContentResolver();
-
-        // insert two participants
-        Uri participantUri = Uri.parse("content://rcs/participant");
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(CANONICAL_ADDRESS_ID_COLUMN, 99);
-        contentValues.put(RCS_ALIAS_COLUMN, "Some alias");
-        mContentResolver.insert(participantUri, contentValues);
-
-        contentValues.clear();
-        contentValues.put(CANONICAL_ADDRESS_ID_COLUMN, 100);
-        contentValues.put(RCS_ALIAS_COLUMN, "Some other alias");
-        mContentResolver.insert(participantUri, contentValues);
-
-        // insert two 1 to 1 threads
-        setup1To1Thread(mContentResolver, 1, 1);
-        setup1To1Thread(mContentResolver, 2, 2);
-
-        // insert one group thread
-        ContentValues groupContentValues = new ContentValues(1);
-        groupContentValues.put(GROUP_NAME_COLUMN, GROUP_NAME);
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/group_thread"),
-                groupContentValues)).isEqualTo(Uri.parse("content://rcs/group_thread/3"));
-
-        // put participants into the group
-        mContentResolver.insert(Uri.parse("content://rcs/group_thread/3/participant/1"), null);
-        mContentResolver.insert(Uri.parse("content://rcs/group_thread/3/participant/2"), null);
-
-        // insert two messages into first thread, leave the second one empty, insert one into group
-        // thread
-        ContentValues messageValues = new ContentValues();
-
-        messageValues.put(ORIGINATION_TIMESTAMP_COLUMN, 300);
-        messageValues.put(MESSAGE_TEXT_COLUMN, "Old message");
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/incoming_message"),
-                messageValues)).isEqualTo(
-                Uri.parse("content://rcs/p2p_thread/1/incoming_message/1"));
-
-        messageValues.clear();
-        messageValues.put(ORIGINATION_TIMESTAMP_COLUMN, 400);
-        messageValues.put(MESSAGE_TEXT_COLUMN, "New message");
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/outgoing_message"),
-                messageValues)).isEqualTo(
-                Uri.parse("content://rcs/p2p_thread/1/outgoing_message/2"));
-
-        messageValues.clear();
-        messageValues.put(ORIGINATION_TIMESTAMP_COLUMN, 200);
-        messageValues.put(MESSAGE_TEXT_COLUMN, "Group message");
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/group_thread/3/incoming_message"),
-                        messageValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/3/incoming_message/3"));
-
-        // Add two events to the group thread
-        ContentValues eventValues = new ContentValues();
-        eventValues.put(NEW_NAME_COLUMN, "New group name");
-        assertThat(mContentResolver.insert(
-                Uri.parse("content://rcs/group_thread/3/name_changed_event"),
-                eventValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/3/name_changed_event/1"));
-
-        eventValues.clear();
-        eventValues.put(SOURCE_PARTICIPANT_ID_COLUMN, 1);
-        eventValues.put(DESTINATION_PARTICIPANT_ID_COLUMN, 2);
-        assertThat(mContentResolver.insert(
-                Uri.parse("content://rcs/group_thread/3/participant_joined_event"),
-                eventValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/3/participant_joined_event/2"));
-    }
-
-    @After
-    public void tearDown() {
-        mRcsProvider.tearDown();
-    }
-
-    @Test
-    public void testCanQueryUnifiedThreads() {
-        RcsThreadQueryParams queryParameters = new RcsThreadQueryParams.Builder().build();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(THREAD_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/thread"),
-                null, bundle, null);
-        assertThat(cursor.getCount()).isEqualTo(3);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(THREAD_TYPE_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getString(cursor.getColumnIndex(GROUP_NAME_COLUMN))).isEqualTo(
-                GROUP_NAME);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(
-                200);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(
-                "Group message");
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(THREAD_TYPE_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(GROUP_NAME_COLUMN))).isEqualTo(null);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(null);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(THREAD_TYPE_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(GROUP_NAME_COLUMN))).isEqualTo(null);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(
-                400);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(
-                "New message");
-    }
-
-    @Test
-    public void testCanQueryUnifiedThreadsWithLimitAndSorting() {
-        RcsThreadQueryParams queryParameters = new RcsThreadQueryParams.Builder()
-                .setThreadType(RcsThreadQueryParams.THREAD_TYPE_1_TO_1).setResultLimit(1)
-                .setSortProperty(RcsThreadQueryParams.SORT_BY_TIMESTAMP).setSortDirection(true)
-                .build();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(THREAD_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/thread"),
-                null, bundle, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(THREAD_TYPE_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(GROUP_NAME_COLUMN))).isEqualTo(null);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(null);
-    }
-
-    @Test
-    public void testCanContinueThreadQuery() {
-        // Limit results to 1.
-        RcsThreadQueryParams queryParameters =
-                new RcsThreadQueryParams.Builder().setResultLimit(1).build();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(THREAD_QUERY_PARAMETERS_KEY, queryParameters);
-
-        // Perform an initial query, verify first thread is returned
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/thread"), null, bundle,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(THREAD_TYPE_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getString(cursor.getColumnIndex(GROUP_NAME_COLUMN))).isEqualTo(
-                GROUP_NAME);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(
-                200);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(
-                "Group message");
-
-        // Put the continuation token in the bundle to do a follow up query
-        RcsQueryContinuationToken continuationToken = cursor.getExtras().getParcelable(
-                QUERY_CONTINUATION_TOKEN);
-        bundle.clear();
-        bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken);
-        cursor.close();
-
-        cursor = mContentResolver.query(Uri.parse("content://rcs/thread"), null, bundle,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(THREAD_TYPE_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(GROUP_NAME_COLUMN))).isEqualTo(null);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(null);
-        cursor.close();
-
-        // Put the continuation token in the bundle to do a follow up query again, verify third
-        // thread is returned
-        continuationToken = cursor.getExtras().getParcelable(QUERY_CONTINUATION_TOKEN);
-        bundle.clear();
-        bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken);
-        cursor = mContentResolver.query(Uri.parse("content://rcs/thread"), null, bundle,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(THREAD_TYPE_COLUMN))).isEqualTo(0);
-        assertThat(cursor.getString(cursor.getColumnIndex(GROUP_NAME_COLUMN))).isEqualTo(null);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(
-                400);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(
-                "New message");
-        cursor.close();
-    }
-
-    @Test
-    public void testQuery1To1Threads() {
-        // verify two threads are returned in the query
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/p2p_thread"),
-                new String[]{RCS_THREAD_ID_COLUMN}, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(2);
-    }
-
-    @Test
-    public void testQueryGroupThreads() {
-        // verify one thread is returned in the query
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/group_thread"),
-                new String[]{GROUP_NAME_COLUMN}, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getString(0)).isEqualTo(GROUP_NAME);
-    }
-
-    @Test
-    public void testQueryParticipant() {
-        RcsParticipantQueryParams queryParameters = new RcsParticipantQueryParams.Builder()
-                .build();
-
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(PARTICIPANT_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/participant"), null, bundle,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(2);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_PARTICIPANT_ID_COLUMN))).isEqualTo(2);
-        assertThat(cursor.getInt(cursor.getColumnIndex(CANONICAL_ADDRESS_ID_COLUMN))).isEqualTo(
-                100);
-        assertThat(cursor.getString(cursor.getColumnIndex(RCS_ALIAS_COLUMN))).isEqualTo(
-                "Some other alias");
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_PARTICIPANT_ID_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getInt(cursor.getColumnIndex(CANONICAL_ADDRESS_ID_COLUMN))).isEqualTo(99);
-        assertThat(cursor.getString(cursor.getColumnIndex(RCS_ALIAS_COLUMN))).isEqualTo(
-                "Some alias");
-    }
-
-    @Test
-    public void testQueryParticipantWithContinuation() {
-        Uri participantUri = Uri.parse("content://rcs/participant");
-
-        // Perform the initial query
-        RcsParticipantQueryParams queryParameters =
-                new RcsParticipantQueryParams.Builder().setAliasLike("%ali%").setSortProperty(
-                        RcsParticipantQueryParams.SORT_BY_ALIAS).setSortDirection(true)
-                        .setResultLimit(1).build();
-
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(PARTICIPANT_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(participantUri, null, bundle, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(1);
-        assertThat(cursor.getInt(1)).isEqualTo(99);
-        assertThat(cursor.getString(2)).isEqualTo("Some alias");
-
-        // Perform the continuation query
-        RcsQueryContinuationToken continuationToken = cursor.getExtras().getParcelable(
-                QUERY_CONTINUATION_TOKEN);
-        bundle.clear();
-        bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken);
-
-        cursor = mContentResolver.query(participantUri, null, bundle, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(2);
-        assertThat(cursor.getInt(1)).isEqualTo(100);
-        assertThat(cursor.getString(2)).isEqualTo("Some other alias");
-
-        // Perform the continuation query to verify no entries left
-        continuationToken = cursor.getExtras().getParcelable(QUERY_CONTINUATION_TOKEN);
-        bundle.clear();
-        bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken);
-
-        cursor = mContentResolver.query(participantUri, null, bundle, null);
-        assertThat(cursor.getCount()).isEqualTo(0);
-        continuationToken = cursor.getExtras().getParcelable(QUERY_CONTINUATION_TOKEN);
-        assertThat(continuationToken).isNull();
-    }
-
-    @Test
-    public void testQueryGroupParticipants() {
-        // TODO - implement
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testQueryEvents() {
-        RcsEventQueryParams queryParameters = new RcsEventQueryParams.Builder().build();
-
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(EVENT_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/event"), null, bundle,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(2);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(EVENT_TYPE_COLUMN))).isEqualTo(
-                PARTICIPANT_JOINED_EVENT_TYPE);
-        assertThat(cursor.getInt(cursor.getColumnIndex(SOURCE_PARTICIPANT_ID_COLUMN))).isEqualTo(
-                1);
-        assertThat(cursor.getInt(cursor.getColumnIndex(DESTINATION_PARTICIPANT_ID_COLUMN))).isEqualTo(
-                2);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(EVENT_TYPE_COLUMN))).isEqualTo(
-                GROUP_THREAD_NAME_CHANGED_EVENT);
-        assertThat(cursor.getString(cursor.getColumnIndex(NEW_NAME_COLUMN))).isEqualTo(
-                "New group name");
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testQueryEventsWithContinuation() {
-        RcsEventQueryParams queryParameters =
-                new RcsEventQueryParams.Builder().setResultLimit(1).setSortDirection(true)
-                        .build();
-
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(EVENT_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/event"), null, bundle,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(EVENT_TYPE_COLUMN))).isEqualTo(
-                GROUP_THREAD_NAME_CHANGED_EVENT);
-        assertThat(cursor.getString(cursor.getColumnIndex(NEW_NAME_COLUMN))).isEqualTo(
-                "New group name");
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testQueryEventsWithTypeLimitation() {
-        RcsEventQueryParams queryParameters =
-                new RcsEventQueryParams.Builder().setEventType(
-                        GROUP_THREAD_NAME_CHANGED_EVENT).build();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(EVENT_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/event"), null, bundle,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(EVENT_TYPE_COLUMN))).isEqualTo(
-                GROUP_THREAD_NAME_CHANGED_EVENT);
-        assertThat(cursor.getString(cursor.getColumnIndex(NEW_NAME_COLUMN))).isEqualTo(
-                "New group name");
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testQueryMessages() {
-        RcsMessageQueryParams queryParameters = new RcsMessageQueryParams.Builder().build();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(MESSAGE_QUERY_PARAMETERS_KEY, queryParameters);
-
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/message"), null, bundle,
-                null);
-
-        assertThat(cursor.getCount()).isEqualTo(3);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(MESSAGE_ID_COLUMN))).isEqualTo(3);
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN))).isEqualTo(3);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(MESSAGE_ID_COLUMN))).isEqualTo(2);
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN))).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(MESSAGE_ID_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN))).isEqualTo(1);
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testQueryMessagesWithContinuation() {
-        RcsMessageQueryParams queryParameters =
-                new RcsMessageQueryParams.Builder().setMessageLike("%o%message").setResultLimit(
-                        1).setSortProperty(RcsMessageQueryParams.SORT_BY_TIMESTAMP)
-                        .setSortDirection(true).build();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(MESSAGE_QUERY_PARAMETERS_KEY, queryParameters);
-
-        // Perform the initial query
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/message"), null, bundle,
-                null);
-
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(MESSAGE_ID_COLUMN))).isEqualTo(3);
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN))).isEqualTo(3);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(
-                200);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TYPE_COLUMN))).isEqualTo(
-                "Group message");
-
-        // Perform the continuation query
-        RcsQueryContinuationToken continuationToken = cursor.getExtras().getParcelable(
-                QUERY_CONTINUATION_TOKEN);
-        assertThat(continuationToken).isNotNull();
-        bundle.clear();
-        bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken);
-
-        cursor = mContentResolver.query(Uri.parse("content://rcs/message"), null, bundle, null);
-
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(MESSAGE_ID_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(
-                300);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(
-                "Old message");
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testQueryMessagesWithThreadFilter() {
-        RcsMessageQueryParams queryParameters =
-                new RcsMessageQueryParams.Builder().setThread(new RcsGroupThread(null, 3))
-                        .build();
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(MESSAGE_QUERY_PARAMETERS_KEY, queryParameters);
-
-        // Perform the initial query
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/message"), null, bundle,
-                null);
-
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(cursor.getColumnIndex(MESSAGE_ID_COLUMN))).isEqualTo(3);
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN))).isEqualTo(3);
-        assertThat(cursor.getInt(cursor.getColumnIndex(ORIGINATION_TIMESTAMP_COLUMN))).isEqualTo(
-                200);
-        assertThat(cursor.getString(cursor.getColumnIndex(MESSAGE_TEXT_COLUMN))).isEqualTo(
-                "Group message");
-
-    }
-
-    @Test
-    public void testQueryParticipantOf1To1Thread() {
-        // query the participant back
-        Uri queryUri = Uri.parse("content://rcs/p2p_thread/1/participant");
-        Cursor cursor = mContentResolver.query(queryUri, null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-
-        assertThat(cursor.getInt(1)).isEqualTo(99);
-        assertThat(cursor.getString(2)).isEqualTo("Some alias");
-    }
-
-    @Test
-    public void testQueryParticipantOfGroupThread() {
-        // query all the participants in this thread
-        Uri queryUri = Uri.parse("content://rcs/group_thread/3/participant");
-        Cursor cursor = mContentResolver.query(queryUri, null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_PARTICIPANT_ID_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getInt(cursor.getColumnIndex(CANONICAL_ADDRESS_ID_COLUMN))).isEqualTo(99);
-        assertThat(cursor.getString(cursor.getColumnIndex(RCS_ALIAS_COLUMN))).isEqualTo(
-                "Some alias");
-    }
-
-    @Test
-    public void testQueryParticipantOfGroupThreadWithId() {
-        Cursor cursor = mContentResolver.query(
-                Uri.parse("content://rcs/group_thread/3/participant/1"), null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-
-        assertThat(cursor.getInt(cursor.getColumnIndex(RCS_PARTICIPANT_ID_COLUMN))).isEqualTo(1);
-        assertThat(cursor.getInt(cursor.getColumnIndex(CANONICAL_ADDRESS_ID_COLUMN))).isEqualTo(99);
-        assertThat(cursor.getString(cursor.getColumnIndex(RCS_ALIAS_COLUMN))).isEqualTo(
-                "Some alias");
-    }
-
-    @Test
-    public void testQueryFileTransfer() {
-        ContentValues values = new ContentValues();
-        // add an incoming message to the thread 2
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/2/incoming_message"),
-                values)).isEqualTo(Uri.parse("content://rcs/p2p_thread/2/incoming_message/4"));
-
-        // add a file transfer
-        values.put(SESSION_ID_COLUMN, "session_id");
-        values.put(FILE_SIZE_COLUMN, 1234567890);
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/message/4/file_transfer"),
-                        values)).isEqualTo(Uri.parse("content://rcs/file_transfer/1"));
-
-        // query the file transfer back
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/file_transfer/1"), null,
-                null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(1);
-        assertThat(cursor.getInt(1)).isEqualTo(4);
-        assertThat(cursor.getString(2)).isEqualTo("session_id");
-        assertThat(cursor.getLong(5)).isEqualTo(1234567890);
-    }
-}
diff --git a/tests/src/com/android/providers/telephony/RcsProviderTestable.java b/tests/src/com/android/providers/telephony/RcsProviderTestable.java
deleted file mode 100644
index 569fcdb..0000000
--- a/tests/src/com/android/providers/telephony/RcsProviderTestable.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.app.AppOpsManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.telephony.TelephonyManager;
-import android.test.mock.MockContentResolver;
-import android.test.mock.MockContext;
-
-import org.mockito.Mockito;
-
-/**
- * A subclass of RcsProvider used for testing on an in-memory database
- */
-public class RcsProviderTestable extends RcsProvider {
-    private MockContextWithProvider mockContextWithProvider;
-
-    @Override
-    public boolean onCreate() {
-        mockContextWithProvider = new MockContextWithProvider(this);
-        mDbOpenHelper = new InMemoryRcsDatabase();
-        mParticipantHelper = new RcsProviderParticipantHelper(mDbOpenHelper);
-        mThreadHelper = new RcsProviderThreadHelper(mDbOpenHelper);
-        mMessageHelper = new RcsProviderMessageHelper(mDbOpenHelper);
-        mEventHelper = new RcsProviderEventHelper(mDbOpenHelper);
-        return true;
-    }
-
-    protected void tearDown() {
-        mDbOpenHelper.close();
-    }
-
-    public SQLiteDatabase getWritableDatabase() {
-        return mDbOpenHelper.getWritableDatabase();
-    }
-
-    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) {
-            MmsSmsDatabaseHelper mmsSmsDatabaseHelper = new MmsSmsDatabaseHelper(
-                mockContextWithProvider, null);
-            mmsSmsDatabaseHelper.createMmsTables(db);
-            mmsSmsDatabaseHelper.createSmsTables(db);
-            mmsSmsDatabaseHelper.createCommonTables(db);
-
-            RcsProviderThreadHelper.createThreadTables(db);
-            RcsProviderParticipantHelper.createParticipantTables(db);
-            RcsProviderMessageHelper.createRcsMessageTables(db);
-            RcsProviderEventHelper.createRcsEventTables(db);
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            // no-op
-        }
-    }
-
-    static 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 PackageManager getPackageManager() {
-            return Mockito.mock(PackageManager.class);
-        }
-
-        @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;
-            }
-        }
-
-        @Override
-        public boolean isCredentialProtectedStorage() {
-            return false;
-        }
-    }
-}
diff --git a/tests/src/com/android/providers/telephony/RcsProviderUpdateTest.java b/tests/src/com/android/providers/telephony/RcsProviderUpdateTest.java
deleted file mode 100644
index 4ba7c1c..0000000
--- a/tests/src/com/android/providers/telephony/RcsProviderUpdateTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * 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.RcsColumns.Rcs1To1ThreadColumns.FALLBACK_THREAD_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.HEIGHT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsFileTransferColumns.WIDTH_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_NAME_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.OWNER_PARTICIPANT_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsIncomingMessageColumns.ARRIVAL_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageColumns.ORIGINATION_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsMessageDeliveryColumns.DELIVERED_TIMESTAMP_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.CANONICAL_ADDRESS_ID_COLUMN;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_ALIAS_COLUMN;
-
-import static com.android.providers.telephony.RcsProviderHelper.setup1To1Thread;
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.Telephony.RcsColumns.RcsMessageDeliveryColumns;
-import android.test.mock.MockContentResolver;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class RcsProviderUpdateTest {
-    private MockContentResolver mContentResolver;
-    private RcsProviderTestable mRcsProvider;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mRcsProvider = new RcsProviderTestable();
-        RcsProviderTestable.MockContextWithProvider
-                context = new RcsProviderTestable.MockContextWithProvider(mRcsProvider);
-        mContentResolver = context.getContentResolver();
-
-        // insert a participant
-        //  first into the MmsSmsProvider
-        mRcsProvider.getWritableDatabase().execSQL(
-                "INSERT INTO canonical_addresses VALUES (1, \"+15551234567\")");
-
-        //  then into the RcsProvider
-        ContentValues participantValues = new ContentValues();
-        participantValues.put(RCS_ALIAS_COLUMN, "Bob");
-        participantValues.put(CANONICAL_ADDRESS_ID_COLUMN, 1);
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/participant"),
-                participantValues)).isEqualTo(Uri.parse("content://rcs/participant/1"));
-
-        // insert fallback threads
-        mRcsProvider.getWritableDatabase().execSQL("INSERT INTO threads(_id) VALUES (1)");
-        mRcsProvider.getWritableDatabase().execSQL("INSERT INTO threads(_id) VALUES (2)");
-
-        setup1To1Thread(mContentResolver);
-
-        // insert one group thread
-        ContentValues groupContentValues = new ContentValues();
-        groupContentValues.put(OWNER_PARTICIPANT_COLUMN, 1);
-        groupContentValues.put(GROUP_NAME_COLUMN, "Name");
-        Uri groupThreadUri = Uri.parse("content://rcs/group_thread");
-        assertThat(mContentResolver.insert(groupThreadUri, groupContentValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2"));
-
-        Uri groupInsertionUri = Uri.parse("content://rcs/group_thread/2/participant/1");
-        assertThat(mContentResolver.insert(groupInsertionUri, null)).isEqualTo(groupInsertionUri);
-
-        // add incoming and outgoing messages to both threads
-        ContentValues messageValues = new ContentValues();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/incoming_message"),
-                messageValues)).isEqualTo(
-                Uri.parse("content://rcs/p2p_thread/1/incoming_message/1"));
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/p2p_thread/1/outgoing_message"),
-                messageValues)).isEqualTo(
-                Uri.parse("content://rcs/p2p_thread/1/outgoing_message/2"));
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/group_thread/2/incoming_message"),
-                        messageValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2/incoming_message/3"));
-        assertThat(
-                mContentResolver.insert(Uri.parse("content://rcs/group_thread/2/outgoing_message"),
-                        messageValues)).isEqualTo(
-                Uri.parse("content://rcs/group_thread/2/outgoing_message/4"));
-
-        // add message delivery to the outgoing messages
-        ContentValues deliveryValues = new ContentValues();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/outgoing_message/2/delivery/1"),
-                deliveryValues)).isEqualTo(
-                Uri.parse("content://rcs/outgoing_message/2/delivery/1"));
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/outgoing_message/4/delivery/1"),
-                deliveryValues)).isEqualTo(
-                Uri.parse("content://rcs/outgoing_message/4/delivery/1"));
-
-        // add a file transfer to an incoming message
-        ContentValues fileTransferValues = new ContentValues();
-        assertThat(mContentResolver.insert(Uri.parse("content://rcs/message/3/file_transfer"),
-                fileTransferValues)).isEqualTo(Uri.parse("content://rcs/file_transfer/1"));
-    }
-
-    @After
-    public void tearDown() {
-        mRcsProvider.tearDown();
-    }
-
-    @Test
-    public void testUpdate1To1ThreadWithSelection() {
-        // update the fallback thread id
-        ContentValues contentValues = new ContentValues(1);
-        contentValues.put(FALLBACK_THREAD_ID_COLUMN, 2);
-        Uri p2pThreadUri = Uri.parse("content://rcs/p2p_thread");
-
-        assertThat(mContentResolver.update(p2pThreadUri, contentValues, "rcs_fallback_thread_id=1",
-                null)).isEqualTo(1);
-
-        // verify the thread is actually updated
-        Cursor cursor = mContentResolver.query(p2pThreadUri,
-                new String[]{FALLBACK_THREAD_ID_COLUMN}, "rcs_fallback_thread_id=2", null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(2);
-    }
-
-    @Test
-    public void testUpdate1To1ThreadWithId() {
-        // update the fallback thread id
-        ContentValues contentValues = new ContentValues(1);
-        contentValues.put(FALLBACK_THREAD_ID_COLUMN, 2);
-        Uri p2pThreadUri = Uri.parse("content://rcs/p2p_thread/1");
-        assertThat(mContentResolver.update(p2pThreadUri, contentValues, null, null)).isEqualTo(1);
-
-        // verify the thread is actually updated
-        Cursor cursor = mContentResolver.query(p2pThreadUri,
-                new String[]{FALLBACK_THREAD_ID_COLUMN}, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(2);
-    }
-
-    @Test
-    public void testUpdateGroupThreadWithSelection() {
-        // update the group name
-        ContentValues contentValues = new ContentValues(1);
-        contentValues.put(GROUP_NAME_COLUMN, "New name");
-        Uri groupThreadUri = Uri.parse("content://rcs/group_thread");
-        assertThat(mContentResolver.update(groupThreadUri, contentValues, "group_name=\"Name\"",
-                null)).isEqualTo(1);
-
-        // verify the thread is actually updated
-        Cursor cursor = mContentResolver.query(groupThreadUri, new String[]{GROUP_NAME_COLUMN},
-                "group_name=\"New name\"", null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-
-        cursor.moveToNext();
-        assertThat(cursor.getString(0)).isEqualTo("New name");
-    }
-
-    @Test
-    public void testUpdateGroupThreadWithId() {
-        // update the group name
-        ContentValues contentValues = new ContentValues(1);
-        contentValues.put(GROUP_NAME_COLUMN, "New name");
-        Uri groupThreadUri = Uri.parse("content://rcs/group_thread/2");
-        assertThat(mContentResolver.update(groupThreadUri, contentValues, null, null)).isEqualTo(1);
-
-        // verify the thread is actually updated
-        Cursor cursor = mContentResolver.query(groupThreadUri, new String[]{GROUP_NAME_COLUMN},
-                null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getString(0)).isEqualTo("New name");
-    }
-
-    @Test
-    public void testUpdateParticipantWithId() {
-        // change the participant name from Bob to Bobby
-        ContentValues contentValues = new ContentValues(1);
-        contentValues.put(RCS_ALIAS_COLUMN, "Bobby");
-
-        Uri participantUri = Uri.parse("content://rcs/participant/1");
-
-        assertThat(mContentResolver.update(participantUri, contentValues, null, null)).isEqualTo(1);
-
-        // verify participant is actually updated
-        Cursor cursor = mContentResolver.query(participantUri, new String[]{RCS_ALIAS_COLUMN}, null,
-                null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getString(0)).isEqualTo("Bobby");
-    }
-
-    @Test
-    public void testUpdate1To1ThreadParticipantFails() {
-        assertThat(
-                mContentResolver.update(Uri.parse("content://rcs/p2p_thread/1/participant/1"), null,
-                        null, null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testUpdateGroupParticipantFails() {
-        assertThat(mContentResolver.update(Uri.parse("content://rcs/group_thread/2/participant/1"),
-                null, null, null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testUpdateUnifiedMessageViewFails() {
-        ContentValues updateValues = new ContentValues();
-        updateValues.put(ORIGINATION_TIMESTAMP_COLUMN, 1234567890);
-
-        assertThat(mContentResolver.update(Uri.parse("content://rcs/message"), updateValues, null,
-                null)).isEqualTo(0);
-        assertThat(mContentResolver.update(Uri.parse("content://rcs/message/1"), updateValues, null,
-                null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testUpdateMessageOnThreadFails() {
-        ContentValues updateValues = new ContentValues();
-        updateValues.put(ORIGINATION_TIMESTAMP_COLUMN, 1234567890);
-
-        assertThat(mContentResolver.update(Uri.parse("content://rcs/p2p_thread/1/incoming_message"),
-                updateValues, null, null)).isEqualTo(0);
-        assertThat(
-                mContentResolver.update(Uri.parse("content://rcs/p2p_thread/1/incoming_message/1"),
-                        updateValues, null, null)).isEqualTo(0);
-        assertThat(
-                mContentResolver.update(Uri.parse("content://rcs/group_thread/2/outgoing_message"),
-                        updateValues, null, null)).isEqualTo(0);
-        assertThat(mContentResolver.update(
-                Uri.parse("content://rcs/groupp_thread/2/outgoing_message/1"), updateValues, null,
-                null)).isEqualTo(0);
-    }
-
-    @Test
-    public void testUpdateMessage() {
-        // update the message
-        ContentValues updateValues = new ContentValues(1);
-        updateValues.put(ORIGINATION_TIMESTAMP_COLUMN, 1234567890);
-        assertThat(
-                mContentResolver.update(Uri.parse("content://rcs/outgoing_message/2"), updateValues,
-                        null, null)).isEqualTo(1);
-
-        // verify the value is actually updated
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/outgoing_message/2"), null,
-                null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getLong(5)).isEqualTo(1234567890);
-        cursor.close();
-    }
-
-    @Test
-    @Ignore // TODO: fix and un-ignore
-    public void testUpdateIncomingMessageSpecificColumn() {
-        // update the message
-        ContentValues updateValues = new ContentValues(1);
-        updateValues.put(ARRIVAL_TIMESTAMP_COLUMN, 987654321);
-        assertThat(
-                mContentResolver.update(Uri.parse("content://rcs/incoming_message/3"), updateValues,
-                        null, null)).isEqualTo(1);
-
-        // verify the value is actually updated
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/incoming_message/3"), null,
-                null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getLong(7)).isEqualTo(987654321);
-        cursor.close();
-    }
-
-    @Test
-    public void testUpdateMessageDelivery() {
-        ContentValues updateValues = new ContentValues();
-        updateValues.put(DELIVERED_TIMESTAMP_COLUMN, 12345);
-        updateValues.put(RcsMessageDeliveryColumns.SEEN_TIMESTAMP_COLUMN, 54321);
-
-        assertThat(mContentResolver.update(Uri.parse("content://rcs/outgoing_message/2/delivery/1"),
-                updateValues, null, null)).isEqualTo(1);
-
-        // verify the value is actually updated
-        Cursor cursor = mContentResolver.query(
-                Uri.parse("content://rcs/outgoing_message/2/delivery"), null, null, null, null,
-                null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(0)).isEqualTo(2);
-        assertThat(cursor.getInt(1)).isEqualTo(1);
-        assertThat(cursor.getLong(2)).isEqualTo(12345);
-        assertThat(cursor.getLong(3)).isEqualTo(54321);
-    }
-
-    @Test
-    public void testUpdateFileTransfer() {
-        ContentValues updateValues = new ContentValues();
-        updateValues.put(WIDTH_COLUMN, 640);
-        updateValues.put(HEIGHT_COLUMN, 480);
-
-        assertThat(mContentResolver.update(Uri.parse("content://rcs/file_transfer/1"), updateValues,
-                null, null)).isEqualTo(1);
-
-        // verify that the values are actually updated
-        Cursor cursor = mContentResolver.query(Uri.parse("content://rcs/file_transfer/1"), null,
-                null, null, null, null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor.moveToNext();
-        assertThat(cursor.getInt(8)).isEqualTo(640);
-        assertThat(cursor.getInt(9)).isEqualTo(480);
-    }
-}
diff --git a/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java b/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
index b6f5508..0cd66e3 100644
--- a/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
+++ b/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
@@ -164,12 +164,12 @@
 
         final int voiceRegState = ss.getVoiceRegState();
         final int dataRegState = ss.getDataRegState();
-        final String voiceOperatorAlphaLong = ss.getVoiceOperatorAlphaLong();
-        final String voiceOperatorAlphaShort = ss.getVoiceOperatorAlphaShort();
-        final String voiceOperatorNumeric = ss.getVoiceOperatorNumeric();
-        final String dataOperatorAlphaLong = ss.getDataOperatorAlphaLong();
-        final String dataOperatorAlphaShort = ss.getDataOperatorAlphaShort();
-        final String dataOperatorNumeric = ss.getDataOperatorNumeric();
+        final String voiceOperatorAlphaLong = ss.getOperatorAlphaLong();
+        final String voiceOperatorAlphaShort = ss.getOperatorAlphaShort();
+        final String voiceOperatorNumeric = ss.getOperatorNumeric();
+        final String dataOperatorAlphaLong = ss.getOperatorAlphaLong();
+        final String dataOperatorAlphaShort = ss.getOperatorAlphaShort();
+        final String dataOperatorNumeric = ss.getOperatorNumeric();
         final int isManualNetworkSelection = (ss.getIsManualSelection()) ? 1 : 0;
         final int rilVoiceRadioTechnology = ss.getRilVoiceRadioTechnology();
         final int rilDataRadioTechnology = ss.getRilDataRadioTechnology();
diff --git a/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
index 8287352..26df3c0 100644
--- a/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyDatabaseHelperTest.java
@@ -59,7 +59,7 @@
     public void setUp() {
         Log.d(TAG, "setUp() +");
         mContext = InstrumentationRegistry.getContext();
-        mHelper = new TelephonyProvider.DatabaseHelper(mContext);
+        mHelper = new TelephonyProviderTestable().new DatabaseHelper(mContext);
         mInMemoryDbHelper = new InMemoryTelephonyProviderV5DbHelper();
         Log.d(TAG, "setUp() -");
     }
@@ -69,7 +69,7 @@
         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));
+        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
 
         // the upgraded db must have the APN_SET_ID field
         Cursor cursor = db.query("carriers", null, null, null, null, null, null);
@@ -84,7 +84,7 @@
         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));
+        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
 
         // the upgraded db must have the Telephony.Carriers.CARRIER_ID field
         Cursor cursor = db.query("carriers", null, null, null, null, null, null);
@@ -97,7 +97,7 @@
     public void databaseHelperOnUpgrade_hasCountryIsoField() {
         Log.d(TAG, "databaseHelperOnUpgrade_hasCountryIsoField");
         SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
-        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.DatabaseHelper.getVersion(mContext));
+        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
 
         // the upgraded db must have the Telephony.Carriers.CARRIER_ID field
         Cursor cursor = db.query("simInfo", null, null, null, null, null, null);
@@ -110,7 +110,7 @@
     public void databaseHelperOnUpgrade_hasProfileClassField() {
         Log.d(TAG, "databaseHelperOnUpgrade_hasProfileClassField");
         SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
-        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.DatabaseHelper.getVersion(mContext));
+        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
 
         // the upgraded db must have the PROFILE_CLASS field
         Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
@@ -124,7 +124,7 @@
         Log.d(TAG, "databaseHelperOnUpgrade_hasSkip464XlatField");
         // (5 << 16 | 6) is the first upgrade trigger in onUpgrade
         SQLiteDatabase db = mInMemoryDbHelper.getWritableDatabase();
-        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.DatabaseHelper.getVersion(mContext));
+        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
 
         // the upgraded db must have the Telephony.Carriers.CARRIER_ID field
         Cursor cursor = db.query("carriers", null, null, null, null, null, null);
@@ -138,7 +138,7 @@
         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));
+        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
 
         // compare upgraded carriers table to a carriers table created from scratch
         db.execSQL(TelephonyProvider.getStringForCarrierTableCreation("carriers_full"));
@@ -174,7 +174,7 @@
         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));
+        mHelper.onUpgrade(db, (4 << 16), TelephonyProvider.getVersion(mContext));
 
         // the upgraded db must have the SubscriptionManager.SUBSCRIPTION_TYPE field
         Cursor cursor = db.query("siminfo", null, null, null, null, null, null);
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index 47c1dc6..bf85625 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -39,6 +39,7 @@
 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 androidx.test.InstrumentationRegistry;
@@ -93,6 +94,7 @@
     private static final String TEST_MCC = "123";
     private static final String TEST_MNC = "456";
     private static final String TEST_SPN = TelephonyProviderTestable.TEST_SPN;
+    private static final int TEST_CARRIERID = 1;
 
     // Used to test the path for URL_TELEPHONY_USING_SUBID with subid 1
     private static final Uri CONTENT_URI_WITH_SUBID = Uri.parse(
@@ -155,6 +157,7 @@
             doReturn(mIcRecords).when(mUiccController).getIccRecords(anyInt(), anyInt());
             doReturn(TEST_SPN).when(mIcRecords).getServiceProviderName();
             doReturn(TEST_SPN).when(mIcRecords).getServiceProviderNameWithBrandOverride();
+            doReturn(TEST_CARRIERID).when(mTelephonyManager).getSimCarrierId();
 
             // Add authority="telephony" to given telephonyProvider
             ProviderInfo providerInfo = new ProviderInfo();
@@ -183,6 +186,16 @@
         }
 
         @Override
+        public String getSystemServiceName(Class<?> serviceClass) {
+            if (serviceClass.equals(TelephonyManager.class)) {
+              return Context.TELEPHONY_SERVICE;
+            } else {
+                Log.d(TAG, "getSystemServiceName: returning null");
+                return null;
+            }
+        }
+
+        @Override
         public Resources getResources() {
             Log.d(TAG, "getResources: returning null");
             return null;
@@ -1479,15 +1492,15 @@
 
     @Test
     @SmallTest
-    public void testSIMAPNLIST_APNMatchTheMCCMNCAndMVNO() {
-        // Test on getCurrentAPNList() step 1
+    public void testSIMAPNLIST_MatchTheMVNOAPN() {
+        // Test on getSubscriptionMatchingAPNList() step 1
         final String apnName = "apnName";
         final String carrierName = "name";
         final String numeric = TEST_OPERATOR;
         final String mvnoType = "spn";
         final String mvnoData = TEST_SPN;
 
-        // Insert the APN and DB only have the MCC/MNC and MVNO APN
+        // Insert the MVNO APN
         ContentValues contentValues = new ContentValues();
         contentValues.put(Carriers.APN, apnName);
         contentValues.put(Carriers.NAME, carrierName);
@@ -1496,6 +1509,13 @@
         contentValues.put(Carriers.MVNO_MATCH_DATA, mvnoData);
         mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
 
+        // Insert the MNO APN
+        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 =
                 {
@@ -1507,7 +1527,9 @@
         Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
                 testProjection, null, null, null);
 
+        // When the DB has MVNO and MNO APN, the query based on SIM_APN_LIST will return MVNO APN
         cursor.moveToFirst();
+        assertEquals(cursor.getCount(), 1);
         assertEquals(apnName, cursor.getString(0));
         assertEquals(carrierName, cursor.getString(1));
         assertEquals(numeric, cursor.getString(2));
@@ -1516,13 +1538,13 @@
 
     @Test
     @SmallTest
-    public void testSIMAPNLIST_APNMatchTheParentMCCMNC() {
-        // Test on getCurrentAPNList() step 2
+    public void testSIMAPNLIST_MatchTheMNOAPN() {
+        // Test on getSubscriptionMatchingAPNList() step 2
         final String apnName = "apnName";
         final String carrierName = "name";
         final String numeric = TEST_OPERATOR;
 
-        // Insert the APN and DB only have the MNO APN
+        // Insert the MNO APN
         ContentValues contentValues = new ContentValues();
         contentValues.put(Carriers.APN, apnName);
         contentValues.put(Carriers.NAME, carrierName);
@@ -1544,4 +1566,91 @@
         assertEquals(carrierName, cursor.getString(1));
         assertEquals(numeric, cursor.getString(2));
     }
+
+    @Test
+    @SmallTest
+    public void testSIMAPNLIST_MatchTheCarrierIDANDMNOAPN() {
+        // Test on getSubscriptionMatchingAPNList() will return the {MCCMNC}
+        final String apnName = "apnName";
+        final String carrierName = "name";
+        final int carrierId = TEST_CARRIERID;
+
+        // Add the APN that only have carrier id
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(Carriers.APN, apnName);
+        contentValues.put(Carriers.NAME, carrierName);
+        contentValues.put(Carriers.CARRIER_ID, carrierId);
+        mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+        // Add MNO APN that added by user
+        contentValues = new ContentValues();
+        contentValues.put(Carriers.APN, apnName);
+        contentValues.put(Carriers.NAME, carrierName);
+        contentValues.put(Carriers.NUMERIC, TEST_OPERATOR);
+        contentValues.put(Carriers.EDITED_STATUS, Carriers.UNEDITED);
+        mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+        // Query DB
+        final String[] testProjection =
+            {
+                Carriers.APN,
+                Carriers.NAME,
+                Carriers.CARRIER_ID,
+            };
+        Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, testProjection, null, null, null);
+
+        // The query based on SIM_APN_LIST will return MNO APN and the APN that has carrier id
+        assertEquals(cursor.getCount(), 2);
+    }
+
+    @Test
+    @SmallTest
+    public void testSIMAPNLIST_MatchTheCarrierAPNAndMVNOAPN() {
+        final String apnName = "apnName";
+        final String carrierName = "name";
+        final String mvnoType = "spn";
+        final String mvnoData = TEST_SPN;
+        final int carrierId = TEST_CARRIERID;
+
+        // Add the APN that only have carrier id
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(Carriers.APN, apnName);
+        contentValues.put(Carriers.NAME, carrierName);
+        contentValues.put(Carriers.CARRIER_ID, carrierId);
+        mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+        // Add MVNO APN that added by user
+        contentValues = new ContentValues();
+        contentValues.put(Carriers.APN, apnName);
+        contentValues.put(Carriers.NAME, carrierName);
+        contentValues.put(Carriers.NUMERIC, TEST_OPERATOR);
+        contentValues.put(Carriers.MVNO_TYPE, mvnoType);
+        contentValues.put(Carriers.MVNO_MATCH_DATA, mvnoData);
+        mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+        // Add MNO APN that added by user
+        contentValues = new ContentValues();
+        contentValues.put(Carriers.APN, apnName);
+        contentValues.put(Carriers.NAME, carrierName);
+        contentValues.put(Carriers.NUMERIC, TEST_OPERATOR);
+        mContentResolver.insert(Carriers.CONTENT_URI, contentValues);
+
+        // Query DB
+        final String[] testProjection =
+            {
+                Carriers.APN,
+                Carriers.NAME,
+                Carriers.CARRIER_ID,
+                Carriers.MVNO_TYPE,
+            };
+        Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
+            testProjection, null, null, null);
+
+        // The query based on SIM_APN_LIST will return MVNO APN and the APN that has carrier id
+        assertEquals(cursor.getCount(), 2);
+        while(cursor.moveToNext()) {
+            assertTrue(!TextUtils.isEmpty(cursor.getString(2))
+                    || !TextUtils.isEmpty(cursor.getString(3)));
+        }
+    }
 }
