diff --git a/dom/mobilemessage/tests/marionette/head.js b/dom/mobilemessage/tests/marionette/head.js index 5b7b72388c88..e44a12bd408a 100644 --- a/dom/mobilemessage/tests/marionette/head.js +++ b/dom/mobilemessage/tests/marionette/head.js @@ -45,6 +45,31 @@ function ensureMobileMessage() { return deferred.promise; } +/** + * Wait for one named MobileMessageManager event. + * + * Resolve if that named event occurs. Never reject. + * + * Fulfill params: the DOMEvent passed. + * + * @param aEventName + * A string event name. + * + * @return A deferred promise. + */ +function waitForManagerEvent(aEventName) { + let deferred = Promise.defer(); + + manager.addEventListener(aEventName, function onevent(aEvent) { + manager.removeEventListener(aEventName, onevent); + + ok(true, "MobileMessageManager event '" + aEventName + "' got."); + deferred.resolve(aEvent); + }); + + return deferred.promise; +} + /** * Send a SMS message to a single receiver. Resolve if it succeeds, reject * otherwise. @@ -331,6 +356,9 @@ function sendTextSmsToEmulator(aFrom, aText) { /** * Send raw SMS TPDU to emulator. * + * @param: aPdu + * A hex string representing the whole SMS T-PDU. + * * Fulfill params: * result -- an array of emulator response lines. * diff --git a/dom/mobilemessage/tests/marionette/manifest.ini b/dom/mobilemessage/tests/marionette/manifest.ini index ceef42b21c0c..31f6a9608890 100644 --- a/dom/mobilemessage/tests/marionette/manifest.ini +++ b/dom/mobilemessage/tests/marionette/manifest.ini @@ -44,3 +44,4 @@ qemu = true [test_mmdb_foreachmatchedmmsdeliveryinfo.js] [test_mmdb_full_storage.js] [test_replace_short_message_type.js] +[test_mt_sms_concatenation.js] diff --git a/dom/mobilemessage/tests/marionette/test_mt_sms_concatenation.js b/dom/mobilemessage/tests/marionette/test_mt_sms_concatenation.js new file mode 100644 index 000000000000..36fa928bb1e4 --- /dev/null +++ b/dom/mobilemessage/tests/marionette/test_mt_sms_concatenation.js @@ -0,0 +1,138 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const PDU_SMSC_NONE = "00"; // no SMSC Address + +const PDU_FIRST_OCTET = "40"; // RP:no, UDHI:yes, SRI:no, MMS:no, MTI:SMS-DELIVER + +const PDU_SENDER = "0A912143658709"; // +1234567890 +const SENDER = "+1234567890"; + +const PDU_PID_NORMAL = "00"; + +const PDU_DCS_NORMAL_UCS2 = "08"; +const PDU_DCS_CLASS0_UCS2 = "18"; +const PDU_DCS_NORMAL_8BIT = "04"; +const PDU_DCS_CLASS0_8BIT = "14"; + +const PDU_TIMESTAMP = "00101000000000"; // 2000/01/01 + +function byteValueToHexString(aValue) { + let str = Number(aValue).toString(16).toUpperCase(); + return str.length == 1 ? "0" + str : str; +} + +let ref_num = 0; +function buildTextPdus(aDcs) { + ref_num++; + + let IEI_CONCATE_1 = "0003" + byteValueToHexString(ref_num) + "0301"; + let IEI_CONCATE_2 = "0003" + byteValueToHexString(ref_num) + "0302"; + let IEI_CONCATE_3 = "0003" + byteValueToHexString(ref_num) + "0303"; + let PDU_UDL = "08"; // UDHL(1) + UDH(5) + UCS2 Char (2) + let PDU_UDHL = "05"; + + let PDU_UD_A = "0041"; // "A" + let PDU_UD_B = "0042"; // "B" + let PDU_UD_C = "0043"; // "C" + + let PDU_COMMON = PDU_SMSC_NONE + PDU_FIRST_OCTET + PDU_SENDER + + PDU_PID_NORMAL + aDcs + PDU_TIMESTAMP + PDU_UDL + PDU_UDHL; + + return [ + PDU_COMMON + IEI_CONCATE_1 + PDU_UD_A, + PDU_COMMON + IEI_CONCATE_2 + PDU_UD_B, + PDU_COMMON + IEI_CONCATE_3 + PDU_UD_C + ]; +} + +function buildBinaryPdus(aDcs) { + ref_num++; + let IEI_PORT = "05040B8423F0"; + + let PDU_DATA1 = "C106316170706C69636174696F6E2F76" + + "6E642E7761702E6D6D732D6D65737361" + + "676500B131302E382E3133302E313800" + + "AF84B4818C82986B4430595538595347" + + "77464E446741416B4876736C58303141" + + "41414141414141008D90890380310096" + + "05EA4D4D53008A808E02024188058103" + + "015F9083687474703A2F2F6D6D732E65"; + + let PDU_DATA2 = "6D6F6D652E6E65743A383030322F6B44" + + "3059553859534777464E446741416B48" + + "76736C583031414141414141414100"; + + let PDU_COMMON = PDU_SMSC_NONE + PDU_FIRST_OCTET + PDU_SENDER + + PDU_PID_NORMAL + aDcs + PDU_TIMESTAMP; + + function construstBinaryUserData(aBinaryData, aSeqNum) { + let ieiConcat = "0003" + byteValueToHexString(ref_num) + "02" + + byteValueToHexString(aSeqNum); + + let udh = IEI_PORT + ieiConcat; + let udhl = byteValueToHexString(udh.length / 2); + let ud = udhl + udh + aBinaryData; + let udl = byteValueToHexString(ud.length / 2); + + return udl + ud; + } + + return [ + PDU_COMMON + construstBinaryUserData(PDU_DATA1, 1), + PDU_COMMON + construstBinaryUserData(PDU_DATA2, 2) + ]; +} + +function sendRawSmsAndWait(aPdus) { + let promises = []; + + promises.push(waitForManagerEvent("received")); + for (let pdu of aPdus) { + promises.push(sendRawSmsToEmulator(pdu)); + } + + return Promise.all(promises); +} + +function verifyTextMessage(aMessage, aMessageClass) { + is(aMessage.messageClass, aMessageClass, "SmsMessage class"); + is(aMessage.sender, SENDER, "SmsMessage sender"); + is(aMessage.body, "ABC", "SmsMessage body"); +} + +function verifyBinaryMessage(aMessage) { + is(aMessage.type, "mms", "MmsMessage type"); + is(aMessage.delivery, "not-downloaded", "MmsMessage delivery"); + + // remove duplicated M-Notification.ind for next test. + return deleteMessagesById([aMessage.id]); +} + +function testText(aDcs, aClass) { + log("testText(): aDcs = " + aDcs + ", aClass = " + aClass); + return sendRawSmsAndWait(buildTextPdus(aDcs)) + .then((resolutions) => verifyTextMessage(resolutions[0].message, aClass)); +} + +function testBinary(aDcs) { + log("testBinary(): aDcs = " + aDcs); + return sendRawSmsAndWait(buildBinaryPdus(aDcs)) + .then((resolutions) => verifyBinaryMessage(resolutions[0].message)); +} + +SpecialPowers.pushPrefEnv( + {"set": [["dom.mms.retrieval_mode", "manual"]]}, + function startTest() { + startTestCommon(function testCaseMain() { + return Promise.resolve() + .then(() => testText(PDU_DCS_NORMAL_UCS2, "normal")) + .then(() => testText(PDU_DCS_CLASS0_UCS2, "class-0")) + .then(() => testBinary(PDU_DCS_NORMAL_8BIT)) + .then(() => testBinary(PDU_DCS_CLASS0_8BIT)); + }); + } +);