Use subId column of raw table.

This is primarily required to include correct subId in intents that
are broadcast for messages in raw table from SmsBroadcastUndelivered.

Test: atest
com.android.internal.telephony.gsm.GsmInboundSmsHandlerTest#testBroadcastUndeliveredMultiSim
Bug: 137124544

Merged-in: I3b02a68658f472714d3be56c91db39dce7404df4
Change-Id: I3b02a68658f472714d3be56c91db39dce7404df4
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 14a1217..cc0e42b 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -148,6 +148,7 @@
     public static final int MESSAGE_BODY_COLUMN = 8;
     public static final int DISPLAY_ADDRESS_COLUMN = 9;
     public static final int DELETED_FLAG_COLUMN = 10;
+    public static final int SUBID_COLUMN = 11;
 
     public static final String SELECT_BY_ID = "_id=?";
 
@@ -758,7 +759,8 @@
                     .makeInboundSmsTracker(sms.getPdu(),
                     sms.getTimestampMillis(), destPort, is3gpp2(), false,
                     sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(),
-                    sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0);
+                    sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0,
+                            mPhone.getSubId());
         } else {
             // Create a tracker for this message segment.
             SmsHeader.ConcatRef concatRef = smsHeader.concatRef;
@@ -770,7 +772,7 @@
                     sms.getTimestampMillis(), destPort, is3gpp2(), sms.getOriginatingAddress(),
                     sms.getDisplayOriginatingAddress(), concatRef.refNumber, concatRef.seqNumber,
                     concatRef.msgCount, false, sms.getMessageBody(),
-                    sms.getMessageClass() == MessageClass.CLASS_0);
+                    sms.getMessageClass() == MessageClass.CLASS_0, mPhone.getSubId());
         }
 
         if (VDBG) log("created tracker: " + tracker);
@@ -958,7 +960,7 @@
                 output.write(pdu, 0, pdu.length);
             }
             int result = mWapPush.dispatchWapPdu(output.toByteArray(), resultReceiver,
-                    this, address);
+                    this, address, tracker.getSubId());
             if (DBG) log("dispatchWapPdu() returned " + result);
             // Add result of WAP-PUSH into metrics. RESULT_SMS_HANDLED indicates that the WAP-PUSH
             // needs to be ignored, so treating it as a success case.
@@ -990,7 +992,7 @@
 
         if (!filterInvoked) {
             dispatchSmsDeliveryIntent(pdus, tracker.getFormat(), destPort, resultReceiver,
-                    tracker.isClass0());
+                    tracker.isClass0(), tracker.getSubId());
         }
 
         return true;
@@ -1085,7 +1087,7 @@
         CarrierServicesSmsFilterCallback filterCallback =
                 new CarrierServicesSmsFilterCallback(
                         pdus, destPort, tracker.getFormat(), resultReceiver, userUnlocked,
-                        tracker.isClass0());
+                        tracker.isClass0(), tracker.getSubId());
         CarrierServicesSmsFilter carrierServicesFilter = new CarrierServicesSmsFilter(
                 mContext, mPhone, pdus, destPort, tracker.getFormat(),
                 filterCallback, getName(), mLocalLog);
