Bug 1047196 - Part 3: Avoid the use of 'jsval' in interfaces (ipc). f=echen, r=smaug
authorJessica Jong <jjong@mozilla.com>
Wed, 08 Oct 2014 02:34:00 -0400
changeset 209824 8ed9bb9f45c4ecc6b28dcd214f3a59d749d03c99
parent 209823 a4603312cfeefad7af370f8b9df72adb6441c6c6
child 209825 b0c62611fff0fc28993441ebd7db3651d3c25bd4
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssmaug
bugs1047196
milestone35.0a1
Bug 1047196 - Part 3: Avoid the use of 'jsval' in interfaces (ipc). f=echen, r=smaug
dom/mobileconnection/ipc/MobileConnectionChild.cpp
dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
dom/mobileconnection/ipc/MobileConnectionParent.cpp
dom/mobileconnection/ipc/PMobileConnection.ipdl
dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl
dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh
--- a/dom/mobileconnection/ipc/MobileConnectionChild.cpp
+++ b/dom/mobileconnection/ipc/MobileConnectionChild.cpp
@@ -234,96 +234,69 @@ MobileConnectionChild::SendMMI(const nsA
 
 NS_IMETHODIMP
 MobileConnectionChild::CancelMMI(nsIMobileConnectionCallback* aCallback)
 {
   return SendRequest(CancelMmiRequest(), aCallback) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::SetCallForwarding(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::SetCallForwarding(uint16_t aAction, uint16_t aReason,
+                                         const nsAString& aNumber,
+                                         uint16_t aTimeSeconds, uint16_t aServiceClass,
                                          nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallForwardingOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(SetCallForwardingRequest(options), aCallback)
+  return SendRequest(SetCallForwardingRequest(aAction, aReason,
+                                              nsString(aNumber),
+                                              aTimeSeconds, aServiceClass),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 MobileConnectionChild::GetCallForwarding(uint16_t aReason,
                                          nsIMobileConnectionCallback* aCallback)
 {
   return SendRequest(GetCallForwardingRequest(aReason), aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::SetCallBarring(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::SetCallBarring(uint16_t aProgram, bool aEnabled,
+                                      const nsAString& aPassword,
+                                      uint16_t aServiceClass,
                                       nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallBarringOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(SetCallBarringRequest(options), aCallback)
+  return SendRequest(SetCallBarringRequest(aProgram, aEnabled,
+                                           nsString(aPassword),
+                                           aServiceClass),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::GetCallBarring(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::GetCallBarring(uint16_t aProgram,
+                                      const nsAString& aPassword,
+                                      uint16_t aServiceClass,
                                       nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallBarringOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(GetCallBarringRequest(options), aCallback)
+  return SendRequest(GetCallBarringRequest(aProgram, nsString(aPassword),
+                                           aServiceClass),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::ChangeCallBarringPassword(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::ChangeCallBarringPassword(const nsAString& aPin,
+                                                 const nsAString& aNewPin,
                                                  nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallBarringOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(ChangeCallBarringPasswordRequest(options), aCallback)
+  return SendRequest(ChangeCallBarringPasswordRequest(nsString(aPin),
+                                                      nsString(aNewPin)),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 MobileConnectionChild::SetCallWaiting(bool aEnabled,
                                       nsIMobileConnectionCallback* aCallback)
 {
   return SendRequest(SetCallWaitingRequest(aEnabled), aCallback)
@@ -592,49 +565,77 @@ MobileConnectionRequestChild::DoReply(co
 
 bool
 MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessMmi& aReply)
 {
   nsAutoString serviceCode(aReply.serviceCode());
   nsAutoString statusMessage(aReply.statusMessage());
   AdditionalInformation info(aReply.additionalInformation());
 
-  nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get());
-
-
   // Handle union types
   switch (info.type()) {
     case AdditionalInformation::Tvoid_t:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage));
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccess(serviceCode,
+                                                                       statusMessage));
+
     case AdditionalInformation::Tuint16_t:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage,
-                                                               info.get_uint16_t()));
-    case AdditionalInformation::TArrayOfnsString:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage,
-                                                               info.get_ArrayOfnsString()));
-    case AdditionalInformation::TArrayOfMozCallForwardingOptions:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage,
-                                                               info.get_ArrayOfMozCallForwardingOptions()));
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithInteger(
+        serviceCode, statusMessage, info.get_uint16_t()));
+
+    case AdditionalInformation::TArrayOfnsString: {
+      uint32_t count = info.get_ArrayOfnsString().Length();
+      const nsTArray<nsString>& additionalInformation = info.get_ArrayOfnsString();
+
+      nsAutoArrayPtr<const char16_t*> additionalInfoPtrs(new const char16_t*[count]);
+      for (size_t i = 0; i < count; ++i) {
+        additionalInfoPtrs[i] = additionalInformation[i].get();
+      }
+
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithStrings(
+        serviceCode, statusMessage, count, additionalInfoPtrs));
+    }
+
+    case AdditionalInformation::TArrayOfnsMobileCallForwardingOptions: {
+      uint32_t count = info.get_ArrayOfnsMobileCallForwardingOptions().Length();
+
+      nsTArray<nsCOMPtr<nsIMobileCallForwardingOptions>> results;
+      for (uint32_t i = 0; i < count; i++) {
+        // Use dont_AddRef here because these instances are already AddRef-ed in
+        // MobileConnectionIPCSerializer.h
+        nsCOMPtr<nsIMobileCallForwardingOptions> item = dont_AddRef(
+          info.get_ArrayOfnsMobileCallForwardingOptions()[i]);
+        results.AppendElement(item);
+      }
+
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithCallForwardingOptions(
+        serviceCode, statusMessage, count,
+        const_cast<nsIMobileCallForwardingOptions**>(info.get_ArrayOfnsMobileCallForwardingOptions().Elements())));
+    }
 
     default:
       MOZ_CRASH("Received invalid type!");
   }
 
   return false;
 }
 
 bool
 MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallForwarding& aReply)
 {
-  nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get());
-  return NS_SUCCEEDED(callback->NotifyGetCallForwardingSuccess(aReply.results()));
+  uint32_t count = aReply.results().Length();
+  nsTArray<nsCOMPtr<nsIMobileCallForwardingOptions>> results;
+  for (uint32_t i = 0; i < count; i++) {
+    // Use dont_AddRef here because these instances are already AddRef-ed in
+    // MobileConnectionIPCSerializer.h
+    nsCOMPtr<nsIMobileCallForwardingOptions> item = dont_AddRef(aReply.results()[i]);
+    results.AppendElement(item);
+  }
+
+  return NS_SUCCEEDED(mRequestCallback->NotifyGetCallForwardingSuccess(
+    count, const_cast<nsIMobileCallForwardingOptions**>(aReply.results().Elements())));
 }
 
 bool
 MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallBarring& aReply)
 {
   return NS_SUCCEEDED(mRequestCallback->NotifyGetCallBarringSuccess(aReply.program(),
                                                                     aReply.enabled(),
                                                                     aReply.serviceClass()));
--- a/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
+++ b/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
@@ -1,29 +1,32 @@
 /* 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_mobileconnection_MobileConnectionIPCSerialiser_h
 #define mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h
 
 #include "ipc/IPCMessageUtils.h"
+#include "mozilla/dom/mobileconnection/MobileCallForwardingOptions.h"
 #include "mozilla/dom/MobileCellInfo.h"
 #include "mozilla/dom/MobileConnectionInfo.h"
 #include "mozilla/dom/MobileNetworkInfo.h"
 #include "mozilla/dom/MozMobileConnectionBinding.h"
 
 using mozilla::AutoJSContext;
+using mozilla::dom::mobileconnection::MobileCallForwardingOptions;
 using mozilla::dom::MobileNetworkInfo;
 using mozilla::dom::MobileCellInfo;
 using mozilla::dom::MobileConnectionInfo;
 
 typedef nsIMobileCellInfo* nsMobileCellInfo;
 typedef nsIMobileConnectionInfo* nsMobileConnectionInfo;
 typedef nsIMobileNetworkInfo* nsMobileNetworkInfo;
+typedef nsIMobileCallForwardingOptions* nsMobileCallForwardingOptions;
 
 namespace IPC {
 
 struct MozCallForwardingOptions : public mozilla::dom::MozCallForwardingOptions
 {
   bool operator==(const MozCallForwardingOptions& aOther) const
   {
     return // Compare mActive
@@ -48,37 +51,93 @@ struct MozCallForwardingOptions : public
              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
+template <>
+struct ParamTraits<nsIMobileCallForwardingOptions*>
 {
-  bool operator==(const MozCallBarringOptions& aOther) const
+  typedef nsIMobileCallForwardingOptions* paramType;
+
+  // Function to serialize a MobileCallForwardingOptions.
+  static void Write(Message *aMsg, const paramType& aParam)
   {
-    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()));
-  };
+    bool isNull = !aParam;
+    WriteParam(aMsg, isNull);
+    // If it is a null object, then we are done.
+    if (isNull) {
+      return;
+    }
+
+    int16_t pShort;
+    nsString pString;
+    bool pBool;
+
+    aParam->GetActive(&pBool);
+    WriteParam(aMsg, pBool);
+
+    aParam->GetAction(&pShort);
+    WriteParam(aMsg, pShort);
+
+    aParam->GetReason(&pShort);
+    WriteParam(aMsg, pShort);
+
+    aParam->GetNumber(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetTimeSeconds(&pShort);
+    WriteParam(aMsg, pShort);
+
+    aParam->GetServiceClass(&pShort);
+    WriteParam(aMsg, pShort);
+  }
+
+  // Function to de-serialize a MobileCallForwardingOptions.
+  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;
+    }
+
+    bool active;
+    int16_t action;
+    int16_t reason;
+    nsString number;
+    int16_t timeSeconds;
+    int16_t serviceClass;
+
+    // It's not important to us where it fails, but rather if it fails
+    if (!(ReadParam(aMsg, aIter, &active) &&
+          ReadParam(aMsg, aIter, &action) &&
+          ReadParam(aMsg, aIter, &reason) &&
+          ReadParam(aMsg, aIter, &number) &&
+          ReadParam(aMsg, aIter, &timeSeconds) &&
+          ReadParam(aMsg, aIter, &serviceClass))) {
+      return false;
+    }
+
+    *aResult = new MobileCallForwardingOptions(active, action, reason,
+                                               number, timeSeconds, serviceClass);
+
+    // We release this ref after receiver finishes processing.
+    NS_ADDREF(*aResult);
+
+    return true;
+  }
 };
 
 /**
  * nsIMobileNetworkInfo Serialize/De-serialize.
  */
 template <>
 struct ParamTraits<nsIMobileNetworkInfo*>
 {
@@ -579,171 +638,11 @@ struct ParamTraits<MozCallForwardingOpti
         }
       }
     }
 
     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 // mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h
