Bug 810099 - B2G MMS: support onretrieving event. r=vyang
authorChia-hung Tai <ctai@mozilla.com>
Fri, 10 May 2013 13:39:22 -0700
changeset 133808 457c9f9544bdee85397a8e38b09482828657ee70
parent 133807 a3fcf6de63880602780b741967f3ec202f40cda6
child 133809 5b571c577bdcd8c0fb7e7cf9c435e59def57c2d0
push id28905
push userryanvm@gmail.com
push dateMon, 03 Jun 2013 15:58:12 +0000
treeherdermozilla-inbound@d2eabe8e27b5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvyang
bugs810099
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 810099 - B2G MMS: support onretrieving event. r=vyang
content/base/src/nsGkAtomList.h
dom/mobilemessage/src/Constants.cpp
dom/mobilemessage/src/Constants.h
dom/mobilemessage/src/MobileMessageManager.cpp
dom/mobilemessage/src/ipc/PSms.ipdl
dom/mobilemessage/src/ipc/SmsChild.cpp
dom/mobilemessage/src/ipc/SmsChild.h
dom/mobilemessage/src/ipc/SmsParent.cpp
dom/mobilemessage/src/ril/MmsService.js
dom/mobilemessage/src/ril/MobileMessageDatabaseService.js
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -757,16 +757,17 @@ GK_ATOM(onpageshow, "onpageshow")
 GK_ATOM(onpaint, "onpaint")
 GK_ATOM(onpaste, "onpaste")
 GK_ATOM(onpopuphidden, "onpopuphidden")
 GK_ATOM(onpopuphiding, "onpopuphiding")
 GK_ATOM(onpopupshowing, "onpopupshowing")
 GK_ATOM(onpopupshown, "onpopupshown")
 GK_ATOM(onreadystatechange, "onreadystatechange")
 GK_ATOM(onreceived, "onreceived")
+GK_ATOM(onretrieving, "onretrieving")
 GK_ATOM(onRequest, "onRequest")
 GK_ATOM(onreset, "onreset")
 GK_ATOM(onresuming, "onresuming")
 GK_ATOM(onMozBeforeResize, "onMozBeforeResize")
 GK_ATOM(onresize, "onresize")
 GK_ATOM(onscroll, "onscroll")
 GK_ATOM(onselect, "onselect")
 GK_ATOM(onsending, "onsending")
