Bug 850127: Expose threadId in SmsMessage and SmsThreadListItem. sr=mounir, r=mounir,gwagner, a=tef+
authorVicamo Yang <vyang@mozilla.com>
Mon, 08 Apr 2013 18:20:48 +0800
changeset 118982 53c3b6ab66cd1708f21699b51f793952f38ad623
parent 118981 b32166f6703be61abc74c062ad244fd4ce348a6c
child 118983 744b05a192ad69800537d3da1d988cfd01b313c3
push id634
push uservyang@mozilla.com
push dateMon, 08 Apr 2013 10:21:26 +0000
reviewersmounir, mounir, gwagner, tef
bugs850127
milestone18.0
Bug 850127: Expose threadId in SmsMessage and SmsThreadListItem. sr=mounir, r=mounir,gwagner, a=tef+
dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
dom/mobilemessage/interfaces/nsIDOMSmsMessage.idl
dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
dom/mobilemessage/interfaces/nsIMobileMessageService.idl
dom/mobilemessage/src/MmsMessage.cpp
dom/mobilemessage/src/MmsMessage.h
dom/mobilemessage/src/MobileMessageService.cpp
dom/mobilemessage/src/SmsMessage.cpp
dom/mobilemessage/src/SmsMessage.h
dom/mobilemessage/src/SmsRequest.cpp
dom/mobilemessage/src/ipc/PSmsRequest.ipdl
dom/mobilemessage/src/ipc/SmsTypes.ipdlh
dom/mobilemessage/src/ril/MobileMessageDatabaseService.js
dom/mobilemessage/tests/marionette/test_getmessage.js
dom/mobilemessage/tests/marionette/test_getmessages.js
dom/mobilemessage/tests/marionette/test_incoming.js
dom/mobilemessage/tests/marionette/test_incoming_delete.js
dom/mobilemessage/tests/marionette/test_incoming_multipart.js
dom/mobilemessage/tests/marionette/test_message_classes.js
dom/mobilemessage/tests/marionette/test_outgoing.js
dom/mobilemessage/tests/marionette/test_outgoing_delete.js
dom/mobilemessage/tests/test_smsservice_createsmsmessage.js
dom/system/gonk/RadioInterfaceLayer.js
widget/android/AndroidJNI.cpp
--- a/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMMozMmsMessage.idl
@@ -8,26 +8,28 @@ interface nsIDOMBlob;
 
 dictionary MmsAttachment
 {
   DOMString? id;
   DOMString? location;
   nsIDOMBlob content;
 };
 
