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..0d8db52
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,23 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsTelephonyProviderTestCases"
+    },
+    {
+      "name": "TeleServiceTests",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    },
+    {
+      "name": "TelephonyProviderTests",
+      "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 dbf85ae..f5aeadc 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;
     }
@@ -552,7 +556,7 @@
             selectionArgs = new String[] { refinedAddress };
         } else {
             selection += " OR PHONE_NUMBERS_EQUAL(address, ?, " +
-                        (mUseStrictPhoneNumberComparation ? 1 : 0) + ")";
+                        (mUseStrictPhoneNumberComparation ? "1)" : "0, " + mMinMatch + ")");
             selectionArgs = new String[] { refinedAddress, refinedAddress };
         }
 
@@ -1007,13 +1011,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,
@@ -1028,7 +1033,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();
 
@@ -1040,7 +1045,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 1213c37..24c610e 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"
     };
 
@@ -302,21 +304,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;
     }
@@ -642,7 +662,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..8936930 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;
@@ -147,7 +147,7 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false; // STOPSHIP if true
 
-    private static final int DATABASE_VERSION = 42 << 16;
+    private static final int DATABASE_VERSION = 43 << 16;
     private static final int URL_UNKNOWN = 0;
     private static final int URL_TELEPHONY = 1;
     private static final int URL_CURRENT = 2;
@@ -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
@@ -407,7 +416,8 @@
                 + SubscriptionManager.WHITE_LISTED_APN_DATA + " INTEGER DEFAULT 0,"
                 + SubscriptionManager.GROUP_OWNER + " TEXT,"
                 + SubscriptionManager.DATA_ENABLED_OVERRIDE_RULES + " TEXT,"
-                + SubscriptionManager.IMSI + " TEXT"
+                + SubscriptionManager.IMSI + " TEXT,"
+                + SubscriptionManager.UICC_APPLICATIONS_ENABLED + " INTEGER DEFAULT 1"
                 + ");";
     }
 
@@ -484,7 +494,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 +545,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 +624,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 +782,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.
 
@@ -1367,6 +1388,21 @@
                 }
             }
 
+            if (oldVersion < (43 << 16 | 6)) {
+                try {
+                    // Try to update the siminfo table. It might not be there.
+                    db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+                            + SubscriptionManager.UICC_APPLICATIONS_ENABLED
+                            + " INTEGER DEFAULT 1;");
+                } catch (SQLiteException e) {
+                    if (DBG) {
+                        log("onUpgrade skipping " + SIMINFO_TABLE + " upgrade. " +
+                                "The table will get created in onOpen.");
+                    }
+                }
+                oldVersion = 43 << 16 | 6;
+            }
+
 
             if (DBG) {
                 log("dbh.onUpgrade:- db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
@@ -1878,7 +1914,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 +2147,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 +2189,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 +2573,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 +2593,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 +2639,6 @@
 
     private static void localLog(String logMsg) {
         Log.d(TAG, logMsg);
-        PhoneFactory.localLog(TAG, logMsg);
     }
 
     private synchronized boolean isManagedApnEnforced() {
@@ -2701,29 +2702,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 +2745,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 +2814,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 +2823,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 +2834,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 +3034,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 +3072,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 +3092,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 +3249,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 +3295,7 @@
                     values = new ContentValues();
                 }
 
-                values = DatabaseHelper.setDefaultValue(values);
+                values = setDefaultValue(values);
                 if (!values.containsKey(EDITED_STATUS)) {
                     values.put(EDITED_STATUS, CARRIER_EDITED);
                 }
@@ -3431,7 +3395,7 @@
 
             case URL_SIMINFO: {
                long id = db.insert(SIMINFO_TABLE, null, initialValues);
-               result = ContentUris.withAppendedId(SubscriptionManager.CONTENT_URI, id);
+               result = ContentUris.withAppendedId(Telephony.SimInfo.CONTENT_URI, id);
                break;
             }
         }
@@ -3462,7 +3426,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 +3662,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,
@@ -3805,7 +3769,7 @@
                     // If not set, any change to SIMINFO will notify observers which listens to
                     // specific field of SIMINFO.
                     getContext().getContentResolver().notifyChange(
-                            SubscriptionManager.CONTENT_URI, null,
+                        Telephony.SimInfo.CONTENT_URI, null,
                             ContentResolver.NOTIFY_SYNC_TO_NETWORK
                                     | ContentResolver.NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS,
                             UserHandle.USER_ALL);
@@ -3933,8 +3897,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 +3910,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 +3933,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 +3954,7 @@
         SQLiteDatabase db = getWritableDatabase();
 
         // Delete preferred APN for all subIds
-        deletePreferredApnId();
+        deletePreferredApnId(getContext());
 
         // Delete entries in db
         try {
@@ -4093,4 +4057,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/AndroidTest.xml b/tests/AndroidTest.xml
index 23310f9..bb0261e 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="TelephonyProviderTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.providers.telephony.tests" />
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
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..4b61798 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
+
 import android.Manifest;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -34,11 +35,13 @@
 import android.os.Process;
 import android.provider.Telephony;
 import android.provider.Telephony.Carriers;
+import android.provider.Telephony.SimInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 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 +96,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 +159,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 +188,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;
@@ -336,13 +351,13 @@
                     return cv;
         }).toArray(ContentValues[]::new);
 
