Bug 674725 - Part M - Receiving SMS: DOM part. r=smaug
authorMounir Lamouri <mounir.lamouri@gmail.com>
Fri, 25 Nov 2011 01:48:57 +0100
changeset 82417 8fc0531d93f5674cf08fc256ec4ed0080fa8b40d
parent 82416 c637a6a53cebf42c9328343d70c4185165b656e9
child 82418 d09ef2ac2a3a17aa2f28e0f72b3225279e4a76cd
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs674725
milestone11.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 M - Receiving SMS: DOM part. r=smaug
dom/base/Navigator.cpp
dom/base/Navigator.h
dom/sms/interfaces/nsIDOMSmsManager.idl
dom/sms/src/Constants.cpp
dom/sms/src/Constants.h
dom/sms/src/Makefile.in
dom/sms/src/SmsManager.cpp
dom/sms/src/SmsManager.h
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -103,16 +103,20 @@ Navigator::~Navigator()
 
   if (mPlugins) {
     mPlugins->Invalidate();
   }
 
   if (mBatteryManager) {
     mBatteryManager->Shutdown();
   }
+
+  if (mSmsManager) {
+    mSmsManager->Shutdown();
+  }
 }
 
 NS_INTERFACE_MAP_BEGIN(Navigator)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorBattery)
@@ -145,16 +149,17 @@ Navigator::SetDocShell(nsIDocShell* aDoc
   }
 
   if (mBatteryManager) {
     mBatteryManager->Shutdown();
     mBatteryManager = nsnull;
   }
 
   if (mSmsManager) {
+    mSmsManager->Shutdown();
     mSmsManager = nsnull;
   }
 }
 
 //*****************************************************************************
 //    Navigator::nsIDOMNavigator
 //*****************************************************************************
 
@@ -529,16 +534,17 @@ Navigator::LoadingNewDocument()
   }
 
   if (mBatteryManager) {
     mBatteryManager->Shutdown();
     mBatteryManager = nsnull;
   }
 
   if (mSmsManager) {
+    mSmsManager->Shutdown();
     mSmsManager = nsnull;
   }
 }
 
 nsresult
 Navigator::RefreshMIMEArray()
 {
   if (mMimeTypes) {
@@ -846,23 +852,37 @@ Navigator::IsSmsSupported() const
   smsService->HasSupport(&result);
 
   return result;
 }
 
 NS_IMETHODIMP
 Navigator::GetMozSms(nsIDOMMozSmsManager** aSmsManager)
 {
+  *aSmsManager = nsnull;
+
   if (!mSmsManager) {
     if (!IsSmsSupported() || !IsSmsAllowed()) {
-      *aSmsManager = nsnull;
       return NS_OK;
     }
 
+    nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell);
+    NS_ENSURE_TRUE(window, NS_OK);
+
+    nsCOMPtr<nsIDocument> document = do_GetInterface(mDocShell);
+    NS_ENSURE_TRUE(document, NS_OK);
+
+    nsIScriptGlobalObject* sgo = document->GetScopeObject();
+    NS_ENSURE_TRUE(sgo, NS_OK);
+
+    nsIScriptContext* scx = sgo->GetContext();
+    NS_ENSURE_TRUE(scx, NS_OK);
+
     mSmsManager = new sms::SmsManager();
+    mSmsManager->Init(window->GetCurrentInnerWindow(), scx);
   }
 
   NS_ADDREF(*aSmsManager = mSmsManager);
 
   return NS_OK;
 }
 
 PRInt64
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -45,17 +45,16 @@
 
 #include "nsIDOMNavigator.h"
 #include "nsIDOMNavigatorGeolocation.h"
 #include "nsIDOMNavigatorDesktopNotification.h"
 #include "nsIDOMClientInformation.h"
 #include "nsIDOMNavigatorBattery.h"
 #include "nsIDOMNavigatorSms.h"
 #include "nsAutoPtr.h"
-#include "nsIDOMSmsManager.h"
 
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsGeolocation;
 class nsDesktopNotificationCenter;
 class nsIDocShell;
 
 //*****************************************************************************
