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);
+ }
}