Merge "Update language to comply with Android's inclusive language guidance"
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 7edf27a..d5c520e 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 52fc821..dd3fe60 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..88c6564 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..287c3d5 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..0e1dde8 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..e52cb71 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
index a5c1bbf..44241f2 100644
--- a/assets/sdk30_carrier_id/carrier_list.pb
+++ 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
index 50ac074..b0a87ef 100644
--- a/assets/sdk30_carrier_id/carrier_list.textpb
+++ 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 44f053d..1f5ad02 100644
--- a/src/com/android/providers/telephony/CarrierIdProvider.java
+++ b/src/com/android/providers/telephony/CarrierIdProvider.java
@@ -85,6 +85,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);
 
@@ -529,9 +532,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 6ff16e5..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
@@ -402,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) {
@@ -415,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);
     }
 
     /**
@@ -446,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);
@@ -904,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");
@@ -944,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) {
@@ -962,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/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 3e0944e..f880618 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -166,6 +166,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;
@@ -2975,10 +2978,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: {
@@ -3113,7 +3119,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();
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index 2018e2c..58b05ec 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);
+    }
 }