diff --git a/Android.bp b/Android.bp
index eabd567..c7ecd27 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,9 +1,9 @@
 android_app {
     name: "TelephonyProvider",
     privileged: true,
-    srcs: ["src/**/*.java"],
+    srcs: ["src/**/*.java", "proto/**/*.proto"],
     platform_apis: true,
     certificate: "platform",
     libs: ["telephony-common"],
-    static_libs: ["android-common"],
+    static_libs: ["android-common", "telephonyprovider-protos"],
 }
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4ae9acf..dbd5436 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -120,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/proto/Android.bp b/proto/Android.bp
new file mode 100644
index 0000000..4420263
--- /dev/null
+++ b/proto/Android.bp
@@ -0,0 +1,29 @@
+// 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.
+
+java_library_static {
+    name: "telephonyprovider-protos",
+    proto: {
+        type: "nano",
+        output_params: [
+            "store_unknown_fields=true",
+            "enum_style=java",
+        ],
+    },
+    srcs: ["src/**/*.proto"],
+    sdk_version: "core_platform",
+    jarjar_rules: "jarjar-rules.txt",
+    // Pin java_version until jarjar is certified to support later versions. http://b/72703434
+    java_version: "1.8",
+}
diff --git a/proto/jarjar-rules.txt b/proto/jarjar-rules.txt
new file mode 100644
index 0000000..e6275e9
--- /dev/null
+++ b/proto/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.nano.** com.android.providers.telephony.protobuf.nano.@1
diff --git a/proto/src/carrierId.proto b/proto/src/carrierId.proto
new file mode 100644
index 0000000..0ba48c1
--- /dev/null
+++ b/proto/src/carrierId.proto
@@ -0,0 +1,91 @@
+//
+// 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.
+//
+
+syntax = "proto2";
+
+package carrierIdentification;
+
+option java_package = "com.android.providers.telephony";
+option java_outer_classname = "CarrierIdProto";
+
+// A complete list of carriers
+message CarrierList {
+  // A collection of carriers. one entry for one carrier.
+  repeated CarrierId carrier_id = 1;
+  // Version number of current carrier list
+  optional int32 version = 2;
+};
+
+// CarrierId is the unique representation of a carrier in CID table.
+message CarrierId {
+  // [Optional] A unique canonical number designated to a carrier.
+  optional int32 canonical_id = 1;
+
+  // [Optional] A user-friendly carrier name (not localized).
+  optional string carrier_name = 2;
+
+  // [Optional] Carrier attributes to match a carrier. At least one value is required.
+  repeated CarrierAttribute carrier_attribute = 3;
+
+  // [Optional] A unique canonical number to represent its parent carrier. The parent-child
+  // relationship can be used to differentiate a single carrier by different networks,
+  // by prepaid v.s. postpaid  or even by 4G v.s. 3G plan.
+  optional int32 parent_canonical_id = 4;
+};
+
+// Attributes used to match a carrier.
+// For each field within this message:
+//   - if not set, the attribute is ignored;
+//   - if set, the device must have one of the specified values to match.
+// Match is based on AND between any field that is set and OR for values within a repeated field.
+message CarrierAttribute {
+  // [Optional] The MCC and MNC that map to this carrier. At least one value is required.
+  repeated string mccmnc_tuple = 1;
+
+  // [Optional] Prefix of IMSI (International Mobile Subscriber Identity) in
+  // decimal format. Some digits can be replaced with "x" symbols matching any digit.
+  // Sample values: 20404794, 21670xx2xxx.
+  repeated string imsi_prefix_xpattern = 2;
+
+  // [Optional] The Service Provider Name. Read from subscription EF_SPN.
+  // Sample values: C Spire, LeclercMobile
+  repeated string spn = 3;
+
+  // [Optional] PLMN network name. Read from subscription EF_PNN.
+  // Sample values:
+  repeated string plmn = 4;
+
+  // [Optional] Group Identifier Level1 for a GSM phone. Read from subscription EF_GID1.
+  // Sample values: 6D, BAE0000000000000
+  repeated string gid1 = 5;
+
+  // [Optional] Group Identifier Level2 for a GSM phone. Read from subscription EF_GID2.
+  // Sample values: 6D, BAE0000000000000
+  repeated string gid2 = 6;
+
+  // [Optional] The Access Point Name, corresponding to "apn" field returned by
+  // "content://telephony/carriers/preferapn" on device.
+  // Sample values: fast.t-mobile.com, internet
+  repeated string preferred_apn = 7;
+
+  // [Optional] Prefix of Integrated Circuit Card Identifier. Read from subscription EF_ICCID.
+  // Sample values: 894430, 894410
+  repeated string iccid_prefix = 8;
+
+  // [Optional] Carrier Privilege Access Rule in hex string.
+  // Sample values: 61ed377e85d386a8dfee6b864bd85b0bfaa5af88
+  repeated string privilege_access_rule = 9;
+};
diff --git a/src/com/android/providers/telephony/CarrierIdProvider.java b/src/com/android/providers/telephony/CarrierIdProvider.java
index 44f053d..97037b8 100644
--- a/src/com/android/providers/telephony/CarrierIdProvider.java
+++ b/src/com/android/providers/telephony/CarrierIdProvider.java
@@ -41,7 +41,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.nano.CarrierIdProto;
+import com.android.providers.telephony.nano.CarrierIdProto;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
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 4add85d..d5aa308 100644
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
@@ -50,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;
 
@@ -295,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) {
@@ -546,19 +540,11 @@
                 intent.putExtra(Intents.EXTRA_IS_INITIAL_CREATE, true);
             }
 
-            mContext.sendBroadcast(intent, android.Manifest.permission.READ_SMS);
+            mContext.sendBroadcast(intent);
         }
         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);
@@ -567,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() {
@@ -1666,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.");
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/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 8e77e18..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;
@@ -113,13 +114,12 @@
 
 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;
@@ -416,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"
                 + ");";
     }
 
@@ -1387,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);
@@ -2557,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)) {
@@ -2629,7 +2639,6 @@
 
     private static void localLog(String logMsg) {
         Log.d(TAG, logMsg);
-        PhoneFactory.localLog(TAG, logMsg);
     }
 
     private synchronized boolean isManagedApnEnforced() {
@@ -2805,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();
@@ -2827,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);
             }
@@ -3026,33 +3035,34 @@
     }
 
     /**
-     * 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) {
@@ -3062,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);
@@ -3080,7 +3092,7 @@
         //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)));
             }
 
@@ -3088,25 +3100,60 @@
                     ApnSettingUtils.mvnoMatches(iccRecords,
                             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);
         }
     }
 
@@ -3348,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;
             }
         }
@@ -3722,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);
@@ -3850,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;
@@ -3886,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(
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/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)));
+        }
+    }
 }
