Bug 843452 - Part 3-1: IPDL for MobileConnection. r=smaug
authorEdgar Chen <echen@mozilla.com>
Tue, 01 Jul 2014 18:09:08 +0800
changeset 203333 df5f41ac3cb9bd244af28098b7994e653263a129
parent 203332 c6896f655e86c8d7a18f5a669bf090de2b564894
child 203334 2202544e8831cdb86387d40ed87ca97213142212
push id48665
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 20:40:15 +0000
treeherdermozilla-inbound@0da762e6868a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs843452
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 843452 - Part 3-1: IPDL for MobileConnection. r=smaug
dom/ipc/PContent.ipdl
dom/mobileconnection/MobileCellInfo.cpp
dom/mobileconnection/MobileCellInfo.h
dom/mobileconnection/MobileConnectionInfo.cpp
dom/mobileconnection/MobileConnectionInfo.h
dom/mobileconnection/MobileNetworkInfo.cpp
dom/mobileconnection/MobileNetworkInfo.h
dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
dom/mobileconnection/ipc/PMobileConnection.ipdl
dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl
dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh
dom/mobileconnection/moz.build
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -17,16 +17,17 @@ include protocol PExternalHelperApp;
 include protocol PDeviceStorageRequest;
 include protocol PFileDescriptorSet;
 include protocol PFMRadio;
 include protocol PFileSystemRequest;
 include protocol PHal;
 include protocol PImageBridge;
 include protocol PIndexedDB;
 include protocol PMemoryReportRequest;
+include protocol PMobileConnection;
 include protocol PNecko;
 include protocol PScreenManager;
 include protocol PSharedBufferManager;
 include protocol PSms;
 include protocol PSpeechSynthesis;
 include protocol PStorage;
 include protocol PTelephony;
 include protocol PTestShell;
@@ -305,16 +306,17 @@ intr protocol PContent
     manages PDeviceStorageRequest;
     manages PFileSystemRequest;
     manages PExternalHelperApp;
     manages PFileDescriptorSet;
     manages PFMRadio;
     manages PHal;
     manages PIndexedDB;
     manages PMemoryReportRequest;
+    manages PMobileConnection;
     manages PNecko;
     manages PScreenManager;
     manages PSms;
     manages PSpeechSynthesis;
     manages PStorage;
     manages PTelephony;
     manages PTestShell;
     manages PJavaScript;
@@ -493,16 +495,18 @@ parent:
 
     sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags)
         returns (bool isSecureURI);
 
     PHal();
 
     PIndexedDB();
 
+    PMobileConnection(uint32_t clientId);
+
     PNecko();
 
     rpc PScreenManager()
         returns (uint32_t numberOfScreens,
                  float systemDefaultScale,
                  bool success);
 
     PSms();