@@ -64,16 +63,20 @@ class nsIDocShell;
 
 namespace mozilla {
 namespace dom {
 
 namespace battery {
 class BatteryManager;
 } // namespace battery
 
+namespace sms {
+class SmsManager;
+} // namespace sms
+
 class Navigator : public nsIDOMNavigator,
                   public nsIDOMClientInformation,
                   public nsIDOMNavigatorGeolocation,
                   public nsIDOMNavigatorDesktopNotification,
                   public nsIDOMMozNavigatorBattery,
                   public nsIDOMMozNavigatorSms
 {
 public:
@@ -109,17 +112,17 @@ private:
 
   static bool sDoNotTrackEnabled;
 
   nsRefPtr<nsMimeTypeArray> mMimeTypes;
   nsRefPtr<nsPluginArray> mPlugins;
   nsRefPtr<nsGeolocation> mGeolocation;
   nsRefPtr<nsDesktopNotificationCenter> mNotification;
   nsRefPtr<battery::BatteryManager> mBatteryManager;
-  nsCOMPtr<nsIDOMMozSmsManager> mSmsManager;
+  nsRefPtr<sms::SmsManager> mSmsManager;
   nsIDocShell* mDocShell; // weak reference
 };
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
 nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
--- a/dom/sms/interfaces/nsIDOMSmsManager.idl
+++ b/dom/sms/interfaces/nsIDOMSmsManager.idl
@@ -29,16 +29,20 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 "nsISupports.idl"
+#include "nsIDOMEventTarget.idl"
 
-[scriptable, function, uuid(473547ee-7a26-46d3-8476-f012985cd0c8)]
-interface nsIDOMMozSmsManager : nsISupports
+interface nsIDOMEventListener;
+
+[scriptable, function, uuid(807d593c-09cb-4aa3-afa5-aa0a671bd0d3)]
+interface nsIDOMMozSmsManager : nsIDOMEventTarget
 {
   unsigned short getNumberOfMessagesForText(in DOMString text);
             void send(in DOMString number, in DOMString message);
+
+  attribute nsIDOMEventListener onreceived;
 };
new file mode 100644
--- /dev/null
+++ b/dom/sms/src/Constants.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mounir Lamouri <mounir.lamouri@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * 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 ***** */
+
+namespace mozilla {
+namespace dom {
+namespace sms {
+
+const char* kSmsReceivedObserverTopic = "sms-received";
+
+} // namespace sms
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/sms/src/Constants.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mounir Lamouri <mounir.lamouri@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * 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 ***** */
+
+#ifndef mozilla_dom_sms_Constants_h
+#define mozilla_dom_sms_Constants_h
+
+namespace mozilla {
+namespace dom {
+namespace sms {
+
+extern const char* kSmsReceivedObserverTopic; // Defined in the .cpp.
+
+} // namespace sms
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_sms_Constants_h
--- a/dom/sms/src/Makefile.in
+++ b/dom/sms/src/Makefile.in
@@ -57,26 +57,28 @@ FORCE_STATIC_LIB = 1
 include $(topsrcdir)/dom/dom-config.mk
 
 EXPORTS_NAMESPACES = mozilla/dom/sms
 
 EXPORTS_mozilla/dom/sms = \
   SmsChild.h \
   SmsParent.h \
   SmsServiceFactory.h \
+  Constants.h
   $(NULL)
 
 CPPSRCS = \
   SmsManager.cpp \
   SmsService.cpp \
   SmsIPCService.cpp \
   SmsServiceFactory.cpp \
   SmsParent.cpp \
   SmsMessage.cpp \
   SmsEvent.cpp \
+  Constants.cpp \
   $(NULL)
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
 # Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
 # subdirectory (and the ipc one).
--- a/dom/sms/src/SmsManager.cpp
+++ b/dom/sms/src/SmsManager.cpp
@@ -33,31 +33,82 @@
  * 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 "SmsManager.h"
 #include "nsIDOMClassInfo.h"
 #include "nsISmsService.h"
+#include "nsIObserverService.h"
+#include "mozilla/Services.h"
+#include "Constants.h"
+#include "SmsEvent.h"
+#include "nsIDOMSmsMessage.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")
 
 DOMCI_DATA(MozSmsManager, mozilla::dom::sms::SmsManager)
 
 namespace mozilla {
 namespace dom {
 namespace sms {
 
-NS_INTERFACE_MAP_BEGIN(SmsManager)
+NS_IMPL_CYCLE_COLLECTION_CLASS(SmsManager)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SmsManager,
+                                                  nsDOMEventTargetWrapperCache)
+  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(received)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SmsManager,
+                                                nsDOMEventTargetWrapperCache)
+  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(received)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SmsManager)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozSmsManager)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozSmsManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSmsManager)
-NS_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
+
+NS_IMPL_ADDREF_INHERITED(SmsManager, nsDOMEventTargetWrapperCache)
+NS_IMPL_RELEASE_INHERITED(SmsManager, nsDOMEventTargetWrapperCache)
+
+void
+SmsManager::Init(nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext)
+{
+  // Those vars come from nsDOMEventTargetHelper.
+  mOwner = aWindow;
+  mScriptContext = aScriptContext;
 
-NS_IMPL_ADDREF(SmsManager)
-NS_IMPL_RELEASE(SmsManager)
+  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+  // GetObserverService() can return null is some situations like shutdown.
+  if (!obs) {
+    return;
+  }
+
+  obs->AddObserver(this, kSmsReceivedObserverTopic, false);
+}
+
+void
+SmsManager::Shutdown()
+{
+  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+  // GetObserverService() can return null is some situations like shutdown.
+  if (!obs) {
+    return;
+  }
+
+  obs->RemoveObserver(this, kSmsReceivedObserverTopic);
+}
 
 NS_IMETHODIMP
 SmsManager::GetNumberOfMessagesForText(const nsAString& aText, PRUint16* aResult)
 {
   nsCOMPtr<nsISmsService> smsService = do_GetService(SMSSERVICE_CONTRACTID);
   NS_ENSURE_TRUE(smsService, NS_OK);
 
   smsService->GetNumberOfMessagesForText(aText, aResult);
@@ -71,11 +122,48 @@ SmsManager::Send(const nsAString& aNumbe
   nsCOMPtr<nsISmsService> smsService = do_GetService(SMSSERVICE_CONTRACTID);
   NS_ENSURE_TRUE(smsService, NS_OK);
 
   smsService->Send(aNumber, aMessage);
 
   return NS_OK;
 }
 
+NS_IMPL_EVENT_HANDLER(SmsManager, received)
+
+nsresult
+SmsManager::DispatchTrustedSmsEventToSelf(const nsAString& aEventName, nsIDOMMozSmsMessage* aMessage)
+{
+  nsRefPtr<nsDOMEvent> event = new SmsEvent(nsnull, nsnull);
+  nsresult rv = static_cast<SmsEvent*>(event.get())->Init(aEventName, false,
+                                                          false, aMessage);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = event->SetTrusted(PR_TRUE);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool dummy;
+  rv = DispatchEvent(event, &dummy);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SmsManager::Observe(nsISupports* aSubject, const char* aTopic,
+                    const PRUnichar* aData)
+{
+  if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
+    nsCOMPtr<nsIDOMMozSmsMessage> message = do_QueryInterface(aSubject);
+    if (!message) {
+      NS_ERROR("Got a 'sms-received' topic without a valid message!");
+      return NS_OK;
+    }
+
+    DispatchTrustedSmsEventToSelf(RECEIVED_EVENT_NAME, message);
+  }
+
+  return NS_OK;
+}
+
 } // namespace sms
 } // namespace dom
 } // namespace mozilla
--- a/dom/sms/src/SmsManager.h
+++ b/dom/sms/src/SmsManager.h
@@ -34,25 +34,45 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_dom_sms_SmsManager_h
 #define mozilla_dom_sms_SmsManager_h
 
 #include "nsIDOMSmsManager.h"
+#include "nsIObserver.h"
+#include "nsDOMEventTargetWrapperCache.h"
+
+class nsIDOMMozSmsMessage;
 
 namespace mozilla {
 namespace dom {
 namespace sms {
 
 class SmsManager : public nsIDOMMozSmsManager
+                 , public nsIObserver
+                 , public nsDOMEventTargetWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
   NS_DECL_NSIDOMMOZSMSMANAGER
+
+  NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetWrapperCache::)
+
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SmsManager,
+                                           nsDOMEventTargetWrapperCache)
+
+  void Init(nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext);
+  void Shutdown();
+
+private:
+  nsresult DispatchTrustedSmsEventToSelf(const nsAString& aEventName,
+                                         nsIDOMMozSmsMessage* aMessage);
+  NS_DECL_EVENT_HANDLER(received)
 };
 
 } // namespace sms
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_sms_SmsManager_h