@@ -1094,7 +1096,7 @@
         }
 
         if (VisualVoicemailSmsFilter.filter(
-                mContext, pdus, tracker.getFormat(), destPort, mPhone.getSubId())) {
+                mContext, pdus, tracker.getFormat(), destPort, tracker.getSubId())) {
             log("Visual voicemail SMS dropped");
             dropSms(resultReceiver);
             return true;
@@ -1114,7 +1116,7 @@
      */
     @UnsupportedAppUsage
     public void dispatchIntent(Intent intent, String permission, int appOp,
-            Bundle opts, BroadcastReceiver resultReceiver, UserHandle user) {
+            Bundle opts, BroadcastReceiver resultReceiver, UserHandle user, int subId) {
         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
         final String action = intent.getAction();
         if (Intents.SMS_DELIVER_ACTION.equals(action)
@@ -1130,6 +1132,14 @@
             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         }
         SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
+
+        // override the subId value in the intent with the values from tracker as they can be
+        // different, specifically if the message is coming from SmsBroadcastUndelivered
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
+            intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
+        }
+
         if (user.equals(UserHandle.ALL)) {
             // Get a list of currently started users.
             int[] users = null;
@@ -1221,7 +1231,7 @@
      * @param resultReceiver the receiver handling the delivery result
      */
     private void dispatchSmsDeliveryIntent(byte[][] pdus, String format, int destPort,
-            SmsBroadcastReceiver resultReceiver, boolean isClass0) {
+            SmsBroadcastReceiver resultReceiver, boolean isClass0, int subId) {
         Intent intent = new Intent();
         intent.putExtra("pdus", pdus);
         intent.putExtra("format", format);
@@ -1269,7 +1279,7 @@
 
         Bundle options = handleSmsWhitelisting(intent.getComponent(), isClass0);
         dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS,
-                AppOpsManager.OP_RECEIVE_SMS, options, resultReceiver, UserHandle.SYSTEM);
+                AppOpsManager.OP_RECEIVE_SMS, options, resultReceiver, UserHandle.SYSTEM, subId);
     }
 
     /**
@@ -1443,6 +1453,8 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
+            int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
             if (action.equals(Intents.SMS_DELIVER_ACTION)) {
                 // Now dispatch the notification only intent
                 intent.setAction(Intents.SMS_RECEIVED_ACTION);
@@ -1455,7 +1467,7 @@
 
                 dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS,
                         AppOpsManager.OP_RECEIVE_SMS,
-                        options, this, UserHandle.ALL);
+                        options, this, UserHandle.ALL, subId);
             } else if (action.equals(Intents.WAP_PUSH_DELIVER_ACTION)) {
                 // Now dispatch the notification only intent
                 intent.setAction(Intents.WAP_PUSH_RECEIVED_ACTION);
@@ -1478,7 +1490,7 @@
                 String mimeType = intent.getType();
                 dispatchIntent(intent, WapPushOverSms.getPermissionForType(mimeType),
                         WapPushOverSms.getAppOpsPermissionForIntent(mimeType), options, this,
-                        UserHandle.SYSTEM);
+                        UserHandle.SYSTEM, subId);
             } else {
                 // Now that the intents have been deleted we can clean up the PDU data.
                 if (!Intents.DATA_SMS_RECEIVED_ACTION.equals(action)
@@ -1520,16 +1532,18 @@
         private final SmsBroadcastReceiver mSmsBroadcastReceiver;
         private final boolean mUserUnlocked;
         private final boolean mIsClass0;
+        private final int mSubId;
 
         CarrierServicesSmsFilterCallback(byte[][] pdus, int destPort, String smsFormat,
                 SmsBroadcastReceiver smsBroadcastReceiver,  boolean userUnlocked,
-                boolean isClass0) {
+                boolean isClass0, int subId) {
             mPdus = pdus;
             mDestPort = destPort;
             mSmsFormat = smsFormat;
             mSmsBroadcastReceiver = smsBroadcastReceiver;
             mUserUnlocked = userUnlocked;
             mIsClass0 = isClass0;
+            mSubId = subId;
         }
 
         @Override
@@ -1537,7 +1551,7 @@
             logv("onFilterComplete: result is " + result);
             if ((result & CarrierMessagingService.RECEIVE_OPTIONS_DROP) == 0) {
                 if (VisualVoicemailSmsFilter.filter(mContext, mPdus,
-                        mSmsFormat, mDestPort, mPhone.getSubId())) {
+                        mSmsFormat, mDestPort, mSubId)) {
                     log("Visual voicemail SMS dropped");
                     dropSms(mSmsBroadcastReceiver);
                     return;
@@ -1545,7 +1559,7 @@
 
                 if (mUserUnlocked) {
                     dispatchSmsDeliveryIntent(
-                            mPdus, mSmsFormat, mDestPort, mSmsBroadcastReceiver, mIsClass0);
+                            mPdus, mSmsFormat, mDestPort, mSmsBroadcastReceiver, mIsClass0, mSubId);
                 } else {
                     // Don't do anything further, leave the message in the raw table if the
                     // credential-encrypted storage is still locked and show the new message
diff --git a/src/java/com/android/internal/telephony/InboundSmsTracker.java b/src/java/com/android/internal/telephony/InboundSmsTracker.java
index 5bf7931..4d9971e 100644
--- a/src/java/com/android/internal/telephony/InboundSmsTracker.java
+++ b/src/java/com/android/internal/telephony/InboundSmsTracker.java
@@ -42,6 +42,7 @@
     private final boolean mIs3gpp2WapPdu;
     private final String mMessageBody;
     private final boolean mIsClass0;
+    private final int mSubId;
 
     // Fields for concatenating multi-part SMS messages
     private final String mAddress;
@@ -105,7 +106,7 @@
      */
     public InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2,
             boolean is3gpp2WapPdu, String address, String displayAddress, String messageBody,
