Bug 674725 - Part Z - Allow sending to multiple recipients with send(). r=mrbkap
authorMounir Lamouri <mounir.lamouri@gmail.com>
Tue, 20 Dec 2011 15:30:16 +0100
changeset 84711 6148455f5ddc84a1fb6fb765db6435cf91cddb78
parent 84710 a09cc4f2fbe92ba7c9050f8e7c9928c807ec0067
child 84712 2fcc66b6b9610a02a84a08e297ae450659088d43
push id21873
push usermlamouri@mozilla.com
push dateWed, 18 Jan 2012 10:29:07 +0000
treeherdermozilla-central@7538f4d4697c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs674725
milestone12.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 674725 - Part Z - Allow sending to multiple recipients with send(). r=mrbkap
dom/sms/interfaces/nsIDOMSmsManager.idl
dom/sms/src/Makefile.in
dom/sms/src/SmsManager.cpp
dom/sms/src/SmsManager.h
--- a/dom/sms/interfaces/nsIDOMSmsManager.idl
+++ b/dom/sms/interfaces/nsIDOMSmsManager.idl
@@ -32,20 +32,24 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
-interface nsIDOMMozSmsRequest;
 
-[scriptable, function, uuid(1c1f23d7-5f4e-40bf-859b-82e8faa36041)]
+[scriptable, function, uuid(1b40f025-33b0-4a95-b7b1-89857bfb8d7c)]
 interface nsIDOMMozSmsManager : nsIDOMEventTarget
 {
   unsigned short      getNumberOfMessagesForText(in DOMString text);
-  nsIDOMMozSmsRequest send(in DOMString number, in DOMString message);
+
+  // The first parameter can be either a DOMString (only one number) or an array
+  // of DOMStrings.
+  // The method returns a SmsRequest object if one number has been passed.
+  // An array of SmsRequest objects otherwise.
+  jsval send(in jsval number, in DOMString message);
 
   attribute nsIDOMEventListener onreceived;
   attribute nsIDOMEventListener onsent;
   attribute nsIDOMEventListener ondelivered;
 };
--- a/dom/sms/src/Makefile.in
+++ b/dom/sms/src/Makefile.in
@@ -83,16 +83,17 @@ CPPSRCS = \
   SmsChild.cpp \
   SmsDatabaseService.cpp \
   SmsRequest.cpp \
   SmsRequestManager.cpp \
   $(NULL)
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
+  -I$(topsrcdir)/dom/base \
   $(NULL)
 
 # Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
 # subdirectory (and the ipc one).
 LOCAL_INCLUDES += $(VPATH:%=-I%)
 
 ifdef MOZ_B2G_RIL
 LOCAL_INCLUDES += \
--- a/dom/sms/src/SmsManager.cpp
+++ b/dom/sms/src/SmsManager.cpp
@@ -40,16 +40,18 @@
 #include "nsISmsService.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "Constants.h"
 #include "SmsEvent.h"
 #include "nsIDOMSmsMessage.h"
 #include "nsIDOMSmsRequest.h"
 #include "SmsRequestManager.h"
+#include "nsJSUtils.h"
+#include "nsContentUtils.h"
 
 /**
  * We have to use macros here because our leak analysis tool things we are
  * leaking strings when we have |static const nsString|. Sad :(
  */
 #define RECEIVED_EVENT_NAME  NS_LITERAL_STRING("received")
 #define SENT_EVENT_NAME      NS_LITERAL_STRING("sent")
 #define DELIVERED_EVENT_NAME NS_LITERAL_STRING("delivered")