--- a/dom/mobilemessage/src/Constants.cpp
+++ b/dom/mobilemessage/src/Constants.cpp
@@ -3,16 +3,17 @@
  * 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/. */
 
 namespace mozilla {
 namespace dom {
 namespace mobilemessage {
 
 const char* kSmsReceivedObserverTopic        = "sms-received";
+const char* kSmsRetrievingObserverTopic      = "sms-retrieving";
 const char* kSmsSendingObserverTopic         = "sms-sending";
 const char* kSmsSentObserverTopic            = "sms-sent";
 const char* kSmsFailedObserverTopic          = "sms-failed";
 const char* kSmsDeliverySuccessObserverTopic = "sms-delivery-success";
 const char* kSmsDeliveryErrorObserverTopic   = "sms-delivery-error";
 
 } // namespace mobilemessage
 } // namespace dom
--- a/dom/mobilemessage/src/Constants.h
+++ b/dom/mobilemessage/src/Constants.h
@@ -7,16 +7,17 @@
 #define mozilla_dom_mobilemessage_Constants_h
 
 namespace mozilla {
 namespace dom {
 namespace mobilemessage {
 
 // Defined in the .cpp.
 extern const char* kSmsReceivedObserverTopic;
+extern const char* kSmsRetrievingObserverTopic;
 extern const char* kSmsSendingObserverTopic;
 extern const char* kSmsSentObserverTopic;
 extern const char* kSmsFailedObserverTopic;
 extern const char* kSmsDeliverySuccessObserverTopic;
 extern const char* kSmsDeliveryErrorObserverTopic;
 
 extern const char* kMmsSendingObserverTopic;
 extern const char* kMmsSentObserverTopic;
--- a/dom/mobilemessage/src/MobileMessageManager.cpp
+++ b/dom/mobilemessage/src/MobileMessageManager.cpp
@@ -25,16 +25,17 @@
 #include "GeneratedEvents.h"
 #include "DOMRequest.h"
 #include "nsIMobileMessageCallback.h"
 #include "MobileMessageCallback.h"
 #include "MobileMessageCursorCallback.h"
 #include "DOMCursor.h"
 
 #define RECEIVED_EVENT_NAME         NS_LITERAL_STRING("received")
+#define RETRIEVING_EVENT_NAME       NS_LITERAL_STRING("retrieving")
 #define SENDING_EVENT_NAME          NS_LITERAL_STRING("sending")
 #define SENT_EVENT_NAME             NS_LITERAL_STRING("sent")
 #define FAILED_EVENT_NAME           NS_LITERAL_STRING("failed")
 #define DELIVERY_SUCCESS_EVENT_NAME NS_LITERAL_STRING("deliverysuccess")
 #define DELIVERY_ERROR_EVENT_NAME   NS_LITERAL_STRING("deliveryerror")
 
 using namespace mozilla::dom::mobilemessage;
 
@@ -48,16 +49,17 @@ NS_INTERFACE_MAP_BEGIN(MobileMessageMana
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileMessageManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(MobileMessageManager, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(MobileMessageManager, nsDOMEventTargetHelper)
 
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, received)
+NS_IMPL_EVENT_HANDLER(MobileMessageManager, retrieving)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, sending)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, sent)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, failed)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, deliverysuccess)
 NS_IMPL_EVENT_HANDLER(MobileMessageManager, deliveryerror)
 
 void
 MobileMessageManager::Init(nsPIDOMWindow *aWindow)
@@ -66,16 +68,17 @@ MobileMessageManager::Init(nsPIDOMWindow
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   // GetObserverService() can return null is some situations like shutdown.
   if (!obs) {
     return;
   }
 
   obs->AddObserver(this, kSmsReceivedObserverTopic, false);
+  obs->AddObserver(this, kSmsRetrievingObserverTopic, false);
   obs->AddObserver(this, kSmsSendingObserverTopic, false);
   obs->AddObserver(this, kSmsSentObserverTopic, false);
   obs->AddObserver(this, kSmsFailedObserverTopic, false);
   obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false);
   obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false);
 }
 
 void
@@ -83,16 +86,17 @@ MobileMessageManager::Shutdown()
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   // GetObserverService() can return null is some situations like shutdown.
   if (!obs) {
     return;
   }
 
   obs->RemoveObserver(this, kSmsReceivedObserverTopic);
+  obs->RemoveObserver(this, kSmsRetrievingObserverTopic);
   obs->RemoveObserver(this, kSmsSendingObserverTopic);
   obs->RemoveObserver(this, kSmsSentObserverTopic);
   obs->RemoveObserver(this, kSmsFailedObserverTopic);
   obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic);
   obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic);
 }
 
 NS_IMETHODIMP
@@ -428,16 +432,20 @@ MobileMessageManager::DispatchTrustedSms
 NS_IMETHODIMP
 MobileMessageManager::Observe(nsISupports* aSubject, const char* aTopic,
                               const PRUnichar* aData)
 {
   if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
     return DispatchTrustedSmsEventToSelf(aTopic, RECEIVED_EVENT_NAME, aSubject);
   }
 
+  if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) {
+    return DispatchTrustedSmsEventToSelf(aTopic, RETRIEVING_EVENT_NAME, aSubject);
+  }
+
   if (!strcmp(aTopic, kSmsSendingObserverTopic)) {
     return DispatchTrustedSmsEventToSelf(aTopic, SENDING_EVENT_NAME, aSubject);
   }
 
   if (!strcmp(aTopic, kSmsSentObserverTopic)) {
     return DispatchTrustedSmsEventToSelf(aTopic, SENT_EVENT_NAME, aSubject);
   }
 
