diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index e5d6a0995555..78657e016c0d 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index eb0c31983d7c..291b05271f5e 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index fd6279290c46..9e727b7a2630 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 7cc42656506c..a71525608a03 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index eb0c31983d7c..291b05271f5e 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index de55b583cfc0..850d3796d1ba 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 1dda1e9a3d5d..b94dfb654ab3 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 11b1e61879ce..dd6829c57de1 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "eeeae73691f91cd5042660b0f19c84747ebc7be2", + "revision": "a10638edfc562e970fa6062c06edffd581c6f057", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index fd63beac7d79..8ae609665f29 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 4e2295388725..84f7a7257773 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index e9e44f50ab23..5ce6323d63e6 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 0abd38a7c112..76c64162edb6 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/dom/mobileconnection/MobileCallForwardingOptions.cpp b/dom/mobileconnection/MobileCallForwardingOptions.cpp new file mode 100644 index 000000000000..2fb5ce9ac3c8 --- /dev/null +++ b/dom/mobileconnection/MobileCallForwardingOptions.cpp @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/mobileconnection/MobileCallForwardingOptions.h" + +namespace mozilla { +namespace dom { +namespace mobileconnection { + +NS_IMPL_ISUPPORTS(MobileCallForwardingOptions, nsIMobileCallForwardingOptions) + +MobileCallForwardingOptions::MobileCallForwardingOptions(bool aActive, + int16_t aAction, + int16_t aReason, + const nsAString& aNumber, + int16_t aTimeSeconds, + int16_t aServiceClass) + : mActive(aActive) + , mAction(aAction) + , mReason(aReason) + , mNumber(aNumber) + , mTimeSeconds(aTimeSeconds) + , mServiceClass(aServiceClass) +{ +} + +NS_IMETHODIMP +MobileCallForwardingOptions::GetActive(bool* aActive) +{ + *aActive = mActive; + return NS_OK; +} + +NS_IMETHODIMP +MobileCallForwardingOptions::GetAction(int16_t* aAction) +{ + *aAction = mAction; + return NS_OK; +} + +NS_IMETHODIMP +MobileCallForwardingOptions::GetReason(int16_t* aReason) +{ + *aReason = mReason; + return NS_OK; +} + +NS_IMETHODIMP +MobileCallForwardingOptions::GetNumber(nsAString& aNumber) +{ + aNumber = mNumber; + return NS_OK; +} + +NS_IMETHODIMP +MobileCallForwardingOptions::GetTimeSeconds(int16_t* aTimeSeconds) +{ + *aTimeSeconds = mTimeSeconds; + return NS_OK; +} + +NS_IMETHODIMP +MobileCallForwardingOptions::GetServiceClass(int16_t *aServiceClass) +{ + *aServiceClass = mServiceClass; + return NS_OK; +} + +} // namespace mobileconnection +} // namespace dom +} // namespace mozilla \ No newline at end of file diff --git a/dom/mobileconnection/MobileCallForwardingOptions.h b/dom/mobileconnection/MobileCallForwardingOptions.h new file mode 100644 index 000000000000..0f149c23c879 --- /dev/null +++ b/dom/mobileconnection/MobileCallForwardingOptions.h @@ -0,0 +1,44 @@ +/* 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_MobileCallForwardingOptions_h +#define mozilla_dom_MobileCallForwardingOptions_h + +#include "nsIMobileCallForwardingOptions.h" +#include "nsString.h" +#include "mozilla/Attributes.h" + +namespace mozilla { +namespace dom { +namespace mobileconnection { + +class MobileCallForwardingOptions MOZ_FINAL : public nsIMobileCallForwardingOptions +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIMOBILECALLFORWARDINGOPTIONS + + MobileCallForwardingOptions(bool aActive, int16_t aAction, + int16_t aReason, const nsAString& aNumber, + int16_t aTimeSeconds, int16_t aServiceClass); + +private: + // Don't try to use the default constructor. + MobileCallForwardingOptions() {} + + ~MobileCallForwardingOptions() {} + + bool mActive; + int16_t mAction; + int16_t mReason; + nsString mNumber; + int16_t mTimeSeconds; + int16_t mServiceClass; +}; + +} // namespace mobileconnection +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_MobileCallForwardingOptions_h \ No newline at end of file diff --git a/dom/mobileconnection/MobileConnection.cpp b/dom/mobileconnection/MobileConnection.cpp index ccd1e848e128..2df8ce18eac5 100644 --- a/dom/mobileconnection/MobileConnection.cpp +++ b/dom/mobileconnection/MobileConnection.cpp @@ -21,6 +21,9 @@ #include "nsJSUtils.h" #include "nsServiceManagerUtils.h" +#define MOBILECONN_ERROR_INVALID_PARAMETER NS_LITERAL_STRING("InvalidParameter") +#define MOBILECONN_ERROR_INVALID_PASSWORD NS_LITERAL_STRING("InvalidPassword") + #ifdef CONVERT_STRING_TO_NULLABLE_ENUM #undef CONVERT_STRING_TO_NULLABLE_ENUM #endif @@ -206,6 +209,84 @@ MobileConnection::UpdateData() mData->Update(info); } +nsresult +MobileConnection::NotifyError(nsIDOMDOMRequest* aRequest, const nsAString& aMessage) +{ + nsCOMPtr rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID); + NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE); + + return rs->FireErrorAsync(aRequest, aMessage); +} + +bool +MobileConnection::IsValidPassword(const nsAString& aPassword) +{ + // Check valid PIN for supplementary services. See TS.22.004 clause 5.2. + if (aPassword.IsEmpty() || aPassword.Length() != 4) { + return false; + } + + nsresult rv; + int32_t password = nsString(aPassword).ToInteger(&rv); + return NS_SUCCEEDED(rv) && password >= 0 && password <= 9999; +} + +bool +MobileConnection::IsValidCallForwardingReason(int32_t aReason) +{ + return aReason >= nsIMobileConnection::CALL_FORWARD_REASON_UNCONDITIONAL && + aReason <= nsIMobileConnection::CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING; +} + +bool +MobileConnection::IsValidCallForwardingAction(int32_t aAction) +{ + return aAction >= nsIMobileConnection::CALL_FORWARD_ACTION_DISABLE && + aAction <= nsIMobileConnection::CALL_FORWARD_ACTION_ERASURE && + // Set operation doesn't allow "query" action. + aAction != nsIMobileConnection::CALL_FORWARD_ACTION_QUERY_STATUS; +} + +bool +MobileConnection::IsValidCallBarringProgram(int32_t aProgram) +{ + return aProgram >= nsIMobileConnection::CALL_BARRING_PROGRAM_ALL_OUTGOING && + aProgram <= nsIMobileConnection::CALL_BARRING_PROGRAM_INCOMING_ROAMING; +} + +bool +MobileConnection::IsValidCallBarringOptions(const MozCallBarringOptions& aOptions, + bool isSetting) +{ + if (!aOptions.mServiceClass.WasPassed() || aOptions.mServiceClass.Value().IsNull() || + !aOptions.mProgram.WasPassed() || aOptions.mProgram.Value().IsNull() || + !IsValidCallBarringProgram(aOptions.mProgram.Value().Value())) { + return false; + } + + // For setting callbarring options, |enabled| and |password| are required. + if (isSetting && + (!aOptions.mEnabled.WasPassed() || aOptions.mEnabled.Value().IsNull() || + !aOptions.mPassword.WasPassed() || aOptions.mPassword.Value().IsVoid())) { + return false; + } + + return true; +} + +bool +MobileConnection::IsValidCallForwardingOptions(const MozCallForwardingOptions& aOptions) +{ + if (!aOptions.mReason.WasPassed() || aOptions.mReason.Value().IsNull() || + !aOptions.mAction.WasPassed() || aOptions.mAction.Value().IsNull() || + !IsValidCallForwardingReason(aOptions.mReason.Value().Value()) || + !IsValidCallForwardingAction(aOptions.mAction.Value().Value())) { + return false; + } + + return true; +} + // WebIDL interface void @@ -568,6 +649,16 @@ MobileConnection::GetCallForwardingOption(uint16_t aReason, ErrorResult& aRv) } nsRefPtr request = new DOMRequest(GetOwner()); + + if (!IsValidCallForwardingReason(aReason)) { + nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return nullptr; + } + return request.forget(); + } + nsRefPtr requestCallback = new MobileConnectionCallback(GetOwner(), request); @@ -589,24 +680,42 @@ MobileConnection::SetCallForwardingOption(const MozCallForwardingOptions& aOptio return nullptr; } - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(GetOwner()))) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - JSContext *cx = jsapi.cx(); - JS::Rooted options(cx); - if (!ToJSValue(cx, aOptions, &options)) { - aRv.Throw(NS_ERROR_TYPE_ERR); - return nullptr; - } - nsRefPtr request = new DOMRequest(GetOwner()); + + if (!IsValidCallForwardingOptions(aOptions)) { + nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return nullptr; + } + return request.forget(); + } + + // Fill in optional attributes. + uint16_t timeSeconds = 0; + if (aOptions.mTimeSeconds.WasPassed() && !aOptions.mTimeSeconds.Value().IsNull()) { + timeSeconds = aOptions.mTimeSeconds.Value().Value(); + } + uint16_t serviceClass = nsIMobileConnection::ICC_SERVICE_CLASS_NONE; + if (aOptions.mServiceClass.WasPassed() && !aOptions.mServiceClass.Value().IsNull()) { + serviceClass = aOptions.mServiceClass.Value().Value(); + } + nsAutoString number; + if (aOptions.mNumber.WasPassed()) { + number = aOptions.mNumber.Value(); + } else { + number.SetIsVoid(true); + } + nsRefPtr requestCallback = new MobileConnectionCallback(GetOwner(), request); - nsresult rv = mMobileConnection->SetCallForwarding(options, requestCallback); + nsresult rv = mMobileConnection->SetCallForwarding(aOptions.mAction.Value().Value(), + aOptions.mReason.Value().Value(), + number, + timeSeconds, + serviceClass, + requestCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -624,24 +733,32 @@ MobileConnection::GetCallBarringOption(const MozCallBarringOptions& aOptions, return nullptr; } - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(GetOwner()))) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - JSContext *cx = jsapi.cx(); - JS::Rooted options(cx); - if (!ToJSValue(cx, aOptions, &options)) { - aRv.Throw(NS_ERROR_TYPE_ERR); - return nullptr; - } - nsRefPtr request = new DOMRequest(GetOwner()); + + if (!IsValidCallBarringOptions(aOptions, false)) { + nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return nullptr; + } + return request.forget(); + } + + // Fill in optional attributes. + nsAutoString password; + if (aOptions.mPassword.WasPassed()) { + password = aOptions.mPassword.Value(); + } else { + password.SetIsVoid(true); + } + nsRefPtr requestCallback = new MobileConnectionCallback(GetOwner(), request); - nsresult rv = mMobileConnection->GetCallBarring(options, requestCallback); + nsresult rv = mMobileConnection->GetCallBarring(aOptions.mProgram.Value().Value(), + password, + aOptions.mServiceClass.Value().Value(), + requestCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -659,24 +776,25 @@ MobileConnection::SetCallBarringOption(const MozCallBarringOptions& aOptions, return nullptr; } - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(GetOwner()))) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - JSContext *cx = jsapi.cx(); - JS::Rooted options(cx); - if (!ToJSValue(cx, aOptions, &options)) { - aRv.Throw(NS_ERROR_TYPE_ERR); - return nullptr; - } - nsRefPtr request = new DOMRequest(GetOwner()); + + if (!IsValidCallBarringOptions(aOptions, true)) { + nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return nullptr; + } + return request.forget(); + } + nsRefPtr requestCallback = new MobileConnectionCallback(GetOwner(), request); - nsresult rv = mMobileConnection->SetCallBarring(options, requestCallback); + nsresult rv = mMobileConnection->SetCallBarring(aOptions.mProgram.Value().Value(), + aOptions.mEnabled.Value().Value(), + aOptions.mPassword.Value(), + aOptions.mServiceClass.Value().Value(), + requestCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -694,25 +812,27 @@ MobileConnection::ChangeCallBarringPassword(const MozCallBarringOptions& aOption return nullptr; } - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(GetOwner()))) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - JSContext *cx = jsapi.cx(); - JS::Rooted options(cx); - if (!ToJSValue(cx, aOptions, &options)) { - aRv.Throw(NS_ERROR_TYPE_ERR); - return nullptr; - } - nsRefPtr request = new DOMRequest(GetOwner()); + + if (!aOptions.mPin.WasPassed() || aOptions.mPin.Value().IsVoid() || + !aOptions.mNewPin.WasPassed() || aOptions.mNewPin.Value().IsVoid() || + !IsValidPassword(aOptions.mPin.Value()) || + !IsValidPassword(aOptions.mNewPin.Value())) { + nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PASSWORD); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return nullptr; + } + return request.forget(); + } + nsRefPtr requestCallback = new MobileConnectionCallback(GetOwner(), request); nsresult rv = - mMobileConnection->ChangeCallBarringPassword(options, requestCallback); + mMobileConnection->ChangeCallBarringPassword(aOptions.mPin.Value(), + aOptions.mNewPin.Value(), + requestCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; diff --git a/dom/mobileconnection/MobileConnection.h b/dom/mobileconnection/MobileConnection.h index 01cad4742e65..ba0aa1274d91 100644 --- a/dom/mobileconnection/MobileConnection.h +++ b/dom/mobileconnection/MobileConnection.h @@ -176,6 +176,27 @@ private: void UpdateData(); + + nsresult + NotifyError(nsIDOMDOMRequest* aRequest, const nsAString& aMessage); + + bool + IsValidPassword(const nsAString& aPassword); + + bool + IsValidCallBarringOptions(const MozCallBarringOptions& aOptions, bool isSetting); + + bool + IsValidCallForwardingOptions(const MozCallForwardingOptions& aOptions); + + bool + IsValidCallForwardingReason(int32_t aReason); + + bool + IsValidCallForwardingAction(int32_t aAction); + + bool + IsValidCallBarringProgram(int32_t aProgram); }; } // namespace dom diff --git a/dom/mobileconnection/MobileConnectionCallback.cpp b/dom/mobileconnection/MobileConnectionCallback.cpp index e66d2c1e830c..121b5b1e6ab4 100644 --- a/dom/mobileconnection/MobileConnectionCallback.cpp +++ b/dom/mobileconnection/MobileConnectionCallback.cpp @@ -27,94 +27,6 @@ MobileConnectionCallback::MobileConnectionCallback(nsPIDOMWindow* aWindow, /** * Notify Success for Send/CancelMmi. */ -nsresult -MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage) -{ - MozMMIResult result; - result.mServiceCode.Assign(aServiceCode); - result.mStatusMessage.Assign(aStatusMessage); - - return NotifySendCancelMmiSuccess(result); -} - -nsresult -MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - JS::Handle aAdditionalInformation) -{ - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(mWindow))) { - return NS_ERROR_FAILURE; - } - - JSContext* cx = jsapi.cx(); - RootedDictionary result(cx); - - result.mServiceCode.Assign(aServiceCode); - result.mStatusMessage.Assign(aStatusMessage); - result.mAdditionalInformation.Construct().SetAsObject() = &aAdditionalInformation.toObject(); - - return NotifySendCancelMmiSuccess(result); -} - -nsresult -MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - uint16_t aAdditionalInformation) -{ - MozMMIResult result; - result.mServiceCode.Assign(aServiceCode); - result.mStatusMessage.Assign(aStatusMessage); - result.mAdditionalInformation.Construct().SetAsUnsignedShort() = aAdditionalInformation; - - return NotifySendCancelMmiSuccess(result); -} - -nsresult -MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - const nsTArray& aAdditionalInformation) -{ - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(mWindow))) { - return NS_ERROR_FAILURE; - } - - JSContext* cx = jsapi.cx(); - JS::Rooted additionalInformation(cx); - - if (!ToJSValue(cx, aAdditionalInformation, &additionalInformation)) { - JS_ClearPendingException(cx); - return NS_ERROR_TYPE_ERR; - } - - return NotifySendCancelMmiSuccess(aServiceCode, aStatusMessage, - additionalInformation); -} - -nsresult -MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - const nsTArray& aAdditionalInformation) -{ - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(mWindow))) { - return NS_ERROR_FAILURE; - } - - JSContext* cx = jsapi.cx(); - JS::Rooted additionalInformation(cx); - - if (!ToJSValue(cx, aAdditionalInformation, &additionalInformation)) { - JS_ClearPendingException(cx); - return NS_ERROR_TYPE_ERR; - } - - return NotifySendCancelMmiSuccess(aServiceCode, aStatusMessage, - additionalInformation); -} - nsresult MobileConnectionCallback::NotifySendCancelMmiSuccess(const MozMMIResult& aResult) { @@ -134,28 +46,6 @@ MobileConnectionCallback::NotifySendCancelMmiSuccess(const MozMMIResult& aResult return NotifySuccess(jsResult); } -/** - * Notify Success for GetCallForwarding. - */ -nsresult -MobileConnectionCallback::NotifyGetCallForwardingSuccess(const nsTArray& aResults) -{ - AutoJSAPI jsapi; - if (!NS_WARN_IF(jsapi.Init(mWindow))) { - return NS_ERROR_FAILURE; - } - - JSContext* cx = jsapi.cx(); - JS::Rooted jsResult(cx); - - if (!ToJSValue(cx, aResults, &jsResult)) { - JS_ClearPendingException(cx); - return NS_ERROR_TYPE_ERR; - } - - return NotifySuccess(jsResult); -} - /** * Notify Success. */ @@ -230,18 +120,186 @@ MobileConnectionCallback::NotifyGetNetworksSuccess(uint32_t aCount, return NotifySuccess(jsResult); } -NS_IMETHODIMP -MobileConnectionCallback::NotifySendCancelMmiSuccess(JS::Handle aResult, - JSContext* aCx) +nsresult +MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode, + const nsAString& aStatusMessage) { - return NotifySuccess(aResult); + MozMMIResult result; + result.mServiceCode.Assign(aServiceCode); + result.mStatusMessage.Assign(aStatusMessage); + + return NotifySendCancelMmiSuccess(result); +} + +nsresult +MobileConnectionCallback::NotifySendCancelMmiSuccessWithInteger(const nsAString& aServiceCode, + const nsAString& aStatusMessage, + uint16_t aAdditionalInformation) +{ + MozMMIResult result; + result.mServiceCode.Assign(aServiceCode); + result.mStatusMessage.Assign(aStatusMessage); + result.mAdditionalInformation.Construct().SetAsUnsignedShort() = aAdditionalInformation; + + return NotifySendCancelMmiSuccess(result); +} + +nsresult +MobileConnectionCallback::NotifySendCancelMmiSuccessWithStrings(const nsAString& aServiceCode, + const nsAString& aStatusMessage, + uint32_t aCount, + const char16_t** aAdditionalInformation) +{ + AutoJSAPI jsapi; + if (!NS_WARN_IF(jsapi.Init(mWindow))) { + return NS_ERROR_FAILURE; + } + + JSContext* cx = jsapi.cx(); + RootedDictionary result(cx); + + result.mServiceCode.Assign(aServiceCode); + result.mStatusMessage.Assign(aStatusMessage); + + nsTArray additionalInformation; + for (uint32_t i = 0; i < aCount; i++) { + additionalInformation.AppendElement(nsDependentString(aAdditionalInformation[i])); + } + + JS::Rooted jsAdditionalInformation(cx); + if (!ToJSValue(cx, additionalInformation, &jsAdditionalInformation)) { + JS_ClearPendingException(cx); + return NS_ERROR_TYPE_ERR; + } + + result.mAdditionalInformation.Construct().SetAsObject() = + &jsAdditionalInformation.toObject(); + + return NotifySendCancelMmiSuccess(result); +} + +nsresult +MobileConnectionCallback::NotifySendCancelMmiSuccessWithCallForwardingOptions( + const nsAString& aServiceCode, + const nsAString& aStatusMessage, + uint32_t aCount, + nsIMobileCallForwardingOptions** aResults) +{ + AutoJSAPI jsapi; + if (!NS_WARN_IF(jsapi.Init(mWindow))) { + return NS_ERROR_FAILURE; + } + + JSContext* cx = jsapi.cx(); + RootedDictionary result(cx); + + result.mServiceCode.Assign(aServiceCode); + result.mStatusMessage.Assign(aStatusMessage); + + nsTArray additionalInformation; + for (uint32_t i = 0; i < aCount; i++) + { + MozCallForwardingOptions options; + int16_t pShort; + nsString pString; + bool pBool; + + aResults[i]->GetActive(&pBool); + options.mActive.Construct(pBool); + + aResults[i]->GetAction(&pShort); + if (pShort != nsIMobileConnection::CALL_FORWARD_ACTION_UNKNOWN) { + options.mAction.Construct(pShort); + } + + aResults[i]->GetReason(&pShort); + if (pShort != nsIMobileConnection::CALL_FORWARD_REASON_UNKNOWN) { + options.mReason.Construct(pShort); + } + + aResults[i]->GetNumber(pString); + options.mNumber.Construct(pString.get()); + + aResults[i]->GetTimeSeconds(&pShort); + if (pShort >= 0) { + options.mTimeSeconds.Construct(pShort); + } + + aResults[i]->GetServiceClass(&pShort); + if (pShort != nsIMobileConnection::ICC_SERVICE_CLASS_NONE) { + options.mServiceClass.Construct(pShort); + } + + additionalInformation.AppendElement(options); + } + + JS::Rooted jsAdditionalInformation(cx); + if (!ToJSValue(cx, additionalInformation, &jsAdditionalInformation)) { + JS_ClearPendingException(cx); + return NS_ERROR_TYPE_ERR; + } + + result.mAdditionalInformation.Construct().SetAsObject() = + &jsAdditionalInformation.toObject(); + + return NotifySendCancelMmiSuccess(result); } NS_IMETHODIMP -MobileConnectionCallback::NotifyGetCallForwardingSuccess(JS::Handle aResults, - JSContext* aCx) +MobileConnectionCallback::NotifyGetCallForwardingSuccess(uint32_t aCount, + nsIMobileCallForwardingOptions** aResults) { - return NotifySuccess(aResults); + nsTArray results; + for (uint32_t i = 0; i < aCount; i++) + { + MozCallForwardingOptions result; + int16_t pShort; + nsString pString; + bool pBool; + + aResults[i]->GetActive(&pBool); + result.mActive.Construct(pBool); + + aResults[i]->GetAction(&pShort); + if (pShort != nsIMobileConnection::CALL_FORWARD_ACTION_UNKNOWN) { + result.mAction.Construct(pShort); + } + + aResults[i]->GetReason(&pShort); + if (pShort != nsIMobileConnection::CALL_FORWARD_REASON_UNKNOWN) { + result.mReason.Construct(pShort); + } + + aResults[i]->GetNumber(pString); + result.mNumber.Construct(pString.get()); + + aResults[i]->GetTimeSeconds(&pShort); + if (pShort >= 0) { + result.mTimeSeconds.Construct(pShort); + } + + aResults[i]->GetServiceClass(&pShort); + if (pShort != nsIMobileConnection::ICC_SERVICE_CLASS_NONE) { + result.mServiceClass.Construct(pShort); + } + + results.AppendElement(result); + } + + AutoJSAPI jsapi; + if (!NS_WARN_IF(jsapi.Init(mWindow))) { + return NS_ERROR_FAILURE; + } + + JSContext* cx = jsapi.cx(); + JS::Rooted jsResult(cx); + + if (!ToJSValue(cx, results, &jsResult)) { + JS_ClearPendingException(cx); + return NS_ERROR_TYPE_ERR; + } + + return NotifySuccess(jsResult); } NS_IMETHODIMP diff --git a/dom/mobileconnection/MobileConnectionCallback.h b/dom/mobileconnection/MobileConnectionCallback.h index af6bc276b1e1..3cce1ce5ec71 100644 --- a/dom/mobileconnection/MobileConnectionCallback.h +++ b/dom/mobileconnection/MobileConnectionCallback.h @@ -32,43 +32,15 @@ public: MobileConnectionCallback(nsPIDOMWindow* aWindow, DOMRequest* aRequest); - /** - * Notify Success for Send/CancelMmi. - */ - nsresult - NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage); - nsresult - NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - JS::Handle aAdditionalInformation); - nsresult - NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - uint16_t aAdditionalInformation); - nsresult - NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - const nsTArray& aAdditionalInformation); - nsresult - NotifySendCancelMmiSuccess(const nsAString& aServiceCode, - const nsAString& aStatusMessage, - const nsTArray& aAdditionalInformation); - nsresult - NotifySendCancelMmiSuccess(const MozMMIResult& aResult); - - /** - * Notify Success for GetCallForwarding. - */ - nsresult - NotifyGetCallForwardingSuccess(const nsTArray& aResults); - private: ~MobileConnectionCallback() {} nsresult NotifySuccess(JS::Handle aResult); + nsresult + NotifySendCancelMmiSuccess(const MozMMIResult& aResult); + nsCOMPtr mWindow; nsRefPtr mRequest; }; diff --git a/dom/mobileconnection/gonk/MobileConnectionService.js b/dom/mobileconnection/gonk/MobileConnectionService.js index 65205597bd97..74786b3f3a6c 100644 --- a/dom/mobileconnection/gonk/MobileConnectionService.js +++ b/dom/mobileconnection/gonk/MobileConnectionService.js @@ -25,6 +25,8 @@ const MOBILENETWORKINFO_CID = Components.ID("{a6c8416c-09b4-46d1-bf29-6520d677d085}"); const MOBILECELLINFO_CID = Components.ID("{0635d9ab-997e-4cdf-84e7-c1883752dff3}"); +const MOBILECALLFORWARDINGOPTIONS_CID = + Components.ID("{e0cf4463-ee63-4b05-ab2e-d94bf764836c}"); const TELEPHONYCALLBACK_CID = Components.ID("{6e1af17e-37f3-11e4-aed3-60a44c237d2b}"); @@ -112,33 +114,29 @@ MobileConnectionInfo.prototype = { relSignalStrength: null }; -function CallForwardingOptions(aOptions) { - this.active = aOptions.active; - this.action = aOptions.action; - this.reason = aOptions.reason; - this.number = aOptions.number; - this.timeSeconds = aOptions.timeSeconds; - this.serviceClass = aOptions.serviceClass; +function MobileCallForwardingOptions(aOptions) { + for (let key in aOptions) { + this[key] = aOptions[key]; + } } -CallForwardingOptions.prototype = { - __exposedProps__ : {active: 'r', - action: 'r', - reason: 'r', - number: 'r', - timeSeconds: 'r', - serviceClass: 'r'}, -}; +MobileCallForwardingOptions.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileCallForwardingOptions]), + classID: MOBILECALLFORWARDINGOPTIONS_CID, + classInfo: XPCOMUtils.generateCI({ + classID: MOBILECALLFORWARDINGOPTIONS_CID, + classDescription: "MobileCallForwardingOptions", + interfaces: [Ci.nsIMobileCallForwardingOptions] + }), -function MMIResult(aOptions) { - this.serviceCode = aOptions.serviceCode; - this.statusMessage = aOptions.statusMessage; - this.additionalInformation = aOptions.additionalInformation; + // nsIMobileForwardingOptions + + active: false, + action: Ci.nsIMobileConnection.CALL_FORWARD_ACTION_UNKNOWN, + reason: Ci.nsIMobileConnection.CALL_FORWARD_REASON_UNKNOWN, + number: null, + timeSeconds: -1, + serviceClass: Ci.nsIMobileConnection.ICC_SERVICE_CLASS_NONE } -MMIResult.prototype = { - __exposedProps__ : {serviceCode: 'r', - statusMessage: 'r', - additionalInformation: 'r'}, -}; /** * Wrap a MobileConnectionCallback to a TelephonyCallback. @@ -150,12 +148,47 @@ TelephonyCallback.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyCallback]), classID: TELEPHONYCALLBACK_CID, + _notifySendCancelMmiSuccess: function(aResult) { + // No additional information. + if (aResult.additionalInformation === undefined) { + this.callback.notifySendCancelMmiSuccess(aResult.serviceCode, + aResult.statusMessage); + return; + } + + // Additional information is an integer. + if (!isNaN(parseInt(aResult.additionalInformation, 10))) { + this.callback.notifySendCancelMmiSuccessWithInteger( + aResult.serviceCode, aResult.statusMessage, aResult.additionalInformation); + return; + } + + // Additional information should be an array. + let array = aResult.additionalInformation; + if (Array.isArray(array) && array.length > 0) { + let item = array[0]; + if (typeof item === "string" || item instanceof String) { + this.callback.notifySendCancelMmiSuccessWithStrings( + aResult.serviceCode, aResult.statusMessage, + aResult.additionalInformation.length, aResult.additionalInformation); + return; + } + + this.callback.notifySendCancelMmiSuccessWithCallForwardingOptions( + aResult.serviceCode, aResult.statusMessage, + aResult.additionalInformation.length, aResult.additionalInformation); + return; + } + + throw Cr.NS_ERROR_UNEXPECTED; + }, + notifyDialMMI: function(mmiServiceCode) { this.serviceCode = mmiServiceCode; }, notifyDialMMISuccess: function(result) { - this.callback.notifySendCancelMmiSuccess(result); + this._notifySendCancelMmiSuccess(result); }, notifyDialMMIError: function(error) { @@ -255,72 +288,6 @@ MobileConnectionProvider.prototype = { return supportedNetworkTypes; }, - /** - * Helper for guarding us against invalid reason values for call forwarding. - */ - _isValidCallForwardingReason: function(aReason) { - switch (aReason) { - case Ci.nsIMobileConnection.CALL_FORWARD_REASON_UNCONDITIONAL: - case Ci.nsIMobileConnection.CALL_FORWARD_REASON_MOBILE_BUSY: - case Ci.nsIMobileConnection.CALL_FORWARD_REASON_NO_REPLY: - case Ci.nsIMobileConnection.CALL_FORWARD_REASON_NOT_REACHABLE: - case Ci.nsIMobileConnection.CALL_FORWARD_REASON_ALL_CALL_FORWARDING: - case Ci.nsIMobileConnection.CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING: - return true; - default: - return false; - } - }, - - /** - * Helper for guarding us against invalid action values for call forwarding. - */ - _isValidCallForwardingAction: function(aAction) { - switch (aAction) { - case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_DISABLE: - case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_ENABLE: - case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_REGISTRATION: - case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_ERASURE: - return true; - default: - return false; - } - }, - - /** - * Helper for guarding us against invalid program values for call barring. - */ - _isValidCallBarringProgram: function(aProgram) { - switch (aProgram) { - case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING: - case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL: - case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME: - case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_ALL_INCOMING: - case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_INCOMING_ROAMING: - return true; - default: - return false; - } - }, - - /** - * Helper for guarding us against invalid options for call barring. - */ - _isValidCallBarringOptions: function(aOptions, aUsedForSetting) { - if (!aOptions || aOptions.serviceClass == null || - !this._isValidCallBarringProgram(aOptions.program)) { - return false; - } - - // For setting callbarring options, |enabled| and |password| are required. - if (aUsedForSetting && - (aOptions.enabled == null || aOptions.password == null)) { - return false; - } - - return true; - }, - /** * Helper for guarding us against invalid mode for clir. */ @@ -423,7 +390,7 @@ MobileConnectionProvider.prototype = { }, _rulesToCallForwardingOptions: function(aRules) { - return aRules.map(rule => new CallForwardingOptions(rule)); + return aRules.map(rule => new MobileCallForwardingOptions(rule)); }, _dispatchNotifyError: function(aCallback, aErrorMsg) { @@ -742,20 +709,13 @@ MobileConnectionProvider.prototype = { }).bind(this)); }, - setCallForwarding: function(aOptions, aCallback) { - if (!aOptions || - !this._isValidCallForwardingReason(aOptions.reason) || - !this._isValidCallForwardingAction(aOptions.action)){ - this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER); - return; - } - + setCallForwarding: function(aAction, aReason, aNumber, aTimeSeconds, + aServiceClass, aCallback) { let options = { - active: aOptions.active, - action: aOptions.action, - reason: aOptions.reason, - number: aOptions.number, - timeSeconds: aOptions.timeSeconds, + action: aAction, + reason: aReason, + number: aNumber, + timeSeconds: aTimeSeconds, serviceClass: RIL.ICC_SERVICE_CLASS_VOICE }; @@ -775,11 +735,6 @@ MobileConnectionProvider.prototype = { }, getCallForwarding: function(aReason, aCallback) { - if (!this._isValidCallForwardingReason(aReason)){ - this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER); - return; - } - this._radioInterface.sendWorkerMessage("queryCallForwardStatus", {reason: aReason}, (function(aResponse) { @@ -788,23 +743,19 @@ MobileConnectionProvider.prototype = { return false; } - aCallback.notifyGetCallForwardingSuccess( - this._rulesToCallForwardingOptions(aResponse.rules)); + let infos = this._rulesToCallForwardingOptions(aResponse.rules); + aCallback.notifyGetCallForwardingSuccess(infos.length, infos); return false; }).bind(this)); }, - setCallBarring: function(aOptions, aCallback) { - if (!this._isValidCallBarringOptions(aOptions, true)) { - this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER); - return; - } - + setCallBarring: function(aProgram, aEnabled, aPassword, aServiceClass, + aCallback) { let options = { - program: aOptions.program, - enabled: aOptions.enabled, - password: aOptions.password, - serviceClass: aOptions.serviceClass + program: aProgram, + enabled: aEnabled, + password: aPassword, + serviceClass: aServiceClass }; this._radioInterface.sendWorkerMessage("setCallBarring", options, @@ -819,16 +770,11 @@ MobileConnectionProvider.prototype = { }).bind(this)); }, - getCallBarring: function(aOptions, aCallback) { - if (!this._isValidCallBarringOptions(aOptions)) { - this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER); - return; - } - + getCallBarring: function(aProgram, aPassword, aServiceClass, aCallback) { let options = { - program: aOptions.program, - password: aOptions.password, - serviceClass: aOptions.serviceClass + program: aProgram, + password: aPassword, + serviceClass: aServiceClass }; this._radioInterface.sendWorkerMessage("queryCallBarringStatus", options, @@ -845,17 +791,10 @@ MobileConnectionProvider.prototype = { }).bind(this)); }, - changeCallBarringPassword: function(aOptions, aCallback) { - // Checking valid PIN for supplementary services. See TS.22.004 clause 5.2. - if (aOptions.pin == null || !aOptions.pin.match(/^\d{4}$/) || - aOptions.newPin == null || !aOptions.newPin.match(/^\d{4}$/)) { - this._dispatchNotifyError(aCallback, "InvalidPassword"); - return; - } - + changeCallBarringPassword: function(aPin, aNewPin, aCallback) { let options = { - pin: aOptions.pin, - newPin: aOptions.newPin + pin: aPin, + newPin: aNewPin }; this._radioInterface.sendWorkerMessage("changeCallBarringPassword", options, diff --git a/dom/mobileconnection/interfaces/nsIMobileCallForwardingOptions.idl b/dom/mobileconnection/interfaces/nsIMobileCallForwardingOptions.idl new file mode 100644 index 000000000000..323c59c2a42e --- /dev/null +++ b/dom/mobileconnection/interfaces/nsIMobileCallForwardingOptions.idl @@ -0,0 +1,51 @@ +/* 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 "nsISupports.idl" + +[scriptable, uuid(c616ecb6-65f5-441e-b97e-c642ddef6888)] +interface nsIMobileCallForwardingOptions : nsISupports +{ + /** + * Call forwarding rule status. + * + * It will be either not active (false), or active (true). + * + * Note: Unused for setting call forwarding options. It reports + * the status of the rule when getting how the rule is + * configured. + * + * @see 3GPP TS 27.007 7.11 "status". + */ + readonly attribute bool active; + + /** + * Indicates what to do with the rule. It shall be one of the + * nsIMobileConnection.CALL_FORWARD_ACTION_* values. + */ + readonly attribute short action; + + /** + * Indicates the reason the call is being forwarded. It shall be one of the + * nsIMobileConnection.CALL_FORWARD_REASON_* values. + */ + readonly attribute short reason; + + /** + * Phone number of forwarding address. + */ + readonly attribute DOMString number; + + /** + * When "no reply" is enabled or queried, this gives the time in + * seconds to wait before call is forwarded. + */ + readonly attribute short timeSeconds; + + /** + * Service for which the call forward is set up. It should be one of the + * nsIMobileConnection.ICC_SERVICE_CLASS_* values. + */ + readonly attribute short serviceClass; +}; diff --git a/dom/mobileconnection/interfaces/nsIMobileConnectionService.idl b/dom/mobileconnection/interfaces/nsIMobileConnectionService.idl index 2d70f2067319..36c3a4517f9e 100644 --- a/dom/mobileconnection/interfaces/nsIMobileConnectionService.idl +++ b/dom/mobileconnection/interfaces/nsIMobileConnectionService.idl @@ -4,12 +4,13 @@ #include "nsISupports.idl" +interface nsIMobileCallForwardingOptions; interface nsIMobileConnection; interface nsIMobileConnectionInfo; interface nsIMobileNetworkInfo; interface nsIVariant; -[scriptable, uuid(bc0d4d76-fd3a-4593-818f-cb6ff87fbb55)] +[scriptable, uuid(823d935e-8262-47ed-8429-8203096b2ff4)] interface nsIMobileConnectionListener : nsISupports { /** @@ -47,15 +48,15 @@ interface nsIMobileConnectionListener : nsISupports * @param success * Indicates whether the set call forwarding request is success. * @param action - * One of the nsIMobileConnectionService.CALL_FORWARD_ACTION_* values. + * One of the nsIMobileConnection.CALL_FORWARD_ACTION_* values. * @param reason - * One of the nsIMobileConnectionService.CALL_FORWARD_REASON_* values. + * One of the nsIMobileConnection.CALL_FORWARD_REASON_* values. * @param number * Phone number of forwarding address. * @param timeSeconds * The time in seconds should wait before call is forwarded. * @param serviceClass - * One of the nsIMobileConnectionService.ICC_SERVICE_CLASS_* values. + * One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values. */ void notifyCFStateChanged(in boolean success, in unsigned short action, @@ -100,7 +101,7 @@ interface nsIMobileConnectionListener : nsISupports * Notify when clir mode is changed. * * @param mode - * One of the nsIMobileConnectionService.CLIR_* values. + * One of the nsIMobileConnection.CLIR_* values. */ void notifyClirModeChanged(in unsigned long mode); @@ -124,7 +125,7 @@ interface nsIMobileConnectionListener : nsISupports #define NO_ADDITIONAL_INFORMATION 0 %} -[scriptable, builtinclass, uuid(7f2dbbe0-42f2-11e4-916c-0800200c9a66)] +[scriptable, builtinclass, uuid(05568ae9-9873-46c6-9acd-0f6994cde756)] interface nsIMobileConnectionCallback : nsISupports { /** @@ -139,11 +140,26 @@ interface nsIMobileConnectionCallback : nsISupports void notifyGetNetworksSuccess(in uint32_t count, [array, size_is(count)] in nsIMobileNetworkInfo networks); - [implicit_jscontext] - void notifySendCancelMmiSuccess(in jsval result /* MozMMIResult */); + void notifySendCancelMmiSuccess(in DOMString aServiceCode, + in DOMString aStatusMessage); + + void notifySendCancelMmiSuccessWithInteger(in DOMString aServiceCode, + in DOMString aStatusMessage, + in unsigned short aAdditionalInformation); + + void notifySendCancelMmiSuccessWithStrings(in DOMString aServiceCode, + in DOMString aStatusMessage, + in unsigned long aLength, + [array, size_is(aLength)] in wstring aAdditionalInformation); + + void notifySendCancelMmiSuccessWithCallForwardingOptions(in DOMString aServiceCode, + in DOMString aStatusMessage, + in unsigned long aLength, + [array, size_is(aLength)] in nsIMobileCallForwardingOptions aAdditionalInformation); + + void notifyGetCallForwardingSuccess(in uint32_t count, + [array, size_is(count)] in nsIMobileCallForwardingOptions results); - [implicit_jscontext] - void notifyGetCallForwardingSuccess(in jsval results /* Array of MozCallForwardingOptions */); void notifyGetCallBarringSuccess(in unsigned short program, in boolean enabled, @@ -218,9 +234,13 @@ already_AddRefed NS_CreateMobileConnectionService(); %} -[scriptable, uuid(04db7331-54fe-4cf7-9347-b9481350f4c2)] +[scriptable, uuid(1b76ccbf-dbc2-4b74-a62a-73ea91599afa)] interface nsIMobileConnection : nsISupports { + /* + * ICC service class. + */ + const long ICC_SERVICE_CLASS_NONE = 0; // not available const long ICC_SERVICE_CLASS_VOICE = (1 << 0); const long ICC_SERVICE_CLASS_DATA = (1 << 1); const long ICC_SERVICE_CLASS_FAX = (1 << 2); @@ -236,6 +256,7 @@ interface nsIMobileConnection : nsISupports * * @see 3GPP TS 27.007 7.11 "mode". */ + const long CALL_FORWARD_ACTION_UNKNOWN = -1; // not available const long CALL_FORWARD_ACTION_DISABLE = 0; const long CALL_FORWARD_ACTION_ENABLE = 1; const long CALL_FORWARD_ACTION_QUERY_STATUS = 2; @@ -247,6 +268,7 @@ interface nsIMobileConnection : nsISupports * * @see 3GPP TS 27.007 7.11 "reason". */ + const long CALL_FORWARD_REASON_UNKNOWN = -1; // not available const long CALL_FORWARD_REASON_UNCONDITIONAL = 0; const long CALL_FORWARD_REASON_MOBILE_BUSY = 1; const long CALL_FORWARD_REASON_NO_REPLY = 2; @@ -257,6 +279,7 @@ interface nsIMobileConnection : nsISupports /** * Call barring program. */ + const long CALL_BARRING_PROGRAM_UNKNOWN = -1; // not available const long CALL_BARRING_PROGRAM_ALL_OUTGOING = 0; const long CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL = 1; const long CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME = 2; @@ -492,7 +515,7 @@ interface nsIMobileConnection : nsISupports * @param requestCallback * Called when request is finished. * - * If successful, the notifySendCancelMmiSuccess() will be called. And the + * If successful, the notifySendCancelMmiSuccess*() will be called. And the * result will contain the information about the mmi operation. * * Otherwise, the notifyError() will be called. @@ -506,7 +529,7 @@ interface nsIMobileConnection : nsISupports * @param requestCallback * Called when request is finished. * - * If successful, the notifySendCancelMmiSuccess() will be called. And the + * If successful, the notifySendCancelMmiSuccess*() will be called. And the * result will contain the information about the mmi operation. * * Otherwise, the notifyError() will be called. @@ -523,8 +546,8 @@ interface nsIMobileConnection : nsISupports * Called when request is finished. * * If successful, the notifyGetCallForwardingSuccess() will be called. And the - * result will be an array of MozCallForwardingOptions. - * @see MozCallForwardingOptions for the detail of result. + * result will be an array of nsIMobileCallForwardingOptions. + * @see nsIMobileCallForwardingOptions for the detail of result. * * Otherwise, the notifyError() will be called, and the error will be either * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter', @@ -536,9 +559,17 @@ interface nsIMobileConnection : nsISupports /** * Configures call forwarding options. * - * @param options - * An object containing the call forward rule to set. - * @see MozCallForwardingOptions for the detail of options. + * @param action + * One of the nsIMobileConnection.CALL_FORWARD_ACTION_* values. + * @param reason + * One of the nsIMobileConnection.CALL_FORWARD_REASON_* values. + * @param number + * Phone number of forwarding address. + * @param timeSeconds + * When "no reply" is enabled or queried, this gives the time in + * seconds to wait before call is forwarded. + * @param serviceClass + * One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values. * @param requestCallback * Called when request is finished. * @@ -548,16 +579,22 @@ interface nsIMobileConnection : nsISupports * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter', * 'IllegalSIMorME', or 'GenericFailure'. */ - void setCallForwarding(in jsval options, + void setCallForwarding(in unsigned short action, + in unsigned short reason, + in DOMString number, + in unsigned short timeSeconds, + in unsigned short serviceClass, in nsIMobileConnectionCallback requestCallback); /** * Queries current call barring status. * - * @param options - * An object containing the call barring rule to query. No need to - * specify 'enabled' property. - * @see MozCallBarringOptions for the detail of options. + * @param program + * One of the nsIMobileConnection.CALL_BARRING_PROGRAM_* values. + * @param password + * Call barring password. Use "" if no password specified. + * @param serviceClass + * One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values. * @param requestCallback * Called when request is finished. * @@ -569,15 +606,22 @@ interface nsIMobileConnection : nsISupports * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter', * 'IllegalSIMorME', or 'GenericFailure'. */ - void getCallBarring(in jsval options, + void getCallBarring(in unsigned short program, + in DOMString password, + in unsigned short serviceClass, in nsIMobileConnectionCallback requestCallback); /** * Configures call barring option. * - * @param options - * An object containing the call barring rule to set. - * @see MozCallBarringOptions for the detail of options. + * @param program + * One of the nsIMobileConnection.CALL_BARRING_PROGRAM_* values. + * @param enabled + * Enable or disable the call barring program. + * @param password + * Call barring password. Use "" if no password specified. + * @param serviceClass + * One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values. * @param requestCallback * Called when request is finished. * @@ -587,17 +631,19 @@ interface nsIMobileConnection : nsISupports * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter', * 'IllegalSIMorME', or 'GenericFailure'. */ - void setCallBarring(in jsval options, + void setCallBarring(in unsigned short program, + in bool enabled, + in DOMString password, + in unsigned short serviceClass, in nsIMobileConnectionCallback requestCallback); /** * Change call barring facility password. * - * @param options - * An object containing information about pin and newPin, and, - * this object must have both "pin" and "newPin" attributes - * to change the call barring facility password. - * @see MozCallBarringOptions for the detail of options. + * @param pin + * Old call barring password. + * @param newPin + * New call barring password. * @param requestCallback * Called when request is finished. * @@ -607,7 +653,8 @@ interface nsIMobileConnection : nsISupports * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter', * 'IllegalSIMorME', or 'GenericFailure'. */ - void changeCallBarringPassword(in jsval options, + void changeCallBarringPassword(in DOMString pin, + in DOMString newPin, in nsIMobileConnectionCallback requestCallback); /** @@ -647,7 +694,7 @@ interface nsIMobileConnection : nsISupports * the called party when originating a call. * * @param clirMode - * One of the nsIMobileConnectionService.CLIR_* values. + * One of the nsIMobileConnection.CLIR_* values. * @param requestCallback * Called when request is finished. * diff --git a/dom/mobileconnection/ipc/MobileConnectionChild.cpp b/dom/mobileconnection/ipc/MobileConnectionChild.cpp index cbf9950ebe91..f7883b348dcd 100644 --- a/dom/mobileconnection/ipc/MobileConnectionChild.cpp +++ b/dom/mobileconnection/ipc/MobileConnectionChild.cpp @@ -239,21 +239,15 @@ MobileConnectionChild::CancelMMI(nsIMobileConnectionCallback* aCallback) } NS_IMETHODIMP -MobileConnectionChild::SetCallForwarding(JS::Handle 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; } @@ -266,59 +260,38 @@ MobileConnectionChild::GetCallForwarding(uint16_t aReason, } NS_IMETHODIMP -MobileConnectionChild::SetCallBarring(JS::Handle 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 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 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; } @@ -597,26 +570,45 @@ MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessMmi& aRe nsAutoString statusMessage(aReply.statusMessage()); AdditionalInformation info(aReply.additionalInformation()); - nsRefPtr callback = static_cast(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& additionalInformation = info.get_ArrayOfnsString(); + + nsAutoArrayPtr 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> results; + for (uint32_t i = 0; i < count; i++) { + // Use dont_AddRef here because these instances are already AddRef-ed in + // MobileConnectionIPCSerializer.h + nsCOMPtr item = dont_AddRef( + info.get_ArrayOfnsMobileCallForwardingOptions()[i]); + results.AppendElement(item); + } + + return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithCallForwardingOptions( + serviceCode, statusMessage, count, + const_cast(info.get_ArrayOfnsMobileCallForwardingOptions().Elements()))); + } default: MOZ_CRASH("Received invalid type!"); @@ -628,8 +620,17 @@ MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessMmi& aRe bool MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallForwarding& aReply) { - nsRefPtr callback = static_cast(mRequestCallback.get()); - return NS_SUCCEEDED(callback->NotifyGetCallForwardingSuccess(aReply.results())); + uint32_t count = aReply.results().Length(); + nsTArray> results; + for (uint32_t i = 0; i < count; i++) { + // Use dont_AddRef here because these instances are already AddRef-ed in + // MobileConnectionIPCSerializer.h + nsCOMPtr item = dont_AddRef(aReply.results()[i]); + results.AppendElement(item); + } + + return NS_SUCCEEDED(mRequestCallback->NotifyGetCallForwardingSuccess( + count, const_cast(aReply.results().Elements()))); } bool diff --git a/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h b/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h index 3e9496761889..51b49b0e55e1 100644 --- a/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h +++ b/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h @@ -6,12 +6,14 @@ #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; @@ -19,6 +21,7 @@ using mozilla::dom::MobileConnectionInfo; typedef nsIMobileCellInfo* nsMobileCellInfo; typedef nsIMobileConnectionInfo* nsMobileConnectionInfo; typedef nsIMobileNetworkInfo* nsMobileNetworkInfo; +typedef nsIMobileCallForwardingOptions* nsMobileCallForwardingOptions; namespace IPC { @@ -53,27 +56,83 @@ struct MozCallForwardingOptions : public mozilla::dom::MozCallForwardingOptions }; }; -struct MozCallBarringOptions : mozilla::dom::MozCallBarringOptions +template <> +struct ParamTraits { - 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; + } }; /** @@ -584,166 +643,6 @@ struct ParamTraits } }; -/** - * MozCallBarringOptions Serialize/De-serialize. - */ -template <> -struct ParamTraits -{ - 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 diff --git a/dom/mobileconnection/ipc/MobileConnectionParent.cpp b/dom/mobileconnection/ipc/MobileConnectionParent.cpp index 8950f15a514c..fff51d16efbb 100644 --- a/dom/mobileconnection/ipc/MobileConnectionParent.cpp +++ b/dom/mobileconnection/ipc/MobileConnectionParent.cpp @@ -423,26 +423,12 @@ MobileConnectionRequestParent::DoRequest(const SetCallForwardingRequest& aReques { 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 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 @@ -450,7 +436,8 @@ MobileConnectionRequestParent::DoRequest(const GetCallForwardingRequest& aReques { NS_ENSURE_TRUE(mMobileConnection, false); - return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(), this)); + return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(), + this)); } bool @@ -458,26 +445,11 @@ 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 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 @@ -485,26 +457,10 @@ 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 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 @@ -512,26 +468,9 @@ MobileConnectionRequestParent::DoRequest(const ChangeCallBarringPasswordRequest& { 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 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 @@ -627,104 +566,63 @@ MobileConnectionRequestParent::NotifyGetNetworksSuccess(uint32_t aCount, } NS_IMETHODIMP -MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle aResult, - JSContext* aCx) +MobileConnectionRequestParent::NotifySendCancelMmiSuccess(const nsAString& aServiceCode, + const nsAString& aStatusMessage) { - RootedDictionary 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 value(aCx); - JS::Rooted 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 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 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; + return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode), + nsString(aStatusMessage), + AdditionalInformation(mozilla::void_t()))); } NS_IMETHODIMP -MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle aResults, - JSContext* aCx) +MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithInteger(const nsAString& aServiceCode, + const nsAString& aStatusMessage, + uint16_t aAdditionalInformation) { - uint32_t length; - JS::Rooted object(aCx, &aResults.toObject()); - nsTArray results; + return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode), + nsString(aStatusMessage), + AdditionalInformation(aAdditionalInformation))); +} - if (!JS_IsArrayObject(aCx, object) || - !JS_GetArrayLength(aCx, object, &length)) { - return NS_ERROR_TYPE_ERR; +NS_IMETHODIMP +MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithStrings(const nsAString& aServiceCode, + const nsAString& aStatusMessage, + uint32_t aCount, + const char16_t** aAdditionalInformation) +{ + nsTArray additionalInformation; + for (uint32_t i = 0; i < aCount; i++) { + additionalInformation.AppendElement(nsDependentString(aAdditionalInformation[i])); } - for (uint32_t i = 0; i < length; i++) { - JS::Rooted 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 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 results; + for (uint32_t i = 0; i < aCount; i++) { + results.AppendElement(aResults[i]); } return SendReply(MobileConnectionReplySuccessCallForwarding(results)); diff --git a/dom/mobileconnection/ipc/PMobileConnection.ipdl b/dom/mobileconnection/ipc/PMobileConnection.ipdl index b76393539f95..e0379365039c 100644 --- a/dom/mobileconnection/ipc/PMobileConnection.ipdl +++ b/dom/mobileconnection/ipc/PMobileConnection.ipdl @@ -109,27 +109,37 @@ 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 diff --git a/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl b/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl index 2afa37ac2672..e224bc368e1e 100644 --- a/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl +++ b/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl @@ -54,7 +54,7 @@ struct MobileConnectionReplySuccessMmi struct MobileConnectionReplySuccessCallForwarding { - MozCallForwardingOptions[] results; + nsMobileCallForwardingOptions[] results; }; struct MobileConnectionReplySuccessCallBarring diff --git a/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh b/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh index b57b3ed5321d..ecd8d474270e 100644 --- a/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh +++ b/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh @@ -8,7 +8,7 @@ using nsMobileConnectionInfo from "mozilla/dom/mobileconnection/MobileConnection 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 { @@ -18,7 +18,7 @@ union AdditionalInformation { void_t; uint16_t; nsString[]; - MozCallForwardingOptions[]; + nsMobileCallForwardingOptions[]; }; } // namespace mobileconnection diff --git a/dom/mobileconnection/moz.build b/dom/mobileconnection/moz.build index 3b8ab15eabc5..e32e9f75914f 100644 --- a/dom/mobileconnection/moz.build +++ b/dom/mobileconnection/moz.build @@ -19,10 +19,12 @@ EXPORTS.mozilla.dom.mobileconnection += [ 'ipc/MobileConnectionChild.h', 'ipc/MobileConnectionIPCSerializer.h', 'ipc/MobileConnectionParent.h', + 'MobileCallForwardingOptions.h', ] XPIDL_SOURCES += [ 'interfaces/nsICellInfo.idl', + 'interfaces/nsIMobileCallForwardingOptions.idl', 'interfaces/nsIMobileCellInfo.idl', 'interfaces/nsIMobileConnectionInfo.idl', 'interfaces/nsIMobileConnectionService.idl', @@ -35,6 +37,7 @@ UNIFIED_SOURCES += [ 'ipc/MobileConnectionChild.cpp', 'ipc/MobileConnectionIPCService.cpp', 'ipc/MobileConnectionParent.cpp', + 'MobileCallForwardingOptions.cpp', 'MobileCellInfo.cpp', 'MobileConnection.cpp', 'MobileConnectionArray.cpp', diff --git a/dom/tests/mochitest/localstorage/mochitest.ini b/dom/tests/mochitest/localstorage/mochitest.ini index 3b3c50c4be3e..1be37ddfcd6d 100644 --- a/dom/tests/mochitest/localstorage/mochitest.ini +++ b/dom/tests/mochitest/localstorage/mochitest.ini @@ -22,7 +22,7 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 793211 # b2g(needs http [test_bug600307-DBOps.html] [test_bug746272-1.html] [test_bug746272-2.html] -skip-if = os == "android" # bug 962029 +skip-if = os == "android" || toolkit == 'gonk' # bug 962029 [test_cookieBlock.html] skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(bug 913706) b2g-desktop(bug 913706) [test_cookieSession.html] diff --git a/services/mobileid/MobileIdentityManager.jsm b/services/mobileid/MobileIdentityManager.jsm index dcf5dc3f1cf2..ec46a38d178d 100644 --- a/services/mobileid/MobileIdentityManager.jsm +++ b/services/mobileid/MobileIdentityManager.jsm @@ -417,7 +417,7 @@ this.MobileIdentityManager = { onUICancel: function() { log.debug("UI cancel"); if (this.activeVerificationFlow) { - this.activeVerificationFlow.cleanup(true); + this.rejectVerification(); } }, @@ -467,7 +467,7 @@ this.MobileIdentityManager = { } this.activeVerificationDeferred.reject(aReason); this.activeVerificationDeferred = null; - this.cleanupVerification(true); + this.cleanupVerification(true /* unregister */); }, resolveVerification: function(aResult) { @@ -479,11 +479,11 @@ this.MobileIdentityManager = { this.cleanupVerification(); }, - cleanupVerification: function() { + cleanupVerification: function(aUnregister = false) { if (!this.activeVerificationFlow) { return; } - this.activeVerificationFlow.cleanup(); + this.activeVerificationFlow.cleanup(aUnregister); this.activeVerificationFlow = null; }, diff --git a/services/mobileid/tests/xpcshell/test_mobileid_manager.js b/services/mobileid/tests/xpcshell/test_mobileid_manager.js index 920ec8bc58b0..6e7d84f69530 100644 --- a/services/mobileid/tests/xpcshell/test_mobileid_manager.js +++ b/services/mobileid/tests/xpcshell/test_mobileid_manager.js @@ -1459,3 +1459,54 @@ add_test(function() { } }); }); + +add_test(function() { + do_print("= Cancel verification flow ="); + + do_register_cleanup(cleanup); + + do_test_pending(); + + let _sessionToken = Date.now(); + + let ui = new MockUi(); + ui.verificationCodePrompt = function() { + MobileIdentityManager.onUICancel(); + }; + MobileIdentityManager.ui = ui; + + let credStore = new MockCredStore(); + MobileIdentityManager.credStore = credStore; + + let client = new MockClient(); + MobileIdentityManager.client = client; + + let promiseId = Date.now(); + let mm = { + sendAsyncMessage: function(aMsg, aData) { + do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData)); + + // Check result. + do_check_eq(aMsg, GET_ASSERTION_RETURN_KO); + do_check_eq(typeof aData, "object"); + do_check_eq(aData.promiseId, promiseId); + do_check_eq(aData.error, DIALOG_CLOSED_BY_USER); + + do_test_finished(); + run_next_test(); + } + }; + + addPermission(Ci.nsIPermissionManager.ALLOW_ACTION); + + MobileIdentityManager.receiveMessage({ + name: GET_ASSERTION_IPC_MSG, + principal: PRINCIPAL, + target: mm, + json: { + promiseId: promiseId, + options: {} + } + }); +}); + diff --git a/testing/marionette/client/marionette/runner/mixins/reporting.py b/testing/marionette/client/marionette/runner/mixins/reporting.py index 0b6c7f0b64e3..b6ea094b2d1d 100644 --- a/testing/marionette/client/marionette/runner/mixins/reporting.py +++ b/testing/marionette/client/marionette/runner/mixins/reporting.py @@ -11,6 +11,7 @@ import pkg_resources import sys import time +from mozlog.structured.structuredlog import get_default_logger import mozversion from xmlgen import html from xmlgen import raw @@ -247,9 +248,9 @@ class HTMLReportingTestResultMixin(object): def gather_debug(self): debug = {} try: - self.marionette.switch_context(self.marionette.CONTEXT_CHROME) + self.marionette.set_context(self.marionette.CONTEXT_CHROME) debug['screenshot'] = self.marionette.screenshot() - self.marionette.switch_context(self.marionette.CONTEXT_CONTENT) + self.marionette.set_context(self.marionette.CONTEXT_CONTENT) debug['source'] = self.marionette.page_source self.marionette.switch_to_frame() debug['settings'] = json.dumps(self.marionette.execute_async_script(""" @@ -260,6 +261,7 @@ req.onsuccess = function() { marionetteScriptFinished(req.result); }""", special_powers=True), sort_keys=True, indent=4, separators=(',', ': ')) except: - pass + logger = get_default_logger() + logger.warning('Failed to gather test failure debug.', exc_info=True) return debug