--- a/dom/mobileconnection/MobileCellInfo.cpp
+++ b/dom/mobileconnection/MobileCellInfo.cpp
@@ -28,16 +28,37 @@ MobileCellInfo::MobileCellInfo(nsPIDOMWi
   , mCdmaBaseStationLatitude(-1)
   , mCdmaBaseStationLongitude(-1)
   , mCdmaSystemId(-1)
   , mCdmaNetworkId(-1)
 {
   SetIsDOMBinding();
 }
 
+MobileCellInfo::MobileCellInfo(int32_t aGsmLocationAreaCode,
+                               int64_t aGsmCellId,
+                               int32_t aCdmaBaseStationId,
+                               int32_t aCdmaBaseStationLatitude,
+                               int32_t aCdmaBaseStationLongitude,
+                               int32_t aCdmaSystemId,
+                               int32_t aCdmaNetworkId)
+  : mGsmLocationAreaCode(aGsmLocationAreaCode)
+  , mGsmCellId(aGsmCellId)
+  , mCdmaBaseStationId(aCdmaBaseStationId)
+  , mCdmaBaseStationLatitude(aCdmaBaseStationLatitude)
+  , mCdmaBaseStationLongitude(aCdmaBaseStationLongitude)
+  , mCdmaSystemId(aCdmaSystemId)
+  , mCdmaNetworkId(aCdmaNetworkId)
+{
+  // The instance created by this way is only used for IPC stuff. It won't be
+  // expose to JS directly, we will clone this instance to the one that is
+  // maintained in MobileConnectionChild. So we don't need SetIsDOMBinding()
+  // here.
+}
+
 void
 MobileCellInfo::Update(nsIMobileCellInfo* aInfo)
 {
   if (!aInfo) {
     return;
   }
 
   aInfo->GetGsmLocationAreaCode(&mGsmLocationAreaCode);
@@ -47,16 +68,17 @@ MobileCellInfo::Update(nsIMobileCellInfo
   aInfo->GetCdmaBaseStationLongitude(&mCdmaBaseStationLongitude);
   aInfo->GetCdmaSystemId(&mCdmaSystemId);
   aInfo->GetCdmaNetworkId(&mCdmaNetworkId);
 }
 
 JSObject*
 MobileCellInfo::WrapObject(JSContext* aCx)
 {
+  MOZ_ASSERT(IsDOMBinding());
   return MozMobileCellInfoBinding::Wrap(aCx, this);
 }
 
 // nsIMobileCellInfo
 
 NS_IMETHODIMP
 MobileCellInfo::GetGsmLocationAreaCode(int32_t* aGsmLocationAreaCode)
 {
--- a/dom/mobileconnection/MobileCellInfo.h
+++ b/dom/mobileconnection/MobileCellInfo.h
@@ -19,16 +19,21 @@ class MobileCellInfo MOZ_FINAL : public 
 {
 public:
   NS_DECL_NSIMOBILECELLINFO
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MobileCellInfo)
 
   MobileCellInfo(nsPIDOMWindow* aWindow);
 
+  MobileCellInfo(int32_t aGsmLocationAreaCode, int64_t aGsmCellId,
+                 int32_t aCdmaBaseStationId, int32_t aCdmaBaseStationLatitude,
+                 int32_t aCdmaBaseStationLongitude, int32_t aCdmaSystemId,
+                 int32_t aCdmaNetworkId);
+
   void
   Update(nsIMobileCellInfo* aInfo);
 
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
--- a/dom/mobileconnection/MobileConnectionInfo.cpp
+++ b/dom/mobileconnection/MobileConnectionInfo.cpp
@@ -53,16 +53,53 @@ MobileConnectionInfo::MobileConnectionIn
   : mConnected(false)
   , mEmergencyCallsOnly(false)
   , mRoaming(false)
   , mWindow(aWindow)
 {
   SetIsDOMBinding();
 }
 
+MobileConnectionInfo::MobileConnectionInfo(const nsAString& aState,
+                                           bool aConnected,
+                                           bool aEmergencyCallsOnly,
+                                           bool aRoaming,
+                                           nsIMobileNetworkInfo* aNetworkInfo,
+                                           const nsAString& aType,
+                                           const Nullable<int32_t>& aSignalStrength,
+                                           const Nullable<uint16_t>& aRelSignalStrength,
+                                           nsIMobileCellInfo* aCellInfo)
+  : mConnected(aConnected)
+  , mEmergencyCallsOnly(aEmergencyCallsOnly)
+  , mRoaming(aRoaming)
+  , mSignalStrength(aSignalStrength)
+  , mRelSignalStrength(aRelSignalStrength)
+{
+  // The instance created by this way is only used for IPC stuff. It won't be
+  // expose to JS directly, we will clone this instance to the one that is
+  // maintained in MobileConnectionChild. So we don't need SetIsDOMBinding()
+  // here.
+
+  // Update mState and mType
+  CONVERT_STRING_TO_NULLABLE_ENUM(aState, MobileConnectionState, mState);
+  CONVERT_STRING_TO_NULLABLE_ENUM(aType, MobileConnectionType, mType);
+
+  // Update mNetworkInfo
+  if (aNetworkInfo) {
+    mNetworkInfo = new MobileNetworkInfo(mWindow);
+    mNetworkInfo->Update(aNetworkInfo);
+  }
+
+  // Update mCellInfo
+  if (aCellInfo) {
+    mCellInfo = new MobileCellInfo(mWindow);
+    mCellInfo->Update(aCellInfo);
+  }
+}
+
 void
 MobileConnectionInfo::Update(nsIMobileConnectionInfo* aInfo)
 {
   if (!aInfo) {
     return;
   }
 
   aInfo->GetConnected(&mConnected);
@@ -121,16 +158,17 @@ MobileConnectionInfo::Update(nsIMobileCo
   } else {
     mCellInfo = nullptr;
   }
 }
 
 JSObject*
 MobileConnectionInfo::WrapObject(JSContext* aCx)
 {
+  MOZ_ASSERT(IsDOMBinding());
   return MozMobileConnectionInfoBinding::Wrap(aCx, this);
 }
 
 // nsIMobileConnectionInfo
 
 NS_IMETHODIMP
 MobileConnectionInfo::GetState(nsAString& aState)
 {
--- a/dom/mobileconnection/MobileConnectionInfo.h
+++ b/dom/mobileconnection/MobileConnectionInfo.h
@@ -22,16 +22,24 @@ class MobileConnectionInfo MOZ_FINAL : p
 {
 public:
   NS_DECL_NSIMOBILECONNECTIONINFO
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MobileConnectionInfo)
 
   MobileConnectionInfo(nsPIDOMWindow* aWindow);
 
+  MobileConnectionInfo(const nsAString& aState, bool aConnected,
+                       bool aEmergencyCallsOnly, bool aRoaming,
+                       nsIMobileNetworkInfo* aNetworkInfo,
+                       const nsAString& aType,
+                       const Nullable<int32_t>& aSignalStrength,
+                       const Nullable<uint16_t>& aRelSignalStrength,
+                       nsIMobileCellInfo* aCellInfo);
+
   void
   Update(nsIMobileConnectionInfo* aInfo);
 
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
--- a/dom/mobileconnection/MobileNetworkInfo.cpp
+++ b/dom/mobileconnection/MobileNetworkInfo.cpp
@@ -20,16 +20,32 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 MobileNetworkInfo::MobileNetworkInfo(nsPIDOMWindow* aWindow)
   : mWindow(aWindow)
 {
   SetIsDOMBinding();
 }
 
+MobileNetworkInfo::MobileNetworkInfo(const nsAString& aShortName,
+                                     const nsAString& aLongName,
+                                     const nsAString& aMcc,
+                                     const nsAString& aMnc,
+                                     const nsAString& aState)
+  : mShortName(aShortName)
+  , mLongName(aLongName)
+  , mMcc(aMcc)
+  , mMnc(aMnc)
+  , mState(aState)
+{
+  // The parent object is nullptr when MobileNetworkInfo is created by this way.
+  // And it won't be exposed to web content.
+  SetIsDOMBinding();
+}
+
 void
 MobileNetworkInfo::Update(nsIMobileNetworkInfo* aInfo)
 {
   if (!aInfo) {
     return;
   }
 
   aInfo->GetShortName(mShortName);
--- a/dom/mobileconnection/MobileNetworkInfo.h
+++ b/dom/mobileconnection/MobileNetworkInfo.h
@@ -22,16 +22,20 @@ class MobileNetworkInfo MOZ_FINAL : publ
 {
 public:
   NS_DECL_NSIMOBILENETWORKINFO
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MobileNetworkInfo)
 
   MobileNetworkInfo(nsPIDOMWindow* aWindow);
 
+  MobileNetworkInfo(const nsAString& aShortName, const nsAString& aLongName,
+                    const nsAString& aMcc, const nsAString& aMnc,
+                    const nsAString& aState);
+
   void
   Update(nsIMobileNetworkInfo* aInfo);
 
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
@@ -0,0 +1,749 @@
+/* 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 dom_mobileconnection_src_ipc_MobileConnectionIPCSerialiser_h
+#define dom_mobileconnection_src_ipc_MobileConnectionIPCSerialiser_h
+
+#include "ipc/IPCMessageUtils.h"
+#include "mozilla/dom/MobileCellInfo.h"
+#include "mozilla/dom/MobileConnectionInfo.h"
+#include "mozilla/dom/MobileNetworkInfo.h"
+#include "MozMobileConnectionBinding.h"
+
+using mozilla::AutoSafeJSContext;
+using mozilla::dom::MobileNetworkInfo;
+using mozilla::dom::MobileCellInfo;
+using mozilla::dom::MobileConnectionInfo;
+
+typedef nsIMobileCellInfo* nsMobileCellInfo;
+typedef nsIMobileConnectionInfo* nsMobileConnectionInfo;
+typedef nsIMobileNetworkInfo* nsMobileNetworkInfo;
+
+namespace IPC {
+
+struct MozCallForwardingOptions : public mozilla::dom::MozCallForwardingOptions
+{
+  bool operator==(const MozCallForwardingOptions& aOther) const
+  {
+    return // Compare mActive
+           ((!mActive.WasPassed() && !aOther.mActive.WasPassed()) ||
+            (mActive.WasPassed() && aOther.mActive.WasPassed() &&
+             mActive.Value() == aOther.mActive.Value())) &&
+           // Compare mAction
+           ((!mAction.WasPassed() && !aOther.mAction.WasPassed()) ||
+            (mAction.WasPassed() && aOther.mAction.WasPassed() &&
+             mAction.Value() == aOther.mAction.Value())) &&
+           // Compare mReason
+           ((!mReason.WasPassed() && !aOther.mReason.WasPassed()) ||
+            (mReason.WasPassed() && aOther.mReason.WasPassed() &&
+             mReason.Value() == aOther.mReason.Value())) &&
+           // Compare mNumber
+           ((!mNumber.WasPassed() && !aOther.mNumber.WasPassed()) ||
+            (mNumber.WasPassed() && aOther.mNumber.WasPassed() &&
+             mNumber.Value() == aOther.mNumber.Value())) &&
+           // Compare mTimeSeconds
+           ((!mTimeSeconds.WasPassed() && !aOther.mTimeSeconds.WasPassed()) ||
+            (mTimeSeconds.WasPassed() && aOther.mTimeSeconds.WasPassed() &&
+             mTimeSeconds.Value() == aOther.mTimeSeconds.Value())) &&
+           // Compare mServiceClass
+           ((!mServiceClass.WasPassed() && !aOther.mServiceClass.WasPassed()) ||
+            (mServiceClass.WasPassed() && aOther.mServiceClass.WasPassed() &&
+             mServiceClass.Value() == aOther.mServiceClass.Value()));
+  };
+};
+
+struct MozCallBarringOptions : mozilla::dom::MozCallBarringOptions
+{
+  bool operator==(const MozCallBarringOptions& aOther) const
+  {
+    return // Compare mEnabled
+           ((!mEnabled.WasPassed() && !aOther.mEnabled.WasPassed()) ||
+            (mEnabled.WasPassed() && aOther.mEnabled.WasPassed() &&
+             mEnabled.Value() == aOther.mEnabled.Value())) &&
+           // Compare mPassword
+           ((!mPassword.WasPassed() && !aOther.mPassword.WasPassed()) ||
+            (mPassword.WasPassed() && aOther.mPassword.WasPassed() &&
+             mPassword.Value() == aOther.mPassword.Value())) &&
+           // Compare mProgram
+           ((!mProgram.WasPassed() && !aOther.mProgram.WasPassed()) ||
+            (mProgram.WasPassed() && aOther.mProgram.WasPassed() &&
+             mProgram.Value() == aOther.mProgram.Value())) &&
+           // Compare mServiceClass
+           ((!mServiceClass.WasPassed() && !aOther.mServiceClass.WasPassed()) ||
+            (mServiceClass.WasPassed() && aOther.mServiceClass.WasPassed() &&
+             mServiceClass.Value() == aOther.mServiceClass.Value()));
+  };
+};
+
+/**
+ * nsIMobileNetworkInfo Serialize/De-serialize.
+ */
+template <>
+struct ParamTraits<nsIMobileNetworkInfo*>
+{
+  typedef nsIMobileNetworkInfo* paramType;
+
+  // Function to serialize a MobileNetworkInfo.
+  static void Write(Message *aMsg, const paramType& aParam)
+  {
+    bool isNull = !aParam;
+    WriteParam(aMsg, isNull);
+    // If it is a null object, then we are done.
+    if (isNull) {
+      return;
+    }
+
+    nsString pString;
+    aParam->GetShortName(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetLongName(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetMcc(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetMnc(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetState(pString);
+    WriteParam(aMsg, pString);
+
+    // We release the ref here given that ipdl won't handle reference counting.
+    aParam->Release();
+  }
+
+  // Function to de-serialize a MobileNetworkInfo.
+  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  {
+    // Check if is the null pointer we have transfered.
+    bool isNull;
+    if (!ReadParam(aMsg, aIter, &isNull)) {
+      return false;
+    }
+
+    if (isNull) {
+      *aResult = nullptr;
+      return true;
+    }
+
+    nsString shortName;
+    nsString longName;
+    nsString mcc;
+    nsString mnc;
+    nsString state;
+
+    // It's not important to us where it fails, but rather if it fails
+    if (!(ReadParam(aMsg, aIter, &shortName) &&
+          ReadParam(aMsg, aIter, &longName) &&
+          ReadParam(aMsg, aIter, &mcc) &&
+          ReadParam(aMsg, aIter, &mnc) &&
+          ReadParam(aMsg, aIter, &state))) {
+      return false;
+    }
+
+    *aResult = new MobileNetworkInfo(shortName,
+                                     longName,
+                                     mcc,
+                                     mnc,
+                                     state);
+    // We release this ref after receiver finishes processing.
+    NS_ADDREF(*aResult);
+
+    return true;
+  }
+};
+
+/**
+ * nsIMobileCellInfo Serialize/De-serialize.
+ */
+template <>
+struct ParamTraits<nsIMobileCellInfo*>
+{
+  typedef nsIMobileCellInfo* paramType;
+
+  // Function to serialize a MobileCellInfo.
+  static void Write(Message *aMsg, const paramType& aParam)
+  {
+    bool isNull = !aParam;
+    WriteParam(aMsg, isNull);
+    // If it is a null object, then we are done.
+    if (isNull) {
+      return;
+    }
+
+    int32_t pLong;
+    int64_t pLongLong;
+
+    aParam->GetGsmLocationAreaCode(&pLong);
+    WriteParam(aMsg, pLong);
+
+    aParam->GetGsmCellId(&pLongLong);
+    WriteParam(aMsg, pLongLong);
+
+    aParam->GetCdmaBaseStationId(&pLong);
+    WriteParam(aMsg, pLong);
+
+    aParam->GetCdmaBaseStationLatitude(&pLong);
+    WriteParam(aMsg, pLong);
+
+    aParam->GetCdmaBaseStationLongitude(&pLong);
+    WriteParam(aMsg, pLong);
+
+    aParam->GetCdmaSystemId(&pLong);
+    WriteParam(aMsg, pLong);
+
+    aParam->GetCdmaNetworkId(&pLong);
+    WriteParam(aMsg, pLong);
+
+    // We release the ref here given that ipdl won't handle reference counting.
+    aParam->Release();
+  }
+
+  // Function to de-serialize a MobileCellInfo.
+  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  {
+    // Check if is the null pointer we have transfered.
+    bool isNull;
+    if (!ReadParam(aMsg, aIter, &isNull)) {
+      return false;
+    }
+
+    if (isNull) {
+      *aResult = nullptr;
+      return true;
+    }
+
+    int32_t gsmLac;
+    int64_t gsmCellId;
+    int32_t cdmaBsId;
+    int32_t cdmaBsLat;
+    int32_t cdmaBsLong;
+    int32_t cdmaSystemId;
+    int32_t cdmaNetworkId;
+
+    // It's not important to us where it fails, but rather if it fails
+    if (!(ReadParam(aMsg, aIter, &gsmLac) &&
+          ReadParam(aMsg, aIter, &gsmCellId) &&
+          ReadParam(aMsg, aIter, &cdmaBsId) &&
+          ReadParam(aMsg, aIter, &cdmaBsLat) &&
+          ReadParam(aMsg, aIter, &cdmaBsLong) &&
+          ReadParam(aMsg, aIter, &cdmaSystemId) &&
+          ReadParam(aMsg, aIter, &cdmaNetworkId))) {
+      return false;
+    }
+
+    *aResult = new MobileCellInfo(gsmLac, gsmCellId, cdmaBsId, cdmaBsLat,
+                                  cdmaBsLong, cdmaSystemId, cdmaNetworkId);
+    // We release this ref after receiver finishes processing.
+    NS_ADDREF(*aResult);
+
+    return true;
+  }
+};
+
+/**
+ * nsIMobileConnectionInfo Serialize/De-serialize.
+ */
+template <>
+struct ParamTraits<nsIMobileConnectionInfo*>
+{
+  typedef nsIMobileConnectionInfo* paramType;
+
+  // Function to serialize a MobileConnectionInfo.
+  static void Write(Message *aMsg, const paramType& aParam)
+  {
+    bool isNull = !aParam;
+    WriteParam(aMsg, isNull);
+    // If it is a null object, then we are done.
+    if (isNull) {
+      return;
+    }
+
+    AutoSafeJSContext cx;
+    nsString pString;
+    bool pBool;
+    nsCOMPtr<nsIMobileNetworkInfo> pNetworkInfo;
+    nsCOMPtr<nsIMobileCellInfo> pCellInfo;
+    JS::Rooted<JS::Value> pJsval(cx);
+    int32_t pInt32;
+
+    aParam->GetState(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetConnected(&pBool);
+    WriteParam(aMsg, pBool);
+
+    aParam->GetEmergencyCallsOnly(&pBool);
+    WriteParam(aMsg, pBool);
+
+    aParam->GetRoaming(&pBool);
+    WriteParam(aMsg, pBool);
+
+    aParam->GetType(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetNetwork(getter_AddRefs(pNetworkInfo));
+    // Release ref when WriteParam is finished.
+    WriteParam(aMsg, pNetworkInfo.forget().take());
+
+    aParam->GetCell(getter_AddRefs(pCellInfo));
+    // Release ref when WriteParam is finished.
+    WriteParam(aMsg, pCellInfo.forget().take());
+
+    // Serialize jsval signalStrength
+    aParam->GetSignalStrength(&pJsval);
+    isNull = !pJsval.isInt32();
+    WriteParam(aMsg, isNull);
+
+    if (!isNull) {
+      pInt32 = pJsval.toInt32();
+      WriteParam(aMsg, pInt32);
+    }
+
+    // Serialize jsval relSignalStrength
+    aParam->GetRelSignalStrength(&pJsval);
+    isNull = !pJsval.isInt32();
+    WriteParam(aMsg, isNull);
+
+    if (!isNull) {
+      pInt32 = pJsval.toInt32();
+      WriteParam(aMsg, pInt32);
+    }
+
+    // We release the ref here given that ipdl won't handle reference counting.
+    aParam->Release();
+  }
+
+  // Function to de-serialize a MobileConectionInfo.
+  static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
+  {
+    // Check if is the null pointer we have transfered.
+    bool isNull;
+    if (!ReadParam(aMsg, aIter, &isNull)) {
+      return false;
+    }
+
+    if (isNull) {
+      *aResult = nullptr;
+      return true;
+    }
+
+    AutoSafeJSContext cx;
+    nsString state;
+    bool connected;
+    bool emergencyOnly;
+    bool roaming;
+    nsString type;
+    nsIMobileNetworkInfo* networkInfo = nullptr;
+    nsIMobileCellInfo* cellInfo = nullptr;
+    Nullable<int32_t> signalStrength;
+    Nullable<uint16_t> relSignalStrength;
+
+    // It's not important to us where it fails, but rather if it fails
+    if (!(ReadParam(aMsg, aIter, &state) &&
+          ReadParam(aMsg, aIter, &connected) &&
+          ReadParam(aMsg, aIter, &emergencyOnly) &&
+          ReadParam(aMsg, aIter, &roaming) &&
+          ReadParam(aMsg, aIter, &type) &&
+          ReadParam(aMsg, aIter, &networkInfo) &&
+          ReadParam(aMsg, aIter, &cellInfo))) {
+      return false;
+    }
+
+    // De-serialize jsval signalStrength
+    if (!ReadParam(aMsg, aIter, &isNull)) {
+      return false;
+    }
+
+    if (!isNull) {
+      int32_t value;
+
+      if (!ReadParam(aMsg, aIter, &value)) {
+        return false;
+      }
+
+      signalStrength.SetValue(value);
+    }
+
+    // De-serialize jsval relSignalStrength
+    if (!ReadParam(aMsg, aIter, &isNull)) {
+      return false;
+    }
+
+    if (!isNull) {
+      int32_t value;
+
+      if (!ReadParam(aMsg, aIter, &value)) {
+        return false;
+      }
+
+      relSignalStrength.SetValue(uint16_t(value));
+    }
+
+    *aResult = new MobileConnectionInfo(state,
+                                        connected,
+                                        emergencyOnly,
+                                        roaming,
+                                        networkInfo,
+                                        type,
+                                        signalStrength,
+                                        relSignalStrength,
+                                        cellInfo);
+    // We release this ref after receiver finishes processing.
+    NS_ADDREF(*aResult);
+    // We already clone the data into MobileConnectionInfo, so release the ref
+    // of networkInfo and cellInfo here.
+    NS_IF_RELEASE(networkInfo);
+    NS_IF_RELEASE(cellInfo);
+
+    return true;
+  }
+};
+
+/**
+ * MozCallForwardingOptions Serialize/De-serialize.
+ */
+template <>
+struct ParamTraits<MozCallForwardingOptions>
+{
+  typedef MozCallForwardingOptions paramType;
+
+  // Function to serialize a MozCallForwardingOptions.
+  static void Write(Message *aMsg, const paramType& aParam)
+  {
+    bool wasPassed = false;
+    bool isNull = false;
+
+    // Write mActive
+    wasPassed = aParam.mActive.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mActive.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mActive.Value().Value());
+      }
+    }
+
+    // Write mAction
+    wasPassed = aParam.mAction.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mAction.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mAction.Value().Value());
+      }
+    }
+
+    // Write mReason
+    wasPassed = aParam.mReason.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mReason.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mReason.Value().Value());
+      }
+    }
+
+    // Write mNumber
+    wasPassed = aParam.mNumber.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      WriteParam(aMsg, aParam.mNumber.Value());
+    }
+
+    // Write mTimeSeconds
+    wasPassed = aParam.mTimeSeconds.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mTimeSeconds.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mTimeSeconds.Value().Value());
+      }
+    }
+
+    // Write mServiceClass
+    wasPassed = aParam.mServiceClass.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mServiceClass.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mServiceClass.Value().Value());
+      }
+    }
+  }
+
+  // Function to de-serialize a MozCallForwardingOptions.
+  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  {
+    bool wasPassed = false;
+    bool isNull = false;
+
+    // Read mActive
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mActive.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mActive.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    // Read mAction
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mAction.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mAction.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    // Read mReason
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mReason.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mReason.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    // Read mNumber
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      if (!ReadParam(aMsg, aIter, &aResult->mNumber.Construct())) {
+        return false;
+      }
+    }
+
+    // Read mTimeSeconds
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mTimeSeconds.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mTimeSeconds.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    // Read mServiceClass
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mServiceClass.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mServiceClass.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+};
+
+/**
+ * MozCallBarringOptions Serialize/De-serialize.
+ */
+template <>
+struct ParamTraits<MozCallBarringOptions>
+{
+  typedef MozCallBarringOptions paramType;
+
+  // Function to serialize a MozCallBarringOptions.
+  static void Write(Message *aMsg, const paramType& aParam)
+  {
+    bool wasPassed = false;
+    bool isNull = false;
+
+    // Write mProgram
+    wasPassed = aParam.mProgram.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mProgram.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mProgram.Value().Value());
+      }
+    }
+
+    // Write mEnabled
+    wasPassed = aParam.mEnabled.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mEnabled.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mEnabled.Value().Value());
+      }
+    }
+
+    // Write mPassword
+    wasPassed = aParam.mPassword.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      WriteParam(aMsg, aParam.mPassword.Value());
+    }
+
+    // Write mServiceClass
+    wasPassed = aParam.mServiceClass.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      isNull = aParam.mServiceClass.Value().IsNull();
+      WriteParam(aMsg, isNull);
+      if (!isNull) {
+        WriteParam(aMsg, aParam.mServiceClass.Value().Value());
+      }
+    }
+
+    // Write mPin
+    wasPassed = aParam.mPin.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      WriteParam(aMsg, aParam.mPin.Value());
+    }
+
+    // Write mNewPin
+    wasPassed = aParam.mNewPin.WasPassed();
+    WriteParam(aMsg, wasPassed);
+    if (wasPassed) {
+      WriteParam(aMsg, aParam.mNewPin.Value());
+    }
+  }
+
+  // Function to de-serialize a MozCallBarringOptions.
+  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  {
+    bool wasPassed = false;
+    bool isNull = false;
+
+    // Read mProgram
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mProgram.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mProgram.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    // Read mEnabled
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mEnabled.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mEnabled.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    // Read mPassword
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      if (!ReadParam(aMsg, aIter, &aResult->mPassword.Construct())) {
+        return false;
+      }
+    }
+
+    // Read mServiceClass
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      aResult->mServiceClass.Construct();
+      if (!ReadParam(aMsg, aIter, &isNull)) {
+        return false;
+      }
+
+      if (!isNull) {
+        if (!ReadParam(aMsg, aIter, &aResult->mServiceClass.Value().SetValue())) {
+          return false;
+        }
+      }
+    }
+
+    // Read mPin
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      if (!ReadParam(aMsg, aIter, &aResult->mPin.Construct())) {
+        return false;
+      }
+    }
+
+    // Read mNewPin
+    if (!ReadParam(aMsg, aIter, &wasPassed)) {
+      return false;
+    }
+    if (wasPassed) {
+      if (!ReadParam(aMsg, aIter, &aResult->mNewPin.Construct())) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+};
+
+} // namespace IPC
+
+#endif // dom_mobileconnection_src_ipc_MobileConnectionIPCSerialiser_h
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/ipc/PMobileConnection.ipdl
@@ -0,0 +1,188 @@
+/* -*- 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;
+include protocol PMobileConnectionRequest;
+include PMobileConnectionTypes;
+
+namespace mozilla {
+namespace dom {
+
+sync protocol PMobileConnection
+{
+  manager PContent;
+  manages PMobileConnectionRequest;
+
+child:
+  NotifyVoiceInfoChanged(nsMobileConnectionInfo aInfo);
+  NotifyDataInfoChanged(nsMobileConnectionInfo aInfo);
+  NotifyUssdReceived(nsString aMessage, bool aSessionEnd);
+  NotifyDataError(nsString aMessage);
+  NotifyCFStateChanged(bool aSuccess, uint16_t aAction, uint16_t aReason,
+                       nsString aNumber, uint16_t aTimeSeconds,
+                       uint16_t aServiceClass);
+  NotifyEmergencyCbModeChanged(bool aActive, uint32_t aTimeoutMs);
+  NotifyOtaStatusChanged(nsString aStatus);
+  NotifyIccChanged(nsString aIccId);
+  NotifyRadioStateChanged(nsString aRadioState);
+  NotifyClirModeChanged(uint32_t aMode);
+  NotifyLastNetworkChanged(nsString aNetwork);
+  NotifyLastHomeNetworkChanged(nsString aNetwork);
+  NotifyNetworkSelectionModeChanged(nsString aMode);
+
+parent:
+  /**
+   * Send when child no longer needs to use PMobileConnection.
+   */
+  __delete__();
+
+  /**
+   * Sent when the child makes an asynchronous request to the parent.
+   */
+  PMobileConnectionRequest(MobileConnectionRequest aRequest);
+
+  /**
+   * Sync call only be called once per child actor for initialization.
+   */
+  sync Init()
+    returns (nsMobileConnectionInfo aVoice, nsMobileConnectionInfo aData,
+             nsString aLastKnownNetwork, nsString aLastKnownHomeNetwork,
+             nsString aIccId, nsString aNetworkSelectionMode,
+             nsString aRadioState, nsString[] aSupportedNetworkTypes);
+};
+
+/**
+ * MobileConnectionRequest
+ */
+struct GetNetworksRequest
+{
+};
+
+struct SelectNetworkRequest
+{
+  nsMobileNetworkInfo network;
+};
+
+struct SelectNetworkAutoRequest
+{
+};
+
+struct SetPreferredNetworkTypeRequest
+{
+  nsString type;
+};
+
+struct GetPreferredNetworkTypeRequest
+{
+};
+
+struct SetRoamingPreferenceRequest
+{
+  nsString mode;
+};
+
+struct GetRoamingPreferenceRequest
+{
+};
+
+struct SetVoicePrivacyModeRequest
+{
+  bool enabled;
+};
+
+struct GetVoicePrivacyModeRequest
+{
+};
+
+struct SendMmiRequest
+{
+  nsString mmi;
+};
+
+struct CancelMmiRequest
+{
+};
+
+struct SetCallForwardingRequest
+{
+  MozCallForwardingOptions options;
+};
+
+struct GetCallForwardingRequest
+{
+  int16_t reason;
+};
+
+struct SetCallBarringRequest
+{
+  MozCallBarringOptions options;
+};
+
+struct GetCallBarringRequest
+{
+  MozCallBarringOptions options;
+};
+
+struct ChangeCallBarringPasswordRequest
+{
+  MozCallBarringOptions options;
+};
+
+struct SetCallWaitingRequest
+{
+  bool enabled;
+};
+
+struct GetCallWaitingRequest
+{
+};
+
+struct SetCallingLineIdRestrictionRequest
+{
+  uint16_t mode;
+};
+
+struct GetCallingLineIdRestrictionRequest
+{
+};
+
+struct ExitEmergencyCbModeRequest
+{
+};
+
+struct SetRadioEnabledRequest
+{
+  bool enabled;
+};
+
+union MobileConnectionRequest
+{
+  GetNetworksRequest;
+  SelectNetworkRequest;
+  SelectNetworkAutoRequest;
+  SetPreferredNetworkTypeRequest;
+  GetPreferredNetworkTypeRequest;
+  SetRoamingPreferenceRequest;
+  GetRoamingPreferenceRequest;
+  SetVoicePrivacyModeRequest;
+  GetVoicePrivacyModeRequest;
+  SendMmiRequest;
+  CancelMmiRequest;
+  SetCallForwardingRequest;
+  GetCallForwardingRequest;
+  SetCallBarringRequest;
+  GetCallBarringRequest;
+  ChangeCallBarringPasswordRequest;
+  SetCallWaitingRequest;
+  GetCallWaitingRequest;
+  SetCallingLineIdRestrictionRequest;
+  GetCallingLineIdRestrictionRequest;
+  ExitEmergencyCbModeRequest;
+  SetRadioEnabledRequest;
+};
+
+} // namespace mozilla
+} // namespace dom
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl
@@ -0,0 +1,103 @@
+/* -*- 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 PMobileConnection;
+include PMobileConnectionTypes;
+
+namespace mozilla {
+namespace dom {
+
+protocol PMobileConnectionRequest
+{
+  manager PMobileConnection;
+
+child:
+  /**
+   * Send when asynchronous request has completed.
+   */
+  __delete__(MobileConnectionReply aResponse);
+};
+
+/**
+ * MobileConnectionReply
+ */
+// Success
+struct MobileConnectionReplySuccess
+{
+};
+
+struct MobileConnectionReplySuccessString
+{
+  nsString result;
+};
+
+struct MobileConnectionReplySuccessBoolean
+{
+  bool result;
+};
+
+struct MobileConnectionReplySuccessNetworks
+{
+  nsMobileNetworkInfo[] results;
+};
+
+struct MobileConnectionReplySuccessMmi
+{
+  nsString serviceCode;
+  nsString statusMessage;
+  AdditionalInformation additionalInformation;
+};
+
+struct MobileConnectionReplySuccessCallForwarding
+{
+  MozCallForwardingOptions[] results;
+};
+
+struct MobileConnectionReplySuccessCallBarring
+{
+  uint16_t program;
+  bool enabled;
+  uint16_t serviceClass;
+};
+
+struct MobileConnectionReplySuccessClirStatus
+{
+  uint16_t n;
+  uint16_t m;
+};
+
+// Error
+struct MobileConnectionReplyError
+{
+  nsString message;
+};
+
+struct MobileConnectionReplyErrorMmi
+{
+  nsString name;
+  nsString message;
+  nsString serviceCode;
+  AdditionalInformation additionalInformation;
+};
+
+union MobileConnectionReply
+{
+  // Success
+  MobileConnectionReplySuccess;
+  MobileConnectionReplySuccessString;
+  MobileConnectionReplySuccessBoolean;
+  MobileConnectionReplySuccessNetworks;
+  MobileConnectionReplySuccessMmi;
+  MobileConnectionReplySuccessCallForwarding;
+  MobileConnectionReplySuccessCallBarring;
+  MobileConnectionReplySuccessClirStatus;
+  // Error
+  MobileConnectionReplyError;
+  MobileConnectionReplyErrorMmi;
+};
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh
@@ -0,0 +1,24 @@
+/* -*- 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/. */
+
+using nsMobileConnectionInfo from "mozilla/dom/MobileConnectionIPCSerializer.h";
+using nsMobileNetworkInfo from "mozilla/dom/MobileConnectionIPCSerializer.h";
+using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
+using struct IPC::MozCallForwardingOptions from "mozilla/dom/MobileConnectionIPCSerializer.h";
+using struct IPC::MozCallBarringOptions from "mozilla/dom/MobileConnectionIPCSerializer.h";
+
+namespace mozilla {
+namespace dom {
+
+union AdditionalInformation {
+  void_t;
+  uint16_t;
+  nsString[];
+  MozCallForwardingOptions[];
+};
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/mobileconnection/moz.build
+++ b/dom/mobileconnection/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['interfaces']
 
 MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
 
 EXPORTS.mozilla.dom += [
     'DOMMMIError.h',
+    'ipc/MobileConnectionIPCSerializer.h',
     'MobileCellInfo.h',
     'MobileConnection.h',
     'MobileConnectionArray.h',
     'MobileConnectionCallback.h',
     'MobileConnectionInfo.h',
     'MobileNetworkInfo.h',
 ]
 
@@ -23,13 +24,19 @@ SOURCES += [
     'MobileCellInfo.cpp',
     'MobileConnection.cpp',
     'MobileConnectionArray.cpp',
     'MobileConnectionCallback.cpp',
     'MobileConnectionInfo.cpp',
     'MobileNetworkInfo.cpp',
 ]
 
+IPDL_SOURCES += [
+    'ipc/PMobileConnection.ipdl',
+    'ipc/PMobileConnectionRequest.ipdl',
+    'ipc/PMobileConnectionTypes.ipdlh',
+]
+
 FAIL_ON_WARNINGS = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'