-            boolean isClass0) {
+            boolean isClass0, int subId) {
         mPdu = pdu;
         mTimestamp = timestamp;
         mDestPort = destPort;
@@ -119,6 +120,7 @@
         mReferenceNumber = -1;
         mSequenceNumber = getIndexOffset();     // 0 or 1, depending on type
         mMessageCount = 1;
+        mSubId = subId;
     }
 
     /**
@@ -142,7 +144,8 @@
      */
     public InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2,
             String address, String displayAddress, int referenceNumber, int sequenceNumber,
-            int messageCount, boolean is3gpp2WapPdu, String messageBody, boolean isClass0) {
+            int messageCount, boolean is3gpp2WapPdu, String messageBody, boolean isClass0,
+            int subId) {
         mPdu = pdu;
         mTimestamp = timestamp;
         mDestPort = destPort;
@@ -157,6 +160,7 @@
         mReferenceNumber = referenceNumber;
         mSequenceNumber = sequenceNumber;
         mMessageCount = messageCount;
+        mSubId = subId;
     }
 
     /**
@@ -190,6 +194,8 @@
         mTimestamp = cursor.getLong(InboundSmsHandler.DATE_COLUMN);
         mAddress = cursor.getString(InboundSmsHandler.ADDRESS_COLUMN);
         mDisplayAddress = cursor.getString(InboundSmsHandler.DISPLAY_ADDRESS_COLUMN);
+        mSubId = cursor.getInt(SmsBroadcastUndelivered.PDU_PENDING_MESSAGE_PROJECTION_INDEX_MAPPING
+                .get(InboundSmsHandler.SUBID_COLUMN));
 
         if (cursor.getInt(InboundSmsHandler.COUNT_COLUMN) == 1) {
             // single-part message
@@ -249,6 +255,7 @@
         }
         values.put("count", mMessageCount);
         values.put("message_body", mMessageBody);
+        values.put("sub_id", mSubId);
         return values;
     }
 
@@ -318,6 +325,10 @@
         return mIsClass0;
     }
 
+    public int getSubId() {
+        return mSubId;
+    }
+
     @UnsupportedAppUsage
     public String getFormat() {
         return mIs3gpp2 ? SmsConstants.FORMAT_3GPP2 : SmsConstants.FORMAT_3GPP;
diff --git a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
index 459d97a..a1d8faa 100644
--- a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
+++ b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
@@ -36,6 +36,7 @@
 
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 
 /**
  * Called when the credential-encrypted storage is unlocked, collecting all acknowledged messages
@@ -65,9 +66,27 @@
             "address",
             "_id",
             "message_body",
-            "display_originating_addr"
+            "display_originating_addr",
+            "sub_id"
     };
 
+    /** Mapping from DB COLUMN to PDU_PENDING_MESSAGE_PROJECTION index */
+    static final Map<Integer, Integer> PDU_PENDING_MESSAGE_PROJECTION_INDEX_MAPPING =
+            new HashMap<Integer, Integer>() {{
+                put(InboundSmsHandler.PDU_COLUMN, 0);
+                put(InboundSmsHandler.SEQUENCE_COLUMN, 1);
+                put(InboundSmsHandler.DESTINATION_PORT_COLUMN, 2);
+                put(InboundSmsHandler.DATE_COLUMN, 3);
+                put(InboundSmsHandler.REFERENCE_NUMBER_COLUMN, 4);
+                put(InboundSmsHandler.COUNT_COLUMN, 5);
+                put(InboundSmsHandler.ADDRESS_COLUMN, 6);
+                put(InboundSmsHandler.ID_COLUMN, 7);
+                put(InboundSmsHandler.MESSAGE_BODY_COLUMN, 8);
+                put(InboundSmsHandler.DISPLAY_ADDRESS_COLUMN, 9);
+                put(InboundSmsHandler.SUBID_COLUMN, 10);
+            }};
+
+
     private static SmsBroadcastUndelivered instance;
 
     /** Content resolver to use to access raw table from SmsProvider. */
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index e5ed3fb..bea4927 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -356,9 +356,9 @@
      */
     public InboundSmsTracker makeInboundSmsTracker(byte[] pdu, long timestamp, int destPort,
             boolean is3gpp2, boolean is3gpp2WapPdu, String address, String displayAddr,
-            String messageBody, boolean isClass0) {
+            String messageBody, boolean isClass0, int subId) {
         return new InboundSmsTracker(pdu, timestamp, destPort, is3gpp2, is3gpp2WapPdu, address,
-                displayAddr, messageBody, isClass0);
+                displayAddr, messageBody, isClass0, subId);
     }
 
     /**
@@ -367,10 +367,10 @@
     public InboundSmsTracker makeInboundSmsTracker(byte[] pdu, long timestamp, int destPort,
             boolean is3gpp2, String address, String displayAddr, int referenceNumber,
             int sequenceNumber, int messageCount, boolean is3gpp2WapPdu, String messageBody,
-            boolean isClass0) {
+            boolean isClass0, int subId) {
         return new InboundSmsTracker(pdu, timestamp, destPort, is3gpp2, address, displayAddr,
                 referenceNumber, sequenceNumber, messageCount, is3gpp2WapPdu, messageBody,
-                isClass0);
+                isClass0, subId);
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/WapPushOverSms.java b/src/java/com/android/internal/telephony/WapPushOverSms.java
index 58ce62b..14942b1 100755
--- a/src/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/src/java/com/android/internal/telephony/WapPushOverSms.java
@@ -326,27 +326,13 @@
      * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
      *
      * @param pdu The WAP PDU, made up of one or more SMS PDUs
-     * @return a result code from {@link android.provider.Telephony.Sms.Intents}, or
-     *         {@link Activity#RESULT_OK} if the message has been broadcast
-     *         to applications
-     */
-    @UnsupportedAppUsage
-    public int dispatchWapPdu(byte[] pdu, BroadcastReceiver receiver, InboundSmsHandler handler) {
-        return dispatchWapPdu(pdu, receiver, handler, null);
-    }
-
-    /**
-     * Dispatches inbound messages that are in the WAP PDU format. See
-     * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
-     *
-     * @param pdu The WAP PDU, made up of one or more SMS PDUs
      * @param address The originating address
      * @return a result code from {@link android.provider.Telephony.Sms.Intents}, or
      *         {@link Activity#RESULT_OK} if the message has been broadcast
      *         to applications
      */
     public int dispatchWapPdu(byte[] pdu, BroadcastReceiver receiver, InboundSmsHandler handler,
-            String address) {
+            String address, int subId) {
         DecodedResult result = decodeWapPdu(pdu, handler);
         if (result.statusCode != Activity.RESULT_OK) {
             return result.statusCode;
@@ -441,7 +427,7 @@
 
         handler.dispatchIntent(intent, getPermissionForType(result.mimeType),
                 getAppOpsPermissionForIntent(result.mimeType), options, receiver,
-                UserHandle.SYSTEM);
+                UserHandle.SYSTEM, subId);
         return Activity.RESULT_OK;
     }
 
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
index 555a421..ec14efa 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
@@ -294,7 +294,8 @@
         InboundSmsTracker tracker = TelephonyComponentFactory.getInstance()
                 .inject(InboundSmsTracker.class.getName()).makeInboundSmsTracker(
                 userData, timestamp, destinationPort, true, address, dispAddr, referenceNumber,
-                segment, totalSegments, true, HexDump.toHexString(userData), false /* isClass0 */);
+                segment, totalSegments, true, HexDump.toHexString(userData), false /* isClass0 */,
+                        mPhone.getSubId());
 
         // de-duping is done only for text messages
         return addTrackerToRawTableAndSendMessage(tracker, false /* don't de-dup */);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
