Bug 864484 - Part 4: Add IPDL Protocol Implementation for CellBroadcast. r=vyang
authorBevis Tseng <btseng@mozilla.com>
Mon, 18 Aug 2014 17:06:11 +0800
changeset 232296 2fe6e70071fff89764ac7a4955b6cfaa29495b94
parent 232295 4090b8c651ab9bf642abeaee2ebe20563adac1ad
child 232297 861971a6b28c2a5a2230a5822c1bd5dfe85f94ff
push id611
push userraliiev@mozilla.com
push dateMon, 05 Jan 2015 23:23:16 +0000
treeherdermozilla-release@345cd3b9c445 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvyang
bugs864484
milestone35.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 864484 - Part 4: Add IPDL Protocol Implementation for CellBroadcast. r=vyang
dom/cellbroadcast/CellBroadcast.cpp
dom/cellbroadcast/interfaces/nsICellBroadcastService.idl
dom/cellbroadcast/interfaces/nsIGonkCellBroadcastService.idl
dom/cellbroadcast/ipc/CellBroadcastIPCService.cpp
dom/cellbroadcast/ipc/CellBroadcastIPCService.h
dom/cellbroadcast/ipc/CellBroadcastParent.cpp
dom/cellbroadcast/ipc/CellBroadcastParent.h
dom/cellbroadcast/ipc/PCellBroadcast.ipdl
dom/cellbroadcast/moz.build
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
layout/build/nsLayoutModule.cpp
--- a/dom/cellbroadcast/CellBroadcast.cpp
+++ b/dom/cellbroadcast/CellBroadcast.cpp
@@ -4,17 +4,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/CellBroadcast.h"
 #include "mozilla/dom/CellBroadcastMessage.h"
 #include "mozilla/dom/MozCellBroadcastBinding.h"
 #include "mozilla/dom/MozCellBroadcastEvent.h"
 #include "nsServiceManagerUtils.h"
 
-#define NS_CELLBROADCASTSERVICE_CONTRACTID "@mozilla.org/cellbroadcast/gonkservice;1"
+// Service instantiation
+#include "ipc/CellBroadcastIPCService.h"
+#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
+#include "nsIGonkCellBroadcastService.h"
+#endif
+#include "nsXULAppAPI.h" // For XRE_GetProcessType()
 
 using namespace mozilla::dom;
 using mozilla::ErrorResult;
 
 /**
  * CellBroadcast::Listener Implementation.
  */
 
@@ -55,17 +60,17 @@ NS_IMPL_ISUPPORTS(CellBroadcast::Listene
 // static
 already_AddRefed<CellBroadcast>
 CellBroadcast::Create(nsPIDOMWindow* aWindow, ErrorResult& aRv)
 {
   MOZ_ASSERT(aWindow);
   MOZ_ASSERT(aWindow->IsInnerWindow());
 
   nsCOMPtr<nsICellBroadcastService> service =
-    do_GetService(NS_CELLBROADCASTSERVICE_CONTRACTID);
+    do_GetService(CELLBROADCAST_SERVICE_CONTRACTID);
   if (!service) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   nsRefPtr<CellBroadcast> cb = new CellBroadcast(aWindow, service);
   return cb.forget();
 }
@@ -81,17 +86,17 @@ CellBroadcast::CellBroadcast(nsPIDOMWind
 }
 
 CellBroadcast::~CellBroadcast()
 {
   MOZ_ASSERT(mListener);
 
   mListener->Disconnect();
   nsCOMPtr<nsICellBroadcastService> service =
-    do_GetService(NS_CELLBROADCASTSERVICE_CONTRACTID);
+    do_GetService(CELLBROADCAST_SERVICE_CONTRACTID);
   if (service) {
     service->UnregisterListener(mListener);
   }
 
   mListener = nullptr;
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(CellBroadcast, DOMEventTargetHelper)
@@ -135,8 +140,24 @@ CellBroadcast::NotifyMessageReceived(uin
                                            aEtwsWarningType,
                                            aEtwsEmergencyUserAlert,
                                            aEtwsPopup);
 
   nsRefPtr<MozCellBroadcastEvent> event =
     MozCellBroadcastEvent::Constructor(this, NS_LITERAL_STRING("received"), init);
   return DispatchTrustedEvent(event);
 }
+
+already_AddRefed<nsICellBroadcastService>
+NS_CreateCellBroadcastService()
+{
+  nsCOMPtr<nsICellBroadcastService> service;
+
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    service = new mozilla::dom::cellbroadcast::CellBroadcastIPCService();
+#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
+  } else {
+    service = do_GetService(GONK_CELLBROADCAST_SERVICE_CONTRACTID);
+#endif
+  }
+
+  return service.forget();
+}
--- a/dom/cellbroadcast/interfaces/nsICellBroadcastService.idl
+++ b/dom/cellbroadcast/interfaces/nsICellBroadcastService.idl
@@ -21,16 +21,23 @@ interface nsICellBroadcastListener : nsI
                              in DOMTimeStamp aTimestamp,
                              in unsigned long aCdmaServiceCategory,
                              in boolean aHasEtwsInfo,
                              in DOMString aEtwsWarningType,
                              in boolean aEtwsEmergencyUserAlert,
                              in boolean aEtwsPopup);
 };
 