--- a/dom/mobilemessage/src/ipc/PSms.ipdl
+++ b/dom/mobilemessage/src/ipc/PSms.ipdl
@@ -83,16 +83,18 @@ union IPCMobileMessageCursor
 sync protocol PSms {
     manager PContent;
     manages PSmsRequest;
     manages PMobileMessageCursor;
 
 child:
   NotifyReceivedMessage(MobileMessageData aMessageData);
 
+  NotifyRetrievingMessage(MobileMessageData aMessageData);
+
   NotifySendingMessage(MobileMessageData aMessageData);
 
   NotifySentMessage(MobileMessageData aMessageData);
 
   NotifyFailedMessage(MobileMessageData aMessageData);
 
   NotifyDeliverySuccessMessage(MobileMessageData aMessageData);
 
--- a/dom/mobilemessage/src/ipc/SmsChild.cpp
+++ b/dom/mobilemessage/src/ipc/SmsChild.cpp
@@ -64,16 +64,23 @@ SmsChild::ActorDestroy(ActorDestroyReaso
 bool
 SmsChild::RecvNotifyReceivedMessage(const MobileMessageData& aData)
 {
   NotifyObserversWithMobileMessage(kSmsReceivedObserverTopic, aData);
   return true;
 }
 
 bool
+SmsChild::RecvNotifyRetrievingMessage(const MobileMessageData& aData)
+{
+  NotifyObserversWithMobileMessage(kSmsRetrievingObserverTopic, aData);
+  return true;
+}
+
+bool
 SmsChild::RecvNotifySendingMessage(const MobileMessageData& aData)
 {
   NotifyObserversWithMobileMessage(kSmsSendingObserverTopic, aData);
   return true;
 }
 
 bool
 SmsChild::RecvNotifySentMessage(const MobileMessageData& aData)
--- a/dom/mobilemessage/src/ipc/SmsChild.h
+++ b/dom/mobilemessage/src/ipc/SmsChild.h
@@ -33,16 +33,19 @@ protected:
 
   virtual void
   ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   virtual bool
   RecvNotifyReceivedMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
 
   virtual bool
+  RecvNotifyRetrievingMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
+
+  virtual bool
   RecvNotifySendingMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
 
   virtual bool
   RecvNotifySentMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
 
   virtual bool
   RecvNotifyFailedMessage(const MobileMessageData& aMessage) MOZ_OVERRIDE;
 
--- a/dom/mobilemessage/src/ipc/SmsParent.cpp
+++ b/dom/mobilemessage/src/ipc/SmsParent.cpp
@@ -140,32 +140,34 @@ SmsParent::SmsParent()
 {
   MOZ_COUNT_CTOR(SmsParent);
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     return;
   }
 
   obs->AddObserver(this, kSmsReceivedObserverTopic, false);
+  obs->AddObserver(this, kSmsRetrievingObserverTopic, false);
   obs->AddObserver(this, kSmsSendingObserverTopic, false);
   obs->AddObserver(this, kSmsSentObserverTopic, false);
   obs->AddObserver(this, kSmsFailedObserverTopic, false);
   obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false);
   obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false);
 }
 
 void
 SmsParent::ActorDestroy(ActorDestroyReason why)
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     return;
   }
 
   obs->RemoveObserver(this, kSmsReceivedObserverTopic);
+  obs->RemoveObserver(this, kSmsRetrievingObserverTopic);
   obs->RemoveObserver(this, kSmsSendingObserverTopic);
   obs->RemoveObserver(this, kSmsSentObserverTopic);
   obs->RemoveObserver(this, kSmsFailedObserverTopic);
   obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic);
   obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic);
 }
 
 NS_IMETHODIMP
@@ -178,16 +180,27 @@ SmsParent::Observe(nsISupports* aSubject
       NS_ERROR("Got a 'sms-received' topic without a valid message!");
       return NS_OK;
     }
 
     unused << SendNotifyReceivedMessage(msgData);
     return NS_OK;
   }
 