index ff473c5..e072a62 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
@@ -42,26 +42,27 @@
     private static final int FAKE_SEQUENCE_NUMBER = 3;
     private static final int FAKE_MESSAGE_COUNT = 5;
     private static final String FAKE_MESSAGE_BODY = "message body";
+    private static final int FAKE_SUBID = 0;
 
     @Before
     public void setUp() throws Exception {
         mInboundSmsTracker = new InboundSmsTracker(FAKE_PDU, FAKE_TIMESTAMP, FAKE_DEST_PORT, false,
                 FAKE_ADDRESS, FAKE_DISPLAY_ADDRESS, FAKE_REFERENCE_NUMBER, FAKE_SEQUENCE_NUMBER,
-                FAKE_MESSAGE_COUNT, false, FAKE_MESSAGE_BODY, false /* isClass0 */);
+                FAKE_MESSAGE_COUNT, false, FAKE_MESSAGE_BODY, false /* isClass0 */, FAKE_SUBID);
     }
 
     public static MatrixCursor createFakeCursor() {
         MatrixCursor mc = new MatrixCursor(
                 new String[]{"pdu", "seq", "dest", "date", "ref", "cnt", "addr", "id", "msg_body",
-                        "display_originating_addr"});
+                        "display_originating_addr", "sub_id"});
         mc.addRow(new Object[]{HexDump.toHexString(FAKE_PDU),
                 FAKE_SEQUENCE_NUMBER, FAKE_DEST_PORT, FAKE_TIMESTAMP,
                 FAKE_REFERENCE_NUMBER, FAKE_MESSAGE_COUNT, FAKE_ADDRESS, 1, FAKE_MESSAGE_BODY,
-                FAKE_DISPLAY_ADDRESS});
+                FAKE_DISPLAY_ADDRESS, FAKE_SUBID});
         mc.addRow(new Object[]{HexDump.toHexString(FAKE_PDU),
                 FAKE_SEQUENCE_NUMBER, FAKE_DEST_PORT, FAKE_TIMESTAMP,
                 FAKE_REFERENCE_NUMBER, FAKE_MESSAGE_COUNT, FAKE_ADDRESS, 2, FAKE_MESSAGE_BODY,
-                FAKE_DISPLAY_ADDRESS});
+                FAKE_DISPLAY_ADDRESS, FAKE_SUBID});
         mc.moveToFirst();
         return mc;
     }
