Bug 1047196 - Part 3: Avoid the use of 'jsval' in interfaces (ipc). f=echen, r=smaug

This commit is contained in:
Jessica Jong 2014-10-08 02:34:00 -04:00
parent 8e462207a9
commit b174cdfa89
6 changed files with 234 additions and 426 deletions

View File

@ -239,21 +239,15 @@ MobileConnectionChild::CancelMMI(nsIMobileConnectionCallback* aCallback)
} }
NS_IMETHODIMP 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) nsIMobileConnectionCallback* aCallback)
{ {
AutoJSAPI jsapi; return SendRequest(SetCallForwardingRequest(aAction, aReason,
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) { nsString(aNumber),
return NS_ERROR_FAILURE; aTimeSeconds, aServiceClass),
} aCallback)
JSContext* cx = jsapi.cx();
IPC::MozCallForwardingOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;
}
return SendRequest(SetCallForwardingRequest(options), aCallback)
? NS_OK : NS_ERROR_FAILURE; ? NS_OK : NS_ERROR_FAILURE;
} }
@ -266,59 +260,38 @@ MobileConnectionChild::GetCallForwarding(uint16_t aReason,
} }
NS_IMETHODIMP NS_IMETHODIMP
MobileConnectionChild::SetCallBarring(JS::Handle<JS::Value> aOptions, MobileConnectionChild::SetCallBarring(uint16_t aProgram, bool aEnabled,
const nsAString& aPassword,
uint16_t aServiceClass,
nsIMobileConnectionCallback* aCallback) nsIMobileConnectionCallback* aCallback)
{ {
AutoJSAPI jsapi; return SendRequest(SetCallBarringRequest(aProgram, aEnabled,
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) { nsString(aPassword),
return NS_ERROR_FAILURE; aServiceClass),
} aCallback)
JSContext* cx = jsapi.cx();
IPC::MozCallBarringOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;
}
return SendRequest(SetCallBarringRequest(options), aCallback)
? NS_OK : NS_ERROR_FAILURE; ? NS_OK : NS_ERROR_FAILURE;
} }
NS_IMETHODIMP NS_IMETHODIMP
MobileConnectionChild::GetCallBarring(JS::Handle<JS::Value> aOptions, MobileConnectionChild::GetCallBarring(uint16_t aProgram,
const nsAString& aPassword,
uint16_t aServiceClass,
nsIMobileConnectionCallback* aCallback) nsIMobileConnectionCallback* aCallback)
{ {
AutoJSAPI jsapi; return SendRequest(GetCallBarringRequest(aProgram, nsString(aPassword),
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) { aServiceClass),
return NS_ERROR_FAILURE; aCallback)
}
JSContext* cx = jsapi.cx();
IPC::MozCallBarringOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;
}
return SendRequest(GetCallBarringRequest(options), aCallback)
? NS_OK : NS_ERROR_FAILURE; ? NS_OK : NS_ERROR_FAILURE;
} }
NS_IMETHODIMP NS_IMETHODIMP
MobileConnectionChild::ChangeCallBarringPassword(JS::Handle<JS::Value> aOptions, MobileConnectionChild::ChangeCallBarringPassword(const nsAString& aPin,
const nsAString& aNewPin,
nsIMobileConnectionCallback* aCallback) nsIMobileConnectionCallback* aCallback)
{ {
AutoJSAPI jsapi; return SendRequest(ChangeCallBarringPasswordRequest(nsString(aPin),
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) { nsString(aNewPin)),
return NS_ERROR_FAILURE; aCallback)
}
JSContext* cx = jsapi.cx();
IPC::MozCallBarringOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;
}
return SendRequest(ChangeCallBarringPasswordRequest(options), aCallback)
? NS_OK : NS_ERROR_FAILURE; ? NS_OK : NS_ERROR_FAILURE;
} }
@ -597,26 +570,45 @@ MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessMmi& aRe
nsAutoString statusMessage(aReply.statusMessage()); nsAutoString statusMessage(aReply.statusMessage());
AdditionalInformation info(aReply.additionalInformation()); AdditionalInformation info(aReply.additionalInformation());
nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get());
// Handle union types // Handle union types
switch (info.type()) { switch (info.type()) {
case AdditionalInformation::Tvoid_t: case AdditionalInformation::Tvoid_t:
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode, return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccess(serviceCode,
statusMessage)); statusMessage));
case AdditionalInformation::Tuint16_t: case AdditionalInformation::Tuint16_t:
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode, return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithInteger(
statusMessage, serviceCode, statusMessage, info.get_uint16_t()));
info.get_uint16_t()));
case AdditionalInformation::TArrayOfnsString: case AdditionalInformation::TArrayOfnsString: {
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode, uint32_t count = info.get_ArrayOfnsString().Length();
statusMessage, const nsTArray<nsString>& additionalInformation = info.get_ArrayOfnsString();
info.get_ArrayOfnsString()));
case AdditionalInformation::TArrayOfMozCallForwardingOptions: nsAutoArrayPtr<const char16_t*> additionalInfoPtrs(new const char16_t*[count]);
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode, for (size_t i = 0; i < count; ++i) {
statusMessage, additionalInfoPtrs[i] = additionalInformation[i].get();
info.get_ArrayOfMozCallForwardingOptions())); }
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: default:
MOZ_CRASH("Received invalid type!"); MOZ_CRASH("Received invalid type!");
@ -628,8 +620,17 @@ MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessMmi& aRe
bool bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallForwarding& aReply) MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallForwarding& aReply)
{ {
nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get()); uint32_t count = aReply.results().Length();
return NS_SUCCEEDED(callback->NotifyGetCallForwardingSuccess(aReply.results())); 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 bool

View File

@ -6,12 +6,14 @@
#define mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h #define mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h
#include "ipc/IPCMessageUtils.h" #include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/mobileconnection/MobileCallForwardingOptions.h"
#include "mozilla/dom/MobileCellInfo.h" #include "mozilla/dom/MobileCellInfo.h"
#include "mozilla/dom/MobileConnectionInfo.h" #include "mozilla/dom/MobileConnectionInfo.h"
#include "mozilla/dom/MobileNetworkInfo.h" #include "mozilla/dom/MobileNetworkInfo.h"
#include "mozilla/dom/MozMobileConnectionBinding.h" #include "mozilla/dom/MozMobileConnectionBinding.h"
using mozilla::AutoJSContext; using mozilla::AutoJSContext;
using mozilla::dom::mobileconnection::MobileCallForwardingOptions;
using mozilla::dom::MobileNetworkInfo; using mozilla::dom::MobileNetworkInfo;
using mozilla::dom::MobileCellInfo; using mozilla::dom::MobileCellInfo;
using mozilla::dom::MobileConnectionInfo; using mozilla::dom::MobileConnectionInfo;
@ -19,6 +21,7 @@ using mozilla::dom::MobileConnectionInfo;
typedef nsIMobileCellInfo* nsMobileCellInfo; typedef nsIMobileCellInfo* nsMobileCellInfo;
typedef nsIMobileConnectionInfo* nsMobileConnectionInfo; typedef nsIMobileConnectionInfo* nsMobileConnectionInfo;
typedef nsIMobileNetworkInfo* nsMobileNetworkInfo; typedef nsIMobileNetworkInfo* nsMobileNetworkInfo;
typedef nsIMobileCallForwardingOptions* nsMobileCallForwardingOptions;
namespace IPC { namespace IPC {
@ -53,27 +56,83 @@ struct MozCallForwardingOptions : public mozilla::dom::MozCallForwardingOptions
}; };
}; };
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 bool isNull = !aParam;
((!mEnabled.WasPassed() && !aOther.mEnabled.WasPassed()) || WriteParam(aMsg, isNull);
(mEnabled.WasPassed() && aOther.mEnabled.WasPassed() && // If it is a null object, then we are done.
mEnabled.Value() == aOther.mEnabled.Value())) && if (isNull) {
// Compare mPassword return;
((!mPassword.WasPassed() && !aOther.mPassword.WasPassed()) || }
(mPassword.WasPassed() && aOther.mPassword.WasPassed() &&
mPassword.Value() == aOther.mPassword.Value())) && int16_t pShort;
// Compare mProgram nsString pString;
((!mProgram.WasPassed() && !aOther.mProgram.WasPassed()) || bool pBool;
(mProgram.WasPassed() && aOther.mProgram.WasPassed() &&
mProgram.Value() == aOther.mProgram.Value())) && aParam->GetActive(&pBool);
// Compare mServiceClass WriteParam(aMsg, pBool);
((!mServiceClass.WasPassed() && !aOther.mServiceClass.WasPassed()) ||
(mServiceClass.WasPassed() && aOther.mServiceClass.WasPassed() && aParam->GetAction(&pShort);
mServiceClass.Value() == aOther.mServiceClass.Value())); 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;
}
}; };
/** /**
@ -584,166 +643,6 @@ struct ParamTraits<MozCallForwardingOptions>
} }
}; };
/**
* 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 } // namespace IPC
#endif // mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h #endif // mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h

View File

@ -423,26 +423,12 @@ MobileConnectionRequestParent::DoRequest(const SetCallForwardingRequest& aReques
{ {
NS_ENSURE_TRUE(mMobileConnection, false); NS_ENSURE_TRUE(mMobileConnection, false);
// There are cases (bug 1070083) where this is called with no JS on the stack. return NS_SUCCEEDED(mMobileConnection->SetCallForwarding(aRequest.action(),
// And since mobileConnectionService might be JS-Implemented, so we just aRequest.reason(),
// create it in the System-Principaled Junk Scope. We are going to get rid of aRequest.number(),
// the "jsval" used in MobileConnection's interface in bug 1047196, after that aRequest.timeSeconds(),
// we don't need these things. aRequest.serviceClass(),
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case this));
// 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));
} }
bool bool
@ -450,7 +436,8 @@ MobileConnectionRequestParent::DoRequest(const GetCallForwardingRequest& aReques
{ {
NS_ENSURE_TRUE(mMobileConnection, false); NS_ENSURE_TRUE(mMobileConnection, false);
return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(), this)); return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(),
this));
} }
bool bool
@ -458,26 +445,11 @@ MobileConnectionRequestParent::DoRequest(const SetCallBarringRequest& aRequest)
{ {
NS_ENSURE_TRUE(mMobileConnection, false); NS_ENSURE_TRUE(mMobileConnection, false);
// There are cases (bug 1070083) where this is called with no JS on the stack. return NS_SUCCEEDED(mMobileConnection->SetCallBarring(aRequest.program(),
// And since mobileConnectionService might be JS-Implemented, so we just aRequest.enabled(),
// create it in the System-Principaled Junk Scope. We are going to get rid of aRequest.password(),
// the "jsval" used in MobileConnection's interface in bug 1047196, after that aRequest.serviceClass(),
// we don't need these things. this));
// 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));
} }
bool bool
@ -485,26 +457,10 @@ MobileConnectionRequestParent::DoRequest(const GetCallBarringRequest& aRequest)
{ {
NS_ENSURE_TRUE(mMobileConnection, false); NS_ENSURE_TRUE(mMobileConnection, false);
// There are cases (bug 1070083) where this is called with no JS on the stack. return NS_SUCCEEDED(mMobileConnection->GetCallBarring(aRequest.program(),
// And since mobileConnectionService might be JS-Implemented, so we just aRequest.password(),
// create it in the System-Principaled Junk Scope. We are going to get rid of aRequest.serviceClass(),
// the "jsval" used in MobileConnection's interface in bug 1047196, after that this));
// 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));
} }
bool bool
@ -512,26 +468,9 @@ MobileConnectionRequestParent::DoRequest(const ChangeCallBarringPasswordRequest&
{ {
NS_ENSURE_TRUE(mMobileConnection, false); NS_ENSURE_TRUE(mMobileConnection, false);
// There are cases (bug 1070083) where this is called with no JS on the stack. return NS_SUCCEEDED(mMobileConnection->ChangeCallBarringPassword(aRequest.pin(),
// And since mobileConnectionService might be JS-Implemented, so we just aRequest.newPin(),
// create it in the System-Principaled Junk Scope. We are going to get rid of this));
// 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));
} }
bool bool
@ -627,104 +566,63 @@ MobileConnectionRequestParent::NotifyGetNetworksSuccess(uint32_t aCount,
} }
NS_IMETHODIMP NS_IMETHODIMP
MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult, MobileConnectionRequestParent::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
JSContext* aCx) const nsAString& aStatusMessage)
{ {
RootedDictionary<MozMMIResult> result(aCx); return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
nsString(aStatusMessage),
if (!result.Init(aCx, aResult)) { AdditionalInformation(mozilla::void_t())));
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;
}
// 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 NS_IMETHODIMP
MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults, MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithInteger(const nsAString& aServiceCode,
JSContext* aCx) const nsAString& aStatusMessage,
uint16_t aAdditionalInformation)
{ {
uint32_t length; return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
JS::Rooted<JSObject*> object(aCx, &aResults.toObject()); nsString(aStatusMessage),
nsTArray<IPC::MozCallForwardingOptions> results; AdditionalInformation(aAdditionalInformation)));
}
if (!JS_IsArrayObject(aCx, object) || NS_IMETHODIMP
!JS_GetArrayLength(aCx, object, &length)) { MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithStrings(const nsAString& aServiceCode,
return NS_ERROR_TYPE_ERR; const nsAString& aStatusMessage,
uint32_t aCount,
const char16_t** aAdditionalInformation)
{
nsTArray<nsString> additionalInformation;
for (uint32_t i = 0; i < aCount; i++) {
additionalInformation.AppendElement(nsDependentString(aAdditionalInformation[i]));
} }
for (uint32_t i = 0; i < length; i++) { return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
JS::Rooted<JS::Value> entry(aCx); nsString(aStatusMessage),
IPC::MozCallForwardingOptions info; AdditionalInformation(additionalInformation)));
}
if (!JS_GetElement(aCx, object, i, &entry) || !info.Init(aCx, entry)) { NS_IMETHODIMP
return NS_ERROR_TYPE_ERR; 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)); return SendReply(MobileConnectionReplySuccessCallForwarding(results));

View File

@ -109,27 +109,37 @@ struct CancelMmiRequest
struct SetCallForwardingRequest struct SetCallForwardingRequest
{ {
MozCallForwardingOptions options; uint16_t action;
uint16_t reason;
nsString number;
uint16_t timeSeconds;
uint16_t serviceClass;
}; };
struct GetCallForwardingRequest struct GetCallForwardingRequest
{ {
int16_t reason; uint16_t reason;
}; };
struct SetCallBarringRequest struct SetCallBarringRequest
{ {
MozCallBarringOptions options; uint16_t program;
bool enabled;
nsString password;
uint16_t serviceClass;
}; };
struct GetCallBarringRequest struct GetCallBarringRequest
{ {
MozCallBarringOptions options; uint16_t program;
nsString password;
uint16_t serviceClass;
}; };
struct ChangeCallBarringPasswordRequest struct ChangeCallBarringPasswordRequest
{ {
MozCallBarringOptions options; nsString pin;
nsString newPin;
}; };
struct SetCallWaitingRequest struct SetCallWaitingRequest

View File

@ -54,7 +54,7 @@ struct MobileConnectionReplySuccessMmi
struct MobileConnectionReplySuccessCallForwarding struct MobileConnectionReplySuccessCallForwarding
{ {
MozCallForwardingOptions[] results; nsMobileCallForwardingOptions[] results;
}; };
struct MobileConnectionReplySuccessCallBarring struct MobileConnectionReplySuccessCallBarring

View File

@ -8,7 +8,7 @@ using nsMobileConnectionInfo from "mozilla/dom/mobileconnection/MobileConnection
using nsMobileNetworkInfo 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 mozilla::void_t from "ipc/IPCMessageUtils.h";
using struct IPC::MozCallForwardingOptions from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.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 mozilla {
namespace dom { namespace dom {
@ -18,7 +18,7 @@ union AdditionalInformation {
void_t; void_t;
uint16_t; uint16_t;
nsString[]; nsString[];
MozCallForwardingOptions[]; nsMobileCallForwardingOptions[];
}; };
} // namespace mobileconnection } // namespace mobileconnection