+%{C++
+#define CELLBROADCAST_SERVICE_CID \
+  { 0xc870bdca, 0x277c, 0x11e4, { 0xac, 0xa3, 0x33, 0x73, 0xa1, 0xef, 0x48, 0xf8 } }
+#define CELLBROADCAST_SERVICE_CONTRACTID \
+  "@mozilla.org/cellbroadcast/cellbroadcastservice;1"
+%}
+
 /**
  * XPCOM component that provides the cell broadcast information.
  */
 [scriptable, uuid(05099b34-21f7-11e4-b3b9-1b1b03487cab)]
 interface nsICellBroadcastService : nsISupports
 {
   /**
    * Attribute CdmaServiceCategory is only valid in CDMA network.
@@ -40,9 +47,16 @@ interface nsICellBroadcastService : nsIS
 
   /**
    * Called to register receiving cellbroadcast messages.
    *
    * 'cellbroadcast' permission is required for registration/unregistration.
    */
   void registerListener(in nsICellBroadcastListener listener);
   void unregisterListener(in nsICellBroadcastListener listener);
-};
\ No newline at end of file
+};
+
+%{C++
+template<typename T> struct already_AddRefed;
+
+already_AddRefed<nsICellBroadcastService>
+NS_CreateCellBroadcastService();
+%}
--- a/dom/cellbroadcast/interfaces/nsIGonkCellBroadcastService.idl
+++ b/dom/cellbroadcast/interfaces/nsIGonkCellBroadcastService.idl
@@ -1,14 +1,19 @@
 /* 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 "nsICellBroadcastService.idl"
 
+%{C++
+#define GONK_CELLBROADCAST_SERVICE_CONTRACTID \
+        "@mozilla.org/cellbroadcast/gonkservice;1"
+%}
+
 [scriptable, uuid(f72ced60-21f9-11e4-8896-6fdff2f5c909)]
 interface nsIGonkCellBroadcastService : nsICellBroadcastService
 {
   /**
    * Called when a cellbroadcast message has been received by the network.
    */
   void notifyMessageReceived(in unsigned long aServiceId,
                              in DOMString aGsmGeographicalScope,
new file mode 100644
--- /dev/null
+++ b/dom/cellbroadcast/ipc/CellBroadcastIPCService.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "CellBroadcastIPCService.h"
+#include "mozilla/dom/ContentChild.h"
+
+namespace mozilla {
+namespace dom {
+namespace cellbroadcast {
+
+NS_IMPL_ISUPPORTS(CellBroadcastIPCService, nsICellBroadcastService)
+
+CellBroadcastIPCService::CellBroadcastIPCService()
+  : mActorDestroyed(false)
+{
+  ContentChild::GetSingleton()->SendPCellBroadcastConstructor(this);
+}
+
+CellBroadcastIPCService::~CellBroadcastIPCService()
+{
+  if (!mActorDestroyed) {
+    Send__delete__(this);
+  }
+
+  mListeners.Clear();
+}
+
+/*
+ * Implementation of nsICellBroadcastService.
+ */
+
+NS_IMETHODIMP
+CellBroadcastIPCService::RegisterListener(nsICellBroadcastListener* aListener)
+{
+  MOZ_ASSERT(!mListeners.Contains(aListener));
+
+  NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_UNEXPECTED);
+
+  // nsTArray doesn't fail.
+  mListeners.AppendElement(aListener);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+CellBroadcastIPCService::UnregisterListener(nsICellBroadcastListener* aListener)
+{
+  MOZ_ASSERT(mListeners.Contains(aListener));
+
+  NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_UNEXPECTED);
+
+  // We always have the element here, so it can't fail.
+  mListeners.RemoveElement(aListener);
+
+  return NS_OK;
+}
+
+/*
+ * Implementation of PCellBroadcastChild.
+ */
+
+bool
+CellBroadcastIPCService::RecvNotifyReceivedMessage(const uint32_t& aServiceId,
+                                              const nsString& aGsmGeographicalScope,
+                                              const uint16_t& aMessageCode,
+                                              const uint16_t& aMessageId,
+                                              const nsString& aLanguage,
+                                              const nsString& aBody,
+                                              const nsString& aMessageClass,
+                                              const uint64_t& aTimestamp,
+                                              const uint32_t& aCdmaServiceCategory,
+                                              const bool& aHasEtwsInfo,
+                                              const nsString& aEtwsWarningType,
+                                              const bool& aEtwsEmergencyUserAlert,
+                                              const bool& aEtwsPopup)
+{
+  // UnregisterListener() could be triggered in
+  // nsICellBroadcastListener::NotifyMessageReceived().
+  // Make a immutable copy for notifying the event.
+  nsTArray<nsCOMPtr<nsICellBroadcastListener>> immutableListeners(mListeners);
+  for (uint32_t i = 0; i < immutableListeners.Length(); i++) {
+    immutableListeners[i]->NotifyMessageReceived(aServiceId,
+                                                 aGsmGeographicalScope,
+                                                 aMessageCode,
+                                                 aMessageId,
+                                                 aLanguage,
+                                                 aBody,
+                                                 aMessageClass,
+                                                 aTimestamp,
+                                                 aCdmaServiceCategory,
+                                                 aHasEtwsInfo,
+                                                 aEtwsWarningType,
+                                                 aEtwsEmergencyUserAlert,
+                                                 aEtwsPopup);
+  }
+
+  return true;
+}
+
+void
+CellBroadcastIPCService::ActorDestroy(ActorDestroyReason aWhy)
+{
+  mActorDestroyed = true;
+}
+
+} // namespace cellbroadcast
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/cellbroadcast/ipc/CellBroadcastIPCService.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef mozilla_dom_cellbroadcast_CellBroadcastIPCService_h
+#define mozilla_dom_cellbroadcast_CellBroadcastIPCService_h
+
+#include "mozilla/dom/cellbroadcast/PCellBroadcastChild.h"
+#include "nsICellBroadcastService.h"
+#include "nsCOMPtr.h"
+#include "nsTArray.h"
+
+namespace mozilla {
+namespace dom {
+namespace cellbroadcast {
+
+class CellBroadcastIPCService MOZ_FINAL : public PCellBroadcastChild
+                                        , public nsICellBroadcastService
+
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSICELLBROADCASTSERVICE
+
+  CellBroadcastIPCService();
+
+  // PCellBroadcastChild interface
+  virtual bool
+  RecvNotifyReceivedMessage(const uint32_t& aServiceId,
+                            const nsString& aGsmGeographicalScope,
+                            const uint16_t& aMessageCode,
+                            const uint16_t& aMessageId,
+                            const nsString& aLanguage,
+                            const nsString& aBody,
+                            const nsString& aMessageClass,
+                            const uint64_t& aTimestamp,
+                            const uint32_t& aCdmaServiceCategory,
+                            const bool& aHasEtwsInfo,
+                            const nsString& aEtwsWarningType,
+                            const bool& aEtwsEmergencyUserAlert,
+                            const bool& aEtwsPopup) MOZ_OVERRIDE;
+
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
+private:
+  // MOZ_FINAL suppresses -Werror,-Wdelete-non-virtual-dtor
+  ~CellBroadcastIPCService();
+
+  bool mActorDestroyed;
+  nsTArray<nsCOMPtr<nsICellBroadcastListener>> mListeners;
+};
+
+} // namespace cellbroadcast
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_cellbroadcast_CellBroadcastIPCService_h
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/cellbroadcast/ipc/CellBroadcastParent.cpp
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "mozilla/dom/cellbroadcast/CellBroadcastParent.h"
+#include "nsServiceManagerUtils.h"
+
+namespace mozilla {
+namespace dom {
+namespace cellbroadcast {
+
+NS_IMPL_ISUPPORTS(CellBroadcastParent, nsICellBroadcastListener)
+
+bool
+CellBroadcastParent::Init()
+{
+  nsCOMPtr<nsICellBroadcastService> service =
+    do_GetService(CELLBROADCAST_SERVICE_CONTRACTID);
+
+  if (service) {
+    return NS_SUCCEEDED(service->RegisterListener(this));
+  }
+
+  return false;
+}
+
+void
+CellBroadcastParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  nsCOMPtr<nsICellBroadcastService> service =
+    do_GetService(CELLBROADCAST_SERVICE_CONTRACTID);
+  if (service) {
+    service->UnregisterListener(this);
+  }
+}
+
+/*
+ * nsICellBroadcastListener
+ */
+NS_IMETHODIMP
+CellBroadcastParent::NotifyMessageReceived(uint32_t aServiceId,
+                                           const nsAString& aGsmGeographicalScope,
+                                           uint16_t aMessageCode,
+                                           uint16_t aMessageId,
+                                           const nsAString& aLanguage,
+                                           const nsAString& aBody,
+                                           const nsAString& aMessageClass,
+                                           DOMTimeStamp aTimestamp,
+                                           uint32_t aCdmaServiceCategory,
+                                           bool aHasEtwsInfo,
+                                           const nsAString& aEtwsWarningType,
+                                           bool aEtwsEmergencyUserAlert,
+                                           bool aEtwsPopup)
+{
+  return SendNotifyReceivedMessage(aServiceId,
+                                   nsString(aGsmGeographicalScope),
+                                   aMessageCode,
+                                   aMessageId,
+                                   nsString(aLanguage),
+                                   nsString(aBody),
+                                   nsString(aMessageClass),
+                                   aTimestamp,
+                                   aCdmaServiceCategory,
+                                   aHasEtwsInfo,
+                                   nsString(aEtwsWarningType),
+                                   aEtwsEmergencyUserAlert,
+                                   aEtwsPopup) ? NS_OK : NS_ERROR_FAILURE;
+}
+
+} // namespace cellbroadcast
+} // namespace dom
+} // namespace mozilla
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/cellbroadcast/ipc/CellBroadcastParent.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+
+#ifndef mozilla_dom_cellbroadcast_CellBroadcastParent_h
+#define mozilla_dom_cellbroadcast_CellBroadcastParent_h
+
+#include "mozilla/dom/cellbroadcast/PCellBroadcastParent.h"
+#include "nsICellBroadcastService.h"
+
+namespace mozilla {
+namespace dom {
+namespace cellbroadcast {
+
+class CellBroadcastParent MOZ_FINAL : public PCellBroadcastParent
+                                    , public nsICellBroadcastListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSICELLBROADCASTLISTENER
+
+  bool Init();
+
+private:
+  // MOZ_FINAL suppresses -Werror,-Wdelete-non-virtual-dtor
+  ~CellBroadcastParent() {};
+
+  virtual void ActorDestroy(ActorDestroyReason aWhy);
+};
+
+} // namespace cellbroadcast
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_cellbroadcast_CellBroadcastParent_h
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/cellbroadcast/ipc/PCellBroadcast.ipdl
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* 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 protocol PContent;
+
+namespace mozilla {
+namespace dom {
+namespace cellbroadcast {
+
+sync protocol PCellBroadcast {
+  manager PContent;
+
+child:
+  NotifyReceivedMessage(uint32_t aServiceId,
+                        nsString aGsmGeographicalScope,
+                        uint16_t aMessageCode,
+                        uint16_t aMessageId,
+                        nsString aLanguage,
+                        nsString aBody,
+                        nsString aMessageClass,
+                        uint64_t aTimestamp,
+                        uint32_t aCdmaServiceCategory,
+                        bool aHasEtwsInfo,
+                        nsString aEtwsWarningType,
+                        bool aEtwsEmergencyUserAlert,
+                        bool aEtwsPopup);
+
+parent:
+  /**
+   * Sent when the child no longer needs to use cellbroadcast.
+   */
+  __delete__();
+
+};
+
+} // namespace mobilemessage
+} // namespace dom
+} // namespace cellbroadcast
\ No newline at end of file
--- a/dom/cellbroadcast/moz.build
+++ b/dom/cellbroadcast/moz.build
@@ -9,19 +9,32 @@ DIRS += ['interfaces']
 EXPORTS.mozilla.dom += [
     'CellBroadcast.h',
     'CellBroadcastMessage.h',
 ]
 
 SOURCES += [
     'CellBroadcast.cpp',
     'CellBroadcastMessage.cpp',
+    'ipc/CellBroadcastIPCService.cpp',
+    'ipc/CellBroadcastParent.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
     EXTRA_COMPONENTS += [
         'gonk/CellBroadcastService.js',
         'gonk/CellBroadcastService.manifest',
     ]
 
+EXPORTS.mozilla.dom.cellbroadcast += [
+    'ipc/CellBroadcastIPCService.h',
+    'ipc/CellBroadcastParent.h',
+]
+
+IPDL_SOURCES += [
+    'ipc/PCellBroadcast.ipdl',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -121,16 +121,17 @@
 #include "nsIAccessibilityService.h"
 #endif
 
 #ifdef MOZ_NUWA_PROCESS
 #include <setjmp.h>
 #include "ipc/Nuwa.h"
 #endif
 
+#include "mozilla/dom/cellbroadcast/CellBroadcastIPCService.h"
 #include "mozilla/dom/indexedDB/PIndexedDBChild.h"
 #include "mozilla/dom/mobileconnection/MobileConnectionChild.h"
 #include "mozilla/dom/mobilemessage/SmsChild.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
 #include "mozilla/dom/PFileSystemRequestChild.h"
 #include "mozilla/dom/FileSystemTaskBase.h"
 #include "mozilla/dom/bluetooth/PBluetoothChild.h"
 #include "mozilla/dom/PFMRadioChild.h"
@@ -156,16 +157,17 @@
 #include "mozilla/dom/voicemail/VoicemailIPCService.h"
 #include "mozilla/net/NeckoMessageUtils.h"
 #include "mozilla/RemoteSpellCheckEngineChild.h"
 
 using namespace base;
 using namespace mozilla;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::bluetooth;
+using namespace mozilla::dom::cellbroadcast;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::dom::mobileconnection;
 using namespace mozilla::dom::mobilemessage;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::dom::telephony;
 using namespace mozilla::dom::voicemail;
 using namespace mozilla::hal_sandbox;
@@ -383,17 +385,17 @@ private:
 
 NS_IMPL_ISUPPORTS(ConsoleListener, nsIConsoleListener)
 
 NS_IMETHODIMP
 ConsoleListener::Observe(nsIConsoleMessage* aMessage)
 {
     if (!mChild)
         return NS_OK;
-    
+
     nsCOMPtr<nsIScriptError> scriptError = do_QueryInterface(aMessage);
     if (scriptError) {
         nsString msg, sourceName, sourceLine;
         nsXPIDLCString category;
         uint32_t lineNum, colNum, flags;
 
         nsresult rv = scriptError->GetErrorMessage(msg);
         NS_ENSURE_SUCCESS(rv, rv);
@@ -1387,16 +1389,40 @@ ContentChild::AllocPExternalHelperAppChi
 bool
 ContentChild::DeallocPExternalHelperAppChild(PExternalHelperAppChild* aService)
 {
     ExternalHelperAppChild *child = static_cast<ExternalHelperAppChild*>(aService);
     child->Release();
     return true;
 }
 
+PCellBroadcastChild*
+ContentChild::AllocPCellBroadcastChild()
+{
+    MOZ_CRASH("No one should be allocating PCellBroadcastChild actors");
+}
+
+PCellBroadcastChild*
+ContentChild::SendPCellBroadcastConstructor(PCellBroadcastChild* aActor)
+{
+    aActor = PContentChild::SendPCellBroadcastConstructor(aActor);
+    if (aActor) {
+        static_cast<CellBroadcastIPCService*>(aActor)->AddRef();
+    }
+
+    return aActor;
+}
+
+bool
+ContentChild::DeallocPCellBroadcastChild(PCellBroadcastChild* aActor)
+{
+    static_cast<CellBroadcastIPCService*>(aActor)->Release();
+    return true;
+}
+
 PSmsChild*
 ContentChild::AllocPSmsChild()
 {
     return new SmsChild();
 }
 
 bool
 ContentChild::DeallocPSmsChild(PSmsChild* aSms)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -222,16 +222,20 @@ public:
             const uint32_t& aContentDispositionHint,
             const nsString& aContentDispositionFilename,
             const bool& aForceSave,
             const int64_t& aContentLength,
             const OptionalURIParams& aReferrer,
             PBrowserChild* aBrowser) MOZ_OVERRIDE;
     virtual bool DeallocPExternalHelperAppChild(PExternalHelperAppChild *aService) MOZ_OVERRIDE;
 
+    virtual PCellBroadcastChild* AllocPCellBroadcastChild() MOZ_OVERRIDE;
+    PCellBroadcastChild* SendPCellBroadcastConstructor(PCellBroadcastChild* aActor);
+    virtual bool DeallocPCellBroadcastChild(PCellBroadcastChild* aActor) MOZ_OVERRIDE;
+
     virtual PSmsChild* AllocPSmsChild() MOZ_OVERRIDE;
     virtual bool DeallocPSmsChild(PSmsChild*) MOZ_OVERRIDE;
 
     virtual PTelephonyChild* AllocPTelephonyChild() MOZ_OVERRIDE;
     virtual bool DeallocPTelephonyChild(PTelephonyChild*) MOZ_OVERRIDE;
 
     virtual PVoicemailChild* AllocPVoicemailChild() MOZ_OVERRIDE;
     PVoicemailChild* SendPVoicemailConstructor(PVoicemailChild* aActor);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -44,16 +44,17 @@
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/dom/bluetooth/PBluetoothParent.h"
 #include "mozilla/dom/PFMRadioParent.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
 #include "mozilla/dom/FileSystemRequestParent.h"
 #include "mozilla/dom/GeolocationBinding.h"
 #include "mozilla/dom/FileDescriptorSetParent.h"
+#include "mozilla/dom/cellbroadcast/CellBroadcastParent.h"
 #include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
 #include "mozilla/dom/mobilemessage/SmsParent.h"
 #include "mozilla/dom/telephony/TelephonyParent.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/dom/voicemail/VoicemailParent.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
@@ -186,16 +187,17 @@ using namespace mozilla::system;
 #endif
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 static const char* sClipboardTextFlavors[] = { kUnicodeMime };
 
 using base::ChildPrivileges;
 using base::KillProcess;
 using namespace mozilla::dom::bluetooth;
+using namespace mozilla::dom::cellbroadcast;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::dom::power;
 using namespace mozilla::dom::mobileconnection;
 using namespace mozilla::dom::mobilemessage;
 using namespace mozilla::dom::telephony;
 using namespace mozilla::dom::voicemail;
 using namespace mozilla::hal;
@@ -2859,17 +2861,17 @@ ContentParent::KillHard()
     if (!KillProcess(OtherProcess(), 1, false)) {
         NS_WARNING("failed to kill subprocess!");
     }
     mSubprocess->SetAlreadyDead();
     XRE_GetIOMessageLoop()->PostTask(
         FROM_HERE,
         NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
                             OtherProcess(), /*force=*/true));
-    //We do clean-up here 
+    //We do clean-up here
     MessageLoop::current()->PostDelayedTask(
         FROM_HERE,
         NewRunnableMethod(this, &ContentParent::ShutDownProcess,
                           /* closeWithError */ true),
         3000);
     // We've now closed the OtherProcess() handle, so must set it to null to
     // prevent our dtor closing it twice.
     SetOtherProcess(0);
@@ -3100,35 +3102,60 @@ ContentParent::AllocPExternalHelperAppPa
                                              const nsString& aContentDispositionFilename,
                                              const bool& aForceSave,
                                              const int64_t& aContentLength,
                                              const OptionalURIParams& aReferrer,
                                              PBrowserParent* aBrowser)
 {
     ExternalHelperAppParent *parent = new ExternalHelperAppParent(uri, aContentLength);
     parent->AddRef();
-    parent->Init(this, 
-                 aMimeContentType, 
+    parent->Init(this,
+                 aMimeContentType,
                  aContentDisposition,
                  aContentDispositionHint,
                  aContentDispositionFilename,
-                 aForceSave, 
-                 aReferrer, 
+                 aForceSave,
+                 aReferrer,
                  aBrowser);
     return parent;
 }
 
 bool
 ContentParent::DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService)
 {
     ExternalHelperAppParent *parent = static_cast<ExternalHelperAppParent *>(aService);
     parent->Release();
     return true;
 }
 
+PCellBroadcastParent*
+ContentParent::AllocPCellBroadcastParent()
+{
+    if (!AssertAppProcessPermission(this, "cellbroadcast")) {
+        return nullptr;
+    }
+
+    CellBroadcastParent* actor = new CellBroadcastParent();
+    actor->AddRef();
+    return actor;
+}
+
+bool
+ContentParent::DeallocPCellBroadcastParent(PCellBroadcastParent* aActor)
+{
+    static_cast<CellBroadcastParent*>(aActor)->Release();
+    return true;
+}
+
+bool
+ContentParent::RecvPCellBroadcastConstructor(PCellBroadcastParent* aActor)
+{
+    return static_cast<CellBroadcastParent*>(aActor)->Init();
+}
+
 PSmsParent*
 ContentParent::AllocPSmsParent()
 {
     if (!AssertAppProcessPermission(this, "sms")) {
         return nullptr;
     }
 
     SmsParent* parent = new SmsParent();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -469,23 +469,27 @@ private:
 
     virtual bool DeallocPNeckoParent(PNeckoParent* necko) MOZ_OVERRIDE;
 
     virtual PExternalHelperAppParent* AllocPExternalHelperAppParent(
             const OptionalURIParams& aUri,
             const nsCString& aMimeContentType,
             const nsCString& aContentDisposition,
             const uint32_t& aContentDispositionHint,
-            const nsString& aContentDispositionFilename, 
+            const nsString& aContentDispositionFilename,
             const bool& aForceSave,
             const int64_t& aContentLength,
             const OptionalURIParams& aReferrer,
             PBrowserParent* aBrowser) MOZ_OVERRIDE;
     virtual bool DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService) MOZ_OVERRIDE;
 
+    virtual PCellBroadcastParent* AllocPCellBroadcastParent() MOZ_OVERRIDE;
+    virtual bool DeallocPCellBroadcastParent(PCellBroadcastParent*) MOZ_OVERRIDE;
+    virtual bool RecvPCellBroadcastConstructor(PCellBroadcastParent* aActor) MOZ_OVERRIDE;
+
     virtual PSmsParent* AllocPSmsParent() MOZ_OVERRIDE;
     virtual bool DeallocPSmsParent(PSmsParent*) MOZ_OVERRIDE;
 
     virtual PTelephonyParent* AllocPTelephonyParent() MOZ_OVERRIDE;
     virtual bool DeallocPTelephonyParent(PTelephonyParent*) MOZ_OVERRIDE;
 
     virtual PVoicemailParent* AllocPVoicemailParent() MOZ_OVERRIDE;
     virtual bool RecvPVoicemailConstructor(PVoicemailParent* aActor) MOZ_OVERRIDE;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -4,16 +4,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/. */
 
 include protocol PAsmJSCacheEntry;
 include protocol PBackground;
 include protocol PBlob;
 include protocol PBluetooth;
 include protocol PBrowser;
+include protocol PCellBroadcast;
 include protocol PCompositor;
 include protocol PContentBridge;
 include protocol PCycleCollectWithLogs;
 include protocol PCrashReporter;
 include protocol PExternalHelperApp;
 include protocol PDeviceStorageRequest;
 include protocol PFileDescriptorSet;
 include protocol PFMRadio;
@@ -36,16 +37,21 @@ include protocol PJavaScript;
 include protocol PRemoteSpellcheckEngine;
 include DOMTypes;
 include JavaScriptTypes;
 include InputStreamParams;
 include PTabContext;
 include URIParams;
 include ProtocolTypes;
 
+// Workaround to prevent error if PContentChild.cpp & PContentBridgeParent.cpp
+// are put into different UnifiedProtocolsXX.cpp files.
+// XXX Remove this once bug 1069073 is fixed
+include "mozilla/dom/PContentBridgeParent.h";
+
 using GeoPosition from "nsGeoPositionIPCSerialiser.h";
 
 using struct ChromePackage from "mozilla/chrome/RegistryMessageUtils.h";
 using struct ResourceMapping from "mozilla/chrome/RegistryMessageUtils.h";
 using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.h";
 using base::ChildPrivileges from "base/process_util.h";
 using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
@@ -316,16 +322,17 @@ intr protocol PContent
     parent opens PSharedBufferManager;
     parent opens PImageBridge;
     child opens PBackground;
 
     manages PAsmJSCacheEntry;
     manages PBlob;
     manages PBluetooth;
     manages PBrowser;
+    manages PCellBroadcast;
     manages PCrashReporter;
     manages PCycleCollectWithLogs;
     manages PDeviceStorageRequest;
     manages PFileSystemRequest;
     manages PExternalHelperApp;
     manages PFileDescriptorSet;
     manages PFMRadio;
     manages PHal;
@@ -528,16 +535,18 @@ parent:
 
     PNecko();
 
     rpc PScreenManager()
         returns (uint32_t numberOfScreens,
                  float systemDefaultScale,
                  bool success);
 
+    PCellBroadcast();
+
     PSms();
 
     PSpeechSynthesis();
 
     PStorage();
 
     PTelephony();
 
@@ -578,34 +587,34 @@ parent:
                           nsString name,
                           nsString bidi,
                           nsString lang,
                           nsString data,
                           Principal principal);
 
     CloseAlert(nsString name, Principal principal);
 
-    PExternalHelperApp(OptionalURIParams uri, 
+    PExternalHelperApp(OptionalURIParams uri,
                        nsCString aMimeContentType,
-                       nsCString aContentDisposition, 
-                       uint32_t aContentDispositionHint, 
-                       nsString aContentDispositionFilename, 
+                       nsCString aContentDisposition,
+                       uint32_t aContentDispositionHint,
+                       nsString aContentDispositionFilename,
                        bool aForceSave,
                        int64_t aContentLength,
                        OptionalURIParams aReferrer,
                        nullable PBrowser aBrowser);
 
     AddGeolocationListener(Principal principal, bool highAccuracy);
     RemoveGeolocationListener();
     SetGeolocationHigherAccuracy(bool enable);
 
     ConsoleMessage(nsString message);
     ScriptError(nsString message, nsString sourceName, nsString sourceLine,
                 uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
-                nsCString category); 
+                nsCString category);
 
     // nsIPermissionManager messages
     sync ReadPermissions() returns (Permission[] permissions);
 
     SetClipboardText(nsString text, bool isPrivateData, int32_t whichClipboard);
     sync GetClipboardText(int32_t whichClipboard)
         returns (nsString text);
     EmptyClipboard(int32_t whichClipboard);
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -209,16 +209,17 @@ static void Shutdown();
 
 #include "nsGeolocation.h"
 #include "nsDeviceSensors.h"
 #ifdef MOZ_GAMEPAD
 #include "mozilla/dom/GamepadService.h"
 #endif
 #include "nsCSPService.h"
 #include "nsCSPContext.h"
+#include "nsICellBroadcastService.h"
 #include "nsISmsService.h"
 #include "nsIMmsService.h"
 #include "nsIMobileConnectionService.h"
 #include "nsIMobileMessageService.h"
 #include "nsIMobileMessageDatabaseService.h"
 #include "nsIPowerManagerService.h"
 #include "nsIAlarmHalService.h"
 #include "nsIMediaManager.h"
@@ -313,16 +314,18 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(AudioChan
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceSensors)
 
 #ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHapticFeedback)
 #endif
 #endif
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ThirdPartyUtil, Init)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsICellBroadcastService,
+                                         NS_CreateCellBroadcastService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsService, NS_CreateSmsService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIMmsService, NS_CreateMmsService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIMobileMessageService,
                                          NS_CreateMobileMessageService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIMobileMessageDatabaseService,
                                          NS_CreateMobileMessageDatabaseService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIPowerManagerService,
                                          PowerManagerService::GetInstance)
@@ -759,16 +762,17 @@ NS_DEFINE_NAMED_CID(THIRDPARTYUTIL_CID);
 NS_DEFINE_NAMED_CID(NS_STRUCTUREDCLONECONTAINER_CID);
 NS_DEFINE_NAMED_CID(NS_DEVICE_SENSORS_CID);
 
 #ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID)
 NS_DEFINE_NAMED_CID(NS_HAPTICFEEDBACK_CID);
 #endif
 #endif
+NS_DEFINE_NAMED_CID(CELLBROADCAST_SERVICE_CID);
 NS_DEFINE_NAMED_CID(SMS_SERVICE_CID);
 NS_DEFINE_NAMED_CID(MMS_SERVICE_CID);
 NS_DEFINE_NAMED_CID(MOBILE_MESSAGE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(MOBILE_MESSAGE_DATABASE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_POWERMANAGERSERVICE_CID);
 NS_DEFINE_NAMED_CID(OSFILECONSTANTSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_ALARMHALSERVICE_CID);
 NS_DEFINE_NAMED_CID(TCPSOCKETCHILD_CID);
@@ -1052,16 +1056,17 @@ static const mozilla::Module::CIDEntry k
   { &kNS_DEVICE_SENSORS_CID, false, nullptr, nsDeviceSensorsConstructor },
 #ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID)
   { &kNS_HAPTICFEEDBACK_CID, false, nullptr, nsHapticFeedbackConstructor },
 #endif
 #endif
   { &kTHIRDPARTYUTIL_CID, false, nullptr, ThirdPartyUtilConstructor },
   { &kNS_STRUCTUREDCLONECONTAINER_CID, false, nullptr, nsStructuredCloneContainerConstructor },
+  { &kCELLBROADCAST_SERVICE_CID, false, nullptr, nsICellBroadcastServiceConstructor },
   { &kSMS_SERVICE_CID, false, nullptr, nsISmsServiceConstructor },
   { &kMMS_SERVICE_CID, false, nullptr, nsIMmsServiceConstructor },
   { &kMOBILE_MESSAGE_SERVICE_CID, false, nullptr, nsIMobileMessageServiceConstructor },
   { &kMOBILE_MESSAGE_DATABASE_SERVICE_CID, false, nullptr, nsIMobileMessageDatabaseServiceConstructor },
   { &kNS_POWERMANAGERSERVICE_CID, false, nullptr, nsIPowerManagerServiceConstructor },
   { &kOSFILECONSTANTSSERVICE_CID, true, nullptr, OSFileConstantsServiceConstructor },
   { &kNS_ALARMHALSERVICE_CID, false, nullptr, nsIAlarmHalServiceConstructor },
   { &kTCPSOCKETCHILD_CID, false, nullptr, TCPSocketChildConstructor },
@@ -1210,16 +1215,17 @@ static const mozilla::Module::ContractID
   { NS_DEVICE_SENSORS_CONTRACTID, &kNS_DEVICE_SENSORS_CID },
 #ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID)
   { "@mozilla.org/widget/hapticfeedback;1", &kNS_HAPTICFEEDBACK_CID },
 #endif
 #endif
   { THIRDPARTYUTIL_CONTRACTID, &kTHIRDPARTYUTIL_CID },
   { NS_STRUCTUREDCLONECONTAINER_CONTRACTID, &kNS_STRUCTUREDCLONECONTAINER_CID },
+  { CELLBROADCAST_SERVICE_CONTRACTID, &kCELLBROADCAST_SERVICE_CID },
   { SMS_SERVICE_CONTRACTID, &kSMS_SERVICE_CID },
   { MMS_SERVICE_CONTRACTID, &kMMS_SERVICE_CID },
   { MOBILE_MESSAGE_SERVICE_CONTRACTID, &kMOBILE_MESSAGE_SERVICE_CID },
   { MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID, &kMOBILE_MESSAGE_DATABASE_SERVICE_CID },
   { POWERMANAGERSERVICE_CONTRACTID, &kNS_POWERMANAGERSERVICE_CID },
   { OSFILECONSTANTSSERVICE_CONTRACTID, &kOSFILECONSTANTSSERVICE_CID },
   { ALARMHALSERVICE_CONTRACTID, &kNS_ALARMHALSERVICE_CID },
   { "@mozilla.org/tcp-socket-child;1", &kTCPSOCKETCHILD_CID },