@@ -82,6 +83,7 @@
         assertEquals(FAKE_MESSAGE_BODY, mInboundSmsTracker.getMessageBody());
         assertEquals(FAKE_DISPLAY_ADDRESS, mInboundSmsTracker.getDisplayAddress());
         assertEquals(false, mInboundSmsTracker.isClass0());
+        assertEquals(FAKE_SUBID, mInboundSmsTracker.getSubId());
 
         String[] args = new String[]{"123"};
         mInboundSmsTracker.setDeleteWhere(InboundSmsHandler.SELECT_BY_ID, args);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java b/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java
index 3643d47..284a859 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java
@@ -84,7 +84,7 @@
                 (byte) 0xFF
         };
 
-        mWapPushOverSmsUT.dispatchWapPdu(pdu, null, mInboundSmsHandler, "123456");
+        mWapPushOverSmsUT.dispatchWapPdu(pdu, null, mInboundSmsHandler, "123456", 0);
 
         ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
         verify(mInboundSmsHandler).dispatchIntent(intentArgumentCaptor.capture(),
@@ -92,7 +92,8 @@
                 eq(AppOpsManager.OP_RECEIVE_WAP_PUSH),
                 nullable(Bundle.class),
                 isNull(BroadcastReceiver.class),
-                eq(UserHandle.SYSTEM));
+                eq(UserHandle.SYSTEM),
+                anyInt());
         Intent intent = intentArgumentCaptor.getValue();
         assertEquals(Telephony.Sms.Intents.WAP_PUSH_DELIVER_ACTION, intent.getAction());
         assertEquals(0xFF, intent.getIntExtra("transactionId", 0));
@@ -138,13 +139,14 @@
                 111, 109, 47, 115, 97, 100, 102, 100, 100, 0};
 
         assertEquals(Telephony.Sms.Intents.RESULT_SMS_HANDLED,
-                mWapPushOverSmsUT.dispatchWapPdu(pdu, null, mInboundSmsHandler));
+                mWapPushOverSmsUT.dispatchWapPdu(pdu, null, mInboundSmsHandler, null, 0));
         verify(mInboundSmsHandler, never()).dispatchIntent(
                 any(Intent.class),
                 any(String.class),
                 anyInt(),
                 any(Bundle.class),
                 any(BroadcastReceiver.class),
-                any(UserHandle.class));
+                any(UserHandle.class),
+                anyInt());
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
index 2dcd428..632f46f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -78,6 +78,7 @@
     private FakeSmsContentProvider mContentProvider;
     private InboundSmsTracker mInboundSmsTracker;
     private byte[] mSmsPdu = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+    private int mSubId0 = 0;
 
     private class CdmaInboundSmsHandlerTestHandler extends HandlerThread {
 
@@ -137,16 +138,17 @@
                 "1234567890", /* address */
                 "1234567890", /* displayAddress */
                 "This is the message body of a single-part message" /* messageBody */,
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
 
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                 anyBoolean(), nullable(String.class), nullable(String.class),
-                nullable(String.class), anyBoolean());
+                nullable(String.class), anyBoolean(), anyInt());
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                 nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(Cursor.class), anyBoolean());
 