@@ -123,29 +125,92 @@ SmsManager::GetNumberOfMessagesForText(c
   nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(smsService, NS_OK);
 
   smsService->GetNumberOfMessagesForText(aText, aResult);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-SmsManager::Send(const nsAString& aNumber, const nsAString& aMessage, nsIDOMMozSmsRequest** aRequest)
+nsresult
+SmsManager::Send(JSContext* aCx, JSObject* aGlobal, JSString* aNumber,
+                 const nsAString& aMessage, jsval* aRequest)
 {
   nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
-  NS_ENSURE_TRUE(smsService, NS_OK);
+  if (!smsService) {
+    NS_ERROR("No SMS Service!");
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIDOMMozSmsRequest> request;
 
   int requestId =
-    SmsRequestManager::GetInstance()->CreateRequest(mOwner, mScriptContext, aRequest);
-  NS_ASSERTION(*aRequest, "The request object must have been created!");
+    SmsRequestManager::GetInstance()->CreateRequest(mOwner, mScriptContext,
+                                                    getter_AddRefs(request));
+  NS_ASSERTION(request, "The request object must have been created!");
+
+  nsDependentJSString number;
+  number.init(aCx, aNumber);
+
+  smsService->Send(number, aMessage, requestId, 0);
+
+  nsresult rv = nsContentUtils::WrapNative(aCx, aGlobal, request, aRequest);
+  if (NS_FAILED(rv)) {
+    NS_ERROR("Failed to create the js value!");
+    return rv;
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SmsManager::Send(const jsval& aNumber, const nsAString& aMessage, jsval* aReturn)
+{
+  JSContext* cx = mScriptContext->GetNativeContext();
+  NS_ASSERTION(cx, "Failed to get a context!");
+
+  if (!aNumber.isString() &&
+      !(aNumber.isObject() && JS_IsArrayObject(cx, &aNumber.toObject()))) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  JSObject* global = mScriptContext->GetNativeGlobal();
+  NS_ASSERTION(global, "Failed to get global object!");
 
-  NS_ADDREF(*aRequest);
+  JSAutoRequest ar(cx);
+  JSAutoEnterCompartment ac;
+  if (!ac.enter(cx, global)) {
+    NS_ERROR("Failed to enter the js compartment!");
+    return NS_ERROR_FAILURE;
+  }
+
+  if (aNumber.isString()) {
+    return Send(cx, global, aNumber.toString(), aMessage, aReturn);
+  }
+
+  // Must be an array then.
+  JSObject& numbers = aNumber.toObject();
 
-  smsService->Send(aNumber, aMessage, requestId, 0);
+  jsuint size;
+  JS_ALWAYS_TRUE(JS_GetArrayLength(cx, &numbers, &size));
+
+  jsval* requests = new jsval[size];
+
+  for (jsuint i=0; i<size; ++i) {
+    jsval number;
+    if (!JS_GetElement(cx, &numbers, i, &number)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+
+    nsresult rv = Send(cx, global, number.toString(), aMessage, &requests[i]);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  aReturn->setObjectOrNull(JS_NewArrayObject(cx, size, requests));
+  NS_ENSURE_TRUE(aReturn->isObject(), NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
 NS_IMPL_EVENT_HANDLER(SmsManager, received)
 NS_IMPL_EVENT_HANDLER(SmsManager, sent)
 NS_IMPL_EVENT_HANDLER(SmsManager, delivered)
 
--- a/dom/sms/src/SmsManager.h
+++ b/dom/sms/src/SmsManager.h
@@ -61,16 +61,22 @@ public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SmsManager,
                                            nsDOMEventTargetWrapperCache)
 
   void Init(nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext);
   void Shutdown();
 
 private:
+  /**
+   * Internal Send() method used to send one message.
+   */
+  nsresult Send(JSContext* aCx, JSObject* aGlobal, JSString* aNumber,
+                const nsAString& aMessage, jsval* aRequest);
+
   nsresult DispatchTrustedSmsEventToSelf(const nsAString& aEventName,
                                          nsIDOMMozSmsMessage* aMessage);
   NS_DECL_EVENT_HANDLER(received)
   NS_DECL_EVENT_HANDLER(sent)
   NS_DECL_EVENT_HANDLER(delivered)
 };
 
 } // namespace sms