+  if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) {
+    MobileMessageData msgData;
+    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
+      NS_ERROR("Got a 'sms-retrieving' topic without a valid message!");
+      return NS_OK;
+    }
+
+    unused << SendNotifyRetrievingMessage(msgData);
+    return NS_OK;
+  }
+
   if (!strcmp(aTopic, kSmsSendingObserverTopic)) {
     MobileMessageData msgData;
     if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
       NS_ERROR("Got a 'sms-sending' topic without a valid message!");
       return NS_OK;
     }
 
     unused << SendNotifySendingMessage(msgData);
--- a/dom/mobilemessage/src/ril/MmsService.js
+++ b/dom/mobilemessage/src/ril/MmsService.js
@@ -23,16 +23,17 @@ try {
   let debugPref = Services.prefs.getBoolPref("mms.debugging.enabled");
   DEBUG = DEBUG || debugPref;
 } catch (e) {}
 
 const kSmsSendingObserverTopic           = "sms-sending";
 const kSmsSentObserverTopic              = "sms-sent";
 const kSmsFailedObserverTopic            = "sms-failed";
 const kSmsReceivedObserverTopic          = "sms-received";
+const kSmsRetrievingObserverTopic        = "sms-retrieving";
 
 const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
 const kXpcomShutdownObserverTopic        = "xpcom-shutdown";
 const kPrefenceChangedObserverTopic      = "nsPref:changed";
 
 // HTTP status codes:
 // @see http://tools.ietf.org/html/rfc2616#page-39
 const HTTP_STATUS_OK = 200;
@@ -1034,28 +1035,30 @@ MmsService.prototype = {
     }
     if (intermediate.content) {
       savable.content = intermediate.content;
     }
     return savable;
   },
 
   /**
-   * @param contentLocation
+   * @param aContentLocation
    *        X-Mms-Content-Location of the message.
-   * @param callback [optional]
+   * @param aCallback [optional]
    *        A callback function that takes two arguments: one for X-Mms-Status,
    *        the other parsed MMS message.
+   * @param aDomMessage
+   *        The nsIDOMMozMmsMessage object.
    */