@@ -232,11 +234,12 @@
                 "1234567890", /* address */
                 blockedNumber, /* displayAddress */
                 "This is the message body of a single-part message" /* messageBody */,
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                 anyBoolean(), nullable(String.class), nullable(String.class),
-                nullable(String.class), anyBoolean());
+                nullable(String.class), anyBoolean(), anyInt());
         mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber);
 
         transitionFromStartupToIdle();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index 03234e6..028e764 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -48,6 +48,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Telephony;
+import android.telephony.SubscriptionManager;
 import android.test.mock.MockContentResolver;
 
 import androidx.test.filters.FlakyTest;
@@ -56,6 +57,7 @@
 import com.android.internal.telephony.FakeSmsContentProvider;
 import com.android.internal.telephony.InboundSmsHandler;
 import com.android.internal.telephony.InboundSmsTracker;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.SmsBroadcastUndelivered;
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.SmsStorageMonitor;
@@ -89,6 +91,9 @@
     private InboundSmsTracker mMockInboundSmsTracker;
     private ContentValues mInboundSmsTrackerCV;
     @Mock
+    private InboundSmsTracker mMockInboundSmsTrackerSub1;
+    private ContentValues mInboundSmsTrackerCVSub1;
+    @Mock
     private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
 
     private GsmInboundSmsHandler mGsmInboundSmsHandler;
@@ -103,6 +108,8 @@
     private String mMessageBody = "This is the message body of a single-part message";
     private String mMessageBodyPart1 = "This is the first part of a multi-part message";
     private String mMessageBodyPart2 = "This is the second part of a multi-part message";
+    private int mSubId0 = 0;
+    private int mSubId1 = 0;
 
     byte[] mSmsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF};
 
@@ -147,6 +154,7 @@
         mInboundSmsTrackerCV.put("date", System.currentTimeMillis());
         mInboundSmsTrackerCV.put("message_body", mMessageBody);
         mInboundSmsTrackerCV.put("display_originating_addr", "1234567890");
+        mInboundSmsTrackerCV.put("sub_id", mSubId0);
 
         doReturn(1).when(mMockInboundSmsTracker).getMessageCount();
         doReturn(1).when(mMockInboundSmsTracker).getReferenceNumber();
@@ -158,9 +166,36 @@
         doReturn(mSmsPdu).when(mMockInboundSmsTracker).getPdu();
         doReturn(mInboundSmsTrackerCV.get("date")).when(mMockInboundSmsTracker).getTimestamp();
         doReturn(mInboundSmsTrackerCV).when(mMockInboundSmsTracker).getContentValues();
+        doReturn(mSubId0).when(mMockInboundSmsTracker).getSubId();
 
