[automerger skipped] Update carrier list on RVC branch am: 6c4b21fcb8 -s ours am: feeadcfdd3 -s ours

am skip reason: Change-Id I76b7cd622aaeb8976dd673d57f998353064788d8 with SHA-1 dffec13df4 is in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/providers/TelephonyProvider/+/11439599

Change-Id: Ie720a1fc39fcd66cc3a0dc11d2bf811ccc262dee
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/assets/README b/assets/README
index ad6a29c..43b0965 100644
--- a/assets/README
+++ b/assets/README
@@ -10,3 +10,50 @@
 DO NOT MANUALLY EDIT THIS FILE
 
 This file defines carrier id and should be single versioned.
+
+===== How to test carrier id locally =====
+
+If you want to make change locally during testing, currently there are two ways:
+
+1. Modify carrierIdentification.db database by SQL command
+
+For example (Insert MCCMNC '12345' and gid1 'test' to carrier id 20000):
+```
+$ adb shell
+device:/ $ su
+device:/ # DB='/data/user_de/0/com.android.providers.telephony/databases/carrierIdentification.db'
+device:/ # sqlite3 $DB "INSERT INTO carrier_id(mccmnc, gid1, carrier_id, carrier_name) VALUES (12345, 'test', 20000, 'test_carrier')"
+device:/ # reboot
+```
+
+2. Override carrier_list.pb
+
+- Modify carrier_list.textpb directly (Note: You should also bump the version
+  number to let TelephonyProvider reload the carrier_list.pb)
+- Generate class file by using the carrier id proto(TelephonyProvider/proto/src/carrierId.proto)
+  (See https://developers.google.com/protocol-buffers/docs/overview#generating)
+- Create a converter by using TextFormat tool to convert textpb to pb
+  (Text Format: https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/TextFormat)
+- Rename file to carrier_list_test.pb and push the output file to
+    /data/user_de/0/com.android.providers.telephony/files/carrier_list_test.pb
+- Reboot the device
+
+Converter example:
+```
+#!/usr/bin/env python3
+from google.protobuf import text_format
+
+# Generated by: protoc -I=./ --python_out=./ ./carrierId.proto
+from carrierId_pb2 import CarrierList
+
+def main():
+  with open("carrier_list.textpb", "r") as rd:
+    carrierList = CarrierList()
+    text_format.Merge(rd.read(), carrierList)
+
+    with open("carrier_list.pb", "wb") as wf:
+      wf.write(carrierList.SerializeToString())
+
+if __name__ == '__main__':
+  main()
+```
diff --git a/assets/latest_carrier_id/carrier_list.pb b/assets/latest_carrier_id/carrier_list.pb
index 44a7056..486f1ae 100644
--- a/assets/latest_carrier_id/carrier_list.pb
+++ b/assets/latest_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/latest_carrier_id/carrier_list.textpb b/assets/latest_carrier_id/carrier_list.textpb
index a5d8050..60064d6 100644
--- a/assets/latest_carrier_id/carrier_list.textpb
+++ b/assets/latest_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk28_carrier_id/carrier_list.pb b/assets/sdk28_carrier_id/carrier_list.pb
index 700eb89..b672006 100644
--- a/assets/sdk28_carrier_id/carrier_list.pb
+++ b/assets/sdk28_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk28_carrier_id/carrier_list.textpb b/assets/sdk28_carrier_id/carrier_list.textpb
index 619d989..131b414 100644
--- a/assets/sdk28_carrier_id/carrier_list.textpb
+++ b/assets/sdk28_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk29_carrier_id/carrier_list.pb b/assets/sdk29_carrier_id/carrier_list.pb
index 3519d2c..be41a43 100644
--- a/assets/sdk29_carrier_id/carrier_list.pb
+++ b/assets/sdk29_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk29_carrier_id/carrier_list.textpb b/assets/sdk29_carrier_id/carrier_list.textpb
index b1c6825..b21d6ec 100644
--- a/assets/sdk29_carrier_id/carrier_list.textpb
+++ b/assets/sdk29_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/assets/sdk30_carrier_id/carrier_list.pb b/assets/sdk30_carrier_id/carrier_list.pb
new file mode 100644
index 0000000..2554f6f
--- /dev/null
+++ b/assets/sdk30_carrier_id/carrier_list.pb
Binary files differ
diff --git a/assets/sdk30_carrier_id/carrier_list.textpb b/assets/sdk30_carrier_id/carrier_list.textpb
new file mode 100644
index 0000000..c76b4fe
--- /dev/null
+++ b/assets/sdk30_carrier_id/carrier_list.textpb
Binary files differ
diff --git a/src/com/android/providers/telephony/CarrierIdProvider.java b/src/com/android/providers/telephony/CarrierIdProvider.java
index a3c299f..3e751aa 100644
--- a/src/com/android/providers/telephony/CarrierIdProvider.java
+++ b/src/com/android/providers/telephony/CarrierIdProvider.java
@@ -83,6 +83,9 @@
     private static final int VERSION_BITMASK = 0x00FFFFFF;
     private static final String OTA_UPDATED_PB_PATH = "misc/carrierid/" + ASSETS_PB_FILE;
     private static final String PREF_FILE = CarrierIdProvider.class.getSimpleName();
+    // For testing purposes only.
+    private static final String OVERRIDE_PB_PATH =
+            "/data/user_de/0/com.android.providers.telephony/files/carrier_list_test.pb";
 
     private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 
@@ -527,9 +530,14 @@
         CarrierIdProto.CarrierList assets = null;
         CarrierIdProto.CarrierList ota = null;
         InputStream is = null;
+        File testFile = new File(OVERRIDE_PB_PATH);
 
         try {
-            is = getContext().getAssets().open(ASSETS_PB_FILE);
+            if (Build.IS_DEBUGGABLE && testFile.exists()) {
+                is = new FileInputStream(testFile);
+            } else {
+                is = getContext().getAssets().open(ASSETS_PB_FILE);
+            }
             assets = CarrierIdProto.CarrierList.parseFrom(readInputStreamToByteArray(is));
         } catch (IOException ex) {
             Log.e(TAG, "read carrier list from assets pb failure: " + ex);
diff --git a/src/com/android/providers/telephony/SmsProvider.java b/src/com/android/providers/telephony/SmsProvider.java
index 81f732b..d378c64 100644
--- a/src/com/android/providers/telephony/SmsProvider.java
+++ b/src/com/android/providers/telephony/SmsProvider.java
@@ -84,7 +84,7 @@
         "body",                         // getDisplayMessageBody
         "date",                         // getTimestampMillis
         "status",                       // getStatusOnIcc
-        "index_on_icc",                 // getIndexOnIcc
+        "index_on_icc",                 // getIndexOnIcc (1-based index)
         "is_status_report",             // isStatusReportMessage
         "transport_type",               // Always "sms".
         "type",                         // depend on getStatusOnIcc
@@ -353,20 +353,42 @@
                 type = Sms.MESSAGE_TYPE_OUTBOX;
                 break;
         }
+
+        String address = (type == Sms.MESSAGE_TYPE_INBOX)
+                ? message.getDisplayOriginatingAddress()
+                : message.getRecipientAddress();
+
+        int index = message.getIndexOnIcc();
+        if (address == null) {
+            // The status byte of an EF_SMS record may not be correct. try to read other address
+            // type again.
+            Log.e(TAG, "convertIccToSms: EF_SMS(" + index + ")=> address=null, type=" + type
+                    + ", status=" + statusOnIcc + "(may not be correct). fallback to other type.");
+            address = (type == Sms.MESSAGE_TYPE_INBOX)
+                    ? message.getRecipientAddress()
+                    : message.getDisplayOriginatingAddress();
+
+            if (address != null) {
+                // Rely on actual PDU(address) to set type again.
+                type = (type == Sms.MESSAGE_TYPE_INBOX)
+                        ? Sms.MESSAGE_TYPE_SENT
+                        : Sms.MESSAGE_TYPE_INBOX;
+                Log.d(TAG, "convertIccToSms: new type=" + type + ", address=xxxxxx");
+            } else {
+                Log.e(TAG, "convertIccToSms: no change");
+            }
+        }
+
         // N.B.: These calls must appear in the same order as the
         // columns appear in ICC_COLUMNS.
         Object[] row = new Object[13];
         row[0] = message.getServiceCenterAddress();
-        row[1] =
-                (type == Sms.MESSAGE_TYPE_INBOX)
-                        ? message.getDisplayOriginatingAddress()
-                        : message.getRecipientAddress();
-
+        row[1] = address;
         row[2] = String.valueOf(message.getMessageClass());
         row[3] = message.getDisplayMessageBody();
         row[4] = message.getTimestampMillis();
         row[5] = statusOnIcc;
-        row[6] = message.getIndexOnIcc();
+        row[6] = index;
         row[7] = message.isStatusReportMessage();
         row[8] = "sms";
         row[9] = type;
@@ -380,7 +402,7 @@
      * Gets single message from the ICC for a subscription ID.
      *
      * @param subId the subscription ID.
-     * @param messageIndex the message index of the messaage in the ICC.
+     * @param messageIndex the message index of the messaage in the ICC (1-based index).
      * @return a cursor containing just one message from the ICC for the subscription ID.
      */
     private Cursor getSingleMessageFromIcc(int subId, int messageIndex) {
@@ -393,19 +415,24 @@
         // Use phone app permissions to avoid UID mismatch in AppOpsManager.noteOp() call.
         long token = Binder.clearCallingIdentity();
         try {
+            // getMessagesFromIcc() returns a zero-based list of valid messages in the ICC.
             messages = smsManager.getMessagesFromIcc();
         } finally {
             Binder.restoreCallingIdentity(token);
         }
 
-        final SmsMessage message = messages.get(messageIndex);
-        if (message == null) {
-            throw new IllegalArgumentException(
-                    "No message in index " + messageIndex + " for subId " + subId);
+        final int count = messages.size();
+        for (int i = 0; i < count; i++) {
+            SmsMessage message = messages.get(i);
+            if (message != null && message.getIndexOnIcc() == messageIndex) {
+                MatrixCursor cursor = new MatrixCursor(ICC_COLUMNS, 1);
+                cursor.addRow(convertIccToSms(message, 0));
+                return cursor;
+            }
         }
-        MatrixCursor cursor = new MatrixCursor(ICC_COLUMNS, 1);
-        cursor.addRow(convertIccToSms(message, 0));
-        return cursor;
+
+        throw new IllegalArgumentException(
+                "No message in index " + messageIndex + " for subId " + subId);
     }
 
     /**
@@ -424,6 +451,7 @@
         // Use phone app permissions to avoid UID mismatch in AppOpsManager.noteOp() call
         long token = Binder.clearCallingIdentity();
         try {
+            // getMessagesFromIcc() returns a zero-based list of valid messages in the ICC.
             messages = smsManager.getMessagesFromIcc();
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -882,31 +910,62 @@
                 count = db.delete("sr_pending", where, whereArgs);
                 break;
 
+            case SMS_ALL_ICC:
+            case SMS_ALL_ICC_SUBID:
+                {
+                    int subId;
+                    int deletedCnt;
+                    if (match == SMS_ALL_ICC) {
+                        subId = SmsManager.getDefaultSmsSubscriptionId();
+                    } else {
+                        try {
+                            subId = Integer.parseInt(url.getPathSegments().get(1));
+                        } catch (NumberFormatException e) {
+                            throw new IllegalArgumentException("Wrong path segements, uri= " + url);
+                        }
+                    }
+                    deletedCnt = deleteAllMessagesFromIcc(subId);
+                    // Notify changes even failure case since there might be some changes should be
+                    // known.
+                    getContext()
+                            .getContentResolver()
+                            .notifyChange(
+                                    match == SMS_ALL_ICC ? ICC_URI : ICC_SUBID_URI,
+                                    null,
+                                    true,
+                                    UserHandle.USER_ALL);
+                    return deletedCnt;
+                }
+
             case SMS_ICC:
             case SMS_ICC_SUBID:
-                int subId;
-                int messageIndex;
-                boolean success;
-                try {
-                    if (match == SMS_ICC) {
-                        subId = SmsManager.getDefaultSmsSubscriptionId();
-                        messageIndex = Integer.parseInt(url.getPathSegments().get(1));
-                    } else {
-                        subId = Integer.parseInt(url.getPathSegments().get(1));
-                        messageIndex = Integer.parseInt(url.getPathSegments().get(2));
+                {
+                    int subId;
+                    int messageIndex;
+                    boolean success;
+                    try {
+                        if (match == SMS_ICC) {
+                            subId = SmsManager.getDefaultSmsSubscriptionId();
+                            messageIndex = Integer.parseInt(url.getPathSegments().get(1));
+                        } else {
+                            subId = Integer.parseInt(url.getPathSegments().get(1));
+                            messageIndex = Integer.parseInt(url.getPathSegments().get(2));
+                        }
+                    } catch (NumberFormatException e) {
+                        throw new IllegalArgumentException("Wrong path segements, uri= " + url);
                     }
-                } catch (NumberFormatException e) {
-                    throw new IllegalArgumentException("Wrong path segements, uri= " + url);
+                    success = deleteMessageFromIcc(subId, messageIndex);
+                    // Notify changes even failure case since there might be some changes should be
+                    // known.
+                    getContext()
+                            .getContentResolver()
+                            .notifyChange(
+                                    match == SMS_ICC ? ICC_URI : ICC_SUBID_URI,
+                                    null,
+                                    true,
+                                    UserHandle.USER_ALL);
+                    return success ? 1 : 0; // return deleted count
                 }
-                success = deleteMessageFromIcc(subId, messageIndex);
-                // Notify changes even failure case since there might be some changes should be
-                // known.
-                getContext().getContentResolver().notifyChange(
-                        match == SMS_ICC ? ICC_URI : ICC_SUBID_URI,
-                        null,
-                        true,
-                        UserHandle.USER_ALL);
-                return success ? 1 : 0; // return deleted count
 
             default:
                 throw new IllegalArgumentException("Unknown URL");
@@ -922,7 +981,7 @@
      * Deletes the message at index from the ICC for a subscription ID.
      *
      * @param subId the subscription ID.
-     * @param messageIndex the message index of the message in the ICC.
+     * @param messageIndex the message index of the message in the ICC (1-based index).
      * @return true for succeess. Otherwise false.
      */
     private boolean deleteMessageFromIcc(int subId, int messageIndex) {
@@ -940,6 +999,38 @@
         }
     }
 
+    /**
+     * Deletes all the messages from the ICC for a subscription ID.
+     *
+     * @param subId the subscription ID.
+     * @return return deleted messaegs count.
+     */
+    private int deleteAllMessagesFromIcc(int subId) {
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID " + subId);
+        }
+        SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
+
+        // Use phone app permissions to avoid UID mismatch in AppOpsManager.noteOp() call.
+        long token = Binder.clearCallingIdentity();
+        try {
+            int deletedCnt = 0;
+            int maxIndex = smsManager.getSmsCapacityOnIcc();
+            // messageIndex is 1-based index of the message in the ICC.
+            for (int messageIndex = 1; messageIndex <= maxIndex; messageIndex++) {
+                if (smsManager.deleteMessageFromIcc(messageIndex)) {
+                    deletedCnt++;
+                } else {
+                    Log.e(TAG, "Fail to delete SMS at index " + messageIndex
+                            + " for subId " + subId);
+                }
+            }
+            return deletedCnt;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     @Override
     public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
         final int callerUid = Binder.getCallingUid();
diff --git a/src/com/android/providers/telephony/TelephonyBackupAgent.java b/src/com/android/providers/telephony/TelephonyBackupAgent.java
index 5c764c8..320fb69 100644
--- a/src/com/android/providers/telephony/TelephonyBackupAgent.java
+++ b/src/com/android/providers/telephony/TelephonyBackupAgent.java
@@ -631,12 +631,16 @@
         ContentValues[] values = new ContentValues[bulkInsertSize];
         while (jsonReader.hasNext()) {
             ContentValues cv = readSmsValuesFromReader(jsonReader);
-            if (doesSmsExist(cv)) {
-                continue;
-            }
-            values[(msgCount++) % bulkInsertSize] = cv;
-            if (msgCount % bulkInsertSize == 0) {
-                mContentResolver.bulkInsert(Telephony.Sms.CONTENT_URI, values);
+            try {
+                if (mSmsProviderQuery.doesSmsExist(cv)) {
+                    continue;
+                }
+                values[(msgCount++) % bulkInsertSize] = cv;
+                if (msgCount % bulkInsertSize == 0) {
+                    mContentResolver.bulkInsert(Telephony.Sms.CONTENT_URI, values);
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "putSmsMessagesToProvider", e);
             }
         }
         if (msgCount % bulkInsertSize > 0) {
@@ -655,16 +659,20 @@
             if (DEBUG) {
                 Log.d(TAG, "putMmsMessagesToProvider " + mms);
             }
-            if (doesMmsExist(mms)) {
-                if (DEBUG) {
-                    Log.e(TAG, String.format("Mms: %s already exists", mms.toString()));
-                } else {
-                    Log.w(TAG, "Mms: Found duplicate MMS");
+            try {
+                if (doesMmsExist(mms)) {
+                    if (DEBUG) {
+                        Log.e(TAG, String.format("Mms: %s already exists", mms.toString()));
+                    } else {
+                        Log.w(TAG, "Mms: Found duplicate MMS");
+                    }
+                    continue;
                 }
-                continue;
+                total++;
+                addMmsMessage(mms);
+            } catch (Exception e) {
+                Log.e(TAG, "putMmsMessagesToProvider", e);
             }
-            total++;
-            addMmsMessage(mms);
         }
         Log.d(TAG, "putMmsMessagesToProvider handled " + total + " new messages.");
     }
@@ -673,15 +681,30 @@
     static final String[] PROJECTION_ID = {BaseColumns._ID};
     private static final int ID_IDX = 0;
 
-    private boolean doesSmsExist(ContentValues smsValues) {
-        final String where = String.format(Locale.US, "%s = %d and %s = %s",
-                Telephony.Sms.DATE, smsValues.getAsLong(Telephony.Sms.DATE),
-                Telephony.Sms.BODY,
-                DatabaseUtils.sqlEscapeString(smsValues.getAsString(Telephony.Sms.BODY)));
-        try (Cursor cursor = mContentResolver.query(Telephony.Sms.CONTENT_URI, PROJECTION_ID, where,
-                null, null)) {
-            return cursor != null && cursor.getCount() > 0;
+    /**
+     * Interface to allow mocking method for testing.
+     */
+    public interface SmsProviderQuery {
+        boolean doesSmsExist(ContentValues smsValues);
+    }
+
+    private SmsProviderQuery mSmsProviderQuery = new SmsProviderQuery() {
+        @Override
+        public boolean doesSmsExist(ContentValues smsValues) {
+            final String where = String.format(Locale.US, "%s = %d and %s = %s",
+                    Telephony.Sms.DATE, smsValues.getAsLong(Telephony.Sms.DATE),
+                    Telephony.Sms.BODY,
+                    DatabaseUtils.sqlEscapeString(smsValues.getAsString(Telephony.Sms.BODY)));
+            try (Cursor cursor = mContentResolver.query(Telephony.Sms.CONTENT_URI, PROJECTION_ID,
+                    where, null, null)) {
+                return cursor != null && cursor.getCount() > 0;
+            }
         }
+    };
+
+    @VisibleForTesting
+    public void setSmsProviderQuery(SmsProviderQuery smsProviderQuery) {
+        mSmsProviderQuery = smsProviderQuery;
     }
 
     private boolean doesMmsExist(Mms mms) {
@@ -1147,9 +1170,9 @@
         if (DEBUG) {
             Log.d(TAG, "Add mms:\n" + mms);
         }
-        final long dummyId = System.currentTimeMillis(); // Dummy ID of the msg.
+        final long placeholderId = System.currentTimeMillis(); // Placeholder ID of the msg.
         final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
-                .appendPath(String.valueOf(dummyId)).appendPath("part").build();
+                .appendPath(String.valueOf(placeholderId)).appendPath("part").build();
 
         final String srcName = String.format(Locale.US, "text.%06d.txt", 0);
         { // Insert SMIL part.
@@ -1157,7 +1180,7 @@
             final String smil = TextUtils.isEmpty(mms.smil) ?
                     String.format(sSmilTextOnly, smilBody) : mms.smil;
             final ContentValues values = new ContentValues(7);
-            values.put(Telephony.Mms.Part.MSG_ID, dummyId);
+            values.put(Telephony.Mms.Part.MSG_ID, placeholderId);
             values.put(Telephony.Mms.Part.SEQ, -1);
             values.put(Telephony.Mms.Part.CONTENT_TYPE, ContentType.APP_SMIL);
             values.put(Telephony.Mms.Part.NAME, "smil.xml");
@@ -1172,7 +1195,7 @@
 
         { // Insert body part.
             final ContentValues values = new ContentValues(8);
-            values.put(Telephony.Mms.Part.MSG_ID, dummyId);
+            values.put(Telephony.Mms.Part.MSG_ID, placeholderId);
             values.put(Telephony.Mms.Part.SEQ, 0);
             values.put(Telephony.Mms.Part.CONTENT_TYPE, ContentType.TEXT_PLAIN);
             values.put(Telephony.Mms.Part.NAME, srcName);
@@ -1194,7 +1217,7 @@
             // Insert the attachment parts.
             for (ContentValues mmsAttachment : mms.attachments) {
                 final ContentValues values = new ContentValues(6);
-                values.put(Telephony.Mms.Part.MSG_ID, dummyId);
+                values.put(Telephony.Mms.Part.MSG_ID, placeholderId);
                 values.put(Telephony.Mms.Part.SEQ, 0);
                 values.put(Telephony.Mms.Part.CONTENT_TYPE,
                         mmsAttachment.getAsString(MMS_MIME_TYPE));
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 4966e5a..499a18e 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -169,6 +169,9 @@
     private static final int URL_FILTERED = 18;
     private static final int URL_FILTERED_ID = 19;
     private static final int URL_ENFORCE_MANAGED = 20;
+    // URL_PREFERAPNSET and URL_PREFERAPNSET_USING_SUBID return all APNs for the current
+    // carrier which have an apn_set_id equal to the preferred APN
+    // (if no preferred APN, or preferred APN has no set id, the query will return null)
     private static final int URL_PREFERAPNSET = 21;
     private static final int URL_PREFERAPNSET_USING_SUBID = 22;
     private static final int URL_SIM_APN_LIST = 23;
@@ -771,7 +774,7 @@
                 confparser.setInput(confreader);
                 XmlUtils.beginDocument(confparser, "apns");
 
-                // Sanity check. Force internal version and confidential versions to agree
+                // Correctness check. Force internal version and confidential versions to agree
                 int confversion = Integer.parseInt(confparser.getAttributeValue(null, "version"));
                 if (publicversion != confversion) {
                     log("initDatabase: throwing exception due to version mismatch");
@@ -2010,7 +2013,7 @@
             int columnIndex = c.getColumnIndex(key);
             if (columnIndex != -1) {
                 String fromCursor = c.getString(columnIndex);
-                if (!TextUtils.isEmpty(fromCursor)) {
+                if (fromCursor != null) {
                     cv.put(key, fromCursor);
                 }
             }
@@ -2927,6 +2930,7 @@
         checkPermissionCompat(match, projectionIn);
         switch (match) {
             case URL_TELEPHONY_USING_SUBID: {
+                // The behaves exactly same as URL_SIM_APN_LIST_ID.
                 subIdString = url.getLastPathSegment();
                 try {
                     subId = Integer.parseInt(subIdString);
@@ -2935,13 +2939,13 @@
                     return null;
                 }
                 if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
-                TelephonyManager telephonyManager = getContext()
-                    .getSystemService(TelephonyManager.class).createForSubscriptionId(subId);
-                constraints.add(NUMERIC + " = '" + telephonyManager.getSimOperator() + "'");
+                qb.appendWhereStandalone(IS_NOT_OWNED_BY_DPC);
+                return getSubscriptionMatchingAPNList(qb, projectionIn, selection, selectionArgs,
+                        sort, subId);
+
                 // TODO b/74213956 turn this back on once insertion includes correct sub id
                 // constraints.add(SUBSCRIPTION_ID + "=" + subIdString);
             }
-            // intentional fall through from above case
             case URL_TELEPHONY: {
                 constraints.add(IS_NOT_OWNED_BY_DPC);
                 break;
@@ -3009,10 +3013,13 @@
             // intentional fall through from above case
             case URL_PREFERAPNSET: {
                 final int set = getPreferredApnSetId(subId);
-                if (set != NO_APN_SET_ID) {
-                    constraints.add(APN_SET_ID + "=" + set);
+                if (set == NO_APN_SET_ID) {
+                    return null;
                 }
-                break;
+                constraints.add(APN_SET_ID + "=" + set);
+                qb.appendWhere(TextUtils.join(" AND ", constraints));
+                return getSubscriptionMatchingAPNList(qb, projectionIn, selection, selectionArgs,
+                        sort, subId);
             }
 
             case URL_DPC: {
@@ -3147,7 +3154,14 @@
     private Cursor getSubscriptionMatchingAPNList(SQLiteQueryBuilder qb, String[] projectionIn,
             String selection, String[] selectionArgs, String sort, int subId) {
         Cursor ret;
-        final TelephonyManager tm = ((TelephonyManager) getContext()
+        Context context = getContext();
+        SubscriptionManager subscriptionManager = (SubscriptionManager) context
+                .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        if (!subscriptionManager.isActiveSubscriptionId(subId)) {
+            return null;
+        }
+
+        final TelephonyManager tm = ((TelephonyManager) context
                 .getSystemService(Context.TELEPHONY_SERVICE))
                 .createForSubscriptionId(subId);
         SQLiteDatabase db = getReadableDatabase();
@@ -3190,10 +3204,19 @@
                 data.add(ret.getString(ret.getColumnIndex(column)));
             }
 
+            boolean isCurrentSimOperator;
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                isCurrentSimOperator = tm.matchesCurrentSimOperator(
+                        ret.getString(numericIndex),
+                        getMvnoTypeIntFromString(ret.getString(mvnoIndex)),
+                        ret.getString(mvnoDataIndex));
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+
             boolean isMVNOAPN = !TextUtils.isEmpty(ret.getString(numericIndex))
-                    && tm.matchesCurrentSimOperator(ret.getString(numericIndex),
-                            getMvnoTypeIntFromString(ret.getString(mvnoIndex)),
-                            ret.getString(mvnoDataIndex));
+                    && isCurrentSimOperator;
             boolean isMNOAPN = !TextUtils.isEmpty(ret.getString(numericIndex))
                     && ret.getString(numericIndex).equals(mccmnc)
                     && TextUtils.isEmpty(ret.getString(mvnoIndex));
diff --git a/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java b/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
index ee0e016..921b59c 100644
--- a/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
+++ b/tests/src/com/android/providers/telephony/CarrierIdProviderTest.java
@@ -58,18 +58,18 @@
 
     private static final String TAG = CarrierIdProviderTest.class.getSimpleName();
 
-    private static final String dummy_mccmnc = "MCCMNC_DUMMY";
-    private static final String dummy_gid1 = "GID1_DUMMY";
-    private static final String dummy_gid2 = "GID2_DUMMY";
-    private static final String dummy_plmn = "PLMN_DUMMY";
-    private static final String dummy_imsi_prefix = "IMSI_PREFIX_DUMMY";
-    private static final String dummy_spn = "SPN_DUMMY";
-    private static final String dummy_apn = "APN_DUMMY";
-    private static final String dummy_iccid_prefix = "ICCID_PREFIX_DUMMY";
-    private static final String dummy_name = "NAME_DUMMY";
-    private static final String dummy_access_rule =
+    private static final String test_mccmnc = "MCCMNC_TEST";
+    private static final String test_gid1 = "GID1_TEST";
+    private static final String test_gid2 = "GID2_TEST";
+    private static final String test_plmn = "PLMN_TEST";
+    private static final String test_imsi_prefix = "IMSI_PREFIX_TEST";
+    private static final String test_spn = "SPN_TEST";
+    private static final String test_apn = "APN_TEST";
+    private static final String test_iccid_prefix = "ICCID_PREFIX_TEST";
+    private static final String test_name = "NAME_TEST";
+    private static final String test_access_rule =
             "B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51465350";
-    private static final int dummy_cid = 0;
+    private static final int test_cid = 0;
 
     private MockContextWithProvider mContext;
     private MockContentResolver mContentResolver;
@@ -204,7 +204,7 @@
         try {
             //insert a row with null mnccmnc to break not null constraint
             ContentValues contentValues = new ContentValues();
-            contentValues.put(CarrierId.All.GID1, dummy_gid1);
+            contentValues.put(CarrierId.All.GID1, test_gid1);
             mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
             Assert.fail("should throw an exception for null mccmnc");
         } catch (SQLException e) {
@@ -227,7 +227,7 @@
         int numRowsDeleted = -1;
         try {
             String whereClause = CarrierId.All.MCCMNC + "=?";
-            String[] whereArgs = new String[] { dummy_mccmnc };
+            String[] whereArgs = new String[] { test_mccmnc };
             numRowsDeleted = mContentResolver.delete(CarrierId.All.CONTENT_URI,
                     whereClause, whereArgs);
         } catch (Exception e) {
@@ -254,7 +254,7 @@
         try {
             contentValues.put(CarrierId.CARRIER_ID, 1);
             mContentResolver.update(CarrierId.All.CONTENT_URI, contentValues,
-                    CarrierId.All.MCCMNC + "=?", new String[] { dummy_mccmnc });
+                    CarrierId.All.MCCMNC + "=?", new String[] { test_mccmnc });
         } catch (Exception e) {
             Log.d(TAG, "Error updating values:" + e);
         }
@@ -262,7 +262,7 @@
         try {
             Cursor findEntry = mContentResolver.query(CarrierId.All.CONTENT_URI,
                     new String[] { CarrierId.CARRIER_ID},
-                    CarrierId.All.MCCMNC + "=?", new String[] { dummy_mccmnc },
+                    CarrierId.All.MCCMNC + "=?", new String[] { test_mccmnc },
                     null);
             findEntry.moveToFirst();
             cid = findEntry.getInt(0);
@@ -282,7 +282,7 @@
             mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
             // insert its MNO
             contentValues = new ContentValues();
-            contentValues.put(CarrierId.All.MCCMNC, dummy_mccmnc);
+            contentValues.put(CarrierId.All.MCCMNC, test_mccmnc);
             contentValues.put(CarrierId.CARRIER_ID, 1);
             mContentResolver.insert(CarrierId.All.CONTENT_URI, contentValues);
         } catch (Exception e) {
@@ -293,7 +293,7 @@
         String[] columns = {CarrierId.CARRIER_ID, CarrierId.All.ICCID_PREFIX};
         try {
             findEntry = mContentResolver.query(CarrierId.All.CONTENT_URI, columns,
-                    CarrierId.All.MCCMNC + "=?", new String[] { dummy_mccmnc },
+                    CarrierId.All.MCCMNC + "=?", new String[] { test_mccmnc },
                     null);
         } catch (Exception e) {
             Log.d(TAG, "Query failed:" + e);
@@ -306,14 +306,14 @@
                     CarrierId.All.MCCMNC + "=? and "
                     + CarrierId.All.GID1 + "=? and "
                     + CarrierId.All.ICCID_PREFIX + "=?",
-                    new String[] { dummy_mccmnc, dummy_gid1, dummy_iccid_prefix }, null);
+                    new String[] { test_mccmnc, test_gid1, test_iccid_prefix }, null);
         } catch (Exception e) {
             Log.d(TAG, "Query failed:" + e);
         }
         assertEquals(1, findEntry.getCount());
         findEntry.moveToFirst();
-        assertEquals(dummy_cid, findEntry.getInt(0));
-        assertEquals(dummy_iccid_prefix, findEntry.getString(1));
+        assertEquals(test_cid, findEntry.getInt(0));
+        assertEquals(test_iccid_prefix, findEntry.getString(1));
     }
 
     @Test
@@ -337,8 +337,8 @@
         // update carrier id for subId 1
         try {
             ContentValues cv = new ContentValues();
-            cv.put(CarrierId.CARRIER_ID, dummy_cid);
-            cv.put(CarrierId.CARRIER_NAME, dummy_name);
+            cv.put(CarrierId.CARRIER_ID, test_cid);
+            cv.put(CarrierId.CARRIER_NAME, test_name);
             when(subscriptionManager.isActiveSubscriptionId(eq(1))).thenReturn(true);
             mContext.getContentResolver().update(Uri.withAppendedPath(CarrierId.CONTENT_URI,
                     "1"), cv, null, null);
@@ -359,8 +359,8 @@
         } catch (Exception e) {
             Log.d(TAG, "Error query current subscription: " + e);
         }
-        assertEquals(dummy_cid, carrierId);
-        assertEquals(dummy_name, carrierName);
+        assertEquals(test_cid, carrierId);
+        assertEquals(test_name, carrierName);
 
         // query carrier id for subId 2
         int count  = -1;
@@ -384,8 +384,8 @@
         } catch (Exception e) {
             Log.d(TAG, "Error query current subscription: " + e);
         }
-        assertEquals(dummy_cid, carrierId);
-        assertEquals(dummy_name, carrierName);
+        assertEquals(test_cid, carrierId);
+        assertEquals(test_name, carrierName);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -410,8 +410,8 @@
     public void testUpdateCurrentSubscription_WrongURI() {
         try {
             ContentValues cv = new ContentValues();
-            cv.put(CarrierId.CARRIER_ID, dummy_cid);
-            cv.put(CarrierId.CARRIER_NAME, dummy_name);
+            cv.put(CarrierId.CARRIER_ID, test_cid);
+            cv.put(CarrierId.CARRIER_NAME, test_name);
             mContext.getContentResolver().update(CarrierId.CONTENT_URI, cv, null, null);
             Assert.fail("should throw an exception for wrong uri");
         } catch (IllegalArgumentException ex) {
@@ -421,17 +421,17 @@
 
     private static ContentValues createCarrierInfoInternal() {
         ContentValues contentValues = new ContentValues();
-        contentValues.put(CarrierId.All.MCCMNC, dummy_mccmnc);
-        contentValues.put(CarrierId.All.GID1, dummy_gid1);
-        contentValues.put(CarrierId.All.GID2, dummy_gid2);
-        contentValues.put(CarrierId.All.PLMN, dummy_plmn);
-        contentValues.put(CarrierId.All.IMSI_PREFIX_XPATTERN, dummy_imsi_prefix);
-        contentValues.put(CarrierId.All.SPN, dummy_spn);
-        contentValues.put(CarrierId.All.APN, dummy_apn);
-        contentValues.put(CarrierId.All.ICCID_PREFIX, dummy_iccid_prefix);
-        contentValues.put(CarrierId.CARRIER_NAME, dummy_name);
-        contentValues.put(CarrierId.CARRIER_ID, dummy_cid);
-        contentValues.put(CarrierId.All.PRIVILEGE_ACCESS_RULE, dummy_access_rule);
+        contentValues.put(CarrierId.All.MCCMNC, test_mccmnc);
+        contentValues.put(CarrierId.All.GID1, test_gid1);
+        contentValues.put(CarrierId.All.GID2, test_gid2);
+        contentValues.put(CarrierId.All.PLMN, test_plmn);
+        contentValues.put(CarrierId.All.IMSI_PREFIX_XPATTERN, test_imsi_prefix);
+        contentValues.put(CarrierId.All.SPN, test_spn);
+        contentValues.put(CarrierId.All.APN, test_apn);
+        contentValues.put(CarrierId.All.ICCID_PREFIX, test_iccid_prefix);
+        contentValues.put(CarrierId.CARRIER_NAME, test_name);
+        contentValues.put(CarrierId.CARRIER_ID, test_cid);
+        contentValues.put(CarrierId.All.PRIVILEGE_ACCESS_RULE, test_access_rule);
         return contentValues;
     }
 }
diff --git a/tests/src/com/android/providers/telephony/CarrierProviderTest.java b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
index 5146aa9..eb95fb6 100644
--- a/tests/src/com/android/providers/telephony/CarrierProviderTest.java
+++ b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
@@ -54,16 +54,16 @@
     private MockContentResolver mContentResolver;
     private CarrierProviderTestable mCarrierProviderTestable;
 
-    public static final int dummy_type = 1;
-    public static final String dummy_mnc = "MNC001";
-    public static final String dummy_mnc2 = "MNC002";
-    public static final String dummy_mcc = "MCC005";
-    public static final String dummy_key1 = "PUBKEY1";
-    public static final String dummy_key2 = "PUBKEY2";
-    public static final String dummy_mvno_type = "100";
-    public static final String dummy_mvno_match_data = "101";
-    public static final String  dummy_key_identifier_data = "key_identifier1";
-    public static final long  dummy_key_expiration = 1496795015L;
+    public static final int test_type = 1;
+    public static final String test_mnc = "MNC001";
+    public static final String test_mnc2 = "MNC002";
+    public static final String test_mcc = "MCC005";
+    public static final String test_key1 = "PUBKEY1";
+    public static final String test_key2 = "PUBKEY2";
+    public static final String test_mvno_type = "100";
+    public static final String test_mvno_match_data = "101";
+    public static final String  test_key_identifier_data = "key_identifier1";
+    public static final long  test_key_expiration = 1496795015L;
 
 
     /**
@@ -144,14 +144,14 @@
     public void testInsertCertificates() {
         int count = -1;
         ContentValues contentValues = new ContentValues();
-        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
-        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
-        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
-        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
-        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
-        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
-        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
-        contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, dummy_key_expiration);
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
+        contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
 
         try {
             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -180,14 +180,14 @@
     public void testUpdateCertificates() {
         String key = null;
         ContentValues contentValues = new ContentValues();
-        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
-        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
-        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
-        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
-        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
-        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
-        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
-        contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, dummy_key_expiration);
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
+        contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
 
         try {
             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -197,10 +197,10 @@
 
         try {
             ContentValues updatedValues = new ContentValues();
-            updatedValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key2);
+            updatedValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2);
             mContentResolver.update(CarrierProvider.CONTENT_URI, updatedValues,
-                    "mcc=? and mnc=? and key_type=?", new String[] { dummy_mcc, dummy_mnc,
-                            String.valueOf(dummy_type) });
+                    "mcc=? and mnc=? and key_type=?", new String[] { test_mcc, test_mnc,
+                            String.valueOf(test_type) });
         } catch (Exception e) {
             Log.d(TAG, "Error updating values:" + e);
         }
@@ -209,13 +209,13 @@
             String[] columns ={CarrierDatabaseHelper.PUBLIC_KEY};
             Cursor findEntry = mContentResolver.query(CarrierProvider.CONTENT_URI, columns,
                     "mcc=? and mnc=? and key_type=?",
-                    new String[] { dummy_mcc, dummy_mnc, String.valueOf(dummy_type) }, null);
+                    new String[] { test_mcc, test_mnc, String.valueOf(test_type) }, null);
             findEntry.moveToFirst();
             key = findEntry.getString(0);
         } catch (Exception e) {
             Log.d(TAG, "Query failed:" + e);
         }
-        assertEquals(key, dummy_key2);
+        assertEquals(key, test_key2);
     }
 
     /**
@@ -226,22 +226,22 @@
     public void testMultipleCertificates() {
         int count = -1;
         ContentValues contentValues = new ContentValues();
-        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
-        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
-        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
-        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
-        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
-        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
-        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
 
         ContentValues contentValuesNew = new ContentValues();
-        contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
-        contentValuesNew.put(CarrierDatabaseHelper.MCC, dummy_mcc);
-        contentValuesNew.put(CarrierDatabaseHelper.MNC, dummy_mnc2);
-        contentValuesNew.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
-        contentValuesNew.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
-        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
-        contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key2.getBytes());
+        contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+        contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc);
+        contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc2);
+        contentValuesNew.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
+        contentValuesNew.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+        contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2.getBytes());
 
         try {
             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -270,12 +270,12 @@
     @Test(expected = SQLException.class)
     public void testDuplicateFailure() {
         ContentValues contentValues = new ContentValues();
-        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
-        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
-        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
-        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
-        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
-        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
 
         try {
             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -297,14 +297,14 @@
     public void testDelete() {
         int numRowsDeleted = -1;
         ContentValues contentValues = new ContentValues();
-        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
-        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
-        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
-        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
-        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
-        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
-        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
-        contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, dummy_key_expiration);
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, test_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, test_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, test_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, test_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes());
+        contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration);
 
         try {
             mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
@@ -314,7 +314,7 @@
 
         try {
             String whereClause = "mcc=? and mnc=?";
-            String[] whereArgs = new String[] { dummy_mcc, dummy_mnc };
+            String[] whereArgs = new String[] { test_mcc, test_mnc };
             numRowsDeleted = mContentResolver.delete(CarrierProvider.CONTENT_URI, whereClause, whereArgs);
         } catch (Exception e) {
             Log.d(TAG, "Error updating values:" + e);
diff --git a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
index b1cd5e4..00bb15e 100644
--- a/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyBackupAgentTest.java
@@ -41,7 +41,6 @@
 import android.util.ArraySet;
 import android.util.JsonReader;
 import android.util.JsonWriter;
-import android.util.Log;
 import android.util.SparseArray;
 
 import libcore.io.IoUtils;
@@ -616,6 +615,35 @@
     }
 
     /**
+     * Test that crashing for one sms does not block restore of other messages.
+     * @throws Exception
+     */
+    public void testRestoreSms_WithException() throws Exception {
+        mTelephonyBackupAgent.initUnknownSender();
+        JsonReader jsonReader = new JsonReader(new StringReader(addRandomDataToJson(mAllSmsJson)));
+        FakeSmsProvider smsProvider = new FakeSmsProvider(mSmsRows, false);
+        mMockContentResolver.addProvider("sms", smsProvider);
+        TelephonyBackupAgent.SmsProviderQuery smsProviderQuery =
+                new TelephonyBackupAgent.SmsProviderQuery() {
+                    int mIteration = 0;
+                    @Override
+                    public boolean doesSmsExist(ContentValues smsValues) {
+                        if (mIteration == 0) {
+                            mIteration++;
+                            throw new RuntimeException("fake crash for first message");
+                        }
+                        return false;
+                    }
+        };
+        mTelephonyBackupAgent.setSmsProviderQuery(smsProviderQuery);
+
+        mTelephonyBackupAgent.putSmsMessagesToProvider(jsonReader);
+        // the "- 1" is due to exception thrown for one of the messages
+        assertEquals(mSmsRows.length - 1, smsProvider.getRowsAdded());
+        assertEquals(mThreadProvider.mIsThreadArchived, mThreadProvider.mUpdateThreadsArchived);
+    }
+
+    /**
      * Test restore mms with the empty json array "[]".
      * @throws Exception
      */
@@ -751,11 +779,17 @@
     private class FakeSmsProvider extends MockContentProvider {
         private int nextRow = 0;
         private ContentValues[] mSms;
+        private boolean mCheckInsertedValues = true;
 
         public FakeSmsProvider(ContentValues[] sms) {
             this.mSms = sms;
         }
 
+        public FakeSmsProvider(ContentValues[] sms, boolean checkInsertedValues) {
+            this.mSms = sms;
+            mCheckInsertedValues = checkInsertedValues;
+        }
+
         @Override
         public Uri insert(Uri uri, ContentValues values) {
             assertEquals(Telephony.Sms.CONTENT_URI, uri);
@@ -771,7 +805,7 @@
                 modifiedValues.put(Telephony.Sms.ADDRESS, TelephonyBackupAgent.UNKNOWN_SENDER);
             }
 
-            assertEquals(modifiedValues, values);
+            if (mCheckInsertedValues) assertEquals(modifiedValues, values);
             return null;
         }
 
@@ -800,7 +834,7 @@
     private class FakeMmsProvider extends MockContentProvider {
         private int nextRow = 0;
         private List<ContentValues> mValues;
-        private long mDummyMsgId = -1;
+        private long mPlaceholderMsgId = -1;
         private long mMsgId = -1;
         private String mFilename;
 
@@ -810,7 +844,7 @@
 
         @Override
         public Uri insert(Uri uri, ContentValues values) {
-            Uri retUri = Uri.parse("dummy_uri");
+            Uri retUri = Uri.parse("test_uri");
             ContentValues modifiedValues = new ContentValues(mValues.get(nextRow++));
             if (values.containsKey("read")) {
                 assertEquals("read: ", modifiedValues.get("read"), values.get("read"));
@@ -820,8 +854,8 @@
             }
             if (APP_SMIL.equals(values.get(Telephony.Mms.Part.CONTENT_TYPE))) {
                 // Smil part.
-                assertEquals(-1, mDummyMsgId);
-                mDummyMsgId = values.getAsLong(Telephony.Mms.Part.MSG_ID);
+                assertEquals(-1, mPlaceholderMsgId);
+                mPlaceholderMsgId = values.getAsLong(Telephony.Mms.Part.MSG_ID);
             }
             if (IMAGE_JPG.equals(values.get(Telephony.Mms.Part.CONTENT_TYPE))) {
                 // Image attachment part.
@@ -839,7 +873,7 @@
             if (values.get(Telephony.Mms.Part.SEQ) != null) {
                 // Part of mms.
                 final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon()
-                        .appendPath(String.valueOf(mDummyMsgId))
+                        .appendPath(String.valueOf(mPlaceholderMsgId))
                         .appendPath("part")
                         .build();
                 assertEquals(expectedUri, uri);
@@ -852,7 +886,7 @@
             }
 
             if (values.get(Telephony.Mms.Part.MSG_ID) != null) {
-                modifiedValues.put(Telephony.Mms.Part.MSG_ID, mDummyMsgId);
+                modifiedValues.put(Telephony.Mms.Part.MSG_ID, mPlaceholderMsgId);
             }
             if (values.containsKey("read")) {
                 assertEquals("read: ", modifiedValues.get("read"), values.get("read"));
@@ -890,7 +924,7 @@
                 assertEquals(expectedUri, uri);
                 assertNotSame(-1, mMsgId);
                 modifiedValues.put(Telephony.Mms.Addr.MSG_ID, mMsgId);
-                mDummyMsgId = -1;
+                mPlaceholderMsgId = -1;
             }
             if (values.containsKey("read")) {
                 assertEquals("read: ", modifiedValues.get("read"), values.get("read"));
@@ -909,7 +943,7 @@
         @Override
         public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
             final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon()
-                    .appendPath(String.valueOf(mDummyMsgId))
+                    .appendPath(String.valueOf(mPlaceholderMsgId))
                     .appendPath("part")
                     .build();
             assertEquals(expectedUri, uri);
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index 18c8d08..203848a 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -51,11 +51,8 @@
 import junit.framework.TestCase;
 
 import org.junit.Test;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.IntStream;
@@ -123,12 +120,14 @@
     private class MockContextWithProvider extends MockContext {
         private final MockContentResolver mResolver;
         private TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
+        private SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class);
 
         private final List<String> GRANTED_PERMISSIONS = Arrays.asList(
                 Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.WRITE_APN_SETTINGS,
                 Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
 
-        public MockContextWithProvider(TelephonyProvider telephonyProvider) {
+        public MockContextWithProvider(TelephonyProvider telephonyProvider,
+                Boolean isActiveSubscription) {
             mResolver = new MockContentResolver() {
                 @Override
                 public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork,
@@ -146,7 +145,8 @@
 
             // return test subId 0 for all operators
             doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator(anyInt());
-
+            doReturn(isActiveSubscription).when(mSubscriptionManager)
+                    .isActiveSubscriptionId(anyInt());
             doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
             doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator();
             doReturn(TEST_CARRIERID).when(mTelephonyManager).getSimCarrierId();
@@ -171,6 +171,9 @@
             if (name.equals(Context.TELEPHONY_SERVICE)) {
                 Log.d(TAG, "getSystemService: returning mock TM");
                 return mTelephonyManager;
+            } else if (name.equals(Context.TELEPHONY_SUBSCRIPTION_SERVICE)){
+                Log.d(TAG, "getSystemService: returning mock SubscriptionManager");
+                return mSubscriptionManager;
             } else {
                 Log.d(TAG, "getSystemService: returning null");
                 return null;
@@ -181,6 +184,8 @@
         public String getSystemServiceName(Class<?> serviceClass) {
             if (serviceClass.equals(TelephonyManager.class)) {
               return Context.TELEPHONY_SERVICE;
+            } else if (serviceClass.equals(SubscriptionManager.class)) {
+                return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
             } else {
                 Log.d(TAG, "getSystemServiceName: returning null");
                 return null;
@@ -223,12 +228,15 @@
         super.setUp();
         MockitoAnnotations.initMocks(this);
         mTelephonyProviderTestable = new TelephonyProviderTestable();
-        mContext = new MockContextWithProvider(mTelephonyProviderTestable);
-        mContentResolver = (MockContentResolver) mContext.getContentResolver();
         notifyChangeCount = 0;
         notifyChangeRestoreCount = 0;
     }
 
+    private void setUpMockContext(boolean isActiveSubId) {
+        mContext = new MockContextWithProvider(mTelephonyProviderTestable, isActiveSubId);
+        mContentResolver = mContext.getContentResolver();
+    }
+
     @Override
     protected void tearDown() throws Exception {
         super.tearDown();
@@ -242,6 +250,8 @@
     @Test
     @SmallTest
     public void testBulkInsertCarriers() {
+        setUpMockContext(true);
+
         // insert 2 test contentValues
         ContentValues contentValues = new ContentValues();
         final String insertApn = "exampleApnName";
@@ -313,6 +323,8 @@
     @Test
     @SmallTest
     public void testMccMncMigration() {
+        setUpMockContext(true);
+
         CarrierIdProviderTestable carrierIdProvider = new CarrierIdProviderTestable();
         carrierIdProvider.initializeForTesting(mContext);
         mContentResolver.addProvider(Telephony.CarrierId.All.CONTENT_URI.getAuthority(),
@@ -372,6 +384,8 @@
     @Test
     @SmallTest
     public void testUpdateConflictingCarriers() {
+        setUpMockContext(true);
+
         // insert 2 test contentValues
         ContentValues contentValues = new ContentValues();
         final String insertApn = "exampleApnName";
@@ -429,6 +443,8 @@
     }
 
     private void doSimpleTestForUri(Uri uri) {
+        setUpMockContext(true);
+
         // insert test contentValues
         ContentValues contentValues = new ContentValues();
         final String insertApn = "exampleApnName";
@@ -479,6 +495,8 @@
     @Test
     @SmallTest
     public void testOwnedBy() {
+        setUpMockContext(true);
+
         // insert test contentValues
         ContentValues contentValues = new ContentValues();
         final String insertApn = "exampleApnName";
@@ -542,6 +560,8 @@
     @Test
     @SmallTest
     public void testSimTable() {
+        setUpMockContext(true);
+
         // insert test contentValues
         ContentValues contentValues = new ContentValues();
         final int insertSubId = 11;
@@ -627,6 +647,8 @@
     @Test
     @SmallTest
     public void testEnforceManagedUri() {
+        setUpMockContext(true);
+
         mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID);
 
         final int current = 1;
@@ -749,6 +771,8 @@
      * Test URL_TELEPHONY cannot insert, query, update or delete DPC records.
      */
     public void testTelephonyUriDpcRecordAccessControl() {
+        setUpMockContext(true);
+
         mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID);
 
         final int current = 1;
@@ -825,6 +849,8 @@
     @Test
     @SmallTest
     public void testDpcUri() {
+        setUpMockContext(true);
+
         int dpcRecordId = 0, othersRecordId = 0;
         try {
             mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID);
@@ -916,6 +942,8 @@
     @Test
     @SmallTest
     public void testDpcUriOnConflict() {
+        setUpMockContext(true);
+
         int dpcRecordId1 = 0, dpcRecordId2 = 0;
         try {
             mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID);
@@ -988,6 +1016,8 @@
     @Test
     @SmallTest
     public void testAccessUrlDpcThrowSecurityExceptionFromOtherUid() {
+        setUpMockContext(true);
+
         mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID + 123456);
 
         // Test insert().
@@ -1091,6 +1121,8 @@
     }
 
     private void preserveEditedValueInMerge(int value) {
+        setUpMockContext(true);
+
         // insert user deleted APN
         String carrierName1 = "carrier1";
         String numeric1 = "123234";
@@ -1138,6 +1170,8 @@
     }
 
     private void preserveDeletedValueInMerge(int value) {
+        setUpMockContext(true);
+
         // insert user deleted APN
         String carrierName1 = "carrier1";
         String numeric1 = "123234";
@@ -1184,6 +1218,8 @@
     @Test
     @SmallTest
     public void testQueryPreferredApn() {
+        setUpMockContext(true);
+
         // create APNs
         ContentValues preferredValues = new ContentValues();
         final String preferredApn = "preferredApn";
@@ -1230,6 +1266,8 @@
     @Test
     @SmallTest
     public void testApnSetId() {
+        setUpMockContext(true);
+
         // create APNs
         ContentValues values1 = new ContentValues();
         final String apn = "apnName";
@@ -1274,6 +1312,8 @@
     @Test
     @SmallTest
     public void testPreferApnSetUrl() {
+        setUpMockContext(true);
+
         // create APNs
         ContentValues values1 = new ContentValues();
         final String apn = "apnName";
@@ -1298,20 +1338,35 @@
         values3.put(Carriers.NUMERIC, TEST_OPERATOR);
         values3.put(Carriers.APN_SET_ID, 1);
 
+        // values4 has a matching setId but it belongs to a different carrier
+        ContentValues values4 = new ContentValues();
+        final String apn4 = "fourthApnName";
+        final String name4 = "name4";
+        values4.put(Carriers.APN, apn4);
+        values4.put(Carriers.NAME, name4);
+        values4.put(Carriers.NUMERIC, "999888");
+        values4.put(Carriers.APN_SET_ID, 1);
+
         // insert APNs
         // we explicitly include subid, as SubscriptionManager.getDefaultSubscriptionId() returns -1
         Log.d(TAG, "testPreferApnSetUrl: inserting contentValues=" + values1 + ", " + values2
-                + ", " + values3);
+                + ", " + values3 + ", " + values4);
         mContentResolver.insert(CONTENT_URI_WITH_SUBID, values1);
         mContentResolver.insert(CONTENT_URI_WITH_SUBID, values2);
+        mContentResolver.insert(CONTENT_URI_WITH_SUBID, values4);
         Uri uri = mContentResolver.insert(CONTENT_URI_WITH_SUBID, values3);
 
-        // before there's a preferred APN set, assert that all APNs are returned
+        // verify all APNs were correctly inserted
         final String[] testProjection = { Carriers.NAME };
         Cursor cursor = mContentResolver.query(
+                Carriers.CONTENT_URI, testProjection, null, null, null);
+        assertEquals(4, cursor.getCount());
+
+        // preferapnset/subId returns null when there is no preferred APN
+        cursor = mContentResolver.query(
                 Uri.withAppendedPath(Carriers.CONTENT_URI, "preferapnset/subId/" + TEST_SUBID),
                 testProjection, null, null, null);
-        assertEquals(3, cursor.getCount());
+        assertNull(cursor);
 
         // set the APN from values3 (apn_set_id = 1) to the preferred APN
         final String preferredApnIdString = uri.getLastPathSegment();
@@ -1326,6 +1381,7 @@
         cursor = mContentResolver.query(
                 Uri.withAppendedPath(Carriers.CONTENT_URI, "preferapnset/subId/" + TEST_SUBID),
                 testProjection, null, null, null);
+        // values4 which was inserted with a different carrier is not included in the results
         assertEquals(2, cursor.getCount());
         cursor.moveToFirst();
         assertEquals(name2, cursor.getString(0));
@@ -1339,6 +1395,8 @@
     @Test
     @SmallTest
     public void testRestoreDefaultApn() {
+        setUpMockContext(true);
+
         // setup for multi-SIM
         TelephonyManager telephonyManager =
                 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
@@ -1435,6 +1493,8 @@
     @Test
     @SmallTest
     public void testUpdateWfcEnabled() {
+        setUpMockContext(true);
+
         // insert test contentValues
         ContentValues contentValues = new ContentValues();
         final int insertSubId = 1;
@@ -1481,6 +1541,8 @@
     @Test
     @SmallTest
     public void testSIMAPNLIST_MatchTheMVNOAPN() {
+        setUpMockContext(true);
+
         // Test on getSubscriptionMatchingAPNList() step 1
         final String apnName = "apnName";
         final String carrierName = "name";
@@ -1519,6 +1581,7 @@
                         Carriers.NUMERIC,
                         Carriers.MVNO_MATCH_DATA
                 };
+
         Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
                 testProjection, null, null, null);
 
@@ -1534,6 +1597,8 @@
     @Test
     @SmallTest
     public void testSIMAPNLIST_MatchTheMNOAPN() {
+        setUpMockContext(true);
+
         // Test on getSubscriptionMatchingAPNList() step 2
         final String apnName = "apnName";
         final String carrierName = "name";
@@ -1553,6 +1618,7 @@
                         Carriers.NAME,
                         Carriers.NUMERIC,
                 };
+
         Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
                 testProjection, null, null, null);
 
@@ -1565,6 +1631,8 @@
     @Test
     @SmallTest
     public void testSIMAPNLIST_MatchTheCarrierIDANDMNOAPN() {
+        setUpMockContext(true);
+
         // Test on getSubscriptionMatchingAPNList() will return the {MCCMNC}
         final String apnName = "apnName";
         final String carrierName = "name";
@@ -1592,6 +1660,7 @@
                 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
@@ -1601,6 +1670,8 @@
     @Test
     @SmallTest
     public void testSIMAPNLIST_MatchTheCarrierAPNAndMVNOAPN() {
+        setUpMockContext(true);
+
         final String apnName = "apnName";
         final String carrierName = "name";
         final String mvnoType = "spn";
@@ -1638,6 +1709,7 @@
                 Carriers.CARRIER_ID,
                 Carriers.MVNO_TYPE,
             };
+
         Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
             testProjection, null, null, null);
 
@@ -1648,4 +1720,34 @@
                     || !TextUtils.isEmpty(cursor.getString(3)));
         }
     }
+
+    @Test
+    @SmallTest
+    public void testSIMAPNLIST_isNotActiveSubscription() {
+        setUpMockContext(false);
+
+        // Test on getSubscriptionMatchingAPNList() step 2
+        final String apnName = "apnName";
+        final String carrierName = "name";
+        final String numeric = TEST_OPERATOR;
+
+        // Insert the MNO APN
+        ContentValues 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 =
+                {
+                        Carriers.APN,
+                        Carriers.NAME,
+                        Carriers.NUMERIC,
+                };
+        Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST,
+                testProjection, null, null, null);
+
+        assertNull(cursor);
+    }
 }