--- a/dom/mobileconnection/ipc/MobileConnectionParent.cpp
+++ b/dom/mobileconnection/ipc/MobileConnectionParent.cpp
@@ -418,125 +418,64 @@ MobileConnectionRequestParent::DoRequest
   return NS_SUCCEEDED(mMobileConnection->CancelMMI(this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const SetCallForwardingRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->SetCallForwarding(options, this));
+  return NS_SUCCEEDED(mMobileConnection->SetCallForwarding(aRequest.action(),
+                                                           aRequest.reason(),
+                                                           aRequest.number(),
+                                                           aRequest.timeSeconds(),
+                                                           aRequest.serviceClass(),
+                                                           this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const GetCallForwardingRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(), this));
+  return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(),
+                                                           this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const SetCallBarringRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->SetCallBarring(options, this));
+  return NS_SUCCEEDED(mMobileConnection->SetCallBarring(aRequest.program(),
+                                                        aRequest.enabled(),
+                                                        aRequest.password(),
+                                                        aRequest.serviceClass(),
+                                                        this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const GetCallBarringRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->GetCallBarring(options, this));
+  return NS_SUCCEEDED(mMobileConnection->GetCallBarring(aRequest.program(),
+                                                        aRequest.password(),
+                                                        aRequest.serviceClass(),
+                                                        this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const ChangeCallBarringPasswordRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->ChangeCallBarringPassword(options, this));
+  return NS_SUCCEEDED(mMobileConnection->ChangeCallBarringPassword(aRequest.pin(),
+                                                                   aRequest.newPin(),
+                                                                   this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const SetCallWaitingRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
   return NS_SUCCEEDED(mMobileConnection->SetCallWaiting(aRequest.enabled(), this));
@@ -622,114 +561,73 @@ MobileConnectionRequestParent::NotifyGet
     // We release the ref after serializing process is finished in
     // MobileConnectionIPCSerializer.
     networks.AppendElement(network.forget().take());
   }
   return SendReply(MobileConnectionReplySuccessNetworks(networks));
 }
 
 NS_IMETHODIMP
-MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult,
-                                                          JSContext* aCx)
+MobileConnectionRequestParent::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
+                                                          const nsAString& aStatusMessage)
 {
-  RootedDictionary<MozMMIResult> result(aCx);
-
-  if (!result.Init(aCx, aResult)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  // No additionInformation passed
-  if (!result.mAdditionalInformation.WasPassed()) {
-    return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                     result.mStatusMessage,
-                                                     AdditionalInformation(mozilla::void_t())));
-  }
-
-  OwningUnsignedShortOrObject& additionInformation = result.mAdditionalInformation.Value();
-
-  if (additionInformation.IsUnsignedShort()) {
-    return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                     result.mStatusMessage,
-                                                     AdditionalInformation(uint16_t(additionInformation.GetAsUnsignedShort()))));
-  }
-
-  if (additionInformation.IsObject()) {
-    uint32_t length;
-    JS::Rooted<JS::Value> value(aCx);
-    JS::Rooted<JSObject*> object(aCx, additionInformation.GetAsObject());
-
-    if (!JS_IsArrayObject(aCx, object) ||
-        !JS_GetArrayLength(aCx, object, &length) || length <= 0 ||
-        // Check first element to decide the format of array.
-        !JS_GetElement(aCx, object, 0, &value)) {
-      return NS_ERROR_TYPE_ERR;
-    }
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(mozilla::void_t())));
+}
 