-[scriptable, builtinclass, uuid(c9683d00-88a6-11e2-85cc-57a33dfbea3b)]
+[scriptable, builtinclass, uuid(210654af-4cc8-42e5-81b2-051f0f393c3a)]
 interface nsIDOMMozMmsMessage : nsISupports
 {
   /**
    * |type| is always "mms".
    */
   readonly attribute DOMString type;
 
   readonly attribute long      id;
 
+  readonly attribute unsigned long long threadId;
+
   /**
    * Should be "not-downloaded", "received", "sending", "sent" or "error".
    */
   readonly attribute DOMString delivery;
 
   [implicit_jscontext]
   readonly attribute jsval     deliveryStatus; // DOMString[]
 
@@ -40,9 +42,9 @@ interface nsIDOMMozMmsMessage : nsISuppo
   readonly attribute jsval     timestamp;      // Date
 
   readonly attribute boolean   read;
   readonly attribute DOMString subject;
   readonly attribute DOMString smil;
 
   [implicit_jscontext]
   readonly attribute jsval     attachments;    // MmsAttachment[]
-};
\ No newline at end of file
+};
--- a/dom/mobilemessage/interfaces/nsIDOMSmsMessage.idl
+++ b/dom/mobilemessage/interfaces/nsIDOMSmsMessage.idl
@@ -1,24 +1,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-[scriptable, builtinclass, uuid(d4d848c4-88a6-11e2-b6da-6f252cbfa716)]
+[scriptable, builtinclass, uuid(b755a401-d5cb-4d35-a93e-47c89d2e15ca)]
 interface nsIDOMMozSmsMessage : nsISupports
 {
   /**
    * |type| is always "sms".
    */
   readonly attribute DOMString type;
 
   readonly attribute long      id;
 
+  readonly attribute unsigned long long threadId;
+
   /**
    * Should be "received", "sending", "sent" or "error".
    */
   readonly attribute DOMString delivery;
 
   /**
    * Possible delivery status values for above delivery states are:
    *
--- a/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
+++ b/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 dictionary SmsThreadListItem
 {
+  unsigned long long id;
   DOMString senderOrReceiver;
   unsigned long long timestamp;
   DOMString body;
   unsigned long long unreadCount;
 };
 
 [scriptable, builtinclass, uuid(edb1de12-8d58-11e2-b382-7bf132b20cb2)]
 interface nsIMobileMessageCallback : nsISupports
--- a/dom/mobilemessage/interfaces/nsIMobileMessageService.idl
+++ b/dom/mobilemessage/interfaces/nsIMobileMessageService.idl
@@ -8,32 +8,34 @@ interface nsIDOMMozSmsMessage;
 interface nsIDOMMozMmsMessage;
 interface nsIDOMMozSmsSegmentInfo;
 
 %{C++
 #define MOBILE_MESSAGE_SERVICE_CID { 0x829c1dd6, 0x0466, 0x4591, { 0x83, 0x6f, 0xb8, 0xf6, 0xfd, 0x1f, 0x7b, 0xa5 } }
 #define MOBILE_MESSAGE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/mobilemessageservice;1"
 %}
 
-[scriptable, builtinclass, uuid(4cbc9594-84c3-11e2-a274-ebada93fa6cd)]
+[scriptable, builtinclass, uuid(944297ed-0dc7-4dee-89a6-c962ea0218d3)]
 interface nsIMobileMessageService : nsISupports
 {
   [implicit_jscontext]
   nsIDOMMozSmsMessage createSmsMessage(in long      id,
+                                       in unsigned long long threadId,
                                        in DOMString delivery,
                                        in DOMString deliveryStatus,
                                        in DOMString sender,
                                        in DOMString receiver,
                                        in DOMString body,
                                        in DOMString messageClass,
                                        in jsval     timestamp,
                                        in bool      read);
 
   [implicit_jscontext]
   nsIDOMMozMmsMessage createMmsMessage(in long      id,
+                                       in unsigned long long threadId,
                                        in DOMString delivery,
                                        in jsval     deliveryStatus,
                                        in DOMString sender,
                                        in jsval     receivers,
                                        in jsval     timestamp,
                                        in boolean   read,
                                        in DOMString subject,
                                        in DOMString smil,
--- a/dom/mobilemessage/src/MmsMessage.cpp
+++ b/dom/mobilemessage/src/MmsMessage.cpp
@@ -25,40 +25,43 @@ NS_INTERFACE_MAP_BEGIN(MmsMessage)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMmsMessage)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(MmsMessage)
 NS_IMPL_RELEASE(MmsMessage)
 
 MmsMessage::MmsMessage(int32_t                         aId,
+                       const uint64_t                  aThreadId,
                        DeliveryState                   aDelivery,
                        const nsTArray<DeliveryStatus>& aDeliveryStatus,
                        const nsAString&                aSender,
                        const nsTArray<nsString>&       aReceivers,
                        uint64_t                        aTimestamp,
                        bool                            aRead,
                        const nsAString&                aSubject,
                        const nsAString&                aSmil,
                        const nsTArray<MmsAttachment>&  aAttachments)
   : mId(aId),
+    mThreadId(aThreadId),
     mDelivery(aDelivery),
     mDeliveryStatus(aDeliveryStatus),
     mSender(aSender),
     mReceivers(aReceivers),
     mTimestamp(aTimestamp),
     mRead(aRead),
     mSubject(aSubject),
     mSmil(aSmil),
     mAttachments(aAttachments)
 {
 }
 
 /* static */ nsresult
 MmsMessage::Create(int32_t               aId,
+                   const uint64_t        aThreadId,
                    const nsAString&      aDelivery,
                    const JS::Value&      aDeliveryStatus,
                    const nsAString&      aSender,
                    const JS::Value&      aReceivers,
                    const JS::Value&      aTimestamp,
                    bool                  aRead,
                    const nsAString&      aSubject,
                    const nsAString&      aSmil,
@@ -187,16 +190,17 @@ MmsMessage::Create(int32_t              
     MmsAttachment attachment;
     nsresult rv = attachment.Init(aCx, &attachmentJsVal);
     NS_ENSURE_SUCCESS(rv, rv);
 
     attachments.AppendElement(attachment);
   }
 
   nsCOMPtr<nsIDOMMozMmsMessage> message = new MmsMessage(aId,
+                                                         aThreadId,
                                                          delivery,
                                                          deliveryStatus,
                                                          aSender,
                                                          receivers,
                                                          timestamp,
                                                          aRead,
                                                          aSubject,
                                                          aSmil,
@@ -215,16 +219,23 @@ MmsMessage::GetType(nsAString& aType)
 NS_IMETHODIMP
 MmsMessage::GetId(int32_t* aId)
 {
   *aId = mId;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+MmsMessage::GetThreadId(uint64_t* aThreadId)
+{
+  *aThreadId = mThreadId;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 MmsMessage::GetDelivery(nsAString& aDelivery)
 {
   switch (mDelivery) {
     case eDeliveryState_Received:
       aDelivery = DELIVERY_RECEIVED;
       break;
     case eDeliveryState_Sending:
       aDelivery = DELIVERY_SENDING;
--- a/dom/mobilemessage/src/MmsMessage.h
+++ b/dom/mobilemessage/src/MmsMessage.h
@@ -18,42 +18,45 @@ namespace dom {
 
 class MmsMessage MOZ_FINAL : public nsIDOMMozMmsMessage
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMMOZMMSMESSAGE
 
   MmsMessage(int32_t                                        aId,
+             const uint64_t                                 aThreadId,
              mobilemessage::DeliveryState                   aDelivery,
              const nsTArray<mobilemessage::DeliveryStatus>& aDeliveryStatus,
              const nsAString&                               aSender,
              const nsTArray<nsString>&                      aReceivers,
              uint64_t                                       aTimestamp,
              bool                                           aRead,
              const nsAString&                               aSubject,
              const nsAString&                               aSmil,
              const nsTArray<MmsAttachment>&                 aAttachments);
 
   static nsresult Create(int32_t               aId,
+                         const uint64_t        aThreadId,
                          const nsAString&      aDelivery,
                          const JS::Value&      aDeliveryStatus,
                          const nsAString&      aSender,
                          const JS::Value&      aReceivers,
                          const JS::Value&      aTimestamp,
                          bool                  aRead,
                          const nsAString&      aSubject,
                          const nsAString&      aSmil,
                          const JS::Value&      aAttachments,
                          JSContext*            aCx,
                          nsIDOMMozMmsMessage** aMessage);
 
 private:
 
   int32_t                                 mId;
+  uint64_t                                mThreadId;
   mobilemessage::DeliveryState            mDelivery;
   nsTArray<mobilemessage::DeliveryStatus> mDeliveryStatus;
   nsString                                mSender;
   nsTArray<nsString>                      mReceivers;
   uint64_t                                mTimestamp;
   bool                                    mRead;
   nsString                                mSubject;
   nsString                                mSmil;
--- a/dom/mobilemessage/src/MobileMessageService.cpp
+++ b/dom/mobilemessage/src/MobileMessageService.cpp
@@ -25,55 +25,59 @@ MobileMessageService::GetInstance()
   }
 
   nsRefPtr<MobileMessageService> service = sSingleton.get();
   return service.forget();
 }
 
 NS_IMETHODIMP
 MobileMessageService::CreateSmsMessage(int32_t aId,
+                                       uint64_t aThreadId,
                                        const nsAString& aDelivery,
                                        const nsAString& aDeliveryStatus,
                                        const nsAString& aSender,
                                        const nsAString& aReceiver,
                                        const nsAString& aBody,
                                        const nsAString& aMessageClass,
                                        const jsval& aTimestamp,
                                        const bool aRead,
                                        JSContext* aCx,
                                        nsIDOMMozSmsMessage** aMessage)
 {
   return SmsMessage::Create(aId,
+                            aThreadId,
                             aDelivery,
                             aDeliveryStatus,
                             aSender,
                             aReceiver,
                             aBody,
                             aMessageClass,
                             aTimestamp,
                             aRead,
                             aCx,
                             aMessage);
 }
 
 NS_IMETHODIMP
 MobileMessageService::CreateMmsMessage(int32_t               aId,
+                                       uint64_t              aThreadId,
                                        const nsAString&      aDelivery,
                                        const JS::Value&      aDeliveryStatus,
                                        const nsAString&      aSender,
                                        const JS::Value&      aReceivers,
                                        const JS::Value&      aTimestamp,
                                        bool                  aRead,
                                        const nsAString&      aSubject,
                                        const nsAString&      aSmil,
                                        const JS::Value&      aAttachments,
                                        JSContext*            aCx,
                                        nsIDOMMozMmsMessage** aMessage)
 {
   return MmsMessage::Create(aId,
+                            aThreadId,
                             aDelivery,
                             aDeliveryStatus,
                             aSender,
                             aReceivers,
                             aTimestamp,
                             aRead,
                             aSubject,
                             aSmil,
--- a/dom/mobilemessage/src/SmsMessage.cpp
+++ b/dom/mobilemessage/src/SmsMessage.cpp
@@ -21,36 +21,38 @@ NS_INTERFACE_MAP_BEGIN(SmsMessage)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSmsMessage)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(SmsMessage)
 NS_IMPL_RELEASE(SmsMessage)
 
 SmsMessage::SmsMessage(int32_t aId,
+                       const uint64_t aThreadId,
                        DeliveryState aDelivery,
                        DeliveryStatus aDeliveryStatus,
                        const nsString& aSender,
                        const nsString& aReceiver,
                        const nsString& aBody,
                        MessageClass aMessageClass,
                        uint64_t aTimestamp,
                        bool aRead)
-  : mData(aId, aDelivery, aDeliveryStatus, aSender, aReceiver, aBody,
+  : mData(aId, aThreadId, aDelivery, aDeliveryStatus, aSender, aReceiver, aBody,
           aMessageClass, aTimestamp, aRead)
 {
 }
 
 SmsMessage::SmsMessage(const SmsMessageData& aData)
   : mData(aData)
 {
 }
 
 /* static */ nsresult
 SmsMessage::Create(int32_t aId,
+                   const uint64_t aThreadId,
                    const nsAString& aDelivery,
                    const nsAString& aDeliveryStatus,
                    const nsAString& aSender,
                    const nsAString& aReceiver,
                    const nsAString& aBody,
                    const nsAString& aMessageClass,
                    const jsval& aTimestamp,
                    const bool aRead,
@@ -58,16 +60,17 @@ SmsMessage::Create(int32_t aId,
                    nsIDOMMozSmsMessage** aMessage)
 {
   *aMessage = nullptr;
 
   // SmsMessageData exposes these as references, so we can simply assign
   // to them.
   SmsMessageData data;
   data.id() = aId;
+  data.threadId() = aThreadId;
   data.sender() = nsString(aSender);
   data.receiver() = nsString(aReceiver);
   data.body() = nsString(aBody);
   data.read() = aRead;
 
   if (aDelivery.Equals(DELIVERY_RECEIVED)) {
     data.delivery() = eDeliveryState_Received;
   } else if (aDelivery.Equals(DELIVERY_SENDING)) {
@@ -145,16 +148,23 @@ SmsMessage::GetType(nsAString& aType)
 NS_IMETHODIMP
 SmsMessage::GetId(int32_t* aId)
 {
   *aId = mData.id();
   return NS_OK;
 }
 
 NS_IMETHODIMP
+SmsMessage::GetThreadId(uint64_t* aThreadId)
+{
+  *aThreadId = mData.threadId();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 SmsMessage::GetDelivery(nsAString& aDelivery)
 {
   switch (mData.delivery()) {
     case eDeliveryState_Received:
       aDelivery = DELIVERY_RECEIVED;
       break;
     case eDeliveryState_Sending:
       aDelivery = DELIVERY_SENDING;
--- a/dom/mobilemessage/src/SmsMessage.h
+++ b/dom/mobilemessage/src/SmsMessage.h
@@ -18,27 +18,29 @@ namespace dom {
 
 class SmsMessage MOZ_FINAL : public nsIDOMMozSmsMessage
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMMOZSMSMESSAGE
 
   SmsMessage(int32_t aId,
+             const uint64_t aThreadId,
              mobilemessage::DeliveryState aDelivery,
              mobilemessage::DeliveryStatus aDeliveryStatus,
              const nsString& aSender,
              const nsString& aReceiver,
              const nsString& aBody,
              mobilemessage::MessageClass aMessageClass,
              uint64_t aTimestamp,
              bool aRead);
   SmsMessage(const mobilemessage::SmsMessageData& aData);
 
   static nsresult Create(int32_t aId,
+                         const uint64_t aThreadId,
                          const nsAString& aDelivery,
                          const nsAString& aDeliveryStatus,
                          const nsAString& aSender,
                          const nsAString& aReceiver,
                          const nsAString& aBody,
                          const nsAString& aMessageClass,
                          const JS::Value& aTimestamp,
                          const bool aRead,
--- a/dom/mobilemessage/src/SmsRequest.cpp
+++ b/dom/mobilemessage/src/SmsRequest.cpp
@@ -530,16 +530,17 @@ SmsRequest::NotifyThreadList(const jsval
 
         MOZ_ASSERT(arrayEntry.isObject());
 
         SmsThreadListItem item;
         nsresult rv = item.Init(aCx, &arrayEntry);
         NS_ENSURE_SUCCESS(rv, rv);
 
         ThreadListItem* ipcItem = ipcItems.AppendElement();
+        ipcItem->id() = item.id;
         ipcItem->senderOrReceiver() = item.senderOrReceiver;
         ipcItem->timestamp() = item.timestamp;
         ipcItem->body() = item.body;
         ipcItem->unreadCount() = item.unreadCount;
       }
     }
 
     return SendMessageReply(reply);
@@ -585,16 +586,18 @@ SmsRequest::NotifyThreadList(const Infal
   JSObject* array = JS_NewArrayObject(cx, aItems.Length(), nullptr);
   NS_ENSURE_TRUE_VOID(array);
 
   bool ok;
 
   for (uint32_t i = 0; i < aItems.Length(); i++) {
     const ThreadListItem& source = aItems[i];
 
+    jsval id = JS_NumberValue(double(source.id()));
+
     nsString temp = source.senderOrReceiver();
 
     jsval senderOrReceiver;
     ok = xpc::StringToJsval(cx, temp, &senderOrReceiver);
     NS_ENSURE_TRUE_VOID(ok);
 
     JSObject* timestampObj = JS_NewDateObjectMsec(cx, source.timestamp());
     NS_ENSURE_TRUE_VOID(timestampObj);
@@ -607,16 +610,19 @@ SmsRequest::NotifyThreadList(const Infal
     ok = xpc::StringToJsval(cx, temp, &body);
     NS_ENSURE_TRUE_VOID(ok);
 
     jsval unreadCount = JS_NumberValue(double(source.unreadCount()));
 
     JSObject* elementObj = JS_NewObject(cx, nullptr, nullptr, nullptr);
     NS_ENSURE_TRUE_VOID(elementObj);
 
+    ok = JS_SetProperty(cx, elementObj, "id", &id);
+    NS_ENSURE_TRUE_VOID(ok);
+
     ok = JS_SetProperty(cx, elementObj, "senderOrReceiver", &senderOrReceiver);
     NS_ENSURE_TRUE_VOID(ok);
 
     ok = JS_SetProperty(cx, elementObj, "timestamp", &timestamp);
     NS_ENSURE_TRUE_VOID(ok);
 
     ok = JS_SetProperty(cx, elementObj, "body", &body);
     NS_ENSURE_TRUE_VOID(ok);
--- a/dom/mobilemessage/src/ipc/PSmsRequest.ipdl
+++ b/dom/mobilemessage/src/ipc/PSmsRequest.ipdl
@@ -82,16 +82,17 @@ struct ReplyMarkeMessageReadFail
 };
 
 struct ReplyNoMessageInList
 {
 };
 
 struct ThreadListItem
 {
+  uint64_t id;
   nsString senderOrReceiver;
   uint64_t timestamp;
   nsString body;
   uint64_t unreadCount;
 };
 
 struct ReplyThreadList
 {
--- a/dom/mobilemessage/src/ipc/SmsTypes.ipdlh
+++ b/dom/mobilemessage/src/ipc/SmsTypes.ipdlh
@@ -20,16 +20,17 @@ struct SmsSegmentInfoData
   int32_t segments;
   int32_t charsPerSegment;
   int32_t charsAvailableInLastSegment;
 };
 
 struct SmsMessageData
 {
   int32_t        id;
+  uint64_t       threadId;
   DeliveryState  delivery;
   DeliveryStatus deliveryStatus;
   nsString       sender;
   nsString       receiver;
   nsString       body;
   MessageClass   messageClass;
   uint64_t       timestamp; // ms since epoch.
   bool           read;
--- a/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js
+++ b/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js
@@ -559,16 +559,17 @@ MobileMessageDatabaseService.prototype =
   },
 
   createDomMessageFromRecord: function createDomMessageFromRecord(aMessageRecord) {
     if (DEBUG) {
       debug("createDomMessageFromRecord: " + JSON.stringify(aMessageRecord));
     }
     if (aMessageRecord.type == "sms") {
       return gMobileMessageService.createSmsMessage(aMessageRecord.id,
+                                                    aMessageRecord.threadId,
                                                     aMessageRecord.delivery,
                                                     aMessageRecord.deliveryStatus,
                                                     aMessageRecord.sender,
                                                     aMessageRecord.receiver,
                                                     aMessageRecord.body,
                                                     aMessageRecord.messageClass,
                                                     aMessageRecord.timestamp,
                                                     aMessageRecord.read);
@@ -603,16 +604,17 @@ MobileMessageDatabaseService.prototype =
           attachments.push({
             "id": partHeaders["content-id"],
             "location": partHeaders["content-location"],
             "content": partContent
           });
         }
       }
       return gMobileMessageService.createMmsMessage(aMessageRecord.id,
+                                                    aMessageRecord.threadId,
                                                     aMessageRecord.delivery,
                                                     aMessageRecord.deliveryStatus,
                                                     aMessageRecord.sender,
                                                     aMessageRecord.receivers,
                                                     aMessageRecord.timestamp,
                                                     aMessageRecord.read,
                                                     subject,
                                                     smil,
@@ -1924,16 +1926,17 @@ MobileMessageDatabaseService.prototype =
         aRequest.notifyThreadListFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
       };
       let request = threadStore.index("lastTimestamp").mozGetAll();
       request.onsuccess = function(event) {
         // TODO: keep backward compatibility of original API interface only.
         let results = [];
         for each (let item in event.target.result) {
           results.push({
+            id: item.id,
             senderOrReceiver: item.participantAddresses[0],
             timestamp: item.lastTimestamp,
             body: item.subject,
             unreadCount: item.unreadCount
           });
         }
         aRequest.notifyThreadList(results);
       };
--- a/dom/mobilemessage/tests/marionette/test_getmessage.js
+++ b/dom/mobilemessage/tests/marionette/test_getmessage.js
@@ -11,16 +11,18 @@ const EMULATOR = "15555215554"; // the e
 
 let sms = window.navigator.mozSms;
 let inText = "Incoming SMS message. Mozilla Firefox OS!";
 let outText = "Outgoing SMS message. Mozilla Firefox OS!";
 let gotSmsOnsent = false;
 let gotReqOnsuccess = false;
 let inSmsId = 0;
 let outSmsId = 0;
+let inThreadId = 0;
+let outThreadId = 0;
 let inSmsTimeStamp;
 let outSmsTimeStamp;
 
 function verifyInitialState() {
   log("Verifying initial state.");
   ok(sms, "mozSms");
   simulateIncomingSms();  
 }
@@ -30,16 +32,18 @@ function simulateIncomingSms() {
 
   sms.onreceived = function onreceived(event) {
     log("Received 'onreceived' smsmanager event.");
     let incomingSms = event.message;
     ok(incomingSms, "incoming sms");
     ok(incomingSms.id, "sms id");
     inSmsId = incomingSms.id;
     log("Received SMS (id: " + inSmsId + ").");
+    ok(incomingSms.threadId, "thread id");
+    inThreadId = incomingSms.threadId;
     is(incomingSms.body, inText, "msg body");
     is(incomingSms.delivery, "received", "delivery");
     is(incomingSms.deliveryStatus, "success", "deliveryStatus");
     is(incomingSms.read, false, "read");
     is(incomingSms.receiver, EMULATOR, "receiver");
     is(incomingSms.sender, REMOTE, "sender");
     is(incomingSms.messageClass, "normal", "messageClass");
     ok(incomingSms.timestamp instanceof Date, "timestamp is instanceof date");
@@ -57,16 +61,18 @@ function sendSms() {
   sms.onsent = function(event) {
     log("Received 'onsent' smsmanager event.");
     gotSmsOnsent = true;
     let sentSms = event.message;
     ok(sentSms, "outgoing sms");
     ok(sentSms.id, "sms id");
     outSmsId = sentSms.id;
     log("Sent SMS (id: " + outSmsId + ").");
+    ok(sentSms.threadId, "thread id");
+    outThreadId = sentSms.threadId;
     is(sentSms.body, outText, "msg body");
     is(sentSms.delivery, "sent", "delivery");
     is(sentSms.deliveryStatus, "pending", "deliveryStatus");
     is(sentSms.read, true, "read");
     is(sentSms.receiver, REMOTE, "receiver");
     is(sentSms.sender, EMULATOR, "sender");
     is(sentSms.messageClass, "normal", "messageClass");
     ok(sentSms.timestamp instanceof Date, "timestamp is instanceof date");  
@@ -106,16 +112,17 @@ function getReceivedSms() {
   ok(requestRet, "smsrequest obj returned");
 
   requestRet.onsuccess = function(event) {
     log("Received 'onsuccess' smsrequest event.");
     ok(event.target.result, "smsrequest event.target.result");
     let foundSms = event.target.result;
     is(foundSms.id, inSmsId, "SMS id matches");
     log("Got SMS (id: " + foundSms.id + ").");
+    is(foundSms.threadId, inThreadId, "thread id matches");
     is(foundSms.body, inText, "SMS msg text matches");
     is(foundSms.delivery, "received", "delivery");
     is(foundSms.deliveryStatus, "success", "deliveryStatus");
     is(foundSms.read, false, "read");
     is(foundSms.receiver, EMULATOR, "receiver");
     is(foundSms.sender, REMOTE, "sender");
     is(foundSms.messageClass, "normal", "messageClass");
     ok(foundSms.timestamp instanceof Date, "timestamp is instanceof date");
@@ -139,16 +146,17 @@ function getSentSms() {
   ok(requestRet, "smsrequest obj returned");
 
   requestRet.onsuccess = function(event) {
     log("Received 'onsuccess' smsrequest event.");
     ok(event.target.result, "smsrequest event.target.result");
     let foundSms = event.target.result;
     is(foundSms.id, outSmsId, "SMS id matches");
     log("Got SMS (id: " + foundSms.id + ").");
+    is(foundSms.threadId, outThreadId, "thread id matches");
     is(foundSms.body, outText, "SMS msg text matches");
     is(foundSms.delivery, "sent", "delivery");
     is(foundSms.deliveryStatus, "pending", "deliveryStatus");
     is(foundSms.read, true, "read");
     is(foundSms.receiver, REMOTE, "receiver");
     is(foundSms.sender, EMULATOR, "sender");
     is(foundSms.messageClass, "normal", "messageClass");
     ok(foundSms.timestamp instanceof Date, "timestamp is instanceof date");
--- a/dom/mobilemessage/tests/marionette/test_getmessages.js
+++ b/dom/mobilemessage/tests/marionette/test_getmessages.js
@@ -185,16 +185,17 @@ function getMsgs(reverse) {
 }
 
 function verifyFoundMsgs(foundSmsList, reverse) {
   if (reverse) {
     smsList.reverse();
   }
   for (var x = 0; x < numberMsgs; x++) {
     is(foundSmsList[x].id, smsList[x].id, "id");
+    is(foundSmsList[x].threadId, smsList[x].threadId, "thread id");
     is(foundSmsList[x].body, smsList[x].body, "body");
     is(foundSmsList[x].delivery, smsList[x].delivery, "delivery");
     is(foundSmsList[x].read, smsList[x].read, "read");
 
     // Bug 805799: receiver null when onreceived event is fired, until do a
     // getMessage. Default emulator (receiver) phone number is 15555215554
     if (!smsList[x].receiver) {
       isIn(foundSmsList[x].receiver, ["15555215554", "+15555215554"], "receiver");
--- a/dom/mobilemessage/tests/marionette/test_incoming.js
+++ b/dom/mobilemessage/tests/marionette/test_incoming.js
@@ -21,16 +21,17 @@ runEmulatorCmd("sms send " + SENDER + " 
 });
 
 sms.onreceived = function onreceived(event) {
   log("Received an SMS!");
 
   let message = event.message;
   ok(message instanceof MozSmsMessage);
 
+  ok(message.threadId, "thread id");
   is(message.delivery, "received");
   is(message.deliveryStatus, "success");
   is(message.sender, SENDER);
   is(message.receiver, RECEIVER);
   is(message.body, body);
   is(message.messageClass, "normal");
   ok(message.timestamp instanceof Date);
   // SMSC timestamp is in seconds.
--- a/dom/mobilemessage/tests/marionette/test_incoming_delete.js
+++ b/dom/mobilemessage/tests/marionette/test_incoming_delete.js
@@ -22,16 +22,17 @@ function simulateIncomingSms() {
   log("Simulating incoming SMS.");
 
   sms.onreceived = function onreceived(event) {
     log("Received 'onreceived' smsmanager event.");
     let incomingSms = event.message;
     ok(incomingSms, "incoming sms");
     ok(incomingSms.id, "sms id");
     log("Received SMS (id: " + incomingSms.id + ").");
+    ok(incomingSms.threadId, "thread id");
     is(incomingSms.body, msgText, "msg body");
     is(incomingSms.delivery, "received", "delivery");
     is(incomingSms.deliveryStatus, "success", "deliveryStatus");
     is(incomingSms.read, false, "read");
     is(incomingSms.receiver, RECEIVER, "receiver");
     is(incomingSms.sender, SENDER, "sender");
     is(incomingSms.messageClass, "normal", "messageClass");
     ok(incomingSms.timestamp instanceof Date, "timestamp is istanceof date");
@@ -48,16 +49,17 @@ function verifySmsExists(incomingSms) {
   let requestRet = sms.getMessage(incomingSms.id);
   ok(requestRet, "smsrequest obj returned");
 
   requestRet.onsuccess = function(event) {
     log("Received 'onsuccess' smsrequest event.");
     ok(event.target.result, "smsrequest event.target.result");
     let foundSms = event.target.result;
     is(foundSms.id, incomingSms.id, "found SMS id matches");
+    is(foundSms.threadId, incomingSms.threadId, "found SMS thread id matches");
     is(foundSms.body, msgText, "found SMS msg text matches");
     is(foundSms.delivery, "received", "delivery");
     is(foundSms.deliveryStatus, "success", "deliveryStatus");
     is(foundSms.read, false, "read");
     is(foundSms.receiver, RECEIVER, "receiver");
     is(foundSms.sender, SENDER, "sender");
     is(foundSms.messageClass, "normal", "messageClass");
     log("Got SMS (id: " + foundSms.id + ") as expected.");
--- a/dom/mobilemessage/tests/marionette/test_incoming_multipart.js
+++ b/dom/mobilemessage/tests/marionette/test_incoming_multipart.js
@@ -28,16 +28,17 @@ function simulateIncomingSms() {
   }
 
   sms.onreceived = function onreceived(event) {
     log("Received 'onreceived' smsmanager event.");
     let incomingSms = event.message;
     ok(incomingSms, "incoming sms");
     ok(incomingSms.id, "sms id");
     log("Received SMS (id: " + incomingSms.id + ").");
+    ok(incomingSms.threadId, "thread id");
     is(incomingSms.body, msgText, "msg body");
     is(incomingSms.delivery, "received", "delivery");
     is(incomingSms.read, false, "read");
     is(incomingSms.receiver, RECEIVER, "receiver");
     is(incomingSms.sender, SENDER, "sender");
     ok(incomingSms.timestamp instanceof Date, "timestamp is istanceof date");
 
     verifySmsExists(incomingSms);
@@ -52,16 +53,17 @@ function verifySmsExists(incomingSms) {
   let requestRet = sms.getMessage(incomingSms.id);
   ok(requestRet, "smsrequest obj returned");
 
   requestRet.onsuccess = function(event) {
     log("Received 'onsuccess' smsrequest event.");
     ok(event.target.result, "smsrequest event.target.result");
     let foundSms = event.target.result;
     is(foundSms.id, incomingSms.id, "found SMS id matches");
+    is(foundSms.threadId, incomingSms.threadId, "found SMS thread id matches");
     is(foundSms.body, incomingSms.body, "found SMS msg text matches");
     is(foundSms.delivery, "received", "delivery");
     is(foundSms.read, false, "read");
     is(foundSms.receiver, RECEIVER, "receiver");
     is(foundSms.sender, SENDER, "sender");
     log("Got SMS (id: " + foundSms.id + ") as expected.");
     deleteSms(incomingSms);
   };
--- a/dom/mobilemessage/tests/marionette/test_message_classes.js
+++ b/dom/mobilemessage/tests/marionette/test_message_classes.js
@@ -26,23 +26,28 @@ function sendSmsPduToEmulator(pdu) {
   runEmulatorCmd(cmd, function (result) {
     --pendingEmulatorCmdCount;
 
     is(result[0], "OK", "Emulator response");
   });
 }
 
 const TIMESTAMP = Date.UTC(2000, 0, 1);
-function checkMessage(message, id, messageClass) {
+function checkMessage(message, id, threadId, messageClass) {
   ok(message instanceof MozSmsMessage,
      "message is instanceof " + message.constructor);
   if (id == null) {
     ok(message.id > 0, "message.id");
   } else {
-    is(message.id, -1, "message.id");
+    is(message.id, id, "message.id");
+  }
+  if (threadId == null) {
+    ok(message.threadId > 0, "message.threadId");
+  } else {
+    is(message.threadId, threadId, "message.threadId");
   }
   is(message.delivery, "received", "message.delivery");
   is(message.deliveryStatus, "success", "message.deliveryStatus");
   is(message.sender, "+1", "message.sender");
   is(message.body, "A", "message.body");
   is(message.messageClass, messageClass, "message.messageClass");
   ok(message.timestamp instanceof Date,
      "message.timestamp is instanceof " + message.timestamp.constructor);
@@ -57,17 +62,17 @@ function test_message_class_0() {
     "F0"  // (no name) Group: 1111
   ];
 
   function do_test(dcsIndex) {
     sms.addEventListener("received", function onReceived(event) {
       sms.removeEventListener("received", onReceived);
 
       let message = event.message;
-      checkMessage(message, -1, "class-0");
+      checkMessage(message, -1, 0, "class-0");
 
       // Make sure the message is not stored.
       let request = sms.getMessages(null, false);
       request.onsuccess = function onsuccess() {
         let cursor = request.result;
         if (cursor.message) {
           // Here we check whether there is any message of the same sender.
           isnot(cursor.message.sender, message.sender, "cursor.message.sender");
@@ -102,17 +107,17 @@ function test_message_class_0() {
 }
 
 function doTestMessageClassGeneric(allDCSs, messageClass, next) {
   function do_test(dcsIndex) {
     sms.addEventListener("received", function onReceived(event) {
       sms.removeEventListener("received", onReceived);
 
       // Make sure we can correctly receive the message
-      checkMessage(event.message, null, messageClass);
+      checkMessage(event.message, null, null, messageClass);
 
       ++dcsIndex;
       if (dcsIndex >= allDCSs.length) {
         window.setTimeout(next, 0);
       } else {
         window.setTimeout(do_test.bind(null, dcsIndex), 0);
       }
     });
@@ -152,17 +157,17 @@ function test_message_class_2() {
     PDU_PID_USIM_DATA_DOWNLOAD
   ];
 
   function do_test_dcs(dcsIndex) {
     function do_test_pid(pidIndex) {
       function onReceived(event) {
         if (pidIndex == 0) {
           // Make sure we can correctly receive the message
-          checkMessage(event.message, null, "class-2");
+          checkMessage(event.message, null, null, "class-2");
 
           next();
           return;
         }
 
         // TODO: Bug 792798 - B2G SMS: develop test cases for Message Class 2
         // Since we have "data download via SMS Point-to-Point" service enabled
         // but no working implementation in emulator SIM, all class 2 messages
--- a/dom/mobilemessage/tests/marionette/test_outgoing.js
+++ b/dom/mobilemessage/tests/marionette/test_outgoing.js
@@ -27,16 +27,17 @@ const LONG_BODY = "Let me not to the mar
                 + "I never writ, nor no man ever loved. ";
 
 function checkMessage(message, delivery, body) {
   ok(message, "message is valid");
   ok(message instanceof MozSmsMessage,
      "message is instanceof " + message.constructor);
 
   ok(message.id, "message.id");
+  ok(message.threadId, "message.threadId");
   is(message.delivery, delivery, "message.delivery");
   is(message.deliveryStatus, "pending", "message.deliveryStatus");
   is(message.sender, SENDER, "message.sender");
   ok(message.receiver, "message.receiver");
   is(message.body, body, "message.body");
   is(message.messageClass, "normal", "message.messageClass");
   ok(message.timestamp instanceof Date,
      "message.timestamp is instanceof " + message.timestamp.constructor);
--- a/dom/mobilemessage/tests/marionette/test_outgoing_delete.js
+++ b/dom/mobilemessage/tests/marionette/test_outgoing_delete.js
@@ -27,16 +27,17 @@ function sendSms() {
   sms.onsent = function(event) {
     log("Received 'onsent' smsmanager event.");
     gotSmsOnsent = true;
     let sentSms = event.message;
     ok(sentSms, "outgoing sms");
     ok(sentSms.id, "sms id");
     smsId = sentSms.id;
     log("Sent SMS (id: " + smsId + ").");
+    ok(sentSms.threadId, "thread id");
     is(sentSms.body, msgText, "msg body");
     is(sentSms.delivery, "sent", "delivery");
     is(sentSms.deliveryStatus, "pending", "deliveryStatus");
     is(sentSms.read, true, "read");
     is(sentSms.receiver, RECEIVER, "receiver");
     is(sentSms.sender, SENDER, "sender");
     is(sentSms.messageClass, "normal", "messageClass");
     ok(sentSms.timestamp instanceof Date, "timestamp is istanceof date");
--- a/dom/mobilemessage/tests/test_smsservice_createsmsmessage.js
+++ b/dom/mobilemessage/tests/test_smsservice_createsmsmessage.js
@@ -27,41 +27,45 @@ function newMessage() {
 function run_test() {
   run_next_test();
 }
 
 /**
  * Ensure an SmsMessage object created has sensible initial values.
  */
 add_test(function test_interface() {
-  let sms = newMessage(null, "sent", "pending", null, null, null, "normal",
-                       new Date(), true);
+  let sms = newMessage(null, null, "sent", "pending", null, null, null,
+                       "normal", new Date(), true);
   do_check_true(sms instanceof Ci.nsIDOMMozSmsMessage);
   do_check_eq(sms.id, 0);
+  do_check_eq(sms.threadId, 0);
   do_check_eq(sms.delivery, "sent");
   do_check_eq(sms.deliveryStatus, "pending");
   do_check_eq(sms.receiver, null);
   do_check_eq(sms.sender, null);
   do_check_eq(sms.body, null);
   do_check_eq(sms.messageClass, "normal");
   do_check_true(sms.timestamp instanceof Date);
   do_check_true(sms.read);
   run_next_test();
 });
 
 /**
  * Verify that attributes are read-only.
  */
 add_test(function test_readonly_attributes() {
-  let sms = newMessage(null, "received", "success", null, null, null,
+  let sms = newMessage(null, null, "received", "success", null, null, null,
                        "normal", new Date(), true);
 
   sms.id = 1;
   do_check_eq(sms.id, 0);
 
+  sms.threadId = 1;
+  do_check_eq(sms.threadId, 0);
+
   sms.delivery = "sent";
   do_check_eq(sms.delivery, "received");
 
   sms.deliveryStatus = "pending";
   do_check_eq(sms.deliveryStatus, "success");
 
   sms.receiver = "a receiver";
   do_check_eq(sms.receiver, null);
@@ -85,19 +89,20 @@ add_test(function test_readonly_attribut
   run_next_test();
 });
 
 /**
  * Test supplying the timestamp as a number of milliseconds.
  */
 add_test(function test_timestamp_number() {
   let ts = Date.now();
-  let sms = newMessage(42, "sent", "pending", "the sender", "the receiver",
+  let sms = newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
                        "the body", "normal", ts, true);
   do_check_eq(sms.id, 42);
+  do_check_eq(sms.threadId, 1);
   do_check_eq(sms.delivery, "sent");
   do_check_eq(sms.deliveryStatus, "pending");
   do_check_eq(sms.sender, "the sender");
   do_check_eq(sms.receiver, "the receiver");
   do_check_eq(sms.body, "the body");
   do_check_eq(sms.messageClass, "normal");
   do_check_true(sms.timestamp instanceof Date);
   do_check_eq(sms.timestamp.getTime(), ts);
@@ -105,19 +110,20 @@ add_test(function test_timestamp_number(
   run_next_test();
 });
 
 /**
  * Test supplying the timestamp as a Date object.
  */
 add_test(function test_timestamp_date() {
   let date = new Date();
-  let sms = newMessage(42, "sent", "pending", "the sender", "the receiver",
+  let sms = newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
                        "the body", "normal", date, true);
   do_check_eq(sms.id, 42);
+  do_check_eq(sms.threadId, 1);
   do_check_eq(sms.delivery, "sent");
   do_check_eq(sms.deliveryStatus, "pending");
   do_check_eq(sms.sender, "the sender");
   do_check_eq(sms.receiver, "the receiver");
   do_check_eq(sms.body, "the body");
   do_check_eq(sms.messageClass, "normal");
   do_check_true(sms.timestamp instanceof Date);
   do_check_eq(sms.timestamp.getTime(), date.getTime());
@@ -125,112 +131,112 @@ add_test(function test_timestamp_date() 
   run_next_test();
 });
 
 /**
  * Test that a floating point number for the timestamp is not allowed.
  */
 add_test(function test_invalid_timestamp_float() {
   do_check_throws(function() {
-    newMessage(42, "sent", "pending", "the sender", "the receiver", "the body",
-               "normal", 3.1415, true);
+    newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
+               "the body", "normal", 3.1415, true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that a null value for the timestamp is not allowed.
  */
 add_test(function test_invalid_timestamp_null() {
   do_check_throws(function() {
-    newMessage(42, "sent", "pending", "the sender", "the receiver", "the body",
-               "normal", null, true);
+    newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
+               "the body", "normal", null, true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that undefined for the timestamp is not allowed.
  */
 add_test(function test_invalid_timestamp_undefined() {
   do_check_throws(function() {
-    newMessage(42, "sent", "pending", "the sender", "the receiver", "the body",
-               "normal", undefined, true);
+    newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
+               "the body", "normal", undefined, true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that a random object for the timestamp is not allowed.
  */
 add_test(function test_invalid_timestamp_object() {
   do_check_throws(function() {
-    newMessage(42, "sent", "pending", "the sender", "the receiver", "the body",
-               "normal", {}, true);
+    newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
+               "the body", "normal", {}, true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that an invalid delivery string is not accepted.
  */
 add_test(function test_invalid_delivery_string() {
   do_check_throws(function() {
-    newMessage(42, "this is invalid", "pending", "the sender", "the receiver",
-               "the body", "normal", new Date(), true);
+    newMessage(42, 1, "this is invalid", "pending", "the sender",
+               "the receiver", "the body", "normal", new Date(), true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that a number is not accepted for the 'delivery' argument.
  */
 add_test(function test_invalid_delivery_string() {
   do_check_throws(function() {
-    newMessage(42, 1, "pending", "the sender", "the receiver", "the body",
+    newMessage(42, 1, 1, "pending", "the sender", "the receiver", "the body",
                "normal", new Date(), true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that an invalid delivery status string is not accepted.
  */
 add_test(function test_invalid_delivery_status_string() {
   do_check_throws(function() {
-    newMessage(42, "sent", "this is invalid", "the sender", "the receiver",
+    newMessage(42, 1, "sent", "this is invalid", "the sender", "the receiver",
                "the body", "normal", new Date(), true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that a number is not accepted for the 'deliveryStatus' argument.
  */
 add_test(function test_invalid_delivery_status_string() {
   do_check_throws(function() {
-    newMessage(42, "sent", 1, "the sender", "the receiver", "the body",
+    newMessage(42, 1, "sent", 1, "the sender", "the receiver", "the body",
                "normal", new Date(), true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that an invalid message class string is not accepted.
  */
 add_test(function test_invalid_message_class_string() {
   do_check_throws(function() {
-    newMessage(42, "sent", "pending", "the sender", "the receiver",
+    newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
                "the body", "this is invalid", new Date(), true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
 
 /**
  * Test that a number is not accepted for the 'messageClass' argument.
  */
 add_test(function test_invalid_message_class_string() {
   do_check_throws(function() {
-    newMessage(42, "sent", "pending", "the sender", "the receiver", "the body",
-               1, new Date(), true);
+    newMessage(42, 1, "sent", "pending", "the sender", "the receiver",
+               "the body", 1, new Date(), true);
   }, Cr.NS_ERROR_INVALID_ARG);
   run_next_test();
 });
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1408,16 +1408,17 @@ RadioInterfaceLayer.prototype = {
     debug("Broadcasting the SMS system message: " + aName);
 
     // Sadly we cannot directly broadcast the aDomMessage object
     // because the system message mechamism will rewrap the object
     // based on the content window, which needs to know the properties.
     gSystemMessenger.broadcastMessage(aName, {
       type:           aDomMessage.type,
       id:             aDomMessage.id,
+      threadId:       aDomMessage.threadId,
       delivery:       aDomMessage.delivery,
       deliveryStatus: aDomMessage.deliveryStatus,
       sender:         aDomMessage.sender,
       receiver:       aDomMessage.receiver,
       body:           aDomMessage.body,
       messageClass:   aDomMessage.messageClass,
       timestamp:      aDomMessage.timestamp.getTime(),
       read:           aDomMessage.read
@@ -1488,22 +1489,24 @@ RadioInterfaceLayer.prototype = {
       Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null);
     }.bind(this);
 
     if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
       message.id = gMobileMessageDatabaseService.saveReceivedMessage(message,
                                                                      notifyReceived);
     } else {
       message.id = -1;
+      message.threadId = 0;
       message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED;
       message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
       message.read = false;
 
       let domMessage =
         gMobileMessageService.createSmsMessage(message.id,
+                                               message.threadId,
                                                message.delivery,
                                                message.deliveryStatus,
                                                message.sender,
                                                message.receiver,
                                                message.body,
                                                message.messageClass,
                                                message.timestamp,
                                                message.read);
--- a/widget/android/AndroidJNI.cpp
+++ b/widget/android/AndroidJNI.cpp
@@ -205,17 +205,18 @@ Java_org_mozilla_gecko_GeckoAppShell_not
         obs->NotifyObservers(message, kSmsReceivedObserverTopic, nullptr);
         return NS_OK;
       }
 
     private:
       SmsMessageData mMessageData;
     };
 
-    SmsMessageData message(0, eDeliveryState_Received, eDeliveryStatus_Success,
+    // TODO Need to correct the message `threadId` parameter value. Bug 859098
+    SmsMessageData message(0, 0, eDeliveryState_Received, eDeliveryStatus_Success,
                            nsJNIString(aSender, jenv), EmptyString(),
                            nsJNIString(aBody, jenv),
                            static_cast<MessageClass>(aMessageClass),
                            aTimestamp, false);
 
     nsCOMPtr<nsIRunnable> runnable = new NotifySmsReceivedRunnable(message);
     NS_DispatchToMainThread(runnable);
 }
@@ -258,17 +259,18 @@ Java_org_mozilla_gecko_GeckoAppShell_not
       }
 
     private:
       SmsMessageData mMessageData;
       int32_t        mRequestId;
     };
 
     // TODO Need to add the message `messageClass` parameter value. Bug 804476
-    SmsMessageData message(aId, eDeliveryState_Sent, eDeliveryStatus_Pending,
+    // TODO Need to correct the message `threadId` parameter value. Bug 859098
+    SmsMessageData message(aId, 0, eDeliveryState_Sent, eDeliveryStatus_Pending,
                            EmptyString(), nsJNIString(aReceiver, jenv),
                            nsJNIString(aBody, jenv), eMessageClass_Normal,
                            aTimestamp, true);
 
     nsCOMPtr<nsIRunnable> runnable = new NotifySmsSentRunnable(message, aRequestId);
     NS_DispatchToMainThread(runnable);
 }
 
@@ -301,17 +303,18 @@ Java_org_mozilla_gecko_GeckoAppShell_not
         return NS_OK;
       }
 
     private:
       SmsMessageData mMessageData;
     };
 
     // TODO Need to add the message `messageClass` parameter value. Bug 804476
-    SmsMessageData message(aId, eDeliveryState_Sent,
+    // TODO Need to correct the message `threadId` parameter value. Bug 859098
+    SmsMessageData message(aId, 0, eDeliveryState_Sent,
                            static_cast<DeliveryStatus>(aDeliveryStatus),
                            EmptyString(), nsJNIString(aReceiver, jenv),
                            nsJNIString(aBody, jenv), eMessageClass_Normal,
                            aTimestamp, true);
 
     nsCOMPtr<nsIRunnable> runnable = new NotifySmsDeliveredRunnable(message);
     NS_DispatchToMainThread(runnable);
 }
@@ -383,17 +386,18 @@ Java_org_mozilla_gecko_GeckoAppShell_not
     };
 
     nsJNIString receiver = nsJNIString(aReceiver, jenv);
     DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
                                              : eDeliveryState_Sent;
 
     // TODO Need to add the message `read` parameter value. Bug 748391
     // TODO Need to add the message `messageClass` parameter value. Bug 804476
-    SmsMessageData message(aId, state,
+    // TODO Need to correct the message `threadId` parameter value. Bug 859098
+    SmsMessageData message(aId, 0, state,
                            static_cast<DeliveryStatus>(aDeliveryStatus),
                            nsJNIString(aSender, jenv), receiver,
                            nsJNIString(aBody, jenv), eMessageClass_Normal,
                            aTimestamp, true);
 
     nsCOMPtr<nsIRunnable> runnable = new NotifyGetSmsRunnable(message, aRequestId);
     NS_DispatchToMainThread(runnable);
 }
@@ -564,17 +568,18 @@ Java_org_mozilla_gecko_GeckoAppShell_not
 
 
     nsJNIString receiver = nsJNIString(aReceiver, jenv);
     DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
                                              : eDeliveryState_Sent;
 
     // TODO Need to add the message `read` parameter value. Bug 748391
     // TODO Need to add the message `messageClass` parameter value. Bug 804476
-    SmsMessageData message(aMessageId, state,
+    // TODO Need to correct the message `threadId` parameter value. Bug 859098
+    SmsMessageData message(aMessageId, 0, state,
                            static_cast<DeliveryStatus>(aDeliveryStatus),
                            nsJNIString(aSender, jenv), receiver,
                            nsJNIString(aBody, jenv), eMessageClass_Normal,
                            aTimestamp, true);
 
     nsCOMPtr<nsIRunnable> runnable =
       new NotifyCreateMessageListRunnable(aListId, message, aRequestId);
     NS_DispatchToMainThread(runnable);
@@ -615,17 +620,18 @@ Java_org_mozilla_gecko_GeckoAppShell_not
 
 
     nsJNIString receiver = nsJNIString(aReceiver, jenv);
     DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
                                              : eDeliveryState_Sent;
 
     // TODO Need to add the message `read` parameter value. Bug 748391
     // TODO Need to add the message `messageClass` parameter value. Bug 804476
-    SmsMessageData message(aMessageId, state,
+    // TODO Need to correct the message `threadId` parameter value. Bug 859098
+    SmsMessageData message(aMessageId, 0, state,
                            static_cast<DeliveryStatus>(aDeliveryStatus),
                            nsJNIString(aSender, jenv), receiver,
                            nsJNIString(aBody, jenv), eMessageClass_Normal,
                            aTimestamp, true);
 
     nsCOMPtr<nsIRunnable> runnable =
       new NotifyGotNextMessageRunnable(message, aRequestId);
     NS_DispatchToMainThread(runnable);