-        mContentResolver.bulkInsert(SubscriptionManager.CONTENT_URI, existingSimInfoEntries);
+        mContentResolver.bulkInsert(SimInfo.CONTENT_URI, existingSimInfoEntries);
 
         // Run the upgrade helper on all the sim info entries.
         String[] proj = {SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID,
                 SubscriptionManager.MCC, SubscriptionManager.MNC,
                 SubscriptionManager.MCC_STRING, SubscriptionManager.MNC_STRING};
-        try (Cursor c = mContentResolver.query(SubscriptionManager.CONTENT_URI, proj,
+        try (Cursor c = mContentResolver.query(SimInfo.CONTENT_URI, proj,
                 null, null, null)) {
             while (c.moveToNext()) {
                 TelephonyProvider.fillInMccMncStringAtCursor(mContext,
@@ -351,7 +366,7 @@
         }
 
         // Loop through and make sure that everything got filled in correctly.
-        try (Cursor c = mContentResolver.query(SubscriptionManager.CONTENT_URI, proj,
+        try (Cursor c = mContentResolver.query(SimInfo.CONTENT_URI, proj,
                 null, null, null)) {
             while (c.moveToNext()) {
                 String mcc = c.getString(c.getColumnIndexOrThrow(SubscriptionManager.MCC_STRING));
@@ -554,7 +569,7 @@
         contentValues.put(SubscriptionManager.PROFILE_CLASS, insertProfileClass);
 
         Log.d(TAG, "testSimTable Inserting contentValues: " + contentValues);
-        mContentResolver.insert(SubscriptionManager.CONTENT_URI, contentValues);
+        mContentResolver.insert(SimInfo.CONTENT_URI, contentValues);
 
         // get values in table
         final String[] testProjection =
@@ -568,7 +583,7 @@
         String[] selectionArgs = { insertDisplayName };
         Log.d(TAG,"\ntestSimTable selection: " + selection
                 + "\ntestSimTable selectionArgs: " + selectionArgs.toString());
-        Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI,
+        Cursor cursor = mContentResolver.query(SimInfo.CONTENT_URI,
                 testProjection, selection, selectionArgs, null);
 
         // verify that inserted values match results of query
@@ -589,12 +604,12 @@
         String[] selectionArgsToDelete = { insertDisplayName };
         Log.d(TAG, "testSimTable deleting selection: " + selectionToDelete
                 + "testSimTable selectionArgs: " + selectionArgs);
-        int numRowsDeleted = mContentResolver.delete(SubscriptionManager.CONTENT_URI,
+        int numRowsDeleted = mContentResolver.delete(SimInfo.CONTENT_URI,
                 selectionToDelete, selectionArgsToDelete);
         assertEquals(1, numRowsDeleted);
 
         // verify that deleted values are gone
-        cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI,
+        cursor = mContentResolver.query(SimInfo.CONTENT_URI,
                 testProjection, selection, selectionArgs, null);
         assertEquals(0, cursor.getCount());
     }
@@ -1440,7 +1455,7 @@
         contentValues.put(SubscriptionManager.CARD_ID, insertCardId);
 
         Log.d(TAG, "testSimTable Inserting wfc contentValues: " + contentValues);
-        mContentResolver.insert(SubscriptionManager.CONTENT_URI, contentValues);
+        mContentResolver.insert(SimInfo.CONTENT_URI, contentValues);
         assertEquals(0, notifyWfcCount);
 
         // update wfc_enabled
@@ -1448,14 +1463,14 @@
         values.put(SubscriptionManager.WFC_IMS_ENABLED, true);
         final String selection = SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?";
         final String[] selectionArgs = { "" + insertSubId };
-        mContentResolver.update(SubscriptionManager.CONTENT_URI, values, selection, selectionArgs);
+        mContentResolver.update(SimInfo.CONTENT_URI, values, selection, selectionArgs);
         assertEquals(1, notifyWfcCount);
         assertEquals(0, notifyWfcCountWithTestSubId);
 
         // update other fields
         values = new ContentValues();
         values.put(SubscriptionManager.DISPLAY_NAME, "exampleDisplayNameNew");
-        mContentResolver.update(SubscriptionManager.CONTENT_URI, values, selection, selectionArgs);
+        mContentResolver.update(SimInfo.CONTENT_URI, values, selection, selectionArgs);
         // expect no change on wfc count
         assertEquals(1, notifyWfcCount);
         assertEquals(0, notifyWfcCountWithTestSubId);
@@ -1479,15 +1494,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 +1511,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 +1529,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 +1540,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 +1568,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)));
+        }
+    }
 }