-  retrieveMessage: function retrieveMessage(contentLocation, callback) {
-    // TODO: bug 810099 - support onretrieving event
-    // TODO: bug 809832 - support customizable max incoming/outgoing message size.
+  retrieveMessage: function retrieveMessage(aContentLocation, aCallback, aDomMessage) {
+    // Notifying observers an MMS message is retrieving.
+    Services.obs.notifyObservers(aDomMessage, kSmsRetrievingObserverTopic, null);
 
-    let transaction = new RetrieveTransaction(contentLocation);
-    transaction.run(callback);
+    let transaction = new RetrieveTransaction(aContentLocation);
+    transaction.run(aCallback);
   },
 
   /**
    * A helper to broadcast the system message to launch registered apps
    * like Costcontrol, Notification and Message app... etc.
    *
    * @param aName
    *        The system message name.
@@ -1270,17 +1273,18 @@ MmsService.prototype = {
       } catch (e) {}
 
       let savableMessage = this.convertIntermediateToSavable(notification, retrievalMode);
 
       gMobileMessageDatabaseService
         .saveReceivedMessage(savableMessage,
                              this.saveReceivedMessageCallback.bind(this,
                                                                    retrievalMode,
-                                                                   savableMessage));
+                                                                   savableMessage),
+                             domMessage);
     }).bind(this));
   },
 
   /**
    * Handle incoming M-Delivery.ind PDU.
    *
    * @param msg
    *        The MMS message object.
--- a/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js
+++ b/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js
@@ -1267,102 +1267,107 @@ MobileMessageDatabaseService.prototype =
         }
         messageStore.put(messageRecord);
       };
     });
   },
 
   getMessageRecordByTransactionId: function getMessageRecordByTransactionId(aTransactionId, aCallback) {
     if (DEBUG) debug("Retrieving message with transaction ID " + aTransactionId);
+    let self = this;
     this.newTxn(READ_ONLY, function (error, txn, messageStore) {
       if (error) {
         if (DEBUG) debug(error);
-        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null);
+        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null, null);
         return;
       }
       let request = messageStore.index("transactionId").get(aTransactionId);
 
       txn.oncomplete = function oncomplete(event) {
         if (DEBUG) debug("Transaction " + txn + " completed.");
         let messageRecord = request.result;
         if (!messageRecord) {
           if (DEBUG) debug("Transaction ID " + aTransactionId + " not found");
-          aCallback.notify(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR, null);
+          aCallback.notify(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR, null, null);
           return;
         }
-        aCallback.notify(Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR, messageRecord);
+        // In this case, we don't need a dom message. Just pass null to the
+        // third argument.
+        aCallback.notify(Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR,
+                         messageRecord, null);
       };
 
       txn.onerror = function onerror(event) {
         if (DEBUG) {
           if (event.target)
             debug("Caught error on transaction", event.target.errorCode);
         }
-        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null);
+        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null, null);
       };
     });
   },
 
   getMessageRecordById: function getMessageRecordById(aMessageId, aCallback) {
     if (DEBUG) debug("Retrieving message with ID " + aMessageId);
+    let self = this;
     this.newTxn(READ_ONLY, function (error, txn, messageStore) {
       if (error) {
         if (DEBUG) debug(error);
-        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null);
+        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null, null);
         return;
       }
       let request = messageStore.mozGetAll(aMessageId);
 
       txn.oncomplete = function oncomplete() {
         if (DEBUG) debug("Transaction " + txn + " completed.");
         if (request.result.length > 1) {
           if (DEBUG) debug("Got too many results for id " + aMessageId);
-          aCallback.notify(Ci.nsIMobileMessageCallback.UNKNOWN_ERROR, null);
+          aCallback.notify(Ci.nsIMobileMessageCallback.UNKNOWN_ERROR, null, null);
           return;
         }
         let messageRecord = request.result[0];
         if (!messageRecord) {
           if (DEBUG) debug("Message ID " + aMessageId + " not found");
-          aCallback.notify(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR, null);
+          aCallback.notify(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR, null, null);
           return;
         }
         if (messageRecord.id != aMessageId) {
           if (DEBUG) {
             debug("Requested message ID (" + aMessageId + ") is " +
                   "different from the one we got");
           }
-          aCallback.notify(Ci.nsIMobileMessageCallback.UNKNOWN_ERROR, null);
+          aCallback.notify(Ci.nsIMobileMessageCallback.UNKNOWN_ERROR, null, null);
           return;
         }
-        aCallback.notify(Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR, messageRecord);
+        let domMessage = self.createDomMessageFromRecord(messageRecord);
+        aCallback.notify(Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR,
+                         messageRecord, domMessage);
       };
 
       txn.onerror = function onerror(event) {
         if (DEBUG) {
           if (event.target) {
             debug("Caught error on transaction", event.target.errorCode);
           }
         }
-        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null);
+        aCallback.notify(Ci.nsIMobileMessageCallback.INTERNAL_ERROR, null, null);
       };
     });
   },
 
   /**
    * nsIMobileMessageDatabaseService API
    */
 
   getMessage: function getMessage(aMessageId, aRequest) {
     if (DEBUG) debug("Retrieving message with ID " + aMessageId);
-    let self = this;
     let notifyCallback = {
-      notify: function notify(aRv, aMessageRecord) {
+      notify: function notify(aRv, aMessageRecord, aDomMessage) {
         if (Ci.nsIMobileMessageCallback.SUCCESS_NO_ERROR == aRv) {
-          let domMessage = self.createDomMessageFromRecord(aMessageRecord);
-          aRequest.notifyMessageGot(domMessage);
+          aRequest.notifyMessageGot(aDomMessage);
           return;
         }
         aRequest.notifyGetMessageFailed(aRv, null);
       }
     };
     this.getMessageRecordById(aMessageId, notifyCallback);
   },