-    // Check first element to decide the format of array.
-    if (value.isString()) {
-      // String[]
-      nsTArray<nsString> infos;
-      for (uint32_t i = 0; i < length; i++) {
-        if (!JS_GetElement(aCx, object, i, &value) || !value.isString()) {
-          return NS_ERROR_TYPE_ERR;
-        }
-
-        nsAutoJSString str;
-        if (!str.init(aCx, value.toString())) {
-          return NS_ERROR_FAILURE;
-        }
-        infos.AppendElement(str);
-      }
-
-      return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                       result.mStatusMessage,
-                                                       AdditionalInformation(infos)));
-    } else {
-      // IPC::MozCallForwardingOptions[]
-      nsTArray<IPC::MozCallForwardingOptions> infos;
-      for (uint32_t i = 0; i < length; i++) {
-        IPC::MozCallForwardingOptions info;
-        if (!JS_GetElement(aCx, object, i, &value) || !info.Init(aCx, value)) {
-          return NS_ERROR_TYPE_ERR;
-        }
-
-        infos.AppendElement(info);
-      }
-
-      return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                       result.mStatusMessage,
-                                                       AdditionalInformation(infos)));
-    }
-  }
-
-  return NS_ERROR_TYPE_ERR;
+NS_IMETHODIMP
+MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithInteger(const nsAString& aServiceCode,
+                                                                     const nsAString& aStatusMessage,
+                                                                     uint16_t aAdditionalInformation)
+{
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(aAdditionalInformation)));
 }
 
 NS_IMETHODIMP
-MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults,
-                                                              JSContext* aCx)
+MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithStrings(const nsAString& aServiceCode,
+                                                                     const nsAString& aStatusMessage,
+                                                                     uint32_t aCount,
+                                                                     const char16_t** aAdditionalInformation)
 {
-  uint32_t length;
-  JS::Rooted<JSObject*> object(aCx, &aResults.toObject());
-  nsTArray<IPC::MozCallForwardingOptions> results;
-
-  if (!JS_IsArrayObject(aCx, object) ||
-      !JS_GetArrayLength(aCx, object, &length)) {
-    return NS_ERROR_TYPE_ERR;
+  nsTArray<nsString> additionalInformation;
+  for (uint32_t i = 0; i < aCount; i++) {
+    additionalInformation.AppendElement(nsDependentString(aAdditionalInformation[i]));
   }
 
-  for (uint32_t i = 0; i < length; i++) {
-    JS::Rooted<JS::Value> entry(aCx);
-    IPC::MozCallForwardingOptions info;
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(additionalInformation)));
+}
 
-    if (!JS_GetElement(aCx, object, i, &entry) || !info.Init(aCx, entry)) {
-      return NS_ERROR_TYPE_ERR;
-    }
+NS_IMETHODIMP
+MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithCallForwardingOptions(const nsAString& aServiceCode,
+                                                                                   const nsAString& aStatusMessage,
+                                                                                   uint32_t aCount,
+                                                                                   nsIMobileCallForwardingOptions** aAdditionalInformation)
+{
+  nsTArray<nsIMobileCallForwardingOptions*> additionalInformation;
+  for (uint32_t i = 0; i < aCount; i++) {
+    additionalInformation.AppendElement(aAdditionalInformation[i]);
+  }
 
-    results.AppendElement(info);
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(additionalInformation)));
+}
+
+NS_IMETHODIMP
+MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(uint32_t aCount,
+                                                              nsIMobileCallForwardingOptions** aResults)
+{
+  nsTArray<nsIMobileCallForwardingOptions*> results;
+  for (uint32_t i = 0; i < aCount; i++) {
+    results.AppendElement(aResults[i]);
   }
 
   return SendReply(MobileConnectionReplySuccessCallForwarding(results));
 }
 
 NS_IMETHODIMP
 MobileConnectionRequestParent::NotifyGetCallBarringSuccess(uint16_t aProgram,
                                                            bool aEnabled,
--- a/dom/mobileconnection/ipc/PMobileConnection.ipdl
+++ b/dom/mobileconnection/ipc/PMobileConnection.ipdl
@@ -104,37 +104,47 @@ struct SendMmiRequest
 };
 
 struct CancelMmiRequest
 {
 };
 
 struct SetCallForwardingRequest
 {
-  MozCallForwardingOptions options;
+  uint16_t action;
+  uint16_t reason;
+  nsString number;
+  uint16_t timeSeconds;
+  uint16_t serviceClass;
 };
 
 struct GetCallForwardingRequest
 {
-  int16_t reason;
+  uint16_t reason;
 };
 
 struct SetCallBarringRequest
 {
-  MozCallBarringOptions options;
+  uint16_t program;
+  bool enabled;
+  nsString password;
+  uint16_t serviceClass;
 };
 
 struct GetCallBarringRequest
 {
-  MozCallBarringOptions options;
+  uint16_t program;
+  nsString password;
+  uint16_t serviceClass;
 };
 
 struct ChangeCallBarringPasswordRequest
 {
-  MozCallBarringOptions options;
+  nsString pin;
+  nsString newPin;
 };
 
 struct SetCallWaitingRequest
 {
   bool enabled;
 };
 
 struct GetCallWaitingRequest
--- a/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl
+++ b/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl
@@ -49,17 +49,17 @@ struct MobileConnectionReplySuccessMmi
 {
   nsString serviceCode;
   nsString statusMessage;
   AdditionalInformation additionalInformation;
 };
 
 struct MobileConnectionReplySuccessCallForwarding
 {
-  MozCallForwardingOptions[] results;
+  nsMobileCallForwardingOptions[] results;
 };
 
 struct MobileConnectionReplySuccessCallBarring
 {
   uint16_t program;
   bool enabled;
   uint16_t serviceClass;
 };
--- a/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh
+++ b/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh
@@ -3,24 +3,24 @@
 /* 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/mobileconnection/MobileConnectionIPCSerializer.h";
 using nsMobileNetworkInfo from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using struct IPC::MozCallForwardingOptions from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
-using struct IPC::MozCallBarringOptions from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
+using nsMobileCallForwardingOptions from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
 
 namespace mozilla {
 namespace dom {
 namespace mobileconnection {
 
 union AdditionalInformation {
   void_t;
   uint16_t;
   nsString[];
-  MozCallForwardingOptions[];
+  nsMobileCallForwardingOptions[];
 };
 
 } // namespace mobileconnection
 } // namespace dom
 } // namespace mozilla