-        doReturn(mMockInboundSmsTracker).when(mTelephonyComponentFactory)
-            .makeInboundSmsTracker(nullable(Cursor.class), anyBoolean());
+        mInboundSmsTrackerCVSub1 = new ContentValues();
+        mInboundSmsTrackerCVSub1.put("destination_port", InboundSmsTracker.DEST_PORT_FLAG_NO_PORT);
+        mInboundSmsTrackerCVSub1.put("pdu", HexDump.toHexString(mSmsPdu));
+        mInboundSmsTrackerCVSub1.put("address", "1234567890");
+        mInboundSmsTrackerCVSub1.put("reference_number", 1);
+        mInboundSmsTrackerCVSub1.put("sequence", 1);
+        mInboundSmsTrackerCVSub1.put("count", 1);
+        mInboundSmsTrackerCVSub1.put("date", System.currentTimeMillis());
+        mInboundSmsTrackerCVSub1.put("message_body", mMessageBody);
+        mInboundSmsTrackerCVSub1.put("display_originating_addr", "1234567890");
+        mInboundSmsTrackerCVSub1.put("sub_id", mSubId1);
+
+        doReturn(1).when(mMockInboundSmsTrackerSub1).getMessageCount();
+        doReturn(1).when(mMockInboundSmsTrackerSub1).getReferenceNumber();
+        doReturn("1234567890").when(mMockInboundSmsTrackerSub1).getAddress();
+        doReturn(1).when(mMockInboundSmsTrackerSub1).getSequenceNumber();
+        doReturn(1).when(mMockInboundSmsTrackerSub1).getIndexOffset();
+        doReturn(-1).when(mMockInboundSmsTrackerSub1).getDestPort();
+        doReturn(mMessageBody).when(mMockInboundSmsTrackerSub1).getMessageBody();
+        doReturn(mSmsPdu).when(mMockInboundSmsTrackerSub1).getPdu();
+        doReturn(mInboundSmsTrackerCVSub1.get("date")).when(mMockInboundSmsTrackerSub1)
+                .getTimestamp();
+        doReturn(mInboundSmsTrackerCVSub1).when(mMockInboundSmsTrackerSub1).getContentValues();
+        doReturn(mSubId1).when(mMockInboundSmsTrackerSub1).getSubId();
+
+        doReturn(mMockInboundSmsTracker).doReturn(mMockInboundSmsTrackerSub1)
+                .when(mTelephonyComponentFactory)
+                .makeInboundSmsTracker(nullable(Cursor.class), anyBoolean());
     }
 
     @Before
@@ -190,11 +225,12 @@
                 "1234567890", /* address */
                 "1234567890", /* displayAddress */
                 mMessageBody, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                 anyBoolean(), nullable(String.class), nullable(String.class),
-                nullable(String.class), anyBoolean());
+                nullable(String.class), anyBoolean(), anyInt());
 
         createMockInboundSmsTracker();
 
@@ -239,11 +275,26 @@
     }
 
     private void verifySmsIntentBroadcasts(int numPastBroadcasts, boolean allowBgActivityStarts) {
+        verifySmsIntentBroadcasts(numPastBroadcasts, allowBgActivityStarts, mSubId0,
+                false /* moreMessages */);
+    }
+
+    private void verifySmsIntentBroadcasts(int numPastBroadcasts, int subId, boolean moreMessages) {
+        verifySmsIntentBroadcasts(numPastBroadcasts, false /* allowBgActivityStarts */, subId,
+                moreMessages);
+    }
+
+    private void verifySmsIntentBroadcasts(int numPastBroadcasts, boolean allowBgActivityStarts,
+            int subId, boolean moreMessages) {
         ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(1 + numPastBroadcasts)).sendBroadcast(
                 intentArgumentCaptor.capture());
-        assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION,
-                intentArgumentCaptor.getAllValues().get(numPastBroadcasts).getAction());
+        Intent intent = intentArgumentCaptor.getAllValues().get(numPastBroadcasts);
+        assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION, intent.getAction());
+        assertEquals(subId, intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+        assertEquals(subId, intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID));
         assertEquals("WaitingState", getCurrentState().getName());
         if (allowBgActivityStarts) {
             Bundle broadcastOptions = mContextFixture.getLastBroadcastOptions();
@@ -256,8 +307,12 @@
         intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(2 + numPastBroadcasts)).sendBroadcast(
                 intentArgumentCaptor.capture());
-        assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION,
-                intentArgumentCaptor.getAllValues().get(numPastBroadcasts + 1).getAction());
+        intent = intentArgumentCaptor.getAllValues().get(numPastBroadcasts + 1);
+        assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION, intent.getAction());
+        assertEquals(subId, intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+        assertEquals(subId, intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID));
         assertEquals("WaitingState", getCurrentState().getName());
 
         mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
@@ -265,9 +320,12 @@
         waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
         // transition from waiting state to delivering state
         waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
-        // transition from delivering state to idle state
-        waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
-        assertEquals("IdleState", getCurrentState().getName());
+        if (!moreMessages) {
+            // transition from delivering state to idle state; if moreMessages are pending will
+            // transition to WaitingState instead of IdleState
+            waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+            assertEquals("IdleState", getCurrentState().getName());
+        }
     }
 
     private void sendNewSms() {
@@ -344,11 +402,12 @@
                 "1234567890", /* address */
                 "1234567890", /* displayAddress */
                 mMessageBody, /* messageBody */
-                true /* isClass0 */);
+                true, /* isClass0 */
+                mSubId0);
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         anyBoolean(), nullable(String.class), nullable(String.class),
-                        nullable(String.class), anyBoolean());
+                        nullable(String.class), anyBoolean(), anyInt());
         mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS,
                 mInboundSmsTracker);
         waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
@@ -371,11 +430,12 @@
                 "1234567890", /* address */
                 "1234567890", /* displayAddress */
                 mMessageBody, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                 anyBoolean(), nullable(String.class), nullable(String.class),
-                nullable(String.class), anyBoolean());
+                nullable(String.class), anyBoolean(), anyInt());
         mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS,
                 mInboundSmsTracker);
         waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
@@ -429,7 +489,8 @@
                 2, /* messageCount */
                 is3gpp2WapPush, /* is3gpp2WapPdu */
                 mMessageBodyPart1, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
 
         // Part 2
         mInboundSmsTrackerPart2 = new InboundSmsTracker(
@@ -444,7 +505,8 @@
                 2, /* messageCount */
                 is3gpp2WapPush, /* is3gpp2WapPdu */
                 mMessageBodyPart2, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
     }
 
     @Test
@@ -467,7 +529,7 @@
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // State machine should go back to idle and wait for second part
@@ -478,7 +540,7 @@
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // State machine should go back to idle and wait for second part
@@ -492,7 +554,7 @@
         doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // verify broadcast intents
@@ -518,7 +580,7 @@
         doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // State machine should go back to idle and wait for second part
@@ -527,7 +589,7 @@
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // verify broadcast intents
@@ -541,7 +603,7 @@
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // verify no additional broadcasts sent
@@ -557,7 +619,7 @@
         doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // verify no additional broadcasts sent
@@ -590,7 +652,8 @@
                 2, /* messageCount */
                 false, /* is3gpp2WapPdu */
                 mMessageBodyPart2, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
 
         mSmsHeader.concatRef = new SmsHeader.ConcatRef();
         doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader();
@@ -598,7 +661,7 @@
         doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // State machine should go back to idle and wait for second part
@@ -607,7 +670,7 @@
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // verify no broadcasts sent
@@ -636,7 +699,7 @@
         doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // verify the message is stored in the raw table
@@ -659,12 +722,13 @@
                 2, /* messageCount */
                 false, /* is3gpp2WapPdu */
                 mMessageBodyPart2, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
 
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         // verify no broadcasts sent
@@ -688,7 +752,7 @@
         doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
 
         sendNewSms();
 
@@ -698,7 +762,7 @@
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         verify(mContext, never()).sendBroadcast(any(Intent.class));
@@ -727,14 +791,15 @@
                 2, /* messageCount */
                 false, /* is3gpp2WapPdu */
                 mMessageBodyPart1, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
 
         mSmsHeader.concatRef = new SmsHeader.ConcatRef();
         doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader();
         doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
 
         sendNewSms();
 
@@ -744,7 +809,7 @@
         doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                         nullable(String.class), nullable(String.class), anyInt(), anyInt(),
-                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean());
+                        anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
         sendNewSms();
 
         verify(mContext, never()).sendBroadcast(any(Intent.class));
@@ -818,11 +883,12 @@
                 "1234567890", /* address */
                 "1234567890", /* displayAddress */
                 mMessageBody, /* messageBody */
-                false /* isClass0 */);
+                false, /* isClass0 */
+                mSubId0);
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
                 anyBoolean(), nullable(String.class), nullable(String.class),
-                nullable(String.class), anyBoolean());
+                nullable(String.class), anyBoolean(), anyInt());
 
         //add a fake entry to db
         ContentValues rawSms = new ContentValues();
@@ -863,4 +929,21 @@
 
         verifySmsIntentBroadcasts(0);
     }
+
+    @Test
+    @MediumTest
+    public void testBroadcastUndeliveredMultiSim() throws Exception {
+        replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null);
+
+        // add SMSs from different subs to db
+        mContentProvider.insert(sRawUri, mMockInboundSmsTracker.getContentValues());
+        mContentProvider.insert(sRawUri, mMockInboundSmsTrackerSub1.getContentValues());
+
+        SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+        // wait for ScanRawTableThread
+        waitForMs(200);
+
+        verifySmsIntentBroadcasts(0, mSubId0, true);
+        verifySmsIntentBroadcasts(2, mSubId1